You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
a template helper trailhead-work-state.js (set --map --ticket --title --step --auto, clear): atomic write of .trailhead/work-state.json, field validation, session stamped from the host session id when exposed (CLAUDE_CODE_SESSION_ID), updatedAt stamped; unit-tested;
the skill prose calls it at work-start, at each step change (discuss | plan | execute | verify | resolve | paused), on auto start/stop, keeps it on pause and clears it at Resolve with session-ticket; resolved via the same three template dirs as the commit-msg sync, a missing helper never blocks the work;
.trailhead/work-state.json gitignored like session-ticket; session-ticket and the commit-msg hook unchanged;
the Codex projection carries the helper and the calls (host-neutral, no mod needed).
Done when working a ticket on Claude Code and on Codex leaves an up-to-date work-state.json at every step and none after Resolve.
Goal. Every worked ticket leaves an up-to-date .trailhead/work-state.json at the working root at each step, on Claude Code and Codex alike, and none after Resolve. Implements the resolution of Where does the mod read the work state from? (#200). Commits land on feat/mod (this map's integration branch).
Steps
Helper, test first (TDD at the seam): plugins/trailhead/hooks/lib/work-state.test.js (RED), then plugins/trailhead/templates/trailhead-work-state.js (GREEN). Self-contained, same shape as trailhead-commit-msg-sync.js (pure functions exported, main(argv, {cwd, stdout, env}) injectable).
CLI: set [--repo <dir>] [--map <n>|none] [--ticket <n>] [--title <t>] [--step <step>] [--auto true|false] and clear [--repo <dir>]; --repo defaults to cwd.
setmerges onto the existing file (a step change passes only --step), except when --ticket names a different ticket than the file holds: then it starts from an empty state (no carry-over of a stale title/map). A resulting state without a ticket or a step is a usage error.
Validation: map positive int or none (null, a whiteboard ticket); ticket positive int; step in discuss | plan | execute | verify | resolve | paused; title trimmed, control chars/newlines collapsed to spaces, capped at 200 chars; autotrue|false (default false on a fresh state). Unknown flag, missing value, or an invalid value -> exit 2 with a stderr line, nothing written.
Stamps: session from CLAUDE_CODE_SESSION_ID when set and non-empty, else null; updatedAt ISO-8601 now. Shape exactly { map, ticket, title, step, auto, session, updatedAt } (matches types/index.d.tsWorkState).
Atomic write: mkdir -p <repo>/.trailhead, write a unique temp file in that dir, rename over work-state.json, temp cleaned on failure. A corrupt existing file is treated as empty (overwritten, never a crash).
clear: unlink if present. Output one JSON line {status, path, state?}, status written | cleared | absent | skipped (skipped = unexpected I/O error, message carried; exit 0 so it never blocks the caller).
Tests cover: fresh set, merge on step change, new ticket resets, none map, validation failures (exit 2, no file), title sanitising, session from env vs absent, atomic write leaves no temp files, corrupt file recovery, clear present/absent, JSON output line.
Gitignore: add .trailhead/work-state.json to the repo .gitignore.
Prose, one canonical paragraph + call sites (source docs, English, no em-dashes):
skills/_shared/teamwork.md: a Work state file paragraph beside the commit-msg hook one: what the file is, <templates> resolved by the same three-dir lookup as the commit-msg sync, the set/clear forms, gitignored like session-ticket, independent of session-ticket and the commit-msg hook, and that a missing helper or a non-zero exit is silent and never blocks the work (no user-facing line).
skills/trailhead-work/SKILL.md: Work the map step 2, a bullet after the session-ticket marker: set --map <n> --ticket <n> --title "<title>" --step discuss at the working root (add the gitignore entry if absent); quick bullet: same, --map none for a whiteboard ticket.
skills/trailhead-work/references/ticket-engines.md: one standing Work state (every type) paragraph near the top mapping steps: build Discuss/Plan/Execute/Verify/Resolve -> discuss/plan/execute/verify/resolve; bug Repro+Diagnose -> discuss, Fix -> execute, Verify -> verify, Resolve -> resolve; decision/prototype/task -> discuss until resolve; a loop back from Verify to Execute/Fix sets execute again.
skills/_shared/session-handoff.md: at the marker removal, also clear the work state.
skills/_shared/teamwork.md Pause/Resume: pause sets --step paused and keeps the file whether or not the claim is released; resume sets the recorded next step (re-creating the file if absent).
skills/trailhead-work/references/auto.md: during a run every set carries --auto true; at run end (drained or interrupt) a remaining file gets set --auto false.
Codex projection: the helper rides templates/ wholesale and the prose is projected; add pins in bin/trailhead.test.js (helper projected byte-identical on --codex) and bin/lib/codex-projection.test.js (convertToCodex keeps trailhead-work-state.js and CLAUDE_CODE_SESSION_ID intact; the projected work skill carries the set/clear calls).
Seams
Helper CLI contract (main with injected cwd/env/stdout) and its pure mergeState/validate functions; the projection text transform.
npm test green (the new suite is picked up by scripts/test.js under hooks/).
Manual run in a temp repo: set at work-start writes the full shape with session from CLAUDE_CODE_SESSION_ID; set --step plan updates only step + updatedAt; clear removes it; on a --codex install the projected helper behaves the same with session: null.
session-ticket handling and the commit-msg hook untouched (no diff in templates/trailhead-commit-msg, hooks/lib/commit-message-check.js).
Every prose call site names the same set/clear forms; no em-dashes introduced.
Goal. Every worked ticket leaves an up-to-date .trailhead/work-state.json at the working root at each step, on Claude Code and Codex alike, and none after Resolve. Implements the resolution of Where does the mod read the work state from? (#200). Commits land on feat/mod (this map's integration branch).
Steps
Helper, test first (TDD at the seam): plugins/trailhead/hooks/lib/work-state.test.js (RED), then plugins/trailhead/templates/trailhead-work-state.js (GREEN). Self-contained, same shape as trailhead-commit-msg-sync.js (pure functions exported, main(argv, {cwd, stdout, env}) injectable).
CLI: set [--repo <dir>] [--map <n>|none] [--ticket <n>] [--title <t>] [--step <step>] [--auto true|false] and clear [--repo <dir>]; --repo defaults to cwd.
setmerges onto the existing file (a step change passes only --step), except when --ticket names a different ticket than the file holds: then it starts from an empty state (no carry-over of a stale title/map). The whole resulting state is validated and normalised after the merge: an existing field that fails validation is dropped (treated as absent), never carried over; a resulting state without a ticket or a step is a usage error.
Validation: map positive int or none (null, a whiteboard ticket); ticket positive int; step in discuss | plan | execute | verify | resolve | paused; title trimmed, control chars/newlines collapsed to spaces, capped at 200 chars; autotrue|false (default false on a fresh state). Unknown flag, missing value, or an invalid value -> exit 2 with a stderr line, nothing written.
Stamps: session from CLAUDE_CODE_SESSION_ID when set and non-empty, else null; updatedAt ISO-8601 now. Shape exactly { map, ticket, title, step, auto, session, updatedAt } (matches types/index.d.tsWorkState).
Atomic write: mkdir -p <repo>/.trailhead, write a unique temp file in that dir, rename over work-state.json, temp cleaned on failure. A corrupt existing file is treated as empty (overwritten, never a crash).
clear: unlink if present. Output one JSON line {status, path, state?}, status written | cleared | absent | skipped (skipped = unexpected I/O error, message carried; exit 0 so it never blocks the caller).
Tests cover: fresh set, merge on step change, new ticket resets, none map, validation failures (exit 2, no file), title sanitising, session from env vs absent, corrupt file recovery, a malformed-but-valid-JSON existing file (bad fields dropped, not carried), clear present/absent, JSON output line, and failure injection (injected fs whose write or rename throws: the previous valid file survives byte-identical and no temp file is left).
Gitignore: add .trailhead/work-state.json to the repo .gitignore.
Prose, one canonical paragraph + call sites (source docs, English, no em-dashes):
skills/_shared/teamwork.md: a Work state file paragraph beside the commit-msg hook one: what the file is, <templates> resolved by the same three-dir lookup as the commit-msg sync, the set/clear forms, gitignored like session-ticket, independent of session-ticket and the commit-msg hook, and that a missing helper or a non-zero exit is silent and never blocks the work (no user-facing line).
skills/trailhead-work/SKILL.md: Work the map step 2, a last bullet, after the isolation workspace is set up (the working root is final only then): set --map <n> --ticket <n> --title "<title>" --step discuss at the working root (add the gitignore entry if absent); quick bullet: same, --map none for a whiteboard ticket.
skills/trailhead-work/references/ticket-engines.md: one standing Work state (every type) paragraph near the top mapping steps: build Discuss/Plan/Execute/Verify/Resolve -> discuss/plan/execute/verify/resolve; bug Repro+Diagnose -> discuss, Fix -> execute, Verify -> verify, Resolve -> resolve; decision/prototype/task -> discuss until resolve; a loop back from Verify to Execute/Fix sets execute again; a UAT follow-up (UAT of:) sets verify. research tickets never write it: they run AFK and possibly in parallel, so the single file tracks only the one ticket in play.
skills/_shared/session-handoff.md: at the marker removal, also clear the work state.
skills/_shared/teamwork.md Pause/Resume: pause sets --step paused and keeps the file whether or not the claim is released; resume sets the recorded next step (re-creating the file if absent).
skills/trailhead-work/references/auto.md: during a run every set carries --auto true; at run end (drained or interrupt) a remaining file gets set --auto false.
Codex projection: the helper rides templates/ wholesale and the prose is projected; add pins in bin/trailhead.test.js (helper projected byte-identical on --codex) and bin/lib/codex-projection.test.js (convertToCodex keeps trailhead-work-state.js and CLAUDE_CODE_SESSION_ID intact; the projected work skill carries the set/clear calls).
Seams
Helper CLI contract (main with injected cwd/env/stdout) and its pure mergeState/validate functions; the projection text transform.
npm test green (the new suite is picked up by scripts/test.js under hooks/).
Manual run in a temp repo: set at work-start writes the full shape with session from CLAUDE_CODE_SESSION_ID; set --step plan updates only step + updatedAt; clear removes it; on a --codex install the projected helper behaves the same with session: null.
session-ticket handling and the commit-msg hook untouched (no diff in templates/trailhead-commit-msg, hooks/lib/commit-message-check.js).
Every prose call site names the same set/clear forms; no em-dashes introduced.
Reviewer: codex (read-only, low effort), one round. The revised PLAN above resolves every blocking concern.
Blocking: initial write placed before the isolated workspace exists. Resolved: the initial set is the last work-start bullet, after the workspace is set up, so it lands at the final working root.
Blocking: parallel research tickets cannot share one file. Resolved: research never writes the work state; the file tracks only the one ticket in play.
Blocking: merged existing data not validated. Resolved: the whole post-merge state is validated; invalid existing fields are dropped, never carried.
Non-blocking: UAT follow-ups map to verify. Accepted.
Non-blocking: failure-injection test for atomic replacement. Accepted.
Non-blocking: prose lifecycle-ordering assertions. Deferred: ordering in prose is reviewed at Verify; string-order tests over Markdown would be brittle. Projection pins stay on the helper and the call forms.
Tests.npm test: 23 ok/skipped, 0 failed (includes the new hooks/lib/work-state.test.js, 75 checks with failure injection, the Codex projection pins, claude plugin validate, claude plugin test).
W1 (warning): resume / pause in a fresh workspace used the step-only set, which exits 2 when no file exists, so the work state was silently never re-created. fixed in 4ddb6ab (Resume and the Work state file paragraph now pass the full work-start form where the file may be absent).
I1 (info): title defaulted to "" though the contract admits null. fixed in df51aa2 (no title -> null, tests updated).
Goal-backward verification: met. Helper run in a temp repo through set / step changes / --auto / new ticket / clear, with and without CLAUDE_CODE_SESSION_ID; a --codex install into a temp dir carries the helper byte-identical (same behaviour, session: null) and the projected prose carries the calls at work-start, each step, pause, resume, auto and Resolve; .trailhead/work-state.json gitignored; session-ticket and the commit-msg hook untouched; no em-dashes introduced.
Acceptance testing: not user-facing (local state file for tooling, no UI yet), so none owed.
Skill prose: canonical Work state file paragraph in _shared/teamwork.md; calls at work-start (after workspace setup, --map none for whiteboard), at each step per the mapping in ticket-engines.md (UAT follow-ups -> verify, research excluded), on pause/resume, during auto (--auto true, --auto false at run end), and clear at Resolve with session-ticket (b3274ee, 4ddb6ab).
Codex: helper rides templates/ and the prose is projected; pinned by tests (f03782c).
Verification and findings ledger: see the VERIFY comment above (all findings fixed).
Activity
ToRvaLDz commentedon Oct 10, 2026
PLAN
Goal. Every worked ticket leaves an up-to-date
.trailhead/work-state.jsonat the working root at each step, on Claude Code and Codex alike, and none after Resolve. Implements the resolution of Where does the mod read the work state from? (#200). Commits land onfeat/mod(this map's integration branch).Steps
plugins/trailhead/hooks/lib/work-state.test.js(RED), thenplugins/trailhead/templates/trailhead-work-state.js(GREEN). Self-contained, same shape astrailhead-commit-msg-sync.js(pure functions exported,main(argv, {cwd, stdout, env})injectable).set [--repo <dir>] [--map <n>|none] [--ticket <n>] [--title <t>] [--step <step>] [--auto true|false]andclear [--repo <dir>];--repodefaults to cwd.setmerges onto the existing file (a step change passes only--step), except when--ticketnames a different ticket than the file holds: then it starts from an empty state (no carry-over of a stale title/map). A resulting state without a ticket or a step is a usage error.mappositive int ornone(null, a whiteboard ticket);ticketpositive int;stepindiscuss | plan | execute | verify | resolve | paused;titletrimmed, control chars/newlines collapsed to spaces, capped at 200 chars;autotrue|false(default false on a fresh state). Unknown flag, missing value, or an invalid value -> exit 2 with a stderr line, nothing written.sessionfromCLAUDE_CODE_SESSION_IDwhen set and non-empty, else null;updatedAtISO-8601 now. Shape exactly{ map, ticket, title, step, auto, session, updatedAt }(matchestypes/index.d.tsWorkState).mkdir -p <repo>/.trailhead, write a unique temp file in that dir, rename overwork-state.json, temp cleaned on failure. A corrupt existing file is treated as empty (overwritten, never a crash).clear: unlink if present. Output one JSON line{status, path, state?}, statuswritten | cleared | absent | skipped(skipped = unexpected I/O error, message carried; exit 0 so it never blocks the caller).nonemap, validation failures (exit 2, no file), title sanitising, session from env vs absent, atomic write leaves no temp files, corrupt file recovery, clear present/absent, JSON output line..trailhead/work-state.jsonto the repo.gitignore.skills/_shared/teamwork.md: a Work state file paragraph beside the commit-msg hook one: what the file is,<templates>resolved by the same three-dir lookup as the commit-msg sync, theset/clearforms, gitignored likesession-ticket, independent ofsession-ticketand the commit-msg hook, and that a missing helper or a non-zero exit is silent and never blocks the work (no user-facing line).skills/trailhead-work/SKILL.md: Work the map step 2, a bullet after the session-ticket marker:set --map <n> --ticket <n> --title "<title>" --step discussat the working root (add the gitignore entry if absent);quickbullet: same,--map nonefor a whiteboard ticket.skills/trailhead-work/references/ticket-engines.md: one standing Work state (every type) paragraph near the top mapping steps: build Discuss/Plan/Execute/Verify/Resolve ->discuss/plan/execute/verify/resolve; bug Repro+Diagnose ->discuss, Fix ->execute, Verify ->verify, Resolve ->resolve; decision/prototype/task ->discussuntilresolve; a loop back from Verify to Execute/Fix setsexecuteagain.skills/_shared/session-handoff.md: at the marker removal, alsoclearthe work state.skills/_shared/teamwork.mdPause/Resume: pause sets--step pausedand keeps the file whether or not the claim is released; resume sets the recorded next step (re-creating the file if absent).skills/trailhead-work/references/auto.md: during a run everysetcarries--auto true; at run end (drained or interrupt) a remaining file getsset --auto false.templates/wholesale and the prose is projected; add pins inbin/trailhead.test.js(helper projected byte-identical on--codex) andbin/lib/codex-projection.test.js(convertToCodexkeepstrailhead-work-state.jsandCLAUDE_CODE_SESSION_IDintact; the projected work skill carries theset/clearcalls).Seams
Helper CLI contract (
mainwith injected cwd/env/stdout) and its puremergeState/validatefunctions; the projection text transform.Files touched
plugins/trailhead/templates/trailhead-work-state.js(new),plugins/trailhead/hooks/lib/work-state.test.js(new),.gitignore,plugins/trailhead/skills/_shared/{teamwork,session-handoff}.md,plugins/trailhead/skills/trailhead-work/SKILL.md,plugins/trailhead/skills/trailhead-work/references/{ticket-engines,auto}.md,bin/trailhead.test.js,bin/lib/codex-projection.test.js.Verification criteria
npm testgreen (the new suite is picked up byscripts/test.jsunderhooks/).setat work-start writes the full shape withsessionfromCLAUDE_CODE_SESSION_ID;set --step planupdates only step + updatedAt;clearremoves it; on a--codexinstall the projected helper behaves the same withsession: null.session-tickethandling and the commit-msg hook untouched (no diff intemplates/trailhead-commit-msg,hooks/lib/commit-message-check.js).set/clearforms; no em-dashes introduced.ToRvaLDz commentedon Oct 10, 2026
PLAN (revised after plan review)
Goal. Every worked ticket leaves an up-to-date
.trailhead/work-state.jsonat the working root at each step, on Claude Code and Codex alike, and none after Resolve. Implements the resolution of Where does the mod read the work state from? (#200). Commits land onfeat/mod(this map's integration branch).Steps
plugins/trailhead/hooks/lib/work-state.test.js(RED), thenplugins/trailhead/templates/trailhead-work-state.js(GREEN). Self-contained, same shape astrailhead-commit-msg-sync.js(pure functions exported,main(argv, {cwd, stdout, env})injectable).set [--repo <dir>] [--map <n>|none] [--ticket <n>] [--title <t>] [--step <step>] [--auto true|false]andclear [--repo <dir>];--repodefaults to cwd.setmerges onto the existing file (a step change passes only--step), except when--ticketnames a different ticket than the file holds: then it starts from an empty state (no carry-over of a stale title/map). The whole resulting state is validated and normalised after the merge: an existing field that fails validation is dropped (treated as absent), never carried over; a resulting state without a ticket or a step is a usage error.mappositive int ornone(null, a whiteboard ticket);ticketpositive int;stepindiscuss | plan | execute | verify | resolve | paused;titletrimmed, control chars/newlines collapsed to spaces, capped at 200 chars;autotrue|false(default false on a fresh state). Unknown flag, missing value, or an invalid value -> exit 2 with a stderr line, nothing written.sessionfromCLAUDE_CODE_SESSION_IDwhen set and non-empty, else null;updatedAtISO-8601 now. Shape exactly{ map, ticket, title, step, auto, session, updatedAt }(matchestypes/index.d.tsWorkState).mkdir -p <repo>/.trailhead, write a unique temp file in that dir, rename overwork-state.json, temp cleaned on failure. A corrupt existing file is treated as empty (overwritten, never a crash).clear: unlink if present. Output one JSON line{status, path, state?}, statuswritten | cleared | absent | skipped(skipped = unexpected I/O error, message carried; exit 0 so it never blocks the caller).nonemap, validation failures (exit 2, no file), title sanitising, session from env vs absent, corrupt file recovery, a malformed-but-valid-JSON existing file (bad fields dropped, not carried), clear present/absent, JSON output line, and failure injection (injected fs whose write or rename throws: the previous valid file survives byte-identical and no temp file is left)..trailhead/work-state.jsonto the repo.gitignore.skills/_shared/teamwork.md: a Work state file paragraph beside the commit-msg hook one: what the file is,<templates>resolved by the same three-dir lookup as the commit-msg sync, theset/clearforms, gitignored likesession-ticket, independent ofsession-ticketand the commit-msg hook, and that a missing helper or a non-zero exit is silent and never blocks the work (no user-facing line).skills/trailhead-work/SKILL.md: Work the map step 2, a last bullet, after the isolation workspace is set up (the working root is final only then):set --map <n> --ticket <n> --title "<title>" --step discussat the working root (add the gitignore entry if absent);quickbullet: same,--map nonefor a whiteboard ticket.skills/trailhead-work/references/ticket-engines.md: one standing Work state (every type) paragraph near the top mapping steps: build Discuss/Plan/Execute/Verify/Resolve ->discuss/plan/execute/verify/resolve; bug Repro+Diagnose ->discuss, Fix ->execute, Verify ->verify, Resolve ->resolve; decision/prototype/task ->discussuntilresolve; a loop back from Verify to Execute/Fix setsexecuteagain; a UAT follow-up (UAT of:) setsverify.researchtickets never write it: they run AFK and possibly in parallel, so the single file tracks only the one ticket in play.skills/_shared/session-handoff.md: at the marker removal, alsoclearthe work state.skills/_shared/teamwork.mdPause/Resume: pause sets--step pausedand keeps the file whether or not the claim is released; resume sets the recorded next step (re-creating the file if absent).skills/trailhead-work/references/auto.md: during a run everysetcarries--auto true; at run end (drained or interrupt) a remaining file getsset --auto false.templates/wholesale and the prose is projected; add pins inbin/trailhead.test.js(helper projected byte-identical on--codex) andbin/lib/codex-projection.test.js(convertToCodexkeepstrailhead-work-state.jsandCLAUDE_CODE_SESSION_IDintact; the projected work skill carries theset/clearcalls).Seams
Helper CLI contract (
mainwith injected cwd/env/stdout) and its puremergeState/validatefunctions; the projection text transform.Files touched
plugins/trailhead/templates/trailhead-work-state.js(new),plugins/trailhead/hooks/lib/work-state.test.js(new),.gitignore,plugins/trailhead/skills/_shared/{teamwork,session-handoff}.md,plugins/trailhead/skills/trailhead-work/SKILL.md,plugins/trailhead/skills/trailhead-work/references/{ticket-engines,auto}.md,bin/trailhead.test.js,bin/lib/codex-projection.test.js.Verification criteria
npm testgreen (the new suite is picked up byscripts/test.jsunderhooks/).setat work-start writes the full shape withsessionfromCLAUDE_CODE_SESSION_ID;set --step planupdates only step + updatedAt;clearremoves it; on a--codexinstall the projected helper behaves the same withsession: null.session-tickethandling and the commit-msg hook untouched (no diff intemplates/trailhead-commit-msg,hooks/lib/commit-message-check.js).set/clearforms; no em-dashes introduced.ToRvaLDz commentedon Oct 10, 2026
PLAN-REVIEW
Reviewer: codex (read-only, low effort), one round. The revised PLAN above resolves every blocking concern.
setis the last work-start bullet, after the workspace is set up, so it lands at the final working root.researchtickets cannot share one file. Resolved:researchnever writes the work state; the file tracks only the one ticket in play.verify. Accepted.ToRvaLDz commentedon Oct 10, 2026
VERIFY
Tests.
npm test: 23 ok/skipped, 0 failed (includes the newhooks/lib/work-state.test.js, 75 checks with failure injection, the Codex projection pins,claude plugin validate,claude plugin test).Code review (ticket diff: the
Refs: #205commits 7bc5850, 826242d, b3274ee, f03782c; fix round df51aa2, 4ddb6ab).critical: 0 · warning: 1 · info: 1
Findings ledger:
set, which exits 2 when no file exists, so the work state was silently never re-created. fixed in 4ddb6ab (Resume and the Work state file paragraph now pass the full work-start form where the file may be absent).titledefaulted to""though the contract admitsnull. fixed in df51aa2 (no title ->null, tests updated).Goal-backward verification: met. Helper run in a temp repo through set / step changes /
--auto/ new ticket / clear, with and withoutCLAUDE_CODE_SESSION_ID; a--codexinstall into a temp dir carries the helper byte-identical (same behaviour,session: null) and the projected prose carries the calls at work-start, each step, pause, resume, auto and Resolve;.trailhead/work-state.jsongitignored;session-ticketand the commit-msg hook untouched; no em-dashes introduced.Acceptance testing: not user-facing (local state file for tooling, no UI yet), so none owed.
ToRvaLDz commentedon Oct 10, 2026
Resolved. The skills now write the work state the mod will read.
plugins/trailhead/templates/trailhead-work-state.js(set/clear): atomic write of.trailhead/work-state.jsonwith{map, ticket, title, step, auto, session, updatedAt}, whole-state validation (invalid existing fields dropped),sessionfromCLAUDE_CODE_SESSION_ID, never blocks the caller (7bc5850, df51aa2)..trailhead/work-state.jsongitignored (826242d)._shared/teamwork.md; calls at work-start (after workspace setup,--map nonefor whiteboard), at each step per the mapping inticket-engines.md(UAT follow-ups ->verify,researchexcluded), on pause/resume, duringauto(--auto true,--auto falseat run end), andclearat Resolve withsession-ticket(b3274ee, 4ddb6ab).templates/and the prose is projected; pinned by tests (f03782c).Verification and findings ledger: see the VERIFY comment above (all findings fixed).
feat: add the work state helper
chore: ignore the work state file
docs: write the work state from the skills
test: pin the work state helper and calls in the Codex projection
fix: write a null work state title when none is given
docs: pass the full work state form where the file may be absent