From 41f5dfe1cdb6c69d1a1048cc0bb99db8da8b9913 Mon Sep 17 00:00:00 2001 From: Torben Nehmer Date: Thu, 3 Sep 2026 06:39:16 +0200 Subject: [PATCH] docs: Issue-Body ist das Plan-File - fortlaufend aktuell, Abschluss ist die letzte Aktualisierung (4.1.2, #44) Files changed: - CHANGES.md - VERSION - instructions/dev/issue-tracking.md - instructions/dev/stack-dev/SKILL.md --- CHANGES.md | 49 ++++++++++++++ VERSION | 2 +- instructions/dev/issue-tracking.md | 101 +++++++++++++++++++++++----- instructions/dev/stack-dev/SKILL.md | 8 ++- 4 files changed, 138 insertions(+), 22 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 3ae14af..71a31cf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,55 @@ their date-only headings. --- +## 4.1.2 - 2026-09-03 - Issue-Abschluss ist ein Body-Rewrite, nicht nur ein Kommentar + +**Author:** Torben Nehmer + +Aufgefallen beim Schließen von #44: der Abschlussbericht stand als Kommentar da, der Body +darunter weiterhin als offene Arbeit — Abschnitt „Zu entscheiden" über eine längst getroffene +Entscheidung, ungehakte Checkliste, Präsens über einen Defekt, den es nicht mehr gab. + +Die Regel gab es dafür schon: Schritt 2 von `instructions/dev/issue-tracking.md` sagt, der Body +ist die aktuelle Wahrheit und wird umgeschrieben, wenn sich der Stand ändert. Nur ließ die +Formulierung offen, *wann* — und Schritt 7 („Close with what actually happened") war vollständig +erfüllbar, ohne den Body anzufassen. Ein Abschlussbericht im Kommentar fühlt sich beim Schreiben +vollständig an; dass der Body dabei zurückbleibt, merkt erst der nächste Leser. + +**Schritt 2 ist deshalb schärfer geworden: der Body ist das Plan-File dieses Stacks.** Dasselbe, +was das Plan-Dokument eines Harness ist, und genauso gepflegt — fortlaufend, sobald etwas darin +nicht mehr stimmt, nicht am Ende. Der Maßstab ist der Abbruch, nicht der Meilenstein: eine +Session kann jederzeit enden, und was der Body in diesem Moment sagt, ist die vollständige +Übergabe. Eine frische Session muss zu **jedem** Zeitpunkt allein aus dem Body weiterarbeiten +können, ohne Kommentare rückwärts zu lesen und ohne einen Menschen, der es neu erklärt. Entschieden +ersetzt die Frage, erledigt hakt das Kriterium ab, verworfen steht mit Begründung dort, wo das +Kriterium stand. + +Schritt 7 ist damit kein Sonderakt mehr, sondern die letzte dieser Aktualisierungen: erst Body +auf den Endstand, dann schließen, dann die Changelog-Zeile aus Schritt 3. Wer Schritt 2 befolgt +hat, ist fast fertig; wer nicht, zahlt die ganze Schuld im schlechtesten Moment — der +geschlossene Body ist die Fassung, die danach alle lesen und niemand mehr aufsucht. #44 steht +als Beispiel drin. + +Schritt 3 zieht die Konsequenz: **ein Kommentar pro Session-Umfang, nicht pro Edit.** Ein +fortlaufend gepflegter Body mit einem Changelog-Kommentar je Änderung wäre Lärm; triviale Pflege +braucht gar keinen. Der `stack-dev`-Skill sagt es beim Aufgreifen mit, weil dort die Entscheidung +fällt, ob eine Session den Body überhaupt anfasst. + +**Und die ehrliche Antwort auf die Frage nach dem Tooling: es gibt keins, und es soll keins +geben.** `wikitool` kennt diesen Tracker nicht. Es wird an Instanzen ausgeliefert, die unter +dieser URL keine Issues haben, während `instructions/dev/` von `dist export` gepruned wird — +ein Gitea-Client im ausgelieferten Tool wäre eine Dev-Abhängigkeit, die jede Instanz mitträgt, +um ein Board zu prüfen, das keine von ihnen hat. Der Tracker ist ausschließlich über +`gitea-mcp` erreichbar, also in einer Session, durch einen Agenten. + +Kein `docs verify` fängt also einen geschlossenen Issue, dessen Body offen klingt, einen Body, +der seinen eigenen Kommentaren widerspricht, oder ein fehlendes Pflichtlabel. Das steht jetzt +als eigener Abschnitt „What no tool checks" in der Instruktion — nicht als Bedauern, sondern als +Begründung dafür, warum die Reihenfolge in Schritt 7 ausgeschrieben ist statt aus Schritt 2 +erschlossen zu werden. + +--- + ## 4.1.1 - 2026-09-03 - Testisolation: kb_dir repointet config.ROOT, lint löst Kollektionen gegen den übergebenen Baum auf **Author:** Torben Nehmer diff --git a/VERSION b/VERSION index 627a3f4..4d0dcda 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.1.1 +4.1.2 diff --git a/instructions/dev/issue-tracking.md b/instructions/dev/issue-tracking.md index b40928e..d06de47 100644 --- a/instructions/dev/issue-tracking.md +++ b/instructions/dev/issue-tracking.md @@ -28,8 +28,12 @@ issues at that URL, which is exactly why `dist export` excludes an assumption nobody has checked, a decision that needs the user. - Picking an issue up: before doing anything else, read the body as the current spec, and re-label it if the ground has moved since. +- **While working on one:** the body is updated as the state moves, not at the + end (step 2). A session that is interrupted leaves the body as its handover. - Prioritising: deciding what to pick up next, or re-labelling after the ground moved. +- Closing one: the body is rewritten to its final state first, and only then + closed (step 7). ## Steps @@ -38,23 +42,47 @@ issues at that URL, which is exactly why `dist export` excludes specific files or commands involved. An issue that only makes sense to whoever wrote it is a note, and notes were the problem. -2. **Treat the body as the current truth, not as a historical first post.** - Work on one issue spans several sessions, often weeks apart, and the body is - the only thing that connects them: a session opening the issue must be able - to reconstruct what is decided and what is still open from the body alone, - without a human re-explaining it. So when the state changes, **rewrite the - body** - do not append to a text that has become wrong. An additively grown - log forces every later reader to reconstruct the current state by filtering - the whole history. +2. **The body is the working state, not a historical first post - keep it + current as you go.** It is this stack's plan file: the same thing a harness's + own plan document is, and it is maintained the same way. Not written once, + not brought up to date at the end, but **updated whenever something in it + stops being true** - a decision made, a criterion met, an approach ruled out, + a new constraint found. + + The test is an abort, not a milestone. A session can end at any moment - an + interrupt, a context limit, a crash, a human walking away - and whatever the + body says at that instant is the entire handover. So the standard is: **at + every point, a fresh session must be able to open the body and pick the work + up from there**, without a human re-explaining it and without reading back + through the comments. If the body would mislead someone who read it right + now, it is already out of date, whether or not the work is finished. + + That means updating *during* the work, not only at its end: + + - a decision gets made → the decision and its reasoning replace the question + - an acceptance criterion is done → tick it, in the same session that did it + - something turns out differently than the issue assumed → the assumption is + corrected where it stands, not contradicted three paragraphs later + - work is deferred or dropped → say so, with the reason, where the criterion is + + **Rewrite, never append.** Do not add to a text that has become wrong: an + additively grown log forces every later reader to reconstruct the current + state by filtering the whole history, which is the exact cost the body exists + to remove. Comments carry the history (step 3); the body carries the state. Body rewrites and comments are an LLM session's job. A human normally touches only labels and metadata directly. -3. **Comment a changelog, never a copy.** Every body rewrite gets one short - comment naming only what changed against the previous state - what is new, - what is gone, what was corrected. Do not snapshot the old body into a - comment: a full copy per revision forces a human to diff two prose texts, - which is not a readable history, only another copy. +3. **Comment a changelog, never a copy.** A body rewrite gets one short comment + naming only what changed against the previous state - what is new, what is + gone, what was corrected. Do not snapshot the old body into a comment: a full + copy per revision forces a human to diff two prose texts, which is not a + readable history, only another copy. + + One comment per *session's worth* of change, not per edit. Step 2 asks the + body to be kept current continuously, and a comment for every tick would bury + the board in noise; the changelog line summarises what that session moved. + Trivial upkeep - a typo, a tightened sentence - needs no comment at all. ``` **Changelog:** Decision 2 tightened - `kind/` may now change over an @@ -127,10 +155,46 @@ issues at that URL, which is exactly why `dist export` excludes answered can drop a size and move `kind/decision` to `kind/build`. Silent re-labelling is how a board stops meaning anything. -7. **Close with what actually happened**, not with a commit hash alone: which - proposals were implemented, which were deliberately left out and why, and - what was verified. The issue is the only place that record survives - a - changelog entry says what changed, not what was decided against. +7. **Closing is the last body update, not a comment.** If step 2 was followed + the body is already nearly there, and closing only settles what the final + run established. If it was not, closing is where the whole debt comes due - + and it comes due at the worst moment, because a closed body is the version + everyone reads afterwards and nobody revisits. + + Either way the body reaches its final state *before* the issue closes: + proposals that were decided read as decided, a "to decide" section has become + the decision with its reasoning, acceptance criteria are ticked or struck with + a reason, and what was verified is named. Then close, with the one-line + changelog comment step 3 asks for. + + Record what actually happened, not a commit hash alone: which proposals were + implemented, which were deliberately left out and why, and what was verified. + The issue is the only place that record survives - a changelog entry says + what changed, not what was decided against. + + **A closing report in a comment does not satisfy this.** It reads as + complete to whoever writes it and leaves a body still phrased as open work: + unticked boxes, an undecided decision section, present tense about a defect + that no longer exists. #44 closed exactly that way, with a thorough comment + above a body that still asked for a decision that had already been made and + shipped. Nothing mechanical catches it (see below), which is why it is a step + rather than a habit. + +## What no tool checks + +`wikitool` does not know this tracker exists, and should not learn. It ships to +instances that have no issues at that URL, while this file and the workflow it +describes are pruned by `dist export` - a Gitea client inside the shipped tool +would be a dev-only dependency carried by every instance, to check a board none +of them have. The tracker is reachable only through the `gitea-mcp` server, in a +session, by an agent. + +So there is no `docs verify` for the board. Nothing reports a closed issue whose +body still reads as open, a body that contradicts its own comments, or an issue +missing one of the four mandatory labels. Every one of those is caught by a +session following this file, or not at all - which is the argument for the +sequence in step 7 being explicit about the order (body first, then close), +rather than leaving it to be inferred from step 2. ## Decision points @@ -144,7 +208,8 @@ issues at that URL, which is exactly why `dist export` excludes - **Rewrite the body, or add a comment?** Rewrite whenever a reader of the body alone would otherwise be misled - a changed decision, a dropped criterion, a new constraint. A comment carries the changelog line for that rewrite, and - nothing else that a future session needs in order to act. + nothing else that a future session needs in order to act. Closing an issue is + always a rewrite - see step 7. - **An old issue carries only `prio/` and `size/`?** Complete it to all four when you touch it, rather than in a sweep. The board reaches the new scheme issue by issue, as each is picked up. diff --git a/instructions/dev/stack-dev/SKILL.md b/instructions/dev/stack-dev/SKILL.md index 5a60764..a096d6d 100644 --- a/instructions/dev/stack-dev/SKILL.md +++ b/instructions/dev/stack-dev/SKILL.md @@ -43,9 +43,11 @@ stack development happens in the origin repo instead (see AGENTS.md's routing li engineering, memory and deploy-time learning; consult before a design decision in those areas. [issue-tracking.md](../issue-tracking.md) - open work lives in Gitea issues, one per work - package, labelled `area/`, `kind/`, `prio/` and `size/`, with the body kept as the current - truth rather than as a first post. There is no `TODO.md`. Read it before filing something - for later, before editing an issue, or before deciding what to pick up next. + package, labelled `area/`, `kind/`, `prio/` and `size/`. There is no `TODO.md`. **The body + of the issue you are working on is this session's plan file:** keep it current as the state + moves, not at the end, so an interrupted session leaves a body the next one can resume from. + Read it before filing something for later, before editing or closing an issue, or before + deciding what to pick up next. [testing-conventions.md](../testing-conventions.md) - the suite runs against a deliberately empty machine; what the autouse fixture already neutralizes, and what a test still has to establish itself. Read it before adding or changing a test.