One idea at a time: definition, necessity, priority, layer, recommendation. Every row is now shipped, scheduled, parked with a trigger, or dropped with a reason — so both tracking files are gone rather than left as a parallel backlog. Roughly a third already shipped. A quarter needed only a theme fragment or CSS, including several the list assumed were features: arbitrary `theme.*` frontmatter attributes already reach templates through Extra (verified), native lazy loading already ships and is deliberately absent on lead figures, and in-page timelines are a theme-defined container. roadmap.md gains an "Order of work" — nine bodies of work in sequence, because the sections this review added had accumulated without one. Item 0 is a decision, not work: core sits at ~2965 of 3000 and logging alone wants the remainder, so discover.go moves out *and* the ceiling rises with an ADR. feed.go and web/extras.go cannot move; they are resolver cases, and three parked items now wait on that same seam decision. Two ADRs came out of it. ADR-0083: the dependency rule described a practice it forbade. "Stdlib first, always" and "usually 40 lines of stdlib" would, read literally, have argued against all five modules here — every one is a format or algorithm somebody else specified, and their allowlist comments say so. Surfaced when this agent proposed hand-rolling Reed–Solomon for QR encoding. The test is now whether you can verify it, not whether you can write it, with compute-versus-hold as the counterweight. conventions.md and allowed-deps.txt contradicted it and were realigned. ADR-0084: the Effect primitive said every Effect is "idempotent and re-runnable from scratch" — true of derivatives, false of anything outbound, since a sent message cannot be recalled. Split into artifact-producing and outbound, the latter idempotent only against a delivery ledger, at-least-once with a dedupe key, and ledgers in a -state directory distinct from the disposable cache. Asked for as forward-looking design so webmentions need no redesign; recorded as a shape rather than built, the way extensions.md records the Extension struct. Also fixed a STATUS claiming Effects were "not buildable yet" when the derivative pass has inhabited them since ADR-0042. Findings that were defects rather than ideas: the Atom feed emits no <author>, which RFC 4287 requires. HTML comments in content are published verbatim — verified — so anything commented out is already public, and a check warning is scheduled rather than the engine deleting authored bytes. `Page` has no Date, so a theme cannot mark up dt-published or show an article's own date. A frontmatter naming rule after this agent proposed `archive` alongside the accepted `archived`: no near-homograph keys, and name the benefit rather than the vendor. reference/microformats-and-indieweb.md is new and is the reference asked for — microformats2 properties and IndieWeb rel values mapped to where a theme puts them, with spec URLs, marked scheduled. rel="me" is the highest-value lowest-cost item in that space and needs no endpoint at all. Four things this agent got wrong and the human caught: asserting "the engine never fetches" from a sentence scoped to the content repo, twice; inventing a data-sovereignty argument for an item he had filed as "a cool geeky thing", when the raw Markdown in his git already is the sovereignty; the archive naming; and claiming microformats could be fully implemented today. 15 files, +556/-385. No code changed. Nothing was scheduled that this agent could not name a consumer for. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
136 lines
10 KiB
Markdown
136 lines
10 KiB
Markdown
# Harness doc map
|
|
|
|
The docs an agent reads to build the engine. Read the one you need. Do not read them all.
|
|
|
|
This directory was `docs/` until ADR-0082 renamed it: `docs/` is reserved for documentation written for
|
|
whoever *uses* khosra, which does not exist yet. Everything here is engine- and agent-facing — a
|
|
specification, a rule, or a record — and none of it is written for an author.
|
|
|
|
| Doc | Contains | Mutability |
|
|
|---|---|---|
|
|
| `architecture.md` | The six primitives, invariants, per-primitive STATUS | Only via an ADR |
|
|
| `state.md` | What exists now: inventory, earn-it counters, latent items | Every feature |
|
|
| `decisions.md` | ADR log — one entry per load-bearing choice | Append-only. One exception: a superseded entry's **Status** line is annotated in place to name what replaced it, because a reader arriving at the older entry has no other way to learn it was replaced. Never the Decision text — that stands as history |
|
|
| `roadmap.md` | Arcs, earn-triggers, the core freeze point | When an arc completes |
|
|
| `content-model.md` | On-disk layout, frontmatter, post types, permalinks — **what the parser accepts today**, never a plan | When the disk format changes |
|
|
| `conventions.md` | Go style floor, package layout, perf and test rules | Rarely; via ADR if contested |
|
|
| `extensions.md` | Extension/plugin contract: target shape + earn gates | When earned or frozen |
|
|
| `toolchain.md` | Versions and agent-tooling contracts this was built against | When you deliberately move a version |
|
|
| `theme-contract.md` | What the engine promises a theme; the only theme-facing obligation | When the contract is extended — additively only |
|
|
| `context-economy.md` | How the agent spends context: what to read, in what form, and the floor no saving may cross | When a technique or a gate for one changes |
|
|
| `surface.md` | **Generated.** Every top-level declaration with its line — read before opening source | Never by hand; `make surface` |
|
|
|
|
Sibling folders sit **outside** `harness/` because they are storage, not working material:
|
|
`../ideas/` (parked ideas, any topic, and `exploration.md` — the catalog of engine features nobody has asked
|
|
for yet) and `../reference/` (durable facts from conversation). Write there when asked to park something;
|
|
open a file only when the human names it. Nothing sweeps them.
|
|
|
|
## Topic ownership — read before you assert
|
|
|
|
The inverse of the refresh triggers: those say what to update *after* changing code, this says what
|
|
to read *before* writing a rule — including when you are only writing an ADR or a comment about it.
|
|
Nearly always exactly one doc; if two seem to apply, the single-source rule is already broken and
|
|
that is the finding to report.
|
|
|
|
| About to assert something about… | Read first |
|
|
|---|---|
|
|
| plugins, extensions, features-as-packages, stage phases | `extensions.md` |
|
|
| a primitive, an invariant, or what is "earned" | `architecture.md` + counters in `state.md` |
|
|
| URL paths, permalinks, frontmatter, on-disk layout, post types | `content-model.md` (+ ADR-0008) |
|
|
| Go style, package layout, file/function size, test shape | `conventions.md` + `scripts/budgets.env` |
|
|
| a dependency | `scripts/allowed-deps.txt` + ADR-0007 |
|
|
| a budget or a gate | `scripts/budgets.env` + `scripts/verify.sh` |
|
|
| the untrusted boundary, comments, webmentions, form input | ADR-0003 + `extensions.md` |
|
|
| language, translation, fallback | ADR-0004 + ADR-0009 |
|
|
| deploy, containers, external services | ADR-0010 |
|
|
| whether a future feature is worth building | `ideas/exploration.md` + `roadmap.md` |
|
|
| **which list owns a piece of pending work** | four kinds, deliberately not merged: **might be built** → `ideas/exploration.md` — the catalogue, plus parked and dropped items each with a trigger or a reason · **is scheduled** → `roadmap.md`, whose "Order of work" says which is next · **is broken and known** → the Latent list in `state.md` · **waits on an observation** → `ideas/deferred-decisions.md` "Triggers — the one list". Merging them would flatten four levels of authority and make pending work expensive to ignore, which is the property that keeps `ideas/` safe to keep |
|
|
| what to build next | the harness first (`CLAUDE.md` §1 read order) and `git log` for what landed, **then** `.scratch/continue.md` for the continuation point and `roadmap.md` for the arc. The handoff is temporary and ungated: check anything it calls pending with `git log -- <the path it names>` before planning from it |
|
|
| how the harness works — a gate, counter, budget, the loop | `HARNESS.md` + `scripts/verify.sh` + `CLAUDE.md` |
|
|
| what one commit contains, and when one happens | `conventions.md` "Git" (shape) + `CLAUDE.md` §4 (cadence, ADR-0052) |
|
|
| how to read, search, or report without wasting context | `context-economy.md` (+ ADR-0053) |
|
|
| a tool version, or why agent tooling stopped working | `toolchain.md` |
|
|
| templates, layout, presentation, what a theme can rely on | `theme-contract.md` (+ ADR-0019, ADR-0023) |
|
|
|
|
## Single-source rule
|
|
|
|
Each fact lives in exactly one doc. Need it elsewhere? Link. This binds ADRs too: an ADR restating
|
|
a rule an owning doc already carries is a duplicate, not a decision — delete it and amend the owner.
|
|
|
|
Values that have drifted before, and their one home. Everywhere else names the concept and points
|
|
here; nothing else may state the value:
|
|
|
|
| Fact | Sole home |
|
|
|---|---|
|
|
| Earn-it thresholds (transforms, routes, views, extensions) | the counters table in `state.md` |
|
|
| LOC ceilings, size warnings, dependency cap, the `CLAUDE.md` ceiling | `scripts/budgets.env` |
|
|
| The permalink path shape | `content-model.md` (decision recorded in ADR-0008) |
|
|
| Which language is at the root, and the prefix form | ADR-0009 |
|
|
| The leaf/trunk definition | `architecture.md` invariant 7 |
|
|
| The sovereignty test | `roadmap.md` Governors |
|
|
| Package layout and the forbidden package names | `conventions.md` |
|
|
| What exists in the code right now | `state.md` inventory |
|
|
| What un-defers a deferred decision | the Triggers table in `ideas/deferred-decisions.md` |
|
|
|
|
A value restated in two places is not redundancy for safety; it is a future contradiction waiting for
|
|
whichever copy gets edited alone.
|
|
|
|
`state.md` is the only doc describing the present; the rest describe rules, shapes, or intentions.
|
|
When code and `state.md` disagree, the code wins and `state.md` is wrong.
|
|
|
|
## Refresh triggers
|
|
|
|
Update in the Document step of the change that caused them. Not later.
|
|
|
|
| Change | Update |
|
|
|---|---|
|
|
| Any code change at all | `state.md` inventory — in the same commit, which is what `verify.sh` compares (ADR-0057) |
|
|
| New transform, route, view, extension, or dependency | the counters table in `state.md` |
|
|
| A choice expensive to reverse | new ADR in `decisions.md` |
|
|
| A primitive becomes real (earned) | STATUS line in `architecture.md` + counters |
|
|
| New frontmatter field, post type, or path shape | `content-model.md` |
|
|
| New dependency approved | `scripts/allowed-deps.txt` + ADR |
|
|
| Budget raised | `scripts/budgets.env` + ADR — once the first feature has shipped. While the harness is still being tuned, edit in place. |
|
|
| A latent item fixed | remove from the Latent list in `state.md` |
|
|
| A planned item completed | **after** the commit lands, delete it from `.scratch/continue.md` and note anything learned that changes a later one. Never during Document: a handoff written mid-change describes the plan, and an amend moves the commit under it — which is how one was written at 01:06 saying a trim awaited a yes that the 01:12 commit had already done |
|
|
| Arc finished | `roadmap.md` + a retro line in `state.md` |
|
|
| Catalog item accepted or rejected | verdict line in `ideas/exploration.md` |
|
|
| `CLAUDE.md`, `scripts/` or `.claude/` changed | `HARNESS.md`, same change. Enforced by `verify.sh`. |
|
|
| A tool version deliberately moved, or a new external contract relied on | `toolchain.md` |
|
|
| The theme contract extended, or embedded templates changed | `theme-contract.md`, same change. Enforced by `verify.sh`. |
|
|
| A request spans engine and theme | contract extension here + a written note of the theme's part; never the theme itself |
|
|
| A new gate, counter, or budget added | `HARNESS.md` "Why the pieces exist" + a row in one of these tables |
|
|
| A top-level declaration added, renamed or moved | nothing by hand — `make surface`, which `verify.sh` then compares |
|
|
| A rule, value, name or path changed | grep the repo for the old form; every doc naming the concept, same change |
|
|
| The disk contract changed | `content-model.md` + `testdata/` fixtures + a written migration step for the site root, which the engine repo cannot touch |
|
|
| A doc or ADR mandates what a change made optional | supersede the ADR; do not reword it in place |
|
|
| A request reversed a recorded decision | new ADR, or supersede the old one — the request does not win by being newer |
|
|
| A request exceeded a convention on purpose | note the deviation where the convention lives |
|
|
| An idea floated, not built now | a file in `../ideas/` + its index line. Adopted later: `Status: adopted → <where>` |
|
|
| A fact worth keeping surfaced in conversation | a file in `../reference/` + its index line, stating how it was established |
|
|
|
|
## Staleness
|
|
|
|
`/refresh-docs` reconciles docs against code and reports drift. Run it after a burst of work,
|
|
before a new arc, and any time a doc surprises you.
|
|
|
|
## House style
|
|
|
|
Present tense. Terse. Written for a reader who has forgotten everything, including their own
|
|
reasoning. No changelog prose, no "recently we…", no preamble. Delete a line before rewriting it.
|
|
A doc needing a table of contents is too long.
|
|
|
|
## Compression contract
|
|
|
|
Shortening a harness doc removes **words, never instructions**. Same rules, gates, thresholds,
|
|
triggers and table rows before and after; the agent must act identically. Redundancy between
|
|
`CLAUDE.md` and `SKILL.md` is deliberate — the constitution is always loaded, the skill is not —
|
|
and is not duplication to be collapsed.
|
|
|
|
Deleting a rule, adding one, or narrowing one is a rule change: it needs its own decision and its
|
|
own reason, and it never rides along in a compression pass.
|
|
|
|
Verify before reporting a saving: table rows, headings, list items and checklist boxes must match
|
|
the pre-pass file (`git diff --stat`, or a snapshot if the change is uncommitted). Report word count,
|
|
not lines — reflowing prose shrinks lines without saving anything.
|