docs: Issue-Body ist das Plan-File - fortlaufend aktuell, Abschluss ist die letzte Aktualisierung (4.1.2, #44)
CI / verify (push) Successful in 52s
Release / release (push) Successful in 38s

Files changed:
- CHANGES.md
- VERSION
- instructions/dev/issue-tracking.md
- instructions/dev/stack-dev/SKILL.md
This commit is contained in:
2026-09-03 06:39:16 +02:00
parent 23307c3c5f
commit 41f5dfe1cd
4 changed files with 138 additions and 22 deletions
+83 -18
View File
@@ -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.