diff --git a/CHANGES.md b/CHANGES.md index 233733f..452e99b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,17 @@ place only: `instructions/dev/version-parts.md` § The candidate model. --- +## 9.0.1-beta.1 - 2026-10-10 - Ketten von Paketen: stack-dev schreibt ## Kette, stack-close nennt das nächste Glied + +**Author:** Torben Nehmer + + +**Low impact** +- Ketten von Paketen: stack-dev schreibt ## Kette, stack-close nennt das nächste Glied + + +--- + ## 9.0.0 - 2026-10-09 - Docs sorted into four areas, generated references, raw derive for real documents **Author:** Torben Nehmer diff --git a/VERSION b/VERSION index f7ee066..b921001 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -9.0.0 +9.0.1-beta.1 diff --git a/instructions/dev/issue-tracking.md b/instructions/dev/issue-tracking.md index 930d82e..460dc5d 100644 --- a/instructions/dev/issue-tracking.md +++ b/instructions/dev/issue-tracking.md @@ -27,6 +27,7 @@ issues at that URL, which is exactly why `dist export` excludes - [Steps](#steps) - [Incoming stubs](#incoming-stubs) - [Ready to build](#ready-to-build) +- [Chains](#chains) - [Renames and other decay in the tracker](#renames-and-other-decay-in-the-tracker) - [Citing an issue in the repo](#citing-an-issue-in-the-repo) - [What no tool checks](#what-no-tool-checks) @@ -50,6 +51,8 @@ issues at that URL, which is exactly why `dist export` excludes ready (§ Ready to build). - Prioritising: deciding what to pick up next, or re-labelling after the ground moved. +- A design session yields several packages with an order, or inserts, removes or moves + one in an existing sequence: write or repair the `## Kette` sections (§ Chains). - Closing one: the body is rewritten to its final state first, and only then closed (step 7). - A rename or move ships: sweep the open issues for text that assumed the old @@ -208,7 +211,7 @@ issues at that URL, which is exactly why `dist export` excludes | `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/blocked` | Waiting on another, still-open issue - not workable on its own, whatever its `prio/` says. Name the blocking issue in the body. A place in a chain (§ Chains) is an order, not a block. | | `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. | @@ -337,6 +340,40 @@ session fills on its own is the same gap a `status/incoming` stub leaves (§ Inc only better disguised. The useful side effect of the cut between the two phases is that it tests this definition - if a cold session cannot build from the body, it was not ready. +## Chains + +Packages that are meant to be built one after another lose the thread when each is closed: +which issue comes next is, at best, written in a body nobody reads after closing. A package that +is part of an ordered sequence therefore ends its body with a section of this exact form, as the +**last** section: + +``` +## Kette + +Kette „“ +- Vorgänger: #A (or: keiner - erstes Glied) +- Nachfolger: #C (or: keiner - letztes Glied) +``` + +The heading and the line openings are quoted vocabulary and stay German, like the bodies they +sit in. Three rules keep it cheap and checkable: + +- **Neighbours only, never a list of all links.** Inserting, removing or moving a package then + touches the two bodies beside it, not every body in the chain. The whole sequence is + recovered by walking `Nachfolger` links from the first link. +- **The two neighbours point at each other.** If #B names #A as `Vorgänger`, #A names #B as + `Nachfolger`. A one-sided pointer is the defect; `stack-dev` checks every link it touched + before ending its phase. +- **Order is a planning decision, not a dependency.** A real dependency still carries + `status/blocked` (step 5) and names the blocker in the body. A chain position alone never + blocks anything. + +`stack-dev` writes the section and keeps the neighbours in step (its steps 3 and 5); +`stack-close` reads it after closing and names the next link (its step 5), and lifts +`status/blocked` from the successor when the closed package was that body's only open blocker, +with the comment step 6 asks for. The successor is *ready* when it carries `kind/build` and +neither `status/incoming` nor `status/unconfirmed`; otherwise the next phase for it is design. + ## Renames and other decay in the tracker A rename is not finished when the tree is green. Renaming a package, a path, diff --git a/instructions/dev/stack-close/SKILL.md b/instructions/dev/stack-close/SKILL.md index aba5e7a..8fb5026 100644 --- a/instructions/dev/stack-close/SKILL.md +++ b/instructions/dev/stack-close/SKILL.md @@ -103,6 +103,31 @@ always will. 4. **Comment, then close.** The closing comment carries the one changelog line `instructions/dev/issue-tracking.md` step 3 asks for. Then close the issue. +5. **Name the next link of the chain, if there is one.** Read the closed body's `## Kette` section + (`instructions/dev/issue-tracking.md` § Chains) and follow its `Nachfolger` line: + + - **Successor open:** if its body names the issue just closed as its only open blocker, take + `status/blocked` off it and say so in a comment there (issue-tracking.md step 6); with + another open blocker the label stays. Then give the line below. + - **Successor already closed:** keep following `Nachfolger` links to the first open link and + name that one. + - **No open link left (`Nachfolger: keiner`, or only closed links):** give the last line below. + - **No `## Kette` section:** give no line, as before. + + Close the phase with exactly one of these fixed lines, in the instance's KB language per + `AGENTS.md` § File naming. A link is *ready* when it carries `kind/build` and neither + `status/incoming` nor `status/unconfirmed`: + + > #N is closed. Next in the chain "": #M - `/stack-build #M`, here or after `/clear`. + + > #N is closed. Next in the chain "": #M - `/stack-dev #M`, here or after `/clear`. + + > Chain "" is complete. + + The first is for a ready link, the second for one that is not and needs design first. **Do + not run the named skill yourself** - the line only tells the operator what comes next, the + same rule as at every other phase end (`instructions/dev/stack-mode.md` § The three phases). + ## Decision points - **The work package spans several sessions?** Run this skill once, at the point the package is @@ -112,6 +137,9 @@ always will. it "correctly." - **Nothing to close - the session's own exploration, no publish happened?** This skill does not apply; there is no package to close. +- **The chain section points at a successor that does not point back, or at an issue that does + not exist?** Say so in the closing line's place instead of guessing a successor, and leave the + repair to `/stack-dev` (`issue-tracking.md` § Chains). ## Scope diff --git a/instructions/dev/stack-dev/SKILL.md b/instructions/dev/stack-dev/SKILL.md index 3b100e5..feb20c6 100644 --- a/instructions/dev/stack-dev/SKILL.md +++ b/instructions/dev/stack-dev/SKILL.md @@ -41,13 +41,22 @@ are split that way. asked in the chat and stays a question in the body until it is answered; it is never settled by a guess. + **A session that yields more than one package with an order gives each of them a + `## Kette` section** (`instructions/dev/issue-tracking.md` § Chains): the chain's name, the + predecessor, the successor, nothing else. When a package is inserted into an existing chain, + taken out of it or moved within it, the neighbours' sections are corrected in the same + session, and the changelog comment names it. The order stays a planning decision; a real + dependency also gets `status/blocked`. + 4. **Name the version part.** Apply the drop-in test in `instructions/dev/version-parts.md` and write the result into the body. Whether a change is a drop-in replacement has no mechanical guard, so it is decided here, not at the bump. A change that crosses the compatibility boundary goes to the user with what breaks, what an instance has to do about it, and the alternatives, before the body can be ready (version-parts.md step 4). -5. **End the phase at a ready body.** Check the body against +5. **End the phase at a ready body.** First, for every package of a chain this session touched, + read both neighbours' `## Kette` sections and confirm that predecessor and successor point at + each other; repair a one-sided pointer before going on. Then check the body against `instructions/dev/issue-tracking.md` § Ready to build. If it fails, say which point is open and stay in this phase. If it passes, recommend one of two ways on, and stop: diff --git a/instructions/dev/stack-mode.md b/instructions/dev/stack-mode.md index 35d873a..28c0604 100644 --- a/instructions/dev/stack-mode.md +++ b/instructions/dev/stack-mode.md @@ -33,9 +33,9 @@ so every handover works either in the same session or after a `/clear`. | Phase | Skill | Invoked by | Ends with (the handover) | What catches a mistake | |---|---|---|---|---| -| 1 Design/triage | `stack-dev` | the harness on a matching task, or `/stack-dev` | the issue body is **ready** ([issue-tracking.md](issue-tracking.md) § Ready to build) | nothing mechanical | +| 1 Design/triage | `stack-dev` | the harness on a matching task, or `/stack-dev` | the issue body is **ready** ([issue-tracking.md](issue-tracking.md) § Ready to build); writes `## Kette` where an order exists ([§ Chains](issue-tracking.md#chains)) | nothing mechanical | | 2 Build | `stack-build` | **only** the operator: `/stack-build #N` | a **green CI run** on the published commit, body current | `pytest`, `docs verify`, `instructions verify`, CI | -| 3 Closing | `stack-close` | **only** the operator: `/stack-close` | body in its final state, issue closed | nothing mechanical | +| 3 Closing | `stack-close` | **only** the operator: `/stack-close` | body in its final state, issue closed; names the next link of a chain | nothing mechanical | `stack-build` and `stack-close` carry `disable-model-invocation: true` in their frontmatter, so in Claude Code only the operator can start them. That is the point of the split: each phase change is