session-close
Close a working session by sweeping what it produced onto durable surfaces, so the next session picks it up cold rather than out of someone's head. Four gated sweeps in order — uncommitted work, the j
Files2
View on GitHubSKILL.mdskills/interactive/.claude/skills/session-close/SKILL.md
GitHubSession Close
Purpose
A session ends with residue, and most of it is only in the session. The repo keeps the files that were written. What dies at the end of the turn is everything else: which of the dirty files were deliberate, where the station actually stands versus where its file says it stands, the three things the session noticed and correctly refused to do, and the correction it earned the hard way.
This skill sweeps that residue onto surfaces that outlive the session. It is a close-out, not a finishing move — it does not decide that work is done, and it never claims a leg was walked.
It routes; it does not act. Every move it identifies already has an owner: a journey verb, the
shared commit recipe, the harness's own memory feature. The sweep's job is to notice that a move is
owed and hand it to whoever owns it. A close-out that performs the moves itself would be a second
implementation of each one, drifting from the first the day either changes —
<CORE>/doctrine/governance/single_source.md is the general form of that rule.
The four sweeps
Run them in order and stop at each gate. The order is not decorative: an uncommitted tree makes the journey's real position unreadable, and a journey left mid-step changes which findings are still this session's to record.
| Sweep | The question it asks | Where the answer goes |
|---|---|---|
| 1. Uncommitted work | What is dirty, and was it meant to be? | A commit through the builder, or a stated reason it stays dirty |
| 2. Journey position | Where does the journey actually stand? | The journey verb that owns the move |
| 3. Loose findings | What did the session surface that is not its work? | A 根回し Nemawashi seed in the owning project's unpicked/ |
| 4. Session-craft | What did the session learn about how to work? | The corrections store, or named as a graduation candidate |
Sweep 1 — uncommitted work
Read the working tree of every repo and worktree the session touched. Not just the one it started in:
a session that ran with --add-dir, or that opened a change worktree, has more than one.
git -C "<repo>" status --porcelain
For each dirty path, decide one of three things and say which:
- Commit it — through
<CORE>/doctrine/governance/commit_via_builder.md, staging that path by name. - Leave it, deliberately — a scratch file, a gitignored artifact, a half-edit the next session will finish. Name it and say why, so the next session does not have to guess whether it was abandoned.
- It is not yours — another session's work in a shared index. Leave it untouched and name it.
Never git add -A to catch everything. The shared recipe rules it out at
<CORE>/doctrine/governance/commit_via_builder.md:52-53, and the builder's staged-set guard refuses a
commit whose staged set was not declared. On a busy machine the file that gets swept in belongs to
somebody else's session.
Gate. Show the list and what happens to each line before committing anything.
Sweep 2 — journey position
The session's own account of where it got to is the least reliable source available at this moment. Read the state instead.
python3 "<CORE>/tools/journey_status.py"
It walks every seedbed, station and change folder in the instance and checks the model's four
invariants (<CORE>/tools/journey_status.py:18-27) — more than one seed at a seedbed root, more than one
open station, a station open with no active seed, a change folder with no change_request.md. A
violation it reports is usually the shape of a session that stopped in the middle.
Then compare where the journey stands against where the session left the work, and route:
| What the session did | The move that is owed | Owner |
|---|---|---|
| Met the station's reached-when | Close it and tick the seed | shukuba-retire |
| Worked the station, did not reach it, is setting it down | Park it, seed item left unticked | shukuba-park |
| Walked the last item on the seed's checklist | Retire the idea | nemawashi-retire |
| Decided the idea is dead — ruled out, superseded, not going to be done | Drop it | nemawashi-drop |
| Is setting the active idea down unfinished | Un-pick it back to the pool | nemawashi-unpick |
| Left a change open on its branch | Carry it on or seal it | <CORE>/launchers/chain-development/launcher.sh <project>, tobiishi-seal |
| Worked inside an open station and it is still open | Nothing — the station carries the position | — |
Six of those moves are seat-gated. shukuba-retire and nemawashi-retire halt outside the Scrum Master,
shukuba-park, nemawashi-unpick and tobiishi-seal outside the PM, and nemawashi-drop outside the Principal PM,
so for those rows the move that is owed is named and handed to that seat rather than run
from this session — which changes nothing about the gate below, since this sweep never runs any of them.
The last row is the common one, and it is a real answer rather than a gap. An open station whose file describes where the work stands is the continuation record. If the file no longer describes that, update the station file — that is a station edit, not a close-out invention.
Do not open a station, and do not pick a seed. Both are the PM's call
(<CORE>/docs/michi_agari.md § How we work, steps 1–2). A close-out that picks the next thing has
started the next session on the previous session's judgment.
Gate. Name the move and the skill that owns it. Wait to be told to run it.
Sweep 3 — loose findings
This is the sweep whose contents have no other home. A session that stays inside its scope accumulates things it noticed and correctly refused to do: a defect in a template it was not editing, a reference that no longer resolves, a capability something obviously wants. In the session they are obvious. An hour after it ends they are gone.
For each, decide whether it is already on the board — a seed in unpicked/, an open station, a line in
a project's docs. Search before writing:
grep -rn "<the distinguishing phrase>" system/projects/*/journey/ system/nemawashi/
If it is not, write one seed per idea into the journey/nemawashi/unpicked/ of the project whose
Agari it serves — not the project the session happened to be working in. A seed states what was found,
why it matters against that Agari, and what a station would have to settle. Keep it terse: a seed is a
working note, not a report.
If no project's Agari covers it, that is itself the finding. Say so rather than filing it somewhere close.
Gate. List the candidates and where each would land before writing any of them.
Sweep 4 — session-craft
A session sometimes earns a rule about how to work — check the tool's actual behaviour before planning against it; verify a filter by its effect rather than by reading it. That is different from a rule about the system, and the two live in different stores.
<CORE>/doctrine/governance/corrections_store.md owns the split: <CORE>/doctrine/ holds rules about
the system and its products; the corrections store holds session-craft, how a session conducts itself.
The subjects do not overlap, and neither store is the other's cache.
So for each candidate, do one thing only — say which store it belongs in, and why:
- Session-craft → the corrections store. Do not write it here. The store's format and mechanism
are the harness's, not kensaiapp's (
corrections_store.md:9-11), and a skill that writes it becomes a second writer of a store it does not own. - A rule about the system → the doctrine file that owns its subject, which is a doctrine edit with
its own routing through
<CORE>/doctrine/task_map.md, not a close-out action. - Recurred, and a doctrine file owns its subject → name it as a graduation candidate per
corrections_store.md§ Graduation. Naming is the whole action. Graduation is one act that states the rule and deletes the correction in the same breath, and doing half of it at session close leaves exactly the copy that section exists to prevent. - One incident, once → it stays a correction, and that is a finished state, not a backlog entry.
Gate. State the routing. Write nothing into either store from this skill.
The close-out summary
End with this, and nothing longer. It is the artifact the next session reads.
## Session close — <YYYY-MM-DD>
**Committed:** <sha> — <what> · <sha> — <what> (or: nothing)
**Journey:** <project> — <where it stands, and the move owed, or "no move owed">
**Seeds written:** <path> — <one line> (or: none)
**Craft routing:** <candidate> → <store>, <reason> (or: nothing durable shifted)
## Left open
<Every question this close-out could not answer, and who has to answer it. "none" when there is none —
never omitted, because an absent section reads as "nothing was left open" and a session that ends with
nothing open is the rare case, not the default.>
Anti-patterns
- Bundling the gates. Each sweep is shown and confirmed before the next runs. Batched, the owner approves a list rather than four decisions, and sweep 3 is the one that quietly empties.
- Skipping a sweep because it "looks clean." Sweeps 3 and 4 leave no trace in
git status. A clean tree is evidence about sweep 1 only. - Writing a no-op. If nothing durable shifted, say so. An invented seed or a manufactured correction costs more than the empty line it replaced.
- Performing a journey move because the owning skill is one call away. The verbs differ in ways that matter — park leaves the seed item unticked, retire ticks it — and a close-out reimplementing them will get that distinction wrong on the day it counts.
- Deciding the work is done. This skill closes a session, never a station, an idea, or a change.
Reference files
<CORE>/docs/michi_agari.md— the journey model and the loop sweep 2 routes against<CORE>/doctrine/governance/corrections_store.md— the two stores and what moves between them<CORE>/doctrine/governance/commit_via_builder.md— how sweep 1 commits<CORE>/tools/journey_status.py— the reader sweep 2 runs