The session-transition front door. Bare invocation TRIAGES the session — context utilization, task-boundary state from current.md, git state, armed /goal — announces one route, then ACTS: continue (checkpoint + one line), clear-next (durable state to disk, git verb, emit /clear), or end-window (full wrap, handoff rendered to handoff-prompt.md, Pick-up-here block). Use at any transition moment: task boundary, heavy context, or end of day. /task-handoff is the checkpoint library this skill calls.
Scanned 9/3/2026
Install to Claude Code
npx -y skills add aberson/skill-mesh --skill session-wrap --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Session Wrap?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/aberson-session-wrap)More formats (shields.io, HTML) on the badges page.
---
name: session-wrap
description: "The session-transition front door. Bare invocation TRIAGES the session — context utilization, task-boundary state from current.md, git state, armed /goal — announces one route, then ACTS: continue (checkpoint + one line), clear-next (durable state to disk, git verb, emit /clear), or end-window (full wrap, handoff rendered to handoff-prompt.md, Pick-up-here block). Use at any transition moment: task boundary, heavy context, or end of day. /task-handoff is the checkpoint library this skill calls."
user-invocable: true
---
# session-wrap
One decision-making front door for session transitions. Invoked bare, it TRIAGES the
session against mechanical signals, announces the chosen route in one line, then ACTS.
No mid-run (y/n) gates — bare invocation is the safest mode. The single ask-first
exception is a detected parallel-session anomaly before the git verb; the detection
pre-flight is the Git-verb router's Step A (section below).
Division of labor: `/task-handoff` is the checkpoint *library* this skill calls; the
`current.md` file contract is owned by
`.claude/references/task-state-schema.md` (workspace reference, not published in
this mirror; cite it, never restate it). Phase-shipping territory (README/plan updates, issue
closing, push-everything) belongs to `/repo-update` — the git-verb router delegates
there; this skill never duplicates it.
---
## Threshold constants (operator-tunable)
Defaults from community threshold doctrine (proactive boundary at ~60% utilization,
~120k-token quality "dumb zone", 95% auto-compact "too late"). The internal
degradation floor is unmeasured — these are defaults, not findings; when the floor
gets measured, one edit here moves them.
| Constant | Value | Raw-token proxy | Meaning |
|---|---|---|---|
| `CONTINUE_MAX_UTIL` | 60% | <=120k tokens | Below this and mid-task -> `continue` |
| `CLEARNEXT_UTIL` | 60% | >120k tokens | At or near a task boundary -> `clear-next` |
| `CLEARNEXT_FORCE_UTIL` | 75% | >150k tokens | Take the next boundary aggressively, regardless of task state |
| (end-window) | — | — | No threshold. Operator intent only ("done", "end of day", explicit `--end`), or no agent-completable next action exists |
Raw tokens are not a percentage: a percentage needs a model-aware window size, and
extended (>200k) windows exist on this machine. When the window size is unknown, apply
the raw-token proxies directly and, if a percentage is reported at all, SAY the
denominator is assumed — e.g. `162,340 tokens (~78% assuming a 200k window)`. Never
present an assumed percentage as a measurement.
---
## Step 0 — triage: collect, score, announce
**Read this session's own state first.** Before deriving any next action or route, read
**this session's** `sessions/<session-id>.md` (the session UUID from your scratchpad path;
fallback to the derived `current.md` rollup, then the freshest session file — resolution +
the per-session model are owned by the schema doc). Reading your OWN session file, not the
shared `current.md` rollup, is what keeps a concurrent window's task from surfacing as this
session's state. Absent file = no recorded task — it gets created on the first route write.
That file plus git is the state; conversation prose is not. Every next action this skill
writes or renders derives from it, never in parallel from prose.
Collect four signals:
**(a) Context utilization.** Chosen signal (decision doc:
[`docs/investigations/context-signal-spike.md`](../../../docs/investigations/context-signal-spike.md)):
the `message.usage` sum (`input_tokens + cache_creation_input_tokens +
cache_read_input_tokens`) of the LAST top-level main-chain assistant entry in the
session transcript JSONL. Run the reference implementation rather than reimplementing
the guarded recipe: `docs/investigations/high-context-usage-tools/read-context-signal.ps1`.
Skill-mode transcript resolution: glob `~/.claude/projects/<project-slug>/*.jsonl` and
require EXACTLY ONE file modified within the last ~2 minutes — zero or more than one
candidate is ambiguous and means signal absent (sibling-session risk; never blindly
take the newest). When the signal is absent for ANY reason, print exactly this line
(ASCII hyphen — this exact wording is the contract) and triage on (b)-(d) alone:
context signal unavailable - boundary-only triage
Never guess, estimate, or fabricate a token count or percentage — a fabricated number
is indistinguishable from a real one and steers the route wrong (measurement-validity
rule).
**(b) Task-boundary state.** From the `current.md` read above: Status + Next Action.
Plus the active plan's step `**Status:**` lines (plan located per CLAUDE.md § Plan
location — `plan.md`/`master_plan.md` at the project root or under
`plans/`/`docs/`/`documentation/`; descriptor-contract §4), and whether the
just-finished turn completed a step or phase. At/near a boundary = Status COMPLETE, a step just flipped
DONE, or the turn closed a task. Mid-task = everything else.
**(c) Git state.** Per touched repo — a multi-project session (2+ distinct project
dirs edited, or a project repo plus `dev/` workspace-root files) checks EACH repo:
branch, short SHA, dirty-file count, ahead-of-origin count.
**(d) Armed `/goal`.** An unmet agent-completable goal biases `continue`.
**Score — first match wins:**
1. Operator intent ("done", "end of day", explicit `--end`), or no agent-completable
next action exists -> `end-window`.
2. Utilization >= `CLEARNEXT_FORCE_UTIL` -> `clear-next` now (finish only the
in-flight edit, not the task).
3. Utilization >= `CLEARNEXT_UTIL` and at/near a boundary -> `clear-next`.
4. Everything else — below `CONTINUE_MAX_UTIL` and mid-task, signal absent with no
operator intent, armed unmet `/goal`, or any uncertainty -> `continue`.
`continue` is the bias because it is the cheapest wrong answer.
**Announce, then act.** Print exactly ONE triage line BEFORE acting, so a wrong route
is visible and correctable immediately:
triage: <route> | context: <N tokens (~X% assuming 200k)> | boundary: <mid-task | at boundary (<what>)> | git: <n dirty, m ahead[, per-repo]> | goal: <armed | none>
(substitute the fail-loud contract line for the context segment when the signal is
absent).
---
## Route: `continue`
Invoke `task-handoff --loop` via the Skill tool. Screen output is ONE composed line
total — the library's own `Checkpoint written.` line is subsumed into it, never
printed separately:
Checkpoint written — continuing (<one-clause reason from the triage>).
Nothing else — no summary, no rendered prompt, no wall of text.
## Route: `clear-next`
Durable state to disk, then the git verb, then hand the operator `/clear`. Execute in
this exact order — `current.md` first, render second, screen last:
1. **Write `current.md`** — invoke `task-handoff --loop --no-commit` via the Skill
tool (read-merge-write per the schema doc, which owns the per-field
append-vs-overwrite rules). Next Action = the exact command or skill invocation.
**No-regress clause:** the read-merge-write must never regress a Next Action that
is already the exact next command from a boundary write made earlier this same
turn/step (e.g. plan-expedite's `--next-task` write) — preserve it verbatim; the
render carries Next Action verbatim (rendering contract item 4), so an overwrite
here would silently drop it.
The route's own git verb (step 5) carries the commit — same no-double-commit
rationale as build-phase Step 2e. Do NOT use `--next-task` here: it commits and
pushes itself, doubling up with the route's git verb.
2. **Decisions log + salvage sweep** (section below) — bounded; results land in
`current.md` (§ Parked / Critical Gotchas) and the render, not on screen.
3. **Cheap memory subset only:** correct the project's MEMORY.md status pointer line
if this session made it wrong, and park unfiled TODOs; the full
memory/lessons/friction passes are end-window-only.
4. **Render `handoff-prompt.md`** from `current.md` + the decisions log (rendering
contract below).
5. **Execute the git verb** — run the Git-verb router (section below): anomaly
pre-flight, commit-owner decision, additive recommendation, one-line report.
The router's base commit is the carrying commit step 1 deferred; when it
delegates, `/repo-update`'s commit sweeps `current.md` in.
6. **Screen: the Pick-up-here block** (contract below), exact next command =
`/clear`. The next window resumes via the SessionStart hook re-injecting
`current.md`.
## Route: `end-window`
Everything in `clear-next`, same order — including step 1's
`task-handoff --loop --no-commit` write — with these passes inserted after step 3
(before the render, so their outcomes are renderable):
- **Full memory pass — read-then-report (invariants 1 and 4).** Read MEMORY.md
(`~/.claude/projects/<project-slug>/memory/MEMORY.md`) fully
(if the first Read reports a partial load, continue with offset reads until the
whole file is covered — a partial read cannot honestly claim "Read MEMORY.md"). For
every topic touched this session, state `existing entry for <topic> was
current|stale` or `no existing entry for <topic>` BEFORE describing any change.
Update stale entries in place; never append a duplicate. Multi-project sessions
check each touched project's heading. If MEMORY.md exceeds 200 lines or any line
exceeds 200 chars, add a `MEMORY.md over budget (X lines)` invariant flag to the
digest — do not auto-trim.
- **Lessons-learned sync.** Any feedback memory created or edited this session syncs
both layers: long form in `docs/lessons-learned.md` (matching `### Title` heading +
ToC entry), thin pointer in the `feedback_*.md`, index line in MEMORY.md. Never
leave the long form duplicated in both layers. Project-scoped memories do not sync
there.
- **Friction review.** Scan the session for patterns that would slow future sessions:
failed commands that needed rework, wrong assumptions, missing context, clunky
workflows. Actionable friction becomes a feedback memory (then syncs per the bullet
above). Skip one-off flukes entirely and never record retry counts (invariant 6). A
clean session reports nothing.
- **Docs staleness.** If plan.md or a session doc no longer reflects what shipped,
update it now or name it in the digest — never silently leave a stale doc. Cheap
side-check: if `docs/friction-catalog.md` exists and any `feedback_*.md` is newer
than its indexed date, add a `friction catalog stale` digest flag (do not
regenerate it).
The Pick-up-here block's exact next command becomes the fresh-window opener instead
of `/clear` (contract below) — the SessionStart hook does not fire on plain startup,
so the opener must carry the pointer. With opt-in `--spawn` (section below), the deep
link then auto-opens the next window pre-filled with that opener; the block on screen
stays the baseline.
---
## Git-verb router (clear-next + end-window, step 5)
The single owner of the route's git verb. Four steps, in order: A anomaly
pre-flight, B commit owner, C additive recommendation, D report. Multi-project
sessions run Steps A-C independently PER TOUCHED REPO — mixed outcomes across
repos are legal — and Step D joins the segments.
**Step A — anomaly pre-flight (before ANY verb, delegation included).**
CLAUDE.md § Parallel session safety and § Session wrap & commit discipline stay
senior to execute-by-default. Run all four checks BEFORE Step B
(PowerShell-first). Scope: check 1 runs at the workspace root — a trigger
there downgrades ALL repos; checks 2-4 run per touched repo — a trigger
downgrades that repo only.
On a trigger, the downgraded scope's Steps B/C are WITHHELD — the route is
not: the render and the Step D report still run, the pending repo's segment
reads `ask-first pending`, and route step 6 does NOT emit `/clear` while any
segment is pending. The Pick-up-here block's exact next command becomes the
ask response — approve or adjust the presented plan — never `/clear` past an
open gate (never co-locate a gate and an action; rendering-contract item 4).
Presentation: base-action path = the scoped add list + the commit message;
delegate path = the intended `/repo-update` invocation + the trigger evidence.
This ask is the single sanctioned (y/n) gate in this skill. The checks:
# 1. Foreign state file at the workspace root
Get-ChildItem -Force <workspace-root>\.plan-expedite-state.* | Where-Object { $_.LastWriteTime -gt (Get-Date).AddHours(-24) }
# 2. Worktrees beyond the main checkout, then two activity probes per hit
git worktree list
git log -1 --format=%cr <worktree-branch>
Get-Item <repo-root>\.git\worktrees\*\index -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -gt (Get-Date).AddHours(-24) }
# 3. Cross-repo/foreign edits
git status --porcelain
# 4. Foreign commits: reachable from other refs, not from this HEAD
git log --all --not HEAD --since='1 hour ago' --oneline
Trigger tests, one per check:
1. **Foreign state file** — a hit whose plan path does not match this
session's active plan (from `current.md`'s Task / plan reference).
Plan-mismatch or unknown = foreign = trigger.
2. **ACTIVE foreign worktree** — a worktree beyond the main checkout whose
branch tip committed within ~24h OR whose git index mtime is within ~24h
(index mtime moves on staging/checkout activity before any commit exists —
a tip-only test reads an uncommitted parallel session as stale). A worktree
failing both probes is stale: ONE digest note line, never an ask.
3. **Cross-repo/foreign edits** — a modified TRACKED file outside this
session's edit set. The edit set = the files the executor knows it edited
this session (its own history), corroborated by `current.md`'s Completed
entries; Key Files is a CURATED subset (schema: populated only on notable
discoveries), never the authoritative touched list. Untracked strays never
fire — they are simply not added.
4. **Foreign commits** — any output line. `--not HEAD` excludes this session's
own HEAD-lineage checkpoints; the session's own commits on OTHER refs (e.g.
an unmerged build-step worktree branch) may still surface — that ask errs
safe.
**Step B — commit owner (exactly one).** The scoped commit+push of session
files is the ALWAYS-RUN base action unless explicitly delegated:
- **Delegate to `/repo-update`** — phase/feature completed this session.
Detection: the active plan (discovered per Step 0(b)) exists, has >= 1
step, and every step reads `**Status:** DONE` (the >= 1-step guard blocks
the vacuous all-DONE of a step-less pointer plan), OR a build-phase
completion report was produced this session. Action: invoke `/repo-update`
via the Skill tool — it owns shipping (README/docs updates, commit, push,
posterity issue); this skill duplicates none of that work. (Task-state is now
gitignored, so nothing sweeps in `current.md`; route step 1's session-file write
is already durable on disk.) If `/repo-update` fails
partway, run the base action below so nothing is stranded, and surface the
repo-update failure in the digest.
- **Base action** — everything else. Detection: the delegate test above did
not match. Action: scoped `git add` of the session edit set (as defined in
check 3) + commit + push, EXECUTED by default. (Task-state is now gitignored —
`sessions/*.md` and the derived `current.md` are NOT committed; route step 1's
session-file write already durably landed on disk, so there is no
carrying-commit of state to defer.) A clean tree is a LEGAL outcome — e.g. a boundary
write earlier this turn (plan-expedite's `--next-task`) already carried the
commit+push; skip the empty commit and report `nothing to commit` in Step D.
Clean but AHEAD of origin (an earlier push failed): still push, and report
`pushed <n> pending` as the verb outcome instead.
Never `git add -A` — every add names explicit
paths; never add `handoff-prompt.md`.
**Step C — additive recommendation (independent of Step B).** Step C runs
regardless of which owner committed (withheld only when Step A downgraded its
scope, like Step B) and NEVER changes the commit owner; the recommended
COMMAND is never run mid-wrap.
Detection: the plan doc structurally changed this session — `### Step`
headings added/removed/renumbered, or step fields (Type / Depends on /
Done when) edited; more than Status-line flips. Action: add ONE recommendation
line to the digest —
- plan-review ran this session (in `current.md` Completed or this
conversation), or the plan carries a fresh review marker → recommend
`/repo-sync`. Order guard: never repo-sync before plan-review
([`.claude/rules/plan-and-issue-flow.md`](../../rules/plan-and-issue-flow.md)).
- review status unknown or absent → treat as NOT reviewed; recommend
`/plan-review` first.
**Step D — report.** One line total, one segment per touched repo,
` / `-joined. Invariant 3 owns the base segment shape (cross-reference, not
restated); Step D appends only the verb outcome, ONE shared shape whichever
Step-B path ran:
<invariant-3 segment> — <repo-update | committed N files + pushed @ <short-sha> | nothing to commit | ask-first pending>
---
## Rendering contract — `handoff-prompt.md`
`<git-root>/.claude/task-state/handoff-prompt.md` is a **rendering of `current.md`
plus the session's decisions log — never independently derived.** Every state field
in it (task, status, next action, SHAs, key files, gotchas) comes from the
just-written `current.md`; if the render needs a fact `current.md` lacks, write
`current.md` first, then render. Write order on both routes: `current.md` -> render
-> screen. Lifecycle + staleness rows live in the schema doc.
- **Untracked-on-purpose.** Session-local; never `git add` it. `current.md` remains
the committed durable state.
- **Self-contained for a zero-context reader**, in this shape:
1. Identity — project name, working directory, one line on what it is.
2. State — Status + one `HEAD @ <short-sha>` line per touched repo (invariant 3).
3. Verify-first instruction (invariant 2, exact form below).
4. Next action — verbatim from `current.md`. If it is gated on human review, split
it into an **Investigate** block ending "post findings and STOP" and a separate
**After approval** block — never co-locate a gate and an action (a zero-context
reader executes a single block sequentially).
5. Decisions log — N decisions = N bullets, rejected alternatives kept.
6. Key files + critical gotchas from `current.md`; parked/salvage pointers.
- **No nested code fences anywhere in the render** (invariant 5): commands as
2-space-indented plain lines, paths and inline code in single backticks.
- **No flukes, no retry counts** (invariant 6).
---
## Pick-up-here screen contract
The screen output of `clear-next` and `end-window` is exactly this — the ONLY
required reading (plus, when `--spawn` was typed, one trailing spawn-status line —
a fired-mechanism report, not part of the render). Digest first, numbered Step
blocks last — the final step's fenced block is the LAST thing on screen, so what to
run next is always the bottom of the output (operator contract, 2026-07-16):
## Pick up here
<digest: <=6 lines>
Full handoff: .claude/task-state/handoff-prompt.md
Step 1 — <label>:
```
<command>
```
Step N — <label>:
```
<final command(s)>
```
- **Digest (<=6 lines), then the pointer line, directly under the heading:** route +
signal values; the git verb executed (repo, branch, SHA); memory/docs updates by
name; invariant flags (`MEMORY.md over budget`, `friction catalog stale`, ...).
Exactly ONE pointer line to `handoff-prompt.md`. Everything longer lives in the
render, not on screen.
- **One fenced code block per step; steps split at observation points** (per
[`command-presentation.md`](../../rules/command-presentation.md)): `/clear` is its
own step; a `/model` reset is its own step; an atomic command pair (`/goal` +
`/build-phase`) shares ONE block, goal line first. Invariant 5 governs the INSIDE
of blocks (no fence ever nests within a block or within the render file) — using
fenced blocks on screen is the norm, not a violation.
- **`clear-next`:** a single step whose block is `/clear` (the SessionStart hook
re-injects `current.md` after the clear) — unless any router segment reads
`ask-first pending`; then the steps are replaced by the ask response (Git-verb
router Step A), never a step past the open gate.
- **`end-window` with a runnable Next Action pair** (the just-written `current.md`
Next Action is a paste-ready command pair, e.g. plan-expedite's `/goal` +
`/build-phase`): Step 1 `/clear` (recycle this window; the hook re-injects state);
then, ONLY when the session's model was explicitly overridden this session (e.g.
Fable for plan authoring — `/clear` keeps the window's session model), a
`/model <pinned-default>` step; then the FINAL step: the pair verbatim in one
block. The digest carries a one-line closed-window alternative:
`closing instead? fresh-window opener: Read <abs-path>\handoff-prompt.md fully, verify git state per its first instruction, then execute its Next Action.`
- **`end-window` without a runnable pair** (wait step, operator handoff, done-for-day
with nothing paste-ready): the single step is the fresh-window opener, verbatim
with an absolute path — never `/clear` (the SessionStart hook does not fire on
plain startup, and nothing runnable follows the clear), e.g.
`Read <git-root>\.claude\task-state\handoff-prompt.md fully, verify git state per its first instruction, then execute its Next Action.`
There is NO minimum length anywhere in this skill — no word-count floor for the
digest, the render, or any block. Terseness and specificity are coupled constraints;
see the note under the invariants.
---
## `--spawn` — auto-open the next window (end-window only, opt-in)
**Opt-in only.** `--spawn` fires only when the operator typed it explicitly (e.g.
`/session-wrap --end --spawn`) AND the routed action is `end-window`. Bare
`/session-wrap`, plain `--end`, the `continue` and `clear-next` routes, and every
chaining skill never auto-open a window — no default path fires a deep link
(plan-expedite's `--new-window` invokes `--end` WITHOUT `--spawn`; build-phase and
build-queue never spawn). `--spawn` alongside a non-`end-window` route is ignored
with this exact line:
--spawn ignored (route was <route>, not end-window).
Fire AFTER the Pick-up-here block is on screen — the baseline must exist whether or
not the link works — via `code --open-url` (PowerShell; re-derived from stranded
commit `1c241a7`, behavior verified 2026-06-22):
# --spawn deep link: try/catch because a missing `code` on PATH raises a
# terminating CommandNotFoundException in PS 5.1 (an unguarded call would
# die before the spawn-failed line could print)
try {
$gitRoot = (git rev-parse --show-toplevel).Trim() -replace '/','\'
$pointer = "Read $gitRoot\.claude\task-state\handoff-prompt.md fully, verify git state per its first instruction, then execute its Next Action."
code --open-url "vscode://anthropic.claude-code/open?prompt=$([uri]::EscapeDataString($pointer))"
if ($LASTEXITCODE -ne 0) { throw "code exited $LASTEXITCODE" }
Write-Output "spawned next window - press Enter there"
} catch {
Write-Output "spawn failed ($($_.Exception.Message)) - use the Pick-up-here block above"
}
- **The pointer IS the Pick-up-here fresh-window opener, verbatim** — one source of
truth. Never pass the handoff text itself (protocol-URI args have a length
ceiling); always the absolute git-root path, so the new session resolves it
regardless of cwd.
- **URL-encoding:** `[uri]::EscapeDataString` percent-encodes spaces, backslashes,
and colons, but leaves `(` `)` `'` un-encoded (live-verified on this machine's
.NET) — so the pointer text must avoid parentheses and apostrophes. Never
hand-build the query string.
- **`code --open-url`, NOT `Start-Process`** — `Start-Process "vscode://..."`
silently no-ops here (the URI reaches the OS handler but never routes to the
running extension's window).
- The deep link PRE-FILLS the prompt but does not auto-submit — the operator presses
Enter once in the spawned window. This window does not auto-close; it stays open
as a backup until the operator switches. First use shows a one-time OS trust
prompt ("allow ... to open this URI").
- **Armed unmet `/goal`:** the Stop hook re-drives this window regardless of the
spawn — true termination is blocked until the goal is met or cleared. The
end-window digest must surface an armed goal (triage signal (d)) so the operator
clears or meets it before the old window actually ends.
**Copy-paste remains the irreducible baseline** (command-presentation rule): with
`--spawn` absent, ignored, or failing, the Pick-up-here block already on screen is
the fully usable handoff — the deep link is best-effort enhancement, never a
replacement. After firing, report exactly ONE spawn-status line, ASCII hyphen, as
emitted by the snippet: `spawned next window - press Enter there`, or on any failure
(`code` missing from PATH, non-zero exit, headless/terminal session with no VS Code
extension) `spawn failed (<reason>) - use the Pick-up-here block above`.
---
## Decisions log + salvage sweep (clear-next + end-window)
Not a session summary. Two bounded passes:
1. **Decisions log.** Enumerate the decisions made this session and the alternatives
REJECTED — N decisions = N bullets, keeping but/except constraints ("chose X over
Y because Z, except in case W"). Rejected alternatives are the part a fresh window
cannot re-derive; keep them.
2. **Salvage sweep.** List knowledge that dies with this window: investigation
findings written nowhere, seed docs worth creating, TODOs discovered but not
filed. Each item is either **written now** (if it takes <= a few minutes) or
**parked** as a pointer in `current.md` § Parked plus the project's MEMORY.md
entry. Nothing gets a third option.
---
## The six behavioral invariants
Explicit requirements — every `clear-next`/`end-window` run satisfies all that apply:
1. **Read-then-report memory discipline.** Read MEMORY.md and the touched memory
files BEFORE updating them; report what was read and the per-topic
current/stale/absent verdicts before describing changes (full form in the
end-window route).
2. **Git-verify-first + SHA anchor.** The render states `HEAD @ <short-sha>` and its
verify-first instruction reads: *"First action — verify git state matches this
prompt: run `git log --oneline -5` and `git rev-parse --short HEAD`. If HEAD does
not match the SHA above, this prompt is stale — re-orient against actual git state
before doing any work."* (Saved prompts freeze a pre-execution view; git is the
only live state.)
3. **Per-repo SHA lines in multi-project sessions.** Every touched repo gets its own
` / `-delimited status segment (name, branch, ahead-count, dirty state — e.g.
`toybox master clean / dev master 2 unpushed, 1 dirty`) and its own
`HEAD @ <sha>` line in the render. One combined SHA is non-conforming.
4. **Duplicate-memory guard + MEMORY.md budget warning.** Check for an existing
memory before writing; update stale entries instead of appending duplicates.
Over-budget MEMORY.md (>200 lines, or any line >200 chars) raises a digest flag,
never an auto-trim.
5. **No nested code fences** in the render or any copy-paste block — indented command
lines and single backticks only; a triple backtick inside a copy-paste block
terminates it and breaks the paste.
6. **Fluke-exclusion.** Transient failures, one-off typos, and retry counts appear
nowhere: not in the render, not in the digest, not in memory. Describe the
pattern, never the episode.
**Coupled-constraint note (edit these together).** Invariants 5-6 plus the <=6-line
digest and the no-floor rule are the *terseness* side; invariants 1-3 plus the
verbatim next action are the *specificity* side. Edited in isolation they regress
each other — 4 of the first 8 eval iterations on the predecessor skill were discarded
for exactly that. Any future edit to one side must re-check the other.
---
## Flags
- **bare** — triage (Step 0), then the routed action. The default and safest mode.
Never fires a deep link.
- **`--end`** — operator intent made explicit: skip threshold scoring, route
`end-window`. (`/task-handoff --end` delegates here.) An optional trailing
free-text token (e.g. the plan path plan-expedite passes) is an advisory focus
hint only — every rendered next action still derives from `current.md`.
- **`--spawn`** — opt-in deep-link auto-open of the next window whenever the routed
action is `end-window`: typically typed as `--end --spawn`, but bare `--spawn`
also fires if triage itself routes `end-window`, and is otherwise ignored with the
exact line in the `--spawn` section above. Nothing ever spawns without the
explicit flag.
- **`--advise`** — triage (Step 0) + a read-only salvage-sweep preview, then the
4-verdict banner + two-line loss report (section below) and STOP. Never writes,
never runs a git verb, never emits `/clear`; `--end`/`--spawn` alongside it are
ignored. `SAFE TO CLOSE` exists only here — bare triage still scores exactly
three routes.
---
## `--advise` — verdict + loss report (read-only, never acts)
For the returning operator who wants the triage verdict WITHOUT the action — "can I
close this window without losing anything?".
- **Same triage, plus a preview.** `--advise` runs Step 0 triage exactly as bare mode
does (same signals, same first-match-wins scoring) plus a READ-ONLY preview of the
salvage sweep — what `end-window`'s sweep (section above) WOULD find: uncommitted
work, unpushed commits, un-checkpointed or git-inconsistent `current.md` state,
findings and TODOs written nowhere. Freshness follows the staleness threshold owned
by [`task-state-schema.md`](../../references/task-state-schema.md); consistency is
Step 0's own Session-SHA-vs-HEAD signal.
- **Prints, then STOPS.** The report below is the entire output. Zero writes, zero
git mutations: no `current.md` write, no render, no git verb, no `task-handoff` or
`/repo-update` invocation, no Pick-up-here block, no `/clear` emission, no spawn.
- **Bare mode untouched.** The 3-route triage-then-act contract runs only when
`--advise` is absent, and `SAFE TO CLOSE` exists only here, never as a fourth bare
route.
- **Flag interplay.** `--end`/`--spawn` alongside `--advise` are ignored (advise
never acts, so there is nothing to force or spawn).
The triage line still prints first (Step 0's announce contract), with the route
segment marked as computed-not-acted:
triage: advise (would route <route>) | context: <N tokens (~X% assuming 200k)> | boundary: <mid-task | at boundary (<what>)> | git: <n dirty, m ahead[, per-repo]> | goal: <armed | none>
Then the report — one verdict banner plus a two-line loss report, nothing else:
## <VERDICT>
Already durable: <what is safe, with evidence - commits/pushes with short SHAs, current.md Last written timestamp + freshness verdict, Session SHA vs HEAD>
Dies with this window: <each at-risk salvage-preview item with a count plus a path/SHA/identifier - or exactly `nothing` when the preview is empty>
**The four verdicts** — exactly one banner per run, from this closed set:
| Verdict | Condition |
|---|---|
| `KEEP GOING` | Triage would route `continue`. |
| `RECYCLE WINDOW` | Triage would route `clear-next`. |
| `WRAP & CLOSE` | Triage would route `end-window` AND something would die with the window. |
| `SAFE TO CLOSE` | `end-window` would be a NO-OP — ALL of: `current.md` fresh (schema-doc threshold) and consistent with git (Session SHA matches HEAD), clean tree in every touched repo, nothing unpushed/ahead anywhere, no armed `/goal`, salvage preview empty. |
The two end-window verdicts partition that route: every no-op condition holds ->
`SAFE TO CLOSE`; any single failure -> `WRAP & CLOSE`, and the failing item IS the
loss — it lands on the `Dies with this window:` line, named concretely. The loss
report is the centerpiece (the operator's real anxiety is losing work): hedged prose
("some work may be lost") is a defect — SHAs, counts, timestamps, and paths are the
contract, and an empty preview reads exactly `nothing`.
## Maintenance
The `evals/` suite targets THIS triage contract (rebuilt 2026-07-12, Step 7 / #297;
`--advise` category added 2026-07-13, Step 3 / #304): **26 assertions** across **6
categories** in `evals/evals.json` (passing threshold **24/26**), **6 scenarios** in
`evals/test_scenarios.json` (one per route, the signal-absent fail-loud path, the
`--advise` SAFE-vs-WRAP close-check, and the end-window runnable-pair handoff), and a golden corpus of 9 goods + 27
single-defect bads under `evals/golden/` (manifest.json maps each bad to the one
assertion it trips). v3.2 (2026-07-16) reshaped the Pick-up-here block (digest first,
fenced Step blocks last, end-window pair/no-pair branches) — assertions 7/8/10 and
every block-bearing golden updated together. Any edit that changes an output contract here (triage line,
route output, Pick-up-here block, render invariants, advise verdict banner or loss
report) must update the affected assertions and goldens in the same diff, keeping
this footer's numbers equal to `evals.json`'s. Terseness and specificity assertions
are coupled (see the invariants note) — re-check both sides after any one-sided
edit.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!