From crucible
Resumes interrupted pipelines from dispatch manifests or replays historical pipelines with template mutations for A/B experimentation. Triggers on /replay, 'resume pipeline', 'replay build', 'A/B test templates'.
npx claudepluginhub raddue/crucibleThis skill uses the workspace's default tool permissions.
<!-- CANONICAL: shared/dispatch-convention.md -->
Orchestrates adversarial plan-implement-review pipeline by spawning role-specific agents with separate contexts. Run after /brainstorm, /repo-eval, /repo-health, or /doc-health.
Performs post-pipeline retrospectives: parses logs, counts productive vs wasted iterations, identifies failure patterns, scores runs, suggests fixes to skills/scripts.
Executes existing HOTL workflow files autonomously: reads steps, loops until success criteria met, auto-approves low-risk gates, pauses high-risk. Handles git preflights and interrupted runs.
Share bugs, ideas, or general feedback.
All subagent dispatches use disk-mediated dispatch. See shared/dispatch-convention.md for the full protocol.
Resume interrupted pipelines from their last successful phase boundary, or replay historical pipelines with mutated dispatch templates for A/B experimentation. Reads dispatch manifests, correlates with shadow git checkpoints, reconstructs orchestrator state from disk, and re-dispatches from the resume point.
Announce at start: "Using replay to [resume interrupted pipeline / replay pipeline with template mutations]."
Skill type: Orchestrator -- dispatches subagents via existing dispatch convention. Does NOT re-implement pipeline phases -- restores state and delegates to the original skill's phase logic.
Key insight: The dispatch convention was explicitly designed for this. Manifests, dispatch files, and checkpoints are all on disk. Replay is the orchestration layer that reads them and re-dispatches.
/replay <scratch-dir-or-manifest-path> [options]
Options:
--from-phase <N> -- Resume from phase N boundary (overrides auto-detection)--from-seq <N> -- Resume from dispatch sequence N (finds enclosing phase boundary)--mutate <original>=<replacement> -- Swap dispatch template (repeatable for multi-template experiments)--diff -- Compare replayed vs original outcomes after completion--dry-run -- Show what would be re-dispatched without executing--template-ref <sha> -- Pin templates to a git ref (for controlled A/B experiments)Path resolution:
manifest.jsonl: use directlymanifest.jsonl in that directory, then in <path>/dispatch-*/manifest.jsonl.pipeline-active to find the dispatch directory, then read its manifestActive when no --mutate flag is present. Restores checkpoint, reconstructs state, and re-dispatches from the last verified phase boundary.
manifest.jsonl with normal status lifecycle (dispatched -> completed)replay_of back-referencing the original seq and replay_session identifying this run--mutate)Same as resume but with template substitutions at dispatch time. Produces structured diff output when combined with --diff.
mutation: "original.md -> replacement.md" in manifest--dry-run)Analyzes the manifest, identifies the resume point, and lists what would be re-dispatched. No state changes, no dispatches, no checkpoint restores.
Output format:
# Replay Plan (dry-run)
**Source:** <manifest path>
**Original pipeline:** <skill> | Session: <id> | Started: <timestamp>
**Crashed at:** Phase <N>, <context>
**Resume point:** Phase <M> boundary (<checkpoint reason>)
**Work preserved:** <time estimate> (phases 1 through M-1)
## Dispatches to skip (verified complete)
| Seq | Role | Phase | Summary |
|-----|------|-------|---------|
| ... | ... | ... | ... |
## Dispatches to re-execute
| Seq | Role | Phase | Original Status | Template |
|-----|------|-------|-----------------|----------|
| ... | ... | ... | ... | ... |
## Template Mutations (if --mutate specified)
- <original> -> <replacement>
Read the manifest from the provided path. Handle errors gracefully:
seq is normal (dispatched -> completed). The last entry for each seq is authoritative.phase field. Within each phase, track the set of dispatches and their final statuses.Manifest location priority:
<scratch>/crucible-dispatch-<session-id>/manifest.jsonl) -- durable, survives /tmp loss/tmp/crucible-dispatch-<session-id>/manifest.jsonl) -- may not survive rebootPartition the manifest into completed and incomplete phases:
status: "completed". A phase is complete if and only if every dispatch within it reached completion.status: "dispatched" (no completion entry) indicate a dispatch that was in flight when the crash occurred. The enclosing phase is incomplete.Phase boundary mapping for build pipelines:
| Phase Boundary | Checkpoint Reason | When |
|---|---|---|
| Pre-Phase 2 | pre-design-gate | After design approval, before planning |
| Late Phase 2 | pre-plan-gate | After plan approval, before execution |
| Pre-Phase 3 | pre-wave-1 | After plan approval, before first execution wave |
| Mid-Phase 3 (wave N) | pre-wave-N | After wave N-1 completion |
| Pre-Phase 4 | pre-code-review | After all execution waves complete |
| Mid-Phase 4 | pre-inquisitor | After code review, before inquisitor |
| Late Phase 4 | pre-impl-gate | After inquisitor, before quality gate |
--from-phase override: If the user specified a phase, use that boundary instead of auto-detection. Warn if the specified phase is earlier than the auto-detected resume point (the user is choosing to redo verified work).
--from-seq resolution: Find the phase containing the specified seq number. Resume from the start of that phase (not mid-phase).
Before committing to a resume point, verify that completed dispatches actually produced their expected artifacts:
For each completed dispatch before the resume point:
a. Mutating agents (implementers): Check git log --oneline for commits that match the dispatch's time window and task description patterns. If no matching commits found but manifest says completed, the manifest may be stale -- fall back to earlier boundary.
b. Output-producing agents (reviewers, red-team): Check that dispatch output files exist in the dispatch directory or scratch copy.
c. Non-artifact agents (quality-gate rounds): No verification needed -- these produce conversation output only.
Verification failure: If any expected artifact is missing for a completed dispatch: a. Log which dispatch failed verification and why b. Fall back to the previous phase boundary c. If fallback also fails verification, continue falling back until a verified boundary is found or no boundaries remain d. If no verified boundary exists: report the situation and offer "resume with current disk state" or "start fresh"
Partial commit detection: For implementer dispatches near the crash point: a. Check git log for commits attributed to the dispatch (timestamp matching, commit message patterns) b. If partial commits found: the checkpoint restore in Step 4 will revert them (checkpoints predate the partial work) c. If no commits found: safe to re-dispatch from the phase boundary
Map the verified resume point to a shadow git checkpoint:
checkpoint-manifest.md from ~/.claude/projects/<hash>/checkpoints/<dir-hash>/pre-design-gatepre-plan-gatepre-wave-1pre-wave-Npre-code-reviewpre-inquisitorpre-impl-gatepre-wave-2 entries from retries): use the most recent by timestamp.If the desired checkpoint is missing (evicted, shadow repo reinitialized, pre-checkpoint-era pipeline):
Branch guard (mandatory): Before offering restore, check the .pipeline-active marker's branch field against the current git branch --show-current. If they differ, abort with:
"Pipeline was running on branch [marker.branch] but you are on [current-branch]. Switch to [marker.branch] before resuming — restoring a checkpoint from a different branch would contaminate your working directory."
Do NOT proceed with restore on the wrong branch. This is a data-safety invariant.
Before any restore, require explicit user confirmation:
"About to restore working directory to checkpoint [reason] (taken at [timestamp], branch [marker.branch]). This will reset uncommitted changes. Proceed? [yes / no]"
On confirmation:
Reconstruct the orchestrator's internal state from disk sources. This seeds the new context window with enough information to continue the pipeline mid-flight.
Sources, in priority order:
Phase Handoff Manifests (handoff-N-to-M.md in scratch directory)
Pipeline-status.md Compression State (~/.claude/projects/<hash>/memory/pipeline-status.md)
## Compression State section for: Goal, Key Decisions, Active Constraints, Next StepsManifest entries (from Step 1)
Dispatch files on disk (in dispatch directory or scratch copy)
Shadow git checkpoint (from Step 4)
Build mode file (/tmp/crucible-build-mode.md)
From the combined state, construct and emit a Compression State Block:
===COMPRESSION_STATE===
Goal: [from handoff manifest or pipeline-status.md]
Skill: [from .pipeline-active marker]
Phase: [resume phase]
Health: GREEN (reset on resume)
Progress:
- Phases 1 through [N-1] completed in prior session
- Resuming from [checkpoint reason] via replay
- [key milestones from manifest summaries]
Key Decisions (prior session):
- [decisions from handoff manifest or pipeline-status.md]
Active Constraints:
- [constraints from handoff manifest or pipeline-status.md]
- Replay session -- prior work verified through Phase [N-1]
Files Modified:
- [recovered from checkpoint diff if available, or "see git log"]
Scratch State:
- Location: [scratch directory path]
- Recovery: pipeline-status.md, handoff manifests, manifest.jsonl
Next Steps:
1. [first action for the resumed phase]
2. [subsequent actions from handoff manifest or manifest analysis]
===END_COMPRESSION_STATE===
After checkpoint restore and state reconstruction, hand off to the original skill's phase logic:
New dispatches during replay append to the original manifest.jsonl:
seq in the manifest + 1"dispatched" -> "completed", etc.) for all dispatches during replay. Replay provenance is tracked via replay_of and replay_session, not via the status field. This ensures existing manifest readers (compaction recovery, forge, debugging) handle replay entries correctly.replay_of field: Set to the original seq number when re-dispatching a previously attempted dispatch. Set to null for new dispatches that have no original counterpart.replay_session field: Set to the current session ID for all entries written during a replay run.mutation field: Set to "original.md -> replacement.md" if a template mutation was applied. null otherwise.The replay skill does NOT re-implement build phases. After emitting the synthetic CSB and setting up the manifest continuation, replay delegates to the build skill's existing phase logic. The build skill continues as if it had just crossed a phase boundary -- the CSB seeds its context, the manifest is ready for new entries, and the working directory is at the checkpoint state.
For non-build skills (future): The same pattern applies -- replay restores state and delegates to the original skill. The phase structure and checkpoint reasons are skill-specific, but the restore/reconstruct/delegate pattern is universal.
Active only when --mutate is specified. This step modifies dispatch behavior during re-execution.
Parse each --mutate argument:
<original-template>=<replacement-path>original-template is a filename (e.g., quality-gate-prompt.md)replacement-path is a path to the replacement template file--mutate flags are allowed for multi-template experimentsWhen writing a dispatch file during re-execution:
original-template"mutation": "original.md -> replacement.md"In A/B mode, check each dispatched template's modification time against the original manifest's first entry timestamp. If any template is newer:
"Warning: Template [name] was modified after the original pipeline run. A/B comparison may be confounded by template changes unrelated to the mutation."
--template-ref)When --template-ref <sha> is specified:
--diff)Active when both --mutate and --diff are specified. Produces a comparison report after the replay completes.
replay_of fieldrole: "red-team" or role: "quality-gate" per phase)# Replay Diff: <original-session> vs <replay-session>
## Template Mutations
- <original.md> -> <replacement.md>
## Outcome Comparison
| Metric | Original | Replayed | Delta |
|--------|----------|----------|-------|
| Total dispatches | N | M | +/-X |
| Quality gate rounds | N | M | +/-X |
| Wall clock time | Xh Ym | Xh Ym | +/-Zm |
| Acceptance tests | PASS/FAIL | PASS/FAIL | =/changed |
## Per-Dispatch Comparison
| Seq | Role | Original Status | Replayed Status | Summary Delta |
|-----|------|----------------|-----------------|---------------|
| N | role | status | status | brief comparison |
## Artifact Diff
- git diff <original-final-sha>..<replayed-final-sha>
N files changed, +X/-Y lines
Append a structured signal to the manifest directory:
{"type":"replay-diff","original_session":"...","replay_session":"...","mutations":["original.md -> replacement.md"],"metrics":{"original_dispatches":N,"replayed_dispatches":M,"original_gate_rounds":N,"replayed_gate_rounds":M,"original_duration_m":N,"replayed_duration_m":M},"outcome":{"original":"PASS","replayed":"PASS"},"artifact_diff":{"files_changed":N,"insertions":X,"deletions":Y}}
This output is designed to be:
Handled in Step 1: per-line JSON parse with error handling. The last valid entry per seq is authoritative. Zero valid entries = cannot resume.
Handled in Step 4 fallback chain: earlier checkpoint -> no checkpoint with user choice.
If dispatch files are missing from both the dispatch directory and scratch copy:
/tmp Lost/tmp is ephemeral. If the machine rebooted, the dispatch directory is gone. But:
Between crash and resume, templates may have been modified. For resume mode this is fine (you want current-best templates). For A/B mode it is a confound -- the staleness warning in Step 7 catches this.
A crash can occur after an implementer commits 2 of 3 files. At resume:
Quality gates during replay follow the same rules as normal runs. A replayed pipeline may have different model versions, different codebase state, or mutated templates -- the quality gate must verify independently.
No changes to the core dispatch protocol. Replay appends to existing manifests and writes dispatch files following the same naming convention. The replay_of, replay_session, and mutation fields are additive and backward-compatible.
Replay runs generate chronicle signals with replay_source field linking to the original manifest. Replay diffs are a separate signal type (skill: "replay-diff"). Chronicle integration is deferred to chronicle implementation -- the schema is forward-compatible.
Replay consumes checkpoints (reads and restores) but does not modify the checkpoint system. New checkpoints are created during the resumed pipeline execution by the normal checkpoint triggers in the delegated skill.
replay_of linkage