Files
chemenu/instructions/dev/stack-close/SKILL.md
T
torbenandClaude Opus 5.5 d8224ee2ab
CI / verify (push) Successful in 5m15s
CI / pwsh (push) Successful in 2m2s
Release / release (push) Successful in 34s
feat: stack development in three phases - stack-dev (design), stack-build, stack-close, handed over through tracker states (#168)
stack-build and stack-close carry disable-model-invocation, so each phase change is
the operator's slash command; no skill offers a mid-session /model or /effort switch.
Mode rules and the phase table move to instructions/dev/stack-mode.md, publish and CI
waiting to instructions/dev/publish-and-ci.md, the ready definition to issue-tracking.md.

Files changed:
- AGENTS.md
- CHANGES.md
- DEVELOPMENT.md
- README.md
- VERSION
- docs/model-and-effort-selection.md
- instructions/CONTRACT.md
- instructions/dev/commonplace-kb.md
- instructions/dev/dev-setup.md
- instructions/dev/doc-pull-through.md
- instructions/dev/issue-tracking.md
- instructions/dev/publish-and-ci.md
- instructions/dev/stack-build/SKILL.md
- instructions/dev/stack-close/SKILL.md
- instructions/dev/stack-dev/SKILL.md
- instructions/dev/stack-mode.md
- instructions/dev/testing-conventions.md
- instructions/dev/version-parts.md
- tools/chemenu/commands/git_publish.py
- tools/chemenu/tests/test_git_publish.py
- tools/chemenu/tests/test_instructions_cmd.py

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
2026-10-02 20:33:07 +02:00

138 lines
8.8 KiB
Markdown

---
name: stack-close
description: Closes out a stack work package once its publish has a green CI run - checks the issue body's final state, checks for docs/ and contract staleness, and records which model and effort ran each phase in the closing comment. Started only by the operator as /stack-close, after stack-build has ended its phase.
disable-model-invocation: true
---
# Stack Close
**Purpose:** Carry out the unchecked closing phase of a stack-development work package, as its
own skill rather than a step the build session has to remember to take on its own.
**Trigger:** The operator runs `/stack-close`, after `stack-build` ended its phase with a green
CI run on the published commit. Nothing else starts this skill: the frontmatter's
`disable-model-invocation` keeps Claude Code from invoking it, and in a harness that ignores that
key this sentence is the rule. Also for a package that was published in an earlier session and
never closed - the operator starts it the same way.
`instructions/dev/stack-mode.md` has the rules of a stack-development session and the three
phases this one ends; read it first when this session started cold.
## Why this is a separate skill, and why the operator starts it
The phases around the checked middle of a work package have no mechanical guard at all -
`pytest`, `docs verify`, `instructions verify` and CI 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 `docs/model-and-effort-selection.md`). Asking the same session to notice it has
crossed into that unchecked stretch - as a prose break inside one long skill - 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. The first split (Gitea #47) moved
the closing procedure into its own skill, so it no longer sat in the session's context as a next
step to run past - but the trigger stayed a sentence: the build skill told the agent to "invoke
it now", and a prose model-switch offer at the same point never once led to a switch (Gitea #50).
Since Gitea #168 the trigger is the operator's slash command, and the skill cannot be invoked by
the agent at all in Claude Code. **Be precise about what that buys.** The phase change is now a
real stop rather than a sentence in the output, and it is where the operator decides on context
and model. What moved is the risk #47 named: forgetting the close is now the operator's failure,
not the agent's. Two signals stay to catch it - `publish`'s note that what follows CI is checked
by nothing, and an open issue on the board whose criteria are ticked and whose CI is green. Treat
a session that reaches this text as the mechanism having worked *this time*, not as proof that it
always will.
## Steps
1. **Check the handover you start from.** The body names a green CI run on the published commit
(`stack-build` step 6). If it does not, or the run is red, this is not the closing phase yet:
say so and recommend `/stack-build #N`. A red run is never closed over.
This phase is meant to run on Opus at high effort - a lower effort gives up multi-file
consistency first, which is exactly what the staleness check in step 3 needs. If this session
runs on something else, say so once and carry on; offer no `/model` or `/effort` switch (see
`instructions/dev/stack-mode.md` § Sessions and models), and record it in step 4.
2. **Check that the body is in its final state.** `stack-build` kept it current at three fixed
points, so this is a check, not a rewrite - but the test is still 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; an open, non-blocking question carries its answer
- 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
Fix what is off by rewriting the body (`instructions/dev/issue-tracking.md` steps 2 and 7).
**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. #44 and #45 both
closed exactly this way, the second an hour after the rule was first written down.
3. **Check whether a `docs/` page, a contract, or a 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 `tools/CONTRACT.md`'s generated command records and any touched
`<stage>/CONTRACT.md`, whose prose `docs verify` checks only for presence and record
membership, never for what a field or a section actually says
(`instructions/dev/doc-pull-through.md`); of `README.md`/`INSTALL.md`/`DEVELOPMENT.md`
prose; and of 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 or the
behaviour one of these documents describes, update it now; if none did, say so rather than
leaving the question unasked.
**If the published diff touches an installation instruction, read the human guide against
it once more.** Which instructions those are and which human document answers for each is
the pull-through table's row in `instructions/dev/doc-pull-through.md` - `stack-build` step 5
applied it before the publish; this is the second reading, after. A deviation found here is
filed as a follow-up issue naming both files and the sentence that disagrees, rather than
fixed in this phase: the pull-through before the publish missed it, and that miss is worth a
record of its own.
**If that update moved a `##`/`###` heading, the file's table of contents is now stale** -
regenerate it with `tools/wikitool docs toc --apply`, never by editing the list. The region
is generated (AGENTS.md invariant 1), `docs verify` fails on stale exactly as on missing, and
a pull-through in this phase is a common way to move a heading without noticing.
**A pull-through of its own needs its own bump, publish and CI run.** The documents this
phase touches are frequently the ones CI's version gate watches - `types/`, `instructions/`,
`tools/`, `AGENTS.md`, any `<stage>/CONTRACT.md`. A commit into one of those without a
`VERSION` line fails the gate (`.gitea/workflows/ci.yml`, "Version gate"), whatever the
session meant it as. Reading the edit as "only documentation" is the trap: `types/source.md`
is a document *and* a shipped behaviour description, and the gate is scoped by path, not by
intent. So run `tools/wikitool version bump --patch` in the same breath as the pull-through -
it only advances the running candidate's counter - then publish and wait per
`instructions/dev/publish-and-ci.md`, and name that run in the body too.
4. **Record the handover, then close.** The closing comment carries the one changelog line
`instructions/dev/issue-tracking.md` step 3 asks for, and the handover for **every phase**,
not only this one:
| Phase | Model | Effort | Own session? | Context overflowed or compacted? |
|---|---|---|---|---|
| 1 Design (`stack-dev`) | | | | |
| 2 Build (`stack-build`) | | | | |
| 3 Closing (`stack-close`) | | | | |
plus the issue's `size/` label. Fill every cell, even when all three phases ran the same
model in one session - a handover that only flags the unusual case stays silent exactly when
an equally unchecked phase also ran cheap. Phases from an earlier session are named from the
record (the issue's comments, `CHANGES.md`), not from memory, and marked unknown where the
record does not say. These rows are the evidence `docs/model-and-effort-selection.md`'s
phase guide is checked against.
Then close the issue.
## 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 a green run - not after every individual publish.
- **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." Step 4 names the earlier phases from the record.
- **Nothing to close - the session's own exploration, no publish happened?** This skill does not
apply; there is no package to close.
## Scope
Follows `stack-build`'s green CI run (`instructions/dev/stack-build/SKILL.md`). Not for wiki
content work - use `wiki-ingest`/`wiki-query`/`wiki-manage`/`wiki-lint`/`wiki-status`/
`gtd-weekly-review` for that, whose own closing conventions (`kb/log.md`, page provenance) are
unrelated to this tracker-body procedure.