diff --git a/CHANGES.md b/CHANGES.md index ebe8269..61f10e6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -35,6 +35,61 @@ dev-checkout concern - readable here, never shipped as something to parse. --- +## 4.7.5-beta.1 - 2026-09-04 - status/incoming: menschliche Stubs werden ausgearbeitet, nie so umgesetzt + +**Author:** Torben Nehmer + + +- status/incoming: menschliche Stubs werden ausgearbeitet, nie so umgesetzt + + +Das Label `status/incoming` gibt es seit heute in Gitea: der Mensch legt einen +Stub an — zwei Sätze, ein Verdacht, ein „wäre interessant" — und der Stack +komplettiert ihn. `instructions/dev/issue-tracking.md` beschrieb es nicht, und +das ist die gefährlichere Hälfte: ein Stub *sieht aus wie* ein Body, und der +Body ist genau das, was eine Sitzung nach Schritt 2 als Spec glaubt. Zwei +solche Issues lagen bereits offen auf dem Board (#60, #61). + +Neu in der Instruction ist deshalb ein eigener Abschnitt „Incoming stubs" mit +dem Verbot als erstem Satz — ein `status/incoming`-Issue wird nie so umgesetzt, +wie es dasteht — und der Ausarbeitung als sechsschrittigem Ablauf: den Wortlaut +als Absichtserklärung lesen, gegen den Baum prüfen, den Originaltext wörtlich in +den Kommentar retten, bevor der Rewrite ihn überschreibt, offene Fragen benennen +statt beantworten (`kind/decision`), erst dann die vier Pflichtlabel, dann das +Flag entfernen. Zwei Ausgänge wie bei `status/unconfirmed`: ausgearbeitet oder +mit Begründung geschlossen. + +Der interessante Punkt ist Schritt 4: `status/incoming` ist das einzige Flag, +das Schritt 4 nicht qualifiziert, sondern **aussetzt**. Die vier Pflichtachsen +fehlen einem Stub nicht, sie sind noch nicht fällig — `kind/`, `prio/` und +`size/` sind Antworten auf Fragen, die niemand gegen den Baum geprüft hat. Ein +Stub auf Sicht durchzulabeln ist der Fehler, nicht das Weglassen: es lässt +Ungeprüftes triagiert aussehen. + +Der Schaden, den das verhindert, ist derselbe wie bei #30, nur eine Stufe +früher: dort schrieb ein Body einen Mechanismus vor und bekam dessen Bugs +gebaut, hier schreibt ein Body gar nichts vor und bekommt die Lücke von +demjenigen gefüllt, der ihn am schnellsten gelesen hat — inklusive Close, womit +die Frage, für die der Stub stand, nie wieder gestellt wird. + +Keine neue Schrittnummer, bewusst: `stack-close/SKILL.md` und ältere +`CHANGES.md`-Einträge verweisen namentlich auf „Schritte 2-3 und 7". Eine +Umnummerierung hätte diese Verweise still falsch gemacht — genau der Zerfall, +den dieselbe Datei in § Renames beschreibt. + +Geändert: [instructions/dev/issue-tracking.md](instructions/dev/issue-tracking.md) +(Frontmatter, § When to run, Schritt 5, neuer § Incoming stubs, § What no tool +checks, § Decision points) und die Routing-Zeile in +`instructions/dev/stack-dev/SKILL.md`. Dev-only — `dist export` schließt +`instructions/dev/` aus, eine ausgelieferte Instanz sieht davon nichts, deshalb +PATCH. + +Offen (#62): `kb/concepts/Issue Label Scheme.md` beschreibt weiter nur die +beiden alten `status/`-Flags. Das ist `kb/`-Inhalt und braucht eine +`wiki-manage`-Sitzung mit einer Quelle, nicht diese hier. + +--- + ## 4.7.4 - 2026-09-04 - bootstrap.md nennt den session-id-WARN nach frischem Bootstrap explizit als erwartet **Author:** Torben Nehmer diff --git a/VERSION b/VERSION index b48b2de..389fc09 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.7.4 +4.7.5-beta.1 diff --git a/instructions/dev/issue-tracking.md b/instructions/dev/issue-tracking.md index 4103b94..8aacf7f 100644 --- a/instructions/dev/issue-tracking.md +++ b/instructions/dev/issue-tracking.md @@ -1,7 +1,7 @@ --- type: types/instruction.md name: issue-tracking -description: Where open work on this stack is tracked, what the four mandatory area/kind/prio/size labels and the two status flags on a Gitea issue mean, and how to keep an issue body current across sessions. +description: Where open work on this stack is tracked, what the four mandatory area/kind/prio/size labels and the three status flags on a Gitea issue mean, why a status/incoming stub is never implemented as it stands, and how to keep an issue body current across sessions. --- # Track open work as Gitea issues, not as prose in the repo @@ -28,6 +28,9 @@ 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. +- **The issue carries `status/incoming`:** it is a human's stub, not a spec, and + it is worked out and triaged before anything is built from it + (§ Incoming stubs). - **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 @@ -185,19 +188,28 @@ issues at that URL, which is exactly why `dist export` excludes on the board; a `prio/waiting size/L` is a thing to talk about before anyone starts. -5. **Add a `status/` flag only when it applies.** Both are optional, because +5. **Add a `status/` flag only when it applies.** All three are optional, because each describes a temporary condition rather than a property every issue has. | `status/` | Means | |---|---| | `status/blocked` | Waiting on another, still-open issue - not workable on its own, whatever its `prio/` says. Name the blocking issue in the body. | | `status/unconfirmed` | A reported suspicion, not yet checked against actual behaviour. Applies to any `kind/`, not just `kind/defect`. | + | `status/incoming` | A human's stub: a request or a thought, filed at whatever length it arrived, deliberately short of everything step 1 asks for. **Never implemented as it stands** - § Incoming stubs. | While `status/unconfirmed` is set, `size/` and `prio/` are provisional. Triage ends it one of two ways: the flag comes off and `size`/`prio` are set for real, or the issue is closed with the reason. An unverified suspicion does not stay open indefinitely - the process-level analogue of AGENTS.md invariant 3. + `status/incoming` is the one flag that **suspends step 4** rather than + qualifying it. The four mandatory labels are not missing from such an issue, + they are not yet due: `area/` may be obvious, but `kind/`, `prio/` and `size/` + are answers to questions the stub has not been read against the tree to + settle. Labelling it all four on sight is the failure, not the omission - it + makes an unexamined stub look triaged. It is also the one flag a session never + *adds*: an issue a session files meets step 1 or it does not get filed. + 6. **Re-label when the ground moves, and say why in a comment.** A trigger that fired turns `prio/waiting` into `prio/planned`. A design question that got answered can drop a size and move `kind/decision` to `kind/build`. Silent @@ -228,6 +240,64 @@ issues at that URL, which is exactly why `dist export` excludes shipped. Nothing mechanical catches it (see below), which is why it is a step rather than a habit. +## Incoming stubs + +**A `status/incoming` issue is never implemented as it stands.** It is worked +out and triaged first, in a session, and only the result of that is built. + +The flag exists because the tracker is also the human's inbox, and the two have +different entry costs. Step 1 asks for a body that survives without its author - +acceptance criteria, files, commands - and a thought worth keeping is not worth +that much work at the moment it occurs. So a stub is admitted at whatever +quality it arrives, and `status/incoming` is the receipt: this text was not held +to step 1, and nobody should read it as if it had been. + +That is the whole danger. A stub *looks* like a body, and a body is what a +session trusts (step 2). What it actually holds is a symptom or a wish - #60 +says the confidence defaults "feel too high", #61 says a mechanism from one +instruction "would be interesting" elsewhere. Neither states what done means, +and the parts they leave out are exactly the parts the human left to be worked +out. Building straight from one produces something that matches the sentence, +misses the intent, and closes the issue - so the question the stub was standing +in for is never asked again. It is step 1's mechanism-versus-invariant lesson +one stage earlier: there, a body prescribed a mechanism and got its bugs built; +here, a body prescribes nothing at all and gets the gap filled by whoever read +it fastest. + +Working one out: + +1. **Read the stub as a statement of intent, not a specification.** Its wording + is the only evidence of what was actually asked for. Reinterpret it and the + record of the request is gone - what remains is the session's reading of it, + indistinguishable from the human's. +2. **Check it against the tree before rewriting anything.** A stub may be a + suspicion (`status/unconfirmed` applies on top where it is), a duplicate of + something already built, or a premise that no longer holds. This is the step + that decides which of the two exits below the issue takes. +3. **Quote the stub verbatim in the elaboration comment, then rewrite the body.** + Step 2's "rewrite, never append" holds here as everywhere - but the rewrite + overwrites the only record of the request, and comments are where history + lives (step 3). Here the history *is* the request. +4. **Name the open questions; do not answer them.** Where the stub leaves + something a session cannot settle from the tree, it stays a question in the + body and the issue becomes `kind/decision`. Guessing turns the human's open + question into a spec that reads as decided, which is worse than the stub was: + the stub at least announced that it was incomplete. +5. **Then step 4 comes due** - all four mandatory labels, set against a body that + has been read against the tree. That is the moment the stub becomes a work + package. +6. **Remove `status/incoming`** and leave the one-line changelog comment step 3 + asks for. + +Triage ends a stub one of two ways, the same two `status/unconfirmed` has: it is +worked out, labelled and the flag comes off, or it is closed with the reason. A +stub does not sit in the inbox indefinitely. + +Elaboration touches no file in the working tree, so it needs no version bump and +no publish - it is tracker work, and several stubs can be worked out in one pass. +What comes *after* it is an ordinary work package, picked up on its merits like +any other. + ## Renames and other decay in the tracker A rename is not finished when the tree is green. Renaming a package, a path, @@ -259,8 +329,9 @@ 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 +body still reads as open, a body that contradicts its own comments, an issue +missing one of the four mandatory labels, or a `status/incoming` stub that got +built as it stood. 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. @@ -279,6 +350,11 @@ rather than leaving it to be inferred from step 2. new constraint. A comment carries the changelog line for that rewrite, and nothing else that a future session needs in order to act. Closing an issue is always a rewrite - see step 7. +- **A `status/incoming` stub looks trivially implementable?** Work it out anyway. + "Trivial" is a judgement about the sentence, and the sentence is the part the + human wrote down cheaply; what it omits is not visible from it. The elaboration + of an obvious stub is short - that is the argument for doing it, not for + skipping it. - **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 1c1071c..0de75cb 100644 --- a/instructions/dev/stack-dev/SKILL.md +++ b/instructions/dev/stack-dev/SKILL.md @@ -48,8 +48,10 @@ 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. Read it before filing something for later, before editing or closing an - issue, or before deciding what to pick up next. + see step 5 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. [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.