skills/standard/checkpoint/SKILL.md
Save and mutate workflow state — init a workflow, update fields, transition phases, and capture a structured handoff before context exhaustion. Use when the user says 'save progress', 'checkpoint', 'I need to stop', or runs /checkpoint. Writes current workflow phase, task progress, and artifacts to the event store for later resumption. Do NOT use for restoring/reading state after a session break (that is /rehydrate) or for workflow initialization framing handled by ideate/debug/refactor commands.
npx skillsauth add lvlup-sw/exarchos checkpointInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Save and mutate persistent workflow state that survives context auto-summarization.
State files store: task details, worktree locations, PR URLs, and review status. This skill owns the write side of workflow state — initializing a workflow, updating fields, transitioning phases, and capturing a structured handoff. For the read/restore side (resuming after a break, reconciling against git, verifying a workflow exists), see @skills/rehydrate/SKILL.md.
Activate this skill when:
ideate)checkpoint)Valid transitions, guards, and prerequisites for all workflow types are documented in references/phase-transitions.md. CRITICAL: Phase mutation is a separate action from field mutation. When a transition has a guard, action: "update" the prerequisite fields first, then action: "transition" — guards read the most recent state, so updates land before guards evaluate. Attempting to mutate phase via action: "update" returns a RESERVED_FIELD error pointing at transition (see "Reserved fields" below).
Use exarchos_workflow({ action: "describe", actions: ["update", "init", "get"] }) for
parameter schemas and exarchos_workflow({ action: "describe", playbook: "feature" })
for phase transitions, guards, and playbook guidance. For the lightweight
oneshot variant (with its implementing → synthesize|completed choice state
driven by synthesisPolicy), call exarchos_workflow({ action: "describe", playbook: "oneshot" })
— oneshot is a first-class playbook alongside feature/debug/refactor. Use
exarchos_event({ action: "describe", eventTypes: ["workflow.transition", "task.completed"] })
for event data schemas.
Workflow state lives in the MCP event store, not the filesystem. Use exarchos_workflow get to read state and exarchos_view pipeline to discover active workflows. The pipeline view is repo-scoped by default — only the caller's repo; when the response reports unscopedTotal greater than page.total, workflows in other repos are hidden — re-query with scope: "all" to reveal them. Do not scan ~/.claude/workflow-state/*.state.json — that path is legacy and may be stale or empty.
For full MCP tool signatures, error handling, and anti-patterns, see references/mcp-tool-reference.md.
At the start of ideate, use exarchos:exarchos_workflow with action: "init" with:
featureId: the workflow identifier (e.g., "user-authentication")workflowType: one of "feature", "debug", "refactor", "oneshot"synthesisPolicy (optional, oneshot only): one of "always", "never", "on-request" (default "on-request") — silently ignored for non-oneshot typesThis creates a new workflow state entry. The initial phase depends on
workflowType:
feature → starts in plandebug → starts in triagerefactor → starts in exploreoneshot → starts in planfeature — full plan → plan-review → delegate → review → synthesize for real features with subagent dispatch and reviewdebug — triage → investigate → (thorough | hotfix) for bug workflows with track selectionrefactor — explore → brief → (polish | overhaul) for code improvements, polish for small and overhaul for multi-taskoneshot — plan → implementing → (completed | synthesize) for trivial changes; direct-commit by default with an opt-in PR path resolved via a choice-state guard driven by synthesisPolicy and the synthesize.requested eventSee @skills/oneshot/SKILL.md for the lightweight variant's full prose, including the choice-state mechanics and finalize_oneshot trigger.
Use exarchos:exarchos_workflow with action: "update" with featureId and updates. This action mutates non-phase fields only — phase, workflowType, featureId, createdAt, and version are reserved (see "Reserved fields" below).
updates: { "artifacts.spec": "docs/specs/2026-01-05-feature.md" }updates: { "tasks[0].status": "complete", "tasks[0].completedAt": "<timestamp>" }updates: { "worktrees.wt-001": { "branch": "feature/001-types", "taskId": "001", "status": "active" } }Worktree status values: 'active' | 'merged' | 'removed'
Use exarchos:exarchos_workflow with action: "transition" with featureId and target:
target: "delegate"Transitions are HSM-validated and emit a workflow.transition event. Guarded transitions read state after the most recent update, so any updates: {...} that the guard depends on must land first.
tasks arrayThe dot-path parser used by set updates recognizes only numeric array brackets (tasks[0], tasks[1], …). Keyed forms like tasks[id=T-001] are NOT supported and now throw an INVALID_INPUT error with a clear message — earlier versions silently wrote to a bogus top-level key, returning success: true while the actual task was untouched. Three patterns are supported:
Replace the whole array (use this when the plan is being revised wholesale):
exarchos_workflow({
action: "update",
featureId: "<id>",
updates: { tasks: [
{ id: "T-001", title: "...", status: "pending" },
{ id: "T-002", title: "...", status: "pending" },
]},
})
Edit one task by its array index:
exarchos_workflow({
action: "update",
featureId: "<id>",
updates: { "tasks[0].status": "complete", "tasks[0].completedAt": "<ts>" },
})
First read tasks (action: "get", query: "tasks") to find the index of the task you want to edit, then set by that index.
Append a new task by writing to the next-free index. If the array currently has length N, write to tasks[N]:
// Suppose tasks already contains T-001 and T-002 (length 2). To append:
exarchos_workflow({
action: "update",
featureId: "<id>",
updates: { "tasks[2]": { id: "T-003", title: "Follow-up", status: "pending" } },
})
The parser allows writing one slot past the current length (MAX_ARRAY_GAP = 1); writing further out (tasks[5] against a length-2 array) throws INVALID_INPUT. Read the current tasks length before appending.
| Event | State Update |
|-------|--------------|
| ideate starts | init the workflow (initial phase plan) |
| Design & Rationale authored | update: { "artifacts.spec": "<path>" } (no transition — plan is the initial phase) |
| Decomposition added | update: { "artifacts.plan": "<path>", "tasks": [...] }, then transition target: "plan-review" |
| Plan-review gaps found | update: { "planReview.gaps": [...] }, auto-loop to plan |
| Plan-review approved | update: { "planReview.approved": true }, then transition target: "delegate" |
| Task dispatched | Set task status = "in_progress", startedAt |
| Task complete | Set task status = "complete", completedAt |
| Worktree created | Add to worktrees object |
| Review complete | Update reviews object |
| PR created | Set artifacts.pr, synthesis.prUrl |
| PR feedback | Append to synthesis.prFeedback |
Oneshot is a first-class workflow type with a compressed lifecycle and an opt-in PR path. The rows below mirror the feature-workflow table above.
| Phase | State updates | Events emitted |
|-------|---------------|----------------|
| plan (oneshot) | oneshot.planSummary, artifacts.plan, optional oneshot.synthesisPolicy | workflow.transition |
| implementing (oneshot) | tasks[].status, artifacts.tests | task.*, optional synthesize.requested (via request_synthesize) |
| synthesize (oneshot) | synthesis.prUrl, artifacts.pr | workflow.transition, stack.submitted |
| completed (oneshot) | — | workflow.transition (to completed) |
The implementing → synthesize | completed fork is a choice state resolved
by finalize_oneshot, which reads the synthesisOptedIn guard
(synthesisPolicy + synthesize.requested events). See
@skills/oneshot/SKILL.md for the full opt-in mechanics.
Skills should update state at key moments:
ideate/SKILL.md:
After authoring the Design & Rationale section of the unified docs/specs/ artifact:
- `action: "update"` — `updates: { "artifacts.spec": "<path>" }`
(no transition — `plan` is the initial phase; continue to decomposition in the same phase)
plan/SKILL.md:
After saving plan:
1. `action: "update"` — `updates: { "artifacts.plan": "<path>", "tasks": [...] }`
2. `action: "transition"` — `target: "plan-review"`
delegate/SKILL.md:
On task dispatch:
- Update task status to "in_progress"
- Add worktree to state if created
On task complete:
- Update task status to "complete"
- Check if all tasks done, suggest checkpoint
See docs/schemas/workflow-state.schema.json for full schema.
Key sections:
version: Schema version (currently "1.1")featureId: Unique workflow identifierworkflowType: Required. One of "feature", "debug", "refactor", or "oneshot"phase: Current workflow phaseartifacts: Paths to design, plan, PRtasks: Task list with statusworktrees: Active git worktreesplanReview: Plan-review delta analysis results (gaps, approved)reviews: Review resultssynthesis: Merge/PR stateexarchos:exarchos_workflow with action: "update" rejects two classes of paths with RESERVED_FIELD:
phase, workflowType, featureId, createdAt, version. Set once at init; never mutated directly._ (e.g. _version, _checkpoint.summary, _eventHints). These are projection or event-store metadata.Alternate write paths:
phase → exarchos:exarchos_workflow with action: "transition" and target: "<phase>". Transitions are HSM-validated and emit transition events.exarchos:exarchos_event with action: "append" (e.g. checkpoint, state.patched). The projection folds the event into the field on the next read.workflowType, featureId, createdAt, version → not migratable. If you need a different workflow type, init a new workflow.A RESERVED_FIELD error envelope now carries a typed data block:
{
"success": false,
"error": {
"code": "RESERVED_FIELD",
"message": "Cannot update reserved field: phase",
"data": {
"rejectedPath": "phase",
"rule": "`phase` is top-level immutable — set once at init, never directly mutated thereafter.",
"alternateWritePath": "Use `exarchos:exarchos_workflow` with `action: \"transition\"` and `target: \"<phase>\"` — phase changes are HSM-validated and emit transition events."
}
}
}
Read the full descriptor — including the regex catch-all for underscore paths — via exarchos:exarchos_workflow with action: "describe" and actions: ["update"]. The returned reservedFields block is the single source of truth.
When capturing a handoff (the checkpoint command surface), emit this structured summary so the agent that resumes sees the same contract you operated under before context clears. The ### House Rules block mirrors the rehydrate output (see @skills/rehydrate/SKILL.md) for correctness-signal symmetry — an agent producing a checkpoint sees the same house rules an agent rehydrating would.
## Checkpoint Saved
**Feature:** <feature-id>
**Phase:** <current-phase>
### Progress
- Tasks: X/Y complete
- Current: <what's in progress>
- Next: <suggested next action>
### House Rules (apply every action this turn forward)
**Skill:** <phasePlaybook.skillRef or "(no playbook for this phase)">
**Tools:** <phasePlaybook.tools rendered as bullets>
**Required model-emitted events:** <phasePlaybook.events rendered as bullets — e.g. `task.progressed`, `phase.advanced`>
**Auto-emitted events (runtime fires these):** <phasePlaybook.autoEmittedEvents rendered as bullets>
**Transition:** <phasePlaybook.transitionCriteria> | Guard: <phasePlaybook.guardPrerequisites>
**Validation scripts:** <phasePlaybook.validationScripts joined>
### Event Emission Hints
<_eventHints.missing rendered as bullets, or "(none — phase machinery satisfied)">
### Resume Instructions
To continue this workflow in a new session, run `rehydrate` — or start the harness fresh, and the SessionStart hook will auto-discover active workflows.
> **Discipline reminder:** every task transition this turn forward MUST land on the workflow event stream via `exarchos_event.append` or `delegate` subagent emission. Direct `Edit` / `Bash` / `git` actions on task branches without corresponding events will desync the workflow tracker (see RCA `docs/rca/2026-05-08-rehydrate-behavioral-gap.md`).
Suggest a checkpoint when:
delegate completes — all tasks done, before reviewsynthesize, before the feedback loop@skills/rehydrate/SKILL.md)@skills/rehydrate/SKILL.md)If an Exarchos MCP tool returns an error:
exarchos:exarchos_workflow with action: "get" and the featureIdexarchos:exarchos_workflow with action: "cancel" and dryRun: trueIf checkpoint is invoked with no active workflow:
exarchos:exarchos_workflow with action: "list" to enumerate active workflows; if the list is empty the checkpoint command's "no active workflow" report is correct — exit cleanlylist returns a candidate, verify it: call exarchos:exarchos_workflow with action: "get" and that featureIdStart new workflow: Use exarchos:exarchos_workflow with action: "init" with featureId: "user-authentication", workflowType: "feature"
After authoring the Design & Rationale section (plan is already the initial phase — no transition):
action: "update", featureId: "user-authentication", updates: { "artifacts.spec": "docs/specs/2026-01-05-user-auth.md" }Save progress before a break: Use checkpoint to capture a structured handoff; resume later with rehydrate (see @skills/rehydrate/SKILL.md).
testing
Create pull request from completed feature branch using GitHub-native stacked PRs. Use when the user says 'create PR', 'submit for review', 'synthesize', or runs /synthesize. Validates branch readiness, creates PR with structured description, and manages merge queue. Do NOT use before review phase completes. Not for draft PRs.
testing
Shepherd PRs through CI and reviews to merge readiness. Operates as an iteration loop within the synthesize phase (not a separate HSM phase). Uses assess_stack to check PR health, fix failures, and request approval. Triggers: 'shepherd', 'tend PRs', 'check CI', or /shepherd.
development
Single adversarial review pass over the integrated branch diff — spec-compliance, code quality, and test adequacy judged together by one fresh-context reviewer. Triggers: /review, 'review the changes', or after delegation completes. Emits one verdict (reviews.review.status). Do NOT use for plan-review (that is its own dispatched gate) or for debugging.
testing
Restore and read workflow state after a context break — re-inject workflow phase, task progress, and behavioral guidance into the current session, reconcile state against git reality, and verify whether a workflow exists. Use when the user says 'resume', 'rehydrate', 'where were we', or runs /rehydrate, or when the agent has drifted after context compaction. Do NOT use for saving or mutating state (that is /checkpoint).