From 441a8151ab0ac6aa62df0627c7e11ffda14c0489 Mon Sep 17 00:00:00 2001 From: Torben Nehmer Date: Fri, 11 Sep 2026 11:58:34 +0200 Subject: [PATCH] fix(docs): AGENTS.md-Contract-Prosa als Sitzungsarbeit klargestellt, doc-pull-through-Instruction (schliesst #90) Files changed: - AGENTS.md - CHANGES.md - VERSION - instructions/dev/doc-pull-through.md - instructions/dev/stack-close/SKILL.md - instructions/dev/stack-dev/SKILL.md - instructions/dev/testing-conventions.md - instructions/dev/version-parts.md - tools/chemenu/commands/docs_verify.py --- AGENTS.md | 13 +++-- CHANGES.md | 42 +++++++++++++++- VERSION | 2 +- instructions/dev/doc-pull-through.md | 67 +++++++++++++++++++++++++ instructions/dev/stack-close/SKILL.md | 16 +++--- instructions/dev/stack-dev/SKILL.md | 12 ++++- instructions/dev/testing-conventions.md | 2 +- instructions/dev/version-parts.md | 2 +- tools/chemenu/commands/docs_verify.py | 11 +++- 9 files changed, 148 insertions(+), 19 deletions(-) create mode 100644 instructions/dev/doc-pull-through.md diff --git a/AGENTS.md b/AGENTS.md index 9db857c..613a26a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -289,11 +289,14 @@ Changes to this schema, the contracts, the instruction layer, `tools/wikitool`, READMEs go in [CHANGES.md](CHANGES.md) - never in an inline version-history table here. Wiki *content* operations are logged separately via `tools/wikitool log append` into `kb/log.md`. -**A stack change is not finished until the human docs describe it.** `README.md`, `EVALS.md` -and `tools/README.md` are part of the change that introduced a stage, a command or a workflow, -not follow-up work: nobody comes back for them, and a document that describes a repo which no -longer exists is worse than none. The mechanical half - command tables, contracts, ignore -canaries - is checked by `tools/wikitool docs verify`; the prose half is yours. +**A stack change is not finished until the human docs describe it.** `README.md`, `EVALS.md`, +`tools/README.md`, `tools/CONTRACT.md` and the touched `/CONTRACT.md` are part of the +change that introduced a stage, a command or a workflow, not follow-up work: nobody comes back +for them, and a document that describes a repo which no longer exists is worse than none. What +`tools/wikitool docs verify` mechanically checks is exactly what its own `docs verify` row in +[tools/CONTRACT.md](tools/CONTRACT.md) lists - no more. **Every cell's text is outside that +check** - a command table entry's description, an error contract's wording, a stage contract's +prose - and is therefore session work, the same as the three README-shaped files. `docs/` pages are held to a different clock than those three. A README goes stale on every new flag; a `docs/` page goes stale only when the reasoning it wrote down stops holding - a gate diff --git a/CHANGES.md b/CHANGES.md index 61c5aa7..1054d74 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -35,7 +35,7 @@ dev-checkout concern - readable here, never shipped as something to parse. --- -## 5.0.0-beta.11 - 2026-09-11 - MCP submit-Tool: Quarantäne-Schreibpfad mit Upload Review Gate (schliesst #32) +## 5.0.0-beta.12 - 2026-09-11 - AGENTS.md-Changelog-Absatz korrigiert: Contract-Prosa ist Sitzungsarbeit, doc-pull-through-Instruction ergaenzt **Author:** Torben Nehmer @@ -64,6 +64,7 @@ dev-checkout concern - readable here, never shipped as something to parse. - Telemetrie-Default nach Installationsform, Byte-Deckel und Session-Retention - tools/CONTRACT.md: raw accept Doku auf Datums-Shard und Capture-Felder nachgezogen (schliesst #89) - MCP submit-Tool: Quarantäne-Schreibpfad mit Upload Review Gate (schliesst #32) +- AGENTS.md-Changelog-Absatz korrigiert: Contract-Prosa ist Sitzungsarbeit, doc-pull-through-Instruction ergaenzt @@ -1177,6 +1178,45 @@ Geändert: `tools/chemenu/upload.py` (neu), `tools/chemenu/commands/upload_cmd.p `instructions/ingest-queue.md` (neu), `raw/CONTRACT.md`, `docs/why-gates-are-code.md`, `INSTALL-MCP.md`, `README.md`. Schließt #32. +**AGENTS.md behauptete, `docs verify` prüfe die Contract-Prosa selbst - das stimmt nicht (#90).** +`check_cli_readme()` prüft nur, ob der gebacktickte Pfad einer Tabellenzeile registriert ist, nie +den Rest der Zelle: eine ausgetauschte Kommandobeschreibung oder ein neues `--flag` bleiben +unsichtbar, und `TABLE_CELL_RE` läuft über das ganze Dokument statt über eine abgegrenzte +"Kommandotabelle". `AGENTS.md` § Changelog zählte trotzdem "command tables, contracts, ignore +canaries" als maschinell geprüft auf und grenzte die Sitzungspflicht auf `README.md`/`EVALS.md`/ +`tools/README.md` ein - `tools/CONTRACT.md` und jedes `/CONTRACT.md` standen damit auf +keiner Liste, die je jemand nachzieht. + +Der Absatz nennt jetzt nur noch, was `docs verify`s eigene Zeile in `tools/CONTRACT.md` +tatsächlich auflistet (Verweis statt Kopie), und macht jede Zellenprosa - Kommandotabelle, +Fehlerkontrakt, Stage-Contract - ausdrücklich zur Sitzungsarbeit, neben den drei README-artigen +Dateien. Die Docstring von `check_cli_readme()` behauptet nicht mehr, sie prüfe +"tools/CONTRACT.md's command table" - sie beschreibt jetzt, dass `TABLE_CELL_RE` das ganze +Dokument scannt und nur den gebacktickten Pfad liest, nie die restliche Zelle. + +Neue Instruction [instructions/dev/doc-pull-through.md](instructions/dev/doc-pull-through.md) +(dev-only) listet je berührter Fläche, welches Dokument eine Behauptung darüber trägt: beide +Tabellen in `tools/CONTRACT.md`, der berührte `/CONTRACT.md`, `AGENTS.md` bei +verschobener Regel/Gate/Invariante, die README-artigen Dateien, `docs/` bei verschobener +Begründung. `stack-dev/SKILL.md` bekommt dafür einen neuen Schritt 5 zwischen Versionsbump und +Verify/Publish (jetzt Schritt 6) - ein Satz plus Link, die Liste bleibt in der Instruction; die +Katalog-Liste in Schritt 2 und `stack-close/SKILL.md` Schritt 3 nennen die neue Instruction bzw. +die Contracts jetzt ebenfalls. `version-parts.md` und `testing-conventions.md` korrigieren dabei +zwei schon vorher falsche Schrittverweise auf `stack-dev` (Schritt 3 -> 4, Schritt 4 -> 6), +gefunden beim Nachziehen der Umnummerierung. + +**MINOR, kein neuer Boundary-Crossing:** additiv und drop-in in beide Richtungen - eine +bestehende Instanz kopiert die neue Instruction und die korrigierte Prosa über sich, ohne +Migration oder Hand-Arbeit; kein Feld, kein Kommando, kein Flag ändert sich. Der Kandidat trägt +seine `--breaking`-Zeile bereits aus einem früheren Bump; diese Änderung fügt keine neue hinzu. + +Geändert: `AGENTS.md`, `tools/chemenu/commands/docs_verify.py`, +`instructions/dev/doc-pull-through.md` (neu), `instructions/dev/stack-dev/SKILL.md`, +`instructions/dev/stack-close/SKILL.md`, `instructions/dev/version-parts.md`, +`instructions/dev/testing-conventions.md`. Verifiziert: `tools/wikitool docs verify`, +`tools/wikitool instructions verify` (nach `instructions sync`), volle `pytest`-Suite (1185 +passed). Schließt #90. + --- ## 4.7.4 - 2026-09-04 - bootstrap.md nennt den session-id-WARN nach frischem Bootstrap explizit als erwartet diff --git a/VERSION b/VERSION index 96d2d86..8777583 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.0.0-beta.11 +5.0.0-beta.12 diff --git a/instructions/dev/doc-pull-through.md b/instructions/dev/doc-pull-through.md new file mode 100644 index 0000000..582f68e --- /dev/null +++ b/instructions/dev/doc-pull-through.md @@ -0,0 +1,67 @@ +--- +type: types/instruction.md +name: doc-pull-through +description: Which document makes a claim about a surface you are about to change - a wikitool command's behaviour, a stage's rules, an AGENTS.md rule/gate/invariant, a README-shaped human doc, a docs/ page's reasoning - and so needs updating in the same session, since tools/wikitool docs verify never reads a cell's prose. +--- +# Update every document that makes a claim about the surface you changed + +`tools/wikitool docs verify` is a hard oracle over presence, not content: it checks that a +command is *listed*, that a contract *exists*, that an ignore canary is (or isn't) caught - never +what a table cell, a contract section, or a README paragraph actually *says*. A command's flag +can change, a gate's threshold can move, a contract's wording can go false, and every one of +those checks stays green (Gitea #90; Gitea #91 narrows what the command-table check matches, but +adds no reading of cell content). Content quality of every document below is therefore session +work, the same duty AGENTS.md's Changelog section states for `README.md`/`EVALS.md`/ +`tools/README.md` - this instruction exists because that duty used to stop at those three files +while the contracts rotted next to a green check (ten stale error-contract rows accumulated this +way; see Gitea #89 for one). + +## When to run + +Before `tools/wikitool docs verify`/`publish` in a `stack-dev` session that changed behaviour - +`stack-dev` step 5 sends you here. Read the table below and update every row whose surface you +touched; a row that does not apply needs no action. + +## Steps + +1. **Name the surface(s) you changed.** A `wikitool` command's flags or behaviour, a stage's + rule, an `AGENTS.md`-level rule/gate/invariant, a workflow a human runs by hand, or the + reasoning behind a design decision - one change can touch more than one row. + +2. **For each surface, update every document the table names - not only the one you were already + editing:** + + | Touched surface | Document(s) that make a claim about it | + |---|---| + | A `wikitool` command's behaviour, flags, or interface | Both tables in [tools/CONTRACT.md](../tools/CONTRACT.md): the command reference row, and its per-command error contract (exit codes, atomicity, retry-safety) | + | A stage's authoring rules (`raw/`, `kb/`, `types/`, `reports/`, `work/`, `tools/`, `instructions/`) | The touched `/CONTRACT.md` | + | A rule, gate, or invariant `AGENTS.md` itself states | The relevant `AGENTS.md` section (Invariants, Gates, File naming, Routing, ...) | + | A workflow, stage, or command a human operates by hand | Whichever of `README.md`, `EVALS.md`, `tools/README.md`, `INSTALL.md`, `DEVELOPMENT.md` names it - AGENTS.md § File naming says which document is for which reader | + | The reasoning behind a gate, boundary, or design decision | The `docs/` page that carries it, if one exists (AGENTS.md § File naming lists all four) | + | A skill's own step sequence or catalogue | The skill's `SKILL.md` source under `instructions//` or `instructions/dev//` | + +3. **Do not re-derive what `docs verify` already checks mechanically** - existence, table-row + membership, ignore-canary state. That enumeration lives once, in + [tools/CONTRACT.md](../tools/CONTRACT.md)'s own `docs verify` row; copying it here would be a + second copy that drifts, the exact failure this instruction exists to describe (Gitea #90). + This instruction is only about the prose no check reads. + +## Decision points + +- **The change touched no document in the table?** Nothing to do - not every stack change moves + a claim. A pure bugfix with an unchanged interface is the common case. +- **Unsure whether a `docs/` page's reasoning moved?** Read it. A `docs/` page carries no + normative sentence and nothing verifies it by construction (AGENTS.md § File naming), so an + unsure guess defaults to reading the page rather than skipping the question - + [`stack-close`](stack-close/SKILL.md) step 3 asks it again at the end of the session as a + backstop, not as the only time it is asked. +- **The surface is a whole new stage, collection, or gate?** The table's rows are the steady + state; a new row-worthy category is itself a change to this instruction - add the row here + rather than leaving the next session to rediscover the gap. + +## Scope + +Applies to `stack-dev` sessions only - wiki content changes have their own provenance and +cross-reference rules (`kb/CONTRACT.md`, `wiki-manage`), which already pull the relevant pages +through as part of the normal skill. Not a replacement for `stack-close` step 3, which re-asks +the `docs/`-staleness question after publish as the second, session-final check. diff --git a/instructions/dev/stack-close/SKILL.md b/instructions/dev/stack-close/SKILL.md index 4ffbe84..ba54d38 100644 --- a/instructions/dev/stack-close/SKILL.md +++ b/instructions/dev/stack-close/SKILL.md @@ -75,12 +75,16 @@ and a fresh subagent starts without the session's context). #45 both closed exactly this way on the old, single-skill shape, the second an hour after the rule was first written down. -3. **Check whether a `docs/` page or new human doc went stale.** A `docs/` page carries no - normative sentence, so nothing verifies it by construction (AGENTS.md § File naming) - the - same is true of `README.md`/`INSTALL.md`/`DEVELOPMENT.md` prose and a new instruction's own - wording, which `instructions verify` checks structurally but never for what it claims. If the - change this package shipped moved the reasoning one of these pages documents, update it now; - if none did, say so rather than leaving the question unasked. +3. **Check whether a `docs/` page, a contract, or a new human doc went stale.** A `docs/` page + carries no normative sentence, so nothing verifies it by construction (AGENTS.md § File + naming) - the same is true of `tools/CONTRACT.md`'s two tables and any touched + `/CONTRACT.md`, whose prose `docs verify` checks only for presence and table-row + membership, never for what a cell or a section actually says + ([doc-pull-through.md](../doc-pull-through.md)); of `README.md`/`INSTALL.md`/`DEVELOPMENT.md` + prose; and of a new instruction's own wording, which `instructions verify` checks structurally + but never for what it claims. If the change this package shipped moved the reasoning or the + behaviour one of these documents describes, update it now; if none did, say so rather than + leaving the question unasked. 4. **Name which model ran which phase - not only this one.** This is the handover in full, not a note about the tail alone: state the model for the design/version-part/boundary-judgment diff --git a/instructions/dev/stack-dev/SKILL.md b/instructions/dev/stack-dev/SKILL.md index c0ff57a..1055b32 100644 --- a/instructions/dev/stack-dev/SKILL.md +++ b/instructions/dev/stack-dev/SKILL.md @@ -48,7 +48,7 @@ stack development happens in the origin repo instead (see AGENTS.md's routing li moves, so an interrupted session leaves a body the next one can resume from, *and* rewrite it to its final state before closing. Both halves bind; the second is what [`stack-close`](../stack-close/SKILL.md) carries out once this skill's own work is published - - see step 5 below. An issue labelled `status/incoming` is the exception to all of that: it is a + see step 6 below. An issue labelled `status/incoming` is the exception to all of that: it is a human's stub, not a spec, and it is **never implemented as it stands** - it gets worked out and triaged first. Read this file before filing something for later, before editing or closing an issue, before picking up an incoming stub, or before deciding what to pick up next. @@ -62,6 +62,10 @@ stack development happens in the origin repo instead (see AGENTS.md's routing li demo/testbed `kb/`, the measurable floors that define it, and what a reactive fix may and may not do to corpus content. Read it before judging whether the corpus can exercise a change, or before any fix that would touch `kb/` content. + [doc-pull-through.md](../doc-pull-through.md) - which document makes a claim about a touched + surface (a `wikitool` command, a stage's rules, an `AGENTS.md` rule/gate/invariant, a + README-shaped human doc, a `docs/` page's reasoning) and therefore needs updating alongside + the code, since `docs verify` never reads a cell's prose. Read it before step 6. More instructions are added here incrementally as stack-development needs come up - this list grows without needing this skill file to change shape. 3. **Settle the design before building - and break there for the model switch.** These are two @@ -135,7 +139,11 @@ stack development happens in the origin repo instead (see AGENTS.md's routing li Prose-only changes (`README.md`, `INSTALL.md`, `EVALS.md`) and the workflows under `.gitea/` do not need a bump - CI's version gate is scoped to what changes behaviour. -5. **Verify, then publish.** `tools/wikitool docs verify`, `tools/wikitool instructions verify`, +5. **Pull through every document that makes a claim about the surface you touched - `docs verify` + checks a cell's presence, never its prose.** [doc-pull-through.md](../doc-pull-through.md) has + the table of which document that is, per surface. + +6. **Verify, then publish.** `tools/wikitool docs verify`, `tools/wikitool instructions verify`, and the relevant `pytest` run in `tools/` - the same checks any stack change must pass, run explicitly rather than assumed. CI (`.gitea/workflows/ci.yml`) runs these plus a full `setup-instance.md` replay against a fresh `dist export`; a push to `main` that moves `VERSION` diff --git a/instructions/dev/testing-conventions.md b/instructions/dev/testing-conventions.md index 8a2febf..bc8aa19 100644 --- a/instructions/dev/testing-conventions.md +++ b/instructions/dev/testing-conventions.md @@ -177,6 +177,6 @@ Whenever you add or change a test under `tools/chemenu/tests/`. ## Scope Applies to `tools/chemenu/tests/` only. It says nothing about what to test - the test/review -expectations for a stack change are the `stack-dev` skill's step 4 (`docs verify`, +expectations for a stack change are the `stack-dev` skill's step 6 (`docs verify`, `instructions verify`, pytest). CI runs the suite once, unhardened, because the fixture makes a second hardened run redundant; see the note on the Tests step in `.gitea/workflows/ci.yml`. diff --git a/instructions/dev/version-parts.md b/instructions/dev/version-parts.md index 77ad639..ed1dbbd 100644 --- a/instructions/dev/version-parts.md +++ b/instructions/dev/version-parts.md @@ -65,7 +65,7 @@ a new one, and only `version release` turns it into something the release workfl ## When to run -Before every `tools/wikitool version bump` - the `stack-dev` skill's step 3 sends you here. +Before every `tools/wikitool version bump` - the `stack-dev` skill's step 4 sends you here. Read it in full the first time a change looks like it might be boundary-crossing; afterwards the three-line test below is usually enough. diff --git a/tools/chemenu/commands/docs_verify.py b/tools/chemenu/commands/docs_verify.py index ccc3a4b..f5b621a 100644 --- a/tools/chemenu/commands/docs_verify.py +++ b/tools/chemenu/commands/docs_verify.py @@ -213,8 +213,15 @@ def documented_commands(readme_text: str) -> list[str]: def check_cli_readme() -> list[str]: - """Every registered command must appear in tools/CONTRACT.md's command - table, and every command documented there must exist. + """Every registered command must appear in tools/CONTRACT.md, and every + command documented there must exist. + + `TABLE_CELL_RE` scans the whole file for any markdown table row whose + first cell is backticked - there is no separate "command table" region it + is scoped to, so a match in the error-contract table (or any other table + shaped the same way) counts too. It reads only the backticked path itself, + never the rest of the cell: a changed flag or a rewritten description in + an existing row is invisible to this check. The reverse check matches a documented cell against the full registered command path (e.g. `xref add`, `migrate verify`), not just its first