-
Locate the handoff: if a topic is given, read claudedocs/handoff-<topic>.md; otherwise find the most recently modified claudedocs/handoff-*.md in the active repo (ls -t claudedocs/handoff-*.md | head). Not every repo uses that lowercase shape — civitai-manager names its handoff <civitai-manager>/claudedocs/SESSION-HANDOFF.md — so if the glob comes back empty, fall back to ls -t claudedocs/*HANDOFF*.md | head before concluding there is no handoff (resume-state.sh resolves it in exactly that order). If BOTH come back empty, say so and offer to reconstruct state from git/PRs instead — and say plainly that nothing was reconciled, rather than reporting the absence of drift as a clean bill of health.
🔴 If you know the doc, put its PATH in the argument. resume-state.sh reads a claudedocs/handoff-*.md / claudedocs/*HANDOFF*.md path out of a prose topic ("…the listing work; handoff: <path>"), which is the form this skill passes through verbatim — and only that shape. A bare README.md mentioned inside a prose topic is prose, not a handoff reference. ⚠ That is about the SCAN, not about the whole argument: an argument that IS a path to an existing file is taken as the handoff whatever it is named — resume-state.sh README.md reconciles README.md — because the explicit-path form accepts any filename by design. If you supply an argument and it resolves nothing — a mistyped topic, or a path that is not there — the run says so as a ! gap naming what you asked for and what it read instead, and withdraws the DRIFT all-clear. That gap means the digest is about a different initiative than you named — re-run with the path. A run with NO argument stays silent, because there "newest" is the contract rather than a guess.
The gap carries one extra clause — "the newest of N … MOVES between runs" — only when the fallback actually had two or more docs to choose between, because only then is it true.
🔴 The working-tree copy is a GUESS about what the handoff says — run step 2 FIRST and read the copy it names. Measured 2026-08-20: a datapacket-talos clone served a handoff 276 lines behind origin/trunk, and the whole resume was framed on it; it was caught by luck. That repo's CLAUDE.md records the same class twice more (a clone once served a skill file 692 commits stale) because a shared clone's checked-out branch is unpredictable and its local refs are routinely far behind. A missing file is not evidence either — git log origin/<default-branch> -- <path> before concluding a handoff does not exist. 🔴 And a third manifestation: a stale clone makes a merge TOOL pick the wrong base and report success — measured 2026-08-21, handoff_doc.py on a clone 313 behind would have rebuilt an 891-line doc from a 290-line base, ~601 lines discarded, exit 0. It warns about that now; the same staleness that misleads you misleads anything reading the tree.
You do not have to remember any of this: resume-state.sh fetches and compares before it reconciles, and prints the answer on its own line. Do not read the doc until you have read that line.
handoff-read: working-tree copy (identical to origin/trunk) — read the file in the tree; they are the same.
handoff-read: 🔴 origin/trunk copy (the working-tree copy is STALE: 412 lines local vs 688 on origin/trunk) — the tree copy is not what the last session wrote. A handoff-other-copy: /tmp/resume-handoff-XXXX.md line gives you the authoritative text as a file; read that path, and say in your report which copy you read. The digest has already reconciled against it, so the digest and the doc agree.
handoff-read: ⚠ working-tree copy, which has UNCOMMITTED edits and differs from origin/trunk — this session's work-in-progress wins, but it is unpushed; handoff-other-copy: holds the origin text for comparison.
handoff-read: working-tree copy — origin freshness UNCHECKED (…) — the comparison could not be made (no remote, no origin/<default-branch> ref, not a git repo). This is not a verification; do not report it as one.
-
Re-verify against live state FIRST — run the deterministic reconciler, don't hand-roll it. It runs before you read the doc on purpose: it is what decides which copy of the doc is authoritative, and reading the wrong one first is the failure this ordering exists to stop.
bash ~/workspace/devrc/scripts/resume-state.sh "$ARGUMENTS"
This is the initiative-scoped, on-demand collector (modeled on standup.sh). It resolves the handoff, then reconciles it against FRESH live state in one call and prints a compact digest: GIT/PR (branch ahead/behind, dirty, referenced PR states + CI, branch existence), WORKLOAD (handoff-named deployment readiness + canary phase — v1: datapacket), ALERTS (firing alerts scoped to the initiative's namespace), CLAWGATE (the task the handoff records, reconciled against the live board), and a DRIFT block. Interpret the digest — especially DRIFT (the lines where live state contradicts the handoff, e.g. a PR the doc calls in-flight has already merged). Do NOT re-derive this by hand-rolling git/kubectl/gh. It degrades gracefully (git-only) when a source is unreachable or the repo isn't datapacket; only reach for a targeted kubectl/gh drill-down if the digest flags something needing one. 🔴 An empty DRIFT is only good news if something was actually reconciled — check that FIRST, in two places. (a) The handoff: line: (none found — git-only) means no doc was loaded and nothing was reconciled at all. (b) The !! GAPS (N) banner inside DRIFT — a ruled-off block listing sources that did not answer, each line still prefixed ! (e.g. gh answered for 0 of 3 referenced PR(s)). It prints alongside real findings too, so a list of - findings is complete only if no gap block sits beside it. The digest states both conditions itself: (no handoff loaded — nothing to reconcile…) and (nothing detected, but a source did not answer — NOT a clean bill of health). Only (none detected — live state matches the handoff's claims) with no gap block is an actual all-clear. A handoff path outside any git repo now reports the gap instead of the all-clear; an unreachable still does not, so a datapacket resume that says has not checked workloads or alerts whatever says.
-
Read the handoff in full — the copy the handoff-read: line named, not reflexively the one in
the working tree — but treat its "Open investigations" section as RECALL, not live state.
🔴 A handoff's open-investigation block is exactly as stale-able as an index bullet, and nothing marks it. The status header is obviously dated; a mid-diagnosis block reads as current forever, because it is written in the present tense by someone who was mid-diagnosis. MEASURED 2026-08-19: a doc's leading hypothesis for an intermittent CI failure was superseded one day after the doc was written — root-caused, with a classifier, tests and a PR-comment integration already shipped in the same repo — and a session re-derived the retracted hypothesis, refuted a variant of it, measured a failure rate, and was about to build a capture mechanism that already existed.
MEASURED AGAIN 2026-08-20, and the block was well written — values, eliminations, a named "Next probe": every ruled-out candidate was still true, yet the framing was wrong. It reported the unattributed rows as an unidentified live producer growing at ~21/h; they were the repo's own test suite, 100% synthetic. A session that trusted the framing would have hunted a caller that does not exist. 🔴 Eliminations age well; the question they serve does not — so re-ask what the block is trying to explain before adopting its hypothesis, and prefer the block's own values over its narrative.
Before working any open item, check whether the repo moved under it:
git -C <repo> log --since=<doc-date> --oneline -- <the pipeline/script/dir the item is about>
A hit means read those commits before re-deriving anything. The cost is one command; the cost of skipping it is a whole session.
-
Surface what the subsystem index already records for this repo (read-only, ~1 command, no network):
python3 ~/workspace/devrc/scripts/lib/subsystem_recall.py --repo <repo>
This is the read half of the store /analyze-service and /handoff write to — the terse pointer sheet that outlives the handoff doc you just read. It had two writers and no reader, so nothing ever opened it at resume time.
What the bare command prints (the digest): the caveat, then a one-line INDEX of every entry in the scope — ref, N nuance (its ## Nuance / work-history bullet count, not entry size), sensitivity=, and — only when they fire — the badges 🔴 N OPEN, 🔴 N NEAR-MISS, ⚠ N UNVERIFIABLE, 🔴 NO <heading> — never truncated, then exactly ONE entry in full (## What it is + ## Pointers + ## Nuance / work-history), then a line saying the other bodies were listed but not printed. Measured 2026-08-13 on datapacket-talos, the scope holding 25 of the store's 29 entries: 4,876 B / ~1,219 tokens, against 31,485 B / ~7,871 tokens for the old default — which also hid 13 of the 25 entries. So it is now both cheaper and complete; the earlier claim that it "costs a page, not a dump" was false for the only scope big enough to matter, and this is the corrected, measured version.
⚠ Those byte figures are from 2026-08-13 and the scope has grown since — re-measure rather than quoting them. Two deltas measured 2026-08-21, when ## What it is was added to the printed body: the digest grew +266 B on datapacket-talos (37 entries), +244 B on civitai, +394 B on devrc — one body's worth, not one per entry — while --list grew by a flat +18 B on all three, which is the footer sentence and nothing else. The per-entry index rows carry no ## What it is at all, deliberately: that surface is printed once per entry on every read.
🔴 🔴 N OPEN means N bullets in that entry DECLARE unfinished business — re-check each against live state before acting on the entry. A remedy that has since landed reads exactly like one that has not: one entry proposed a one-line fix that shipped and went on being served as outstanding for 22 days. — the marker is opt-in and predates almost none of the corpus.
-
Report:
- One-paragraph "where things stand" (reconciled with what you just verified).
- Ranked next steps, with the single highest-leverage action first.
- Any drift you found between the handoff and live state.
- Anything the index recalled that bears on the next steps — labelled
from index, kept separate from what step 2 measured.
-
🔴 BEFORE ACTING ON A NEXT-STEP, CLAIM IT — the ranked list is a SHARED
QUEUE, and claim-work is the lock. This is a COMMAND, not a habit.
claim-work --list
SLUG=$(claim-work --slug-for <handoff-doc> <rank>)
claim-work "$SLUG" --subject "<the item, in your own words>"
rc 10 ⇒ STOP — it prints who holds it, since when, and what they called
it. Pick another item, or coordinate. rc 11 ⇒ the claim is past its TTL and
may be abandoned: decide explicitly, then claim-work --steal "$SLUG" or
--release "$SLUG". claim-work --release "$SLUG" when you finish or
abandon the item — an unreleased ref is the one way this blocks work.
🔴 It FAILS OPEN. No origin, no network, no auth ⇒ a loud stderr warning
and exit 0. A degraded run means you are UNCLAIMED, not that you hold it —
fall back to the manual half (gh pr list --state open before you start and
again before gh pr create, and push the branch the moment you create it).
Why a claim and not a check: whoever moves FIRST cannot see the second
session at all — it does not exist yet — so no pre-flight check can protect
them. The claim happens at DRAW time, before any work, and the push to
claim/<slug> is git's own atomic ref compare-and-swap, so two simultaneous
first movers resolve to exactly one winner.
🔴 Worktree isolation does NOT prevent this and is not the answer. Every
colliding session isolated correctly and no file was ever clobbered — this is
a TASK-ALLOCATION collision, and isolation is what HIDES it.
⚠ The exact-slug match is the HARD lock; --list's SUBJECT column is a SOFT
signal. It does not catch a reworded duplicate — read the list yourself.
📖 Measurements, rejected alternatives and the limitation:
~/.claude/skills/handoff/reference/shared-queue.md.
Then wait for direction. Pair: /handoff (it writes the index entries this step reads).