Land the session — commit, push, merge, file what was promised, clear the end check — and end on the archive line. Use to wrap up or end a session, or to clear what the end-check hook flagged.
Resources
2Install
npx skillscat add surreptakos/claude-dotfiles/session-end Install via the SkillsCat registry.
Finish a session
Four steps. Typing /session-end is the standing OK for every one of them; passive wrap-up
wording ("wrap up", "handing off") asks before each shared-state action instead.
- Commit and push. One commit that says what changed and why. A hook failure gets fixed and
the commit made again; never--no-verify.git push -u origin <branch>if there is no
upstream. - Open, wait, merge, pull. Complete when the PR reads MERGED and the main checkout's HEAD is
the merge commit. Only a failing check, branch protection or a refused merge ends the session
short of the archive line, named in one line.gh pr create --base <default> --head <branch>with aCloses #Nline per issue the
commits resolve.- Wait for the checks:
gh pr checks <n> --watch --fail-fastblocks until every check has a
verdict (the Windows restore test takes about eight minutes; rerun the command when the tool
timeout cuts it off). Pending checks are a wait, never a stop (Dan, 2026-09-30, after a
session ended on "10 of 12 checks green, merge waits on CI"). - Every check green:
gh pr merge <n> --squash, then on the anchor PCgit -C <main checkout> pull --ff-onlyso the scheduled task and the desktop routines run the merged code. - The session deletes only its own branch:
git push origin --delete <branch>ifdelete_branch_on_mergedid not, andgit branch -d(never-D). If the classifier
refuses, say in one line that the stale-ref sweep takes it on its next run, and file nothing.
- File what was promised. Read the conversation once for anything that will die with it: a
thing the user deferred ("later", "after X"), a thing you offered and never did, a known limit
you named, a question that got no answer, a step only the owner can take. Each is either
already on an open ticket (name the number), not worth tracking (say why in one line), or a new
ticket — publish every one through/to-ticketsin one batch, reaper group included, with no
approval round:/session-endis the approval (Dan, 2026-09-23). The weekly reaper parks what
should not have been filed. A line that hands work to someone without a#numberin it is a
ticket you have not filed yet. - Re-run the end check and clear it —
node ~/.claude/hooks/session-gate.js report --end --refresh(ornode ~/.claude/skills/session-check/check.js --endwhere the hook file is
absent). It reads the tree, the pushed state and the last run of every tracker job (below).
Resolve everySTOPand every!!, advisories included, whichever session or job raised them
(Dan, 2026-09-23): assign the milestone, reword the stale citation, rebuild or stamp the plugin,
then re-run the job or the check until the line is gone. What a job flags and leaves red is
cleared here, never handed off as aready-for-local-agentticket. The only lines left standing
are the ones no action in this session can change (the worktreeSTOP), each named in one line.
The reply opens with a summary of the whole session, shaped by the global rules' I-HAVE-ADHD
section (Dan, 2026-10-05). It covers everything the session did from its first message, not just
these four steps: re-read the conversation for it, since a summary built from the end check alone
drops the work that brought the session here. Plain English, outcomes over mechanics, one line per
item.
Its first line is a one-sentence verdict, plain text with no heading: what the session got done and
whether anything waits on him ("Session landed: the guard no longer freezes phone sessions; nothing
waits on you."). It is a result, not a second next action: the reply's one next action is its last
line. Then come these sections, each a bold heading line with a numbered list under it:
- What now works: at most five items, ranked by what matters most to him. Each says what is
different now and how he would see it ("a phone session past 250k tokens now answers with a
/compact line instead of going silent"), not just a PR number. Past five, the rest go in one
plain sentence after the list ("Also: 3 smaller fixes to ..."), never a sixth item. - Waiting on you: the steps no one else can take, each already a ticket on his queue, ranked,
with its#number. They are there so he knows they exist, not as things to do now: the one
thing to do now is the last line. At most five; past five, name the top five and say in one
sentence how many more the queue holds. Leave the heading out when there are none. - Left standing: each blocker that stopped one of the four steps, and each end-check line
nothing in the session could clear (the worktreeSTOP), one line each with the reason. At most
five; past five, say in one sentence how many more. Leave the heading out when there are none.
The reply ends with the block below, as plain lines, never bullets:
Landed: <PR or commit, one line each>
Filed: #<n> <title> — ready-for-agent | ready-for-human (or: none)
Next: archive this sessionNext: archive this session is the last line, verbatim, and only when the four steps (commit,
merge, file, end check) are clear; an end-check line step 4 allows to stand (the worktree STOP)
does not block it. When a step is blocked, the last line is Next: plus one thing Dan can do in
under two minutes to move the first blocked step, in step order: his own step when the blocker is
his (an approval, a UI toggle), otherwise the word that sends the session back to clear it ("Next:
reply 'keep going' and I fix the repo-tests failure, about 10 minutes").
The tracker jobs
Closure guard, board sweep, metadata audit, stale-ref sweep and tracker audit run on their own:
they reopen a ticket a merge closed with boxes unticked, move closed cards to Done, assign the
single open milestone, delete landed agent/* and claude/* refs, and audit the tracker.sweep-closed-to-done.js in this directory is the board-sweep job's script, not a step here.
In a cloud container
Same four steps. gh pr and gh issue are GraphQL and the proxy refuses them: step 2 uses the
GitHub MCP create_pull_request and merge_pull_request, step 3's tickets go through the same/to-tickets batch with MCP issue_write, and gh api repos/<owner>/<repo>/... (REST) works
for everything else. If the classifier refuses a bash gh api --method POST|PATCH, retry once,
then use the MCP tool for the same write.
Related
/session-start; a project's own docs/runbooks/session.md, if it has one.