Files
khosra/ideas/exploration.md
T
bdeshiandClaude Opus 5 ec6e9838f0 rename docs/ to harness/, and reserve docs/ for the reader
docs/content-model.md opens with "Engine specification". It is also where the
rule lives that a leading underscore makes a file unaddressable — and the human
who owns this site did not know that rule, because nothing in this repository is
addressed to an author. Twelve documents named docs/ while being exclusively
about building the parser is a signpost pointing at the wrong room.

Naming the directory for its audience makes the gap visible instead of hiding it.
docs/ is now reserved and deliberately absent: an empty docs/ is an honest
statement that end-user documentation does not exist, where docs/ full of parser
specs was a claim that it did.

HARNESS.md stays at the root. Root holds the three entry points — README.md for a
human, CLAUDE.md for an agent, HARNESS.md for whoever maintains the machine — and
harness/README.md is the map of the directory, so moving the guide inside would
have collided with it for nothing.

Mechanical and wide: 100 path references across 24 files. Every verify.sh gate
that names a doc by path, the directory lists the dangling-path and ADR-number
gates scan, surface.sh's output target, the Makefile, CLAUDE.md's read order, the
skill, four commands, and two Go package comments. A first pass with a shell loop
silently edited only four files and the rest still said docs/; the fix was to
write the file list out and check the remaining count was zero rather than trust
the loop's exit status.

No rule, threshold, gate or obligation moved — this is a rename, and the gates
demonstrated it twice: they stayed green on the new paths, and the ADR-number gate
caught ADR-0082 before the entry existed.

Deferred, both on the human's call: the end-user documentation site itself, which
wants its own decision about where it lives and whether its claims are gated; and
moving examples/ under docs/, since demo-site is a live site root that verify.sh,
the coverage test and make demo all point at, and moving it would couple a rename
to a design nobody has made.

31 files, +146/-106.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 20:11:06 +06:00

6.3 KiB
Raw Blame History

Exploration catalog

Status: catalog — the verdicts are inside, one row each

Possible futures. Nothing here is committed. Presence in this list is not permission to build.

= highest fit-to-effort for this project's identity and values.

The leaf/trunk test — apply before any of this gets built

Definitions: architecture.md invariant 7. Leaf → buildable when wanted. Trunk → waits for an explicit human decision, in an ADR, on purpose.

Known trunks: ActivityPub, IPFS, Solid, hosted annotation servers, CRDT-backed editing. Sovereignty test for any of them: if this vanishes, do I lose data, or only convenience?

Use /leaf <topic> to get a verdict written into this file.

Verdicts

Item Verdict Reduces to Note
(empty — filled by /leaf)

Catalog

IndieWeb — Micropub★, Microsub, Webmention, WebSub, microformats2, IndieAuth, rel=me, PESOS/POSSE, Bridgy and Bridgy Fed, Vouch.

Protocols — Gemini + gemtext★, Gopher, Nostr (NIP-23 long-form), ActivityPub (trunk), AT Protocol, SSB, Solid (trunk), IPFS (trunk), Hypercore, content negotiation (one URL → many formats).

Small web and discovery — webrings, guestbooks, 88×31 buttons, finger, tildeverse, OPML blogroll★, full-text feeds★ (for indie search indexing: Marginalia, Kagi Small Web, ooh.directory, indieblog.page, feedle, powRSS), random / "surprise me", /now pages.

Reading and annotation — Web Annotation + Hypothesis (hosted = trunk), reading progress, interlinear and parallel translation.

Permanence — outbound-link archiving★, WARC self-archive, Memento over git, permalink discipline, exposed revision history.

Identity and integrity — rel=me, Keyoxide, signing (age/minisign/PGP), C2PA, DIDs.

Feeds and data — RSS/Atom, JSON Feed, h-feed, OPDS (publication catalog), JSON-LD and schema.org, OpenGraph, Dublin Core, sitemaps, RSS-to-email.

Page as program — Ink★, Twine, Inform 7, PICO-8/TIC-80, Godot HTML5 embeds, explorable explanations, TiddlyWiki and single-file artifacts.

Print — Typst, Pandoc, EPUB and PDF chapbooks, on-demand anthologies.

Client side — View Transitions★ (palette-shift-as-navigation), Houdini, Canvas, WebGL, WebGPU, modern CSS, WASM, islands, HTMX, Web Components, PWA offline, prefetch, accessibility and prefers-reduced-motion.

Build time — SQLite FTS5, Pagefind, sqlite-wasm + OPFS, Djot, Templ, libvips, ThumbHash and BlurHash, content-addressed and Merkle builds, Datasette, CRDTs (heavy, trunk).

Aesthetic — dithering and palette Stage★, ANSI/PETSCII, teletext, demoscene, e-ink View.

Valuesrobots.txt / ai.txt (training control), llms.txt (low proven impact), sustainable and low-carbon web, privacy-respecting analytics or none at all, sovereignty, sneakernet and QR offline distribution.

Standing notes

  • Bengali tokenisation for search is the one item here nobody else will solve for you. Treat it as original work, not as a checkbox inside "add search."
  • Micropub before an admin panel. It buys an ecosystem of existing editors for the price of one endpoint, and it composes with git instead of fighting it.
  • Gemini output is nearly free once the View layer exists, and it validates the claim that a View can target something other than HTML. Good early proof, low cost.

Shapes recorded before anything asked for them

Moved out of harness/content-model.md, which now describes only what the parser accepts. Each is intent, not a plan: the shape is decided by whatever eventually builds it, and being written here is not permission.

Galleries, collections [spec]

Both are a Query over bundle metadata with a stable sort; neither justifies a new primitive. A gallery is a Query plus an image View. Related posts are a Query with a scoring function, not a stored graph.

Taxonomies [spec]

Two kinds, deliberately. Recorded intent (ideas/deferred-decisions.md), not built.

tags are one global namespace across every type. /tags/{tag}/ lists everything carrying the tag; /{section}/tags/{tag}/ narrows it; listing views group results by type so a busy tag stays readable. Cross-type discovery is the point — one tag spanning a comic, a poem and a photo essay is a feature here, not noise. Term slugs are derived by locale and overridable by hand (ADR-0015).

Declared taxonomies are structural: a fixed term set that changes engine behaviour, declared on the type — series for ordering, medium for art, genre for writing. These never enter the tag pool. The test: a tag is free-form and cross-cutting, a declared taxonomy has known terms and drives behaviour.

Feeds follow the same shape: /tags/{tag}/feed.xml comes free from the same Query as the listing.

Time-dependent presentation [spec]

Anything derivable from a page plus the current clock is computed by a Stage, never stored in content: an "this article is old" banner compares date to now, relative dates likewise. Because renders are cached (ADR-0005), such a Stage also declares how long its output stays true — a banner until date+threshold, a relative date for a minute — and the cached entry expires then. Future-dated publication is the same shape seen from the other side: the page becomes reachable at a moment nobody is requesting it.

Below the site level [spec]

Section-level and bundle-level settings are not built: a bundle's own frontmatter covers it, and nothing reads a section override yet. The parked shape is site → section → bundle, nearest explicit value winning (ideas/deferred-decisions.md).

Level Where it lives
site site.yaml at the site root
section, and any enclosing section that directory's _index.<lang>.md frontmatter
bundle the bundle's own frontmatter

The cascade carries stage toggles, view selection, taxonomy defaults, cache flags, and metadata defaults — declared keys only, never arbitrary engine internals. Stages run on everything by default and are switched off by a cascade key, not by a predicate inside the stage: a stage that finds nothing to do returns early on content shape ("no images here"), which has nothing to do with type.

This is also how a template is chosen: type default, then section override, then the bundle's view (ADR-0019).