--- name: stack-close description: Close out a stack-dev work package after its publish has landed - rewrite the issue body to its final state, check for docs/ staleness, and name which model ran which phase of the session. Use right after a stack-dev session's tools/wikitool publish succeeds, or when resuming a package that was published but never closed. --- # Stack Close **Purpose:** Carry out the unchecked closing phase of a stack-development work package, as its own skill rather than a break `stack-dev` has to remember to ask for mid-flow. **Trigger:** A `stack-dev` session's `tools/wikitool publish` just succeeded - `stack-dev` ends there and hands off here rather than continuing into this phase in the same breath. Also: `publish` printed its stack-machinery note ("this publish touched stack machinery...") and nothing has closed the work package it belongs to yet; or a package was published in an earlier session and never went through this skill (the gap this split exists to make impossible to skip past silently - see [issue-tracking.md](../issue-tracking.md)'s note that a closed body is the version everyone reads afterwards and nobody revisits). **This directory is dev-only.** Same boundary as `stack-dev` ([its own note](../stack-dev/SKILL.md) has the full reasoning) - `dist export` prunes `instructions/dev/` wholesale, so this skill never reaches a distributed instance. ## Why this is a separate skill, not `stack-dev`'s step 6 The two phases around the mechanical middle of a stack-dev session have no mechanical guard at all - `pytest`, `docs verify` and `instructions verify` cover the code and tests in between, and nothing covers a changelog entry's accuracy, a `docs/` page's staleness, or an issue body's final state (see [claude-code-model-selection.md](../../claude-code-model-selection.md)). Asking the same session to notice it has crossed into that second unchecked stretch - as a prose break inside `stack-dev`'s own step 6 - failed twice in a row on this stack (Gitea #42, then #30): both times the session knew the rule and skipped past it anyway, because nothing in the moment forced the question. Splitting the phase into its own skill does not add a check either - `wikitool` still does not know this tracker exists and must not learn (see [issue-tracking.md](../issue-tracking.md) § What no tool checks) - but it removes the thing that was actually failing: the closing *procedure* is no longer sitting in the session's context as a next step to run past - it exists only inside a skill someone has to invoke. **Be precise about what that does and does not buy**, because the honest version is weaker than "now it cannot be skipped". What did **not** change is the trigger: `stack-dev`'s "invoke it now" is still a sentence, and `publish`'s stack-machinery note is deliberately generic enough not to name this skill at all. Two of the three links in that chain remain self-discipline. The split narrows the failure, it does not close it - treat a session that reaches this text as the mechanism having worked *this time*, not as proof that it always will. See Gitea #47 for the full incident history and the rejected alternative (a model-switched subagent - not buildable in Claude Code, where a fork inherits the parent's model and a fresh subagent starts without the session's context). ## Steps 1. **Offer the model switch back up, once, and keep working either way.** > Ab hier greift kein maschineller Check mehr - Issue-Body, `docs/`-Veralterung und > Changelog-Prosa prüft nichts. Wenn du zurück auf Opus willst, ist jetzt der Moment. **Never block on the answer.** The change is already published; a session that stops here leaves exactly the state this skill exists to prevent. 2. **Rewrite the issue body to its final state, then close.** The test is what a reader who opens the closed issue tomorrow would conclude: - every acceptance criterion ticked, or struck with the reason it was dropped - proposals that were decided read as decided; a "to decide" section has become the decision and its reasoning - nothing left in the present tense about a defect that no longer exists - what was verified is named - which checks ran, which CI run - not a commit hash alone Then one short comment naming what changed against the previous state, and nothing else - [issue-tracking.md](../issue-tracking.md) steps 2-3 and 7 have the full shape; this is that procedure, run at the point this skill exists to guarantee it actually gets run. **A closing report in a comment does not satisfy this**, however thorough: it reads as complete to whoever writes it and leaves a body still phrased as open work. Nothing mechanical catches it, which is why this is a step - and now a whole skill - rather than a habit. #44 and #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. 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 phase (`stack-dev` step 3), for the mechanical middle (code, tests, the version bump), and for this closing phase - all three, even when they are all the same model. A handover that only flags a cheap-model *closing* phase stays silent exactly when the earlier, equally unchecked design phase also ran cheap and nobody offered the switch back then either; naming all three every time is what keeps that omission from being the quiet default. ## Decision points - **The work package spans several sessions?** Run this skill once, at the point the package is actually finished and its last publish has landed - not after every individual publish. A package still open across sessions keeps its body current per [issue-tracking.md](../issue-tracking.md) step 2 in the meantime; that is maintenance, not closing. - **Resuming a package whose publish landed in an earlier, already-ended session?** Run this skill now, on whatever model the current session is - do not reopen the earlier session to run it "correctly." The handover in step 4 names the earlier phases from the historical record (the issue's comments, `CHANGES.md`) rather than from memory. - **Nothing to close - the session's own exploration, no publish happened?** This skill does not apply; there is no package to rewrite a body for. ## Scope Follows a `stack-dev` session's publish. Not for wiki content work - use `wiki-ingest`/`wiki-query`/`wiki-manage`/`wiki-lint`/`wiki-status` for that, whose own closing conventions (`kb/log.md`, page provenance) are unrelated to this tracker-body procedure.