From exarchos
Saves and mutates workflow state — init, update fields, transition phases, and capture structured handoffs before context exhaustion.
How this skill is triggered — by the user, by Claude, or both
Slash command
/exarchos:checkpointThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Save and mutate persistent workflow state that survives context auto-summarization.
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).
npx claudepluginhub lvlup-sw/exarchosSaves and resumes state for multi-phase commands like /debug, /epic, /feature, /implement, and /plan, enabling work to survive session interruptions.
Manages persistent state across Claude Code agent sessions: load context at start, track progress/decisions/learnings, save for next session. Use when resuming work or hitting blockers.
Wraps up a work session by recording changed files, caveats, decisions, and next steps so a fresh session can resume without re-deriving context.