From shipwright-iterate
Manages post-completion code changes in Shipwright projects with complexity-adaptive process: feature, bugfix, or change. Supports external review and escape hatches.
How this skill is triggered — by the user, by Claude, or both
Slash command
/shipwright-iterate:iterateThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Complexity-adaptive change lifecycle for completed Shipwright projects. Detects intent (feature, change, bug), assesses complexity, runs the right amount of process.
references/F-debug.mdreferences/F-simplify.mdreferences/F0.5.mdreferences/F0.mdreferences/F1.mdreferences/F11.mdreferences/F12.mdreferences/F2.mdreferences/F3.mdreferences/F3a.mdreferences/F4.mdreferences/F5.mdreferences/F5b.mdreferences/F5c.mdreferences/F6.5.mdreferences/F6.mdreferences/F7.mdreferences/F7b.mdreferences/artifact-ownership.mdreferences/boundary-probes.mdComplexity-adaptive change lifecycle for completed Shipwright projects. Detects intent (feature, change, bug), assesses complexity, runs the right amount of process.
How invoked: directly via
/shipwright-iterate, or via thesuggest_iterate.pyUserPromptSubmit hook context. External review (v0.5.x+): medium+ uses{shared_root}/scripts/tools/external_review.py --mode iterate,check-external-review-keys.py,mark-review-state.py(Branch A/B/C gate).
| Section | Reference |
|---|---|
| Repo Scout, Mini-Plan | iteration-planning · escape-hatch |
| Self-Review, Full Review, Handoff | iteration-reviews |
| Design Check, Testing, Visual, E2E | design-and-testing |
| Reflection, Boundary Probes, Round-Trip, Confidence | reflection · boundary-probes · round-trip-tests · confidence-anti-patterns |
| Context Loading | context-loading |
| Path A / B / C body (+ SIMPLIFY sub-mode) | path-a-feature · path-b-change · path-c-bug · F-debug (BUG systematic-debugging) · F-simplify (SIMPLIFY behavior-preserving) |
| Campaign Mode, Escalation, Degraded, Errors | campaign-mode · mid-flight-escalation · degraded-mode · error-handling |
| Artifact Ownership | artifact-ownership |
| Phase Timing (Iterate-Rail durations, M-Pre-1) | phase-timing |
| Finalization F-phases | F0 · F0.5 · F1 · F2 · F3 · F3a · F4 · F5 · F5b · F5c · F6 · F6.5 · F7 · F7b · F11 · F12 |
| Risk Taxonomy, Override Classes, Phase Matrix | this file (inline — NORMATIVE) |
Governing rules: read and follow shared/constitution.md (ALWAYS / ASK FIRST / NEVER). BEFORE any other tools:
================================================================================
SHIPWRIGHT-ITERATE: Adaptive Change Lifecycle
================================================================================
Usage: /shipwright-iterate --type feature|change|bug "description"
or: Auto-detected from your prompt (via hook context)
Paths: FEATURE / CHANGE → [interview]→[spec]→[plan]→[approval]→[review]→[design]→build→test→commit
BUG → [spec]→reproduce→[plan]→fix→test→commit
Complexity: trivial | small | medium | large (auto-detected, overridable)
In plain words (shared index → docs/guide.md Appendix A):
ADR: Log of architectural decisions with rationale (why this database, why this pattern)
Conventional Commits: Standardized commit-message format (`feat:`, `fix:`, etc.) so version history is machine-readable
================================================================================
Verify shipwright_run_config.json exists with status: "complete" (or iterate_history exists). Otherwise print the "Completed Project Required" notice and stop.
Every iterate runs in a worktree under .worktrees/<slug>/. If inside a worktree (git rev-parse --git-common-dir resolves above cwd), resume in place. Otherwise enumerate branches with uv run "{shared_root}/scripts/tools/list_iterate_branches.py" --project-root . (surfaces locked = resumable, stale = housekeeping). Check .shipwright/agent_docs/session_handoff.md for run_id. Offer Resume / Abandon / Complete. Resume/Complete replay-check: if medium+ has no external-review marker AND feedback_iterations > 0, run Step 4 first. If the iterate ADR has no Self-Review: block, run Step 7 before commit.
uv run "{shared_root}/scripts/tools/setup_iterate_worktree.py" \
--project-root . --slug "<slug>" --run-id "<run_id>"
Creates .worktrees/<slug> off freshly-fetched origin/<default> with branch iterate/<slug>. Parse the JSON; {project_root} for the rest of the run = the helper's project_root field. cd shell into it. Exit codes: 0 ok · 2 slug collision · 3 fetch failed (STOP unless SHIPWRIGHT_ITERATE_NO_FETCH=1). One iterate = one worktree = one branch = one PR. .worktrees/<slug> is .gitignore'd. Re-hydrate .env* + node_modules/.venv per project shape. Cleanup after PR merge: git worktree remove + git branch -D.
Read all Layer 1 of references/context-loading.md — CLAUDE.md, conventions.md, decision_log.md, architecture.md, shipwright_sync_config.json, all spec.md, shipwright_test_results.json, shipwright_events.jsonl, git log --oneline -20. Missing files: warn but continue.
run_id = iterate-{YYYY-MM-DD}-{short-description} (canonical RUN_ID_STRICT form). Propagate through all artifacts. → Phase Timing: emit mark scope here — right after the run_id exists and before Repo Scout (§E), so the scope node captures it (see phase-timing).
Priority: --type flag → [Shipwright] Detected: ... hook context → classify_intent.py → ask user (if confidence < 0.7). A mode: simplify classification (simplify/clean-up vocabulary) selects the behavior-preserving SIMPLIFY sub-mode (Path B → F-simplify, Spec Impact NONE).
uv run "{plugin_root}/scripts/lib/classify_complexity.py" \
--message "{user_message}" --sync-config "{project_root}/shipwright_sync_config.json" \
--project-root "{project_root}" --run-id "{run_id}"
Parse: estimate, confidence, risk_flags, enforcements, signals (incl. signals.prior_source). Passing --run-id additively persists the session plan (phases/skips/risk_flags/complexity) to .shipwright/agent_docs/iterates/{run_id}.plan.json for the WebUI scoped Plan-Card — stdout is byte-unchanged. User override: --complexity. Safety floor: risk flags enforce minimums. Fall-through default is history-calibrated: when no scope keyword matches, the estimate is the median final complexity of the last finalized runs (.shipwright/agent_docs/iterates/, prior_source: history, capped at medium) instead of bare trivial; a keyword match always wins (prior_source: keyword); cold start keeps trivial (prior_source: default). Stage 2: Repo Scout — Quick (trivial/small) or Thorough (medium); see references/iteration-planning.md. After Stage 2 complexity is locked (unless mid-flight escalation).
Print Run ID / Intent / Complexity (+ reasoning) / Prior source (keyword | history | default) / Risk flags / Phases / Skipping / Safety floor. User can adjust per Override Classes (below).
| Complexity | FEATURE | CHANGE | BUG |
|---|---|---|---|
| Trivial | skip | skip | skip (reproduce instead) |
| Small | 1 confirmation Q | 1 confirmation Q | skip (reproduce instead) |
| Medium | 2-3 scoping Qs | 1-2 scoping Qs | skip (reproduce instead) |
| Large | → escape hatch | → escape hatch | → escape hatch |
CRITICAL: Wait for user answers before proceeding to any path step.
Feedback Parsing Protocol (Interview / Approval Gate / any correction): extract ALL items, echo as numbered checklist, wait for user confirmation, track as TodoWrite tasks, no silent dropping. NEVER proceed without all feedback items captured and confirmed.
| Risk Flag | Trigger Paths | Min Complexity | Enforces |
|---|---|---|---|
touches_auth | src/middleware.ts, src/lib/supabase/, **/auth/** | small | mandatory review |
touches_rls | supabase/migrations/*rls*, RLS policy changes | small | mandatory review |
touches_middleware | src/middleware.ts, next.config.* | small | mandatory review |
touches_migrations | supabase/migrations/ | small | mandatory review + down.sql |
touches_billing | **/stripe/**, **/payment*/**, webhook handlers | small | mandatory review |
touches_shared_infra | src/lib/, src/components/ui/, layout components | small | full test suite |
cross_split | changes span 2+ planning splits | medium | full review + full test suite |
touches_public_api | API route handlers, exported types | small | mandatory review |
touches_build | package.json, *-lock.*, next.config.*, vite.config.*, tailwind.config.*, webpack.config.*, rollup.config.*, tsconfig.json | small | performance test layer (Lighthouse + bundle gate via /shipwright-test Step 3.8) |
touches_io_boundary | .env*, hooks.json, settings.json, *_config.json, *_state.json; or anchored producer/consumer keywords (parse_env, json.dump(s)?, json.load(s)?, yaml.dump, yaml.safe_load) | small | round-trip test (Boundary Probe sub-step in Build TDD — see references/boundary-probes.md + references/round-trip-tests.md) |
cross_component | FRAMEWORK cross-component machinery (diff-driven, classify_complexity.CROSS_COMPONENT_FILE_PATTERNS): merge/churn/event-log resolver (integrate_main, ensure_current, churn_merge, gitattributes_*, resolve_churn_conflicts, events_log), Claude-Code hooks + hook fan-out (hooks.json, **/hooks/*.py), pipeline phase validators (verify_phase, get_phase_context), campaign drain (autonomous_loop, campaign_*, campaign-mode.md) | medium | integration coverage — a real-scenario integration test proving the components compose (reference: shared/tests/test_parallel_merge_cascade_integration.py), recorded as a category:"integration" behavior in the Test Completeness Ledger. NON-dodgeable: the F11 verifier check_integration_coverage RECOMPUTES the flag from the diff and STOPs without it. + full test suite |
"touches_db" (ordinary query/model edits without schema changes) is NOT a risk flag. touches_build triggers /shipwright-test's Step 3.8 (skip-rules apply: no dev_url → skip Lighthouse, no build artifacts → skip bundle).
| Category | Phases | User can skip? |
|---|---|---|
| Mandatory | Self-review, unit test, commit, ADR, compliance, test results JSON, iterate_history, Confidence Calibration (medium+), Test Completeness Ledger (medium+) | Never skippable |
| Safety-enforced | Full review (when risk flags), full test suite (when shared infra), down.sql (when migrations), Boundary Probe (when touches_io_boundary), Confidence Calibration (small with touches_io_boundary), Test Completeness Ledger (small) | Only with explicit risk acknowledgment |
| Advisory | Design check, mini-plan, design fidelity, E2E update, external LLM review, release prompt, Confidence Calibration (trivial / small without touches_io_boundary), Test Completeness Ledger (trivial → auto n/a) | Freely skippable |
| Complexity-gated | Iterate spec, context scan depth | Adjustable via "make it medium/small" |
Full body in references/path-a-feature.md. The Step 1 / Step 6 / Step 7 / Step 7.5 / Step 8 / Step 11a / Step 11b anchors stay inline here for drift-protection tests.
Create .shipwright/planning/iterate/{date}-{short-description}.md. Full template in references/path-a-feature.md. The template MUST contain ## Confidence Calibration with the four bullets:
## Confidence Calibration
- **Boundaries touched:** {list from Affected Boundaries}
- **Empirical probes run:** {one-line per probe + finding}
- **Test Completeness Ledger:** {table — every testable behavior → `tested`
(evidence) | `untestable` (closed-vocab reason_code); 0 untested-testable}
- **Confidence-pattern check:** {asymptote (depth) + coverage (breadth)}
Tests first (outcomes, not internal state; one happy + one error path per AC). Implementation, verify wiring, Boundary Probe sub-step when touches_io_boundary. Full body in references/path-a-feature.md. → Phase Timing: emit mark build at entry. The three governance-rule anchors stay inline so tests/test_skill_step_6_rules_present.py continues to fire:
shared/scripts/lib/* references files/identifiers on disk, BOTH directions of drift protection MUST exist: forward (every value resolves to a file) AND reverse (every namespace-matched file has a registry entry).pytest.skip(...) on missing-binary or cross-plugin sys.path-pollution / ImportError paths MUST hard-fail in CI with an actionable install hint. Pattern: if os.environ.get("CI", "").lower() in ("true", "1"): pytest.fail(...) guarding the skip.See references/iteration-reviews.md for the 7-point checklist (item 7: Affected Boundaries). → Phase Timing: emit mark review at entry.
touches_io_boundary)"Are you confident?" is unfalsifiable — replace with empirical probes per references/confidence-anti-patterns.md. Before F0, populate the spec's Confidence Calibration section with: (1) boundaries touched, (2) empirical probes run + finding, (3) the Test Completeness Ledger, (4) confidence-pattern check (asymptote depth + coverage breadth + integration composition — when cross_component machinery is touched, add a category:"integration" behavior proving the pieces compose; the F11 verifier check_integration_coverage recomputes the flag from the diff and STOPs without it). Override Classes: Mandatory at medium+, Safety-enforced at small with touches_io_boundary, Advisory otherwise.
Test Completeness Ledger (the empirical-completeness gate). Principle: testable ⇒ tested. Enumerate every behavior this diff introduces/changes; classify each as exactly one of tested (cite the test + result) or untestable (cite a reason_code from the closed vocabulary in references/confidence-anti-patterns.md — requires-prod-credential, requires-external-nondeterministic-service, requires-physical-device, requires-manual-visual-judgment, requires-interactive-tty, covered-by-existing-test). The disposition "could-test-but-didn't" is abolished — "I should still test X" is a blocking work item, not a spec note. At F5, record the machine-readable block iterate_latest.test_completeness in shipwright_test_results.json (shape in references/F5.md); the F11 verifier check_test_completeness_ledger STOPs the run if any behavior is testable-but-untested, or an untestable row lacks a valid reason_code, or the enumeration is short of the AC count. Graduated: enforced at small/medium/large; auto n/a (with a one-line justification) at trivial.
See references/iteration-reviews.md for trigger rules.
See references/design-and-testing.md → "End-to-End Verification — Authoring".
See references/design-and-testing.md → "End-to-End Verification — Execution". Spec-only authoring without execution is forbidden at medium+. Execution is verified at F0.5; the chokepoint is shared/scripts/surface_verification.py.
See references/path-b-change.md. Same steps as FEATURE; default Spec Impact is MODIFY. Step 7.5 (Confidence Calibration) applies identically — mandatory at medium+, also at small with touches_io_boundary. SIMPLIFY sub-mode — when intent-classification returns mode: simplify (simplify / clean up / declutter / streamline / tidy) OR Spec Impact is NONE (behavior-preserving refactor): route through F-simplify — Behavior-Snapshot ({shared_root}/scripts/tools/behavior_snapshot.py snapshot, refuses a red baseline) → Simplify (Five Principles + Chesterton-Fence + the shared reducibility catalog D·A·X·C·S·M·P·T) → Behavior-Verify (behavior_snapshot.py verify). The reviewer rejects a simplify that ships behavior drift or removed test coverage (fewer lines is not the goal); Spec Impact is forced NONE. The gate is only as strong as coverage, so removed coverage is a hard reject.
BUG intent (intent-classification kind: bug-fix) routes through F-debug BEFORE any fix — Iron Law: NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST (4 phases: Read Error → Reproduce → Recent Changes → Component-Boundary Instrumentation). The reviewer rejects a fix that patches a symptom rather than the root cause (no root-cause statement / no test pinning it). Then follow references/path-c-bug.md (investigation, reproduce, root-cause, write-failing-test, fix). Step 7.5 (Confidence Calibration) applies identically — mandatory at medium+, also at small with touches_io_boundary.
See references/campaign-mode.md for the full protocol: campaign setup, autonomous interleaved-serial loop (init/next/record/merge/finalize — build one sub-iterate → PR → CI-green → merge → next from fresh origin/main; branch_strategy: serial is the default), sub-iterate-runner contract, F12 release prompt. Review steps in autonomous-loop briefing (ADR-029): the sub-iterate-runner contract mandates Step 3.5 (External Plan Review) and Step 3.7 (Code Review Cascade) between Build and Finalization for medium+ iterates. The runner has no Agent tool, so the internal code-reviewer is delegated back to the orchestrator. Skipping these review steps silently is a contract violation under ADR-029. Manual sub-iterate stamp (campaign S1): a hand-run sub-iterate — /shipwright-iterate --campaign <slug> --sub-iterate-id <id> "<sub-iterate spec path>" (or any direct invocation on a campaign sub-iterate spec) — MUST stamp its work_completed event exactly like the runner does: include "campaign": "<slug>" and "sub_iterate_id": "<id>" in the F5b --event-extras-json (see references/F5b.md); additive metadata, does not replace the FR-gate classification fields.
Single Source of Truth for phase selection. All prose, diagrams, examples MUST be consistent. Large is a "soft boundary" — force-continue supported with mandatory review + full tests.
| Phase | Trivial | Small | Medium | Large |
|---|---|---|---|---|
| Repo Scout | quick | quick | thorough | → escape hatch |
| Interview | skip | 1 confirmation Q | FEATURE: 2-3 Q, CHANGE: 1-2 Q | → escape hatch |
| Iterate Spec | skip | skip | own file in .shipwright/planning/iterate/ | — |
| Spec Impact (ADD/MODIFY/REMOVE/NONE) | always (BUG: classify; NONE default) | always (BUG: classify; NONE default) | always (BUG: classify; NONE default) | — |
| Mini-Plan | skip | FEATURE only | yes + alternative (all types) | — |
| User Approval | skip | skip | before build | — |
| External LLM Review | skip | skip | auto | — |
| Design Check | skip | Tier 1 (text) | Tier 2 (markdown) | — |
| Build (TDD) | always | always | always | — |
| Boundary Probe | skip | if touches_io_boundary | if touches_io_boundary | — |
| Self-Review | always | always | always | — |
| Confidence Calibration | skip | if touches_io_boundary | always | always |
| Test Completeness Ledger | n/a (auto) | always | always | always |
| Integration Coverage (cross-component) | skip | skip | if cross_component | if cross_component |
| Full Code Review | only if risk flags | only if risk flags | always | — |
| Browser Verify | if UI | if UI | if UI | — |
| Smoke Test | if server up | if server up | if server up | — |
| Unit Test | --related | --related | full suite | — |
| Integration Test | if CRUD | if CRUD | full suite | — |
| pgTAP DB Test | if new RLS | if new RLS | full suite | — |
| E2E Verification (author + execute) | if feature+UI | if feature+UI or touches_io_boundary | always | — |
| Design Fidelity | skip | if structural UI | if UI | — |
| Performance Budget | if touches_build | if touches_build | if touches_build OR if UI | — |
| architecture.md | if structural impact | if structural impact | if structural impact | — |
| Test Results JSON | always | always | always | — |
| run_config iterate_history | always | always | always | — |
| Session Handoff | skip | if needed | if needed | — |
| Release Prompt | always | always | always | — |
E2E Verification "always" at medium+ means author AND run, not author OR run. Spec-only authorship counts as no test (see F0.5). Large routes to the escape-hatch pipeline.
See references/mid-flight-escalation.md (trivial → small → medium → large transitions, dirty-tree handling, WIP checkpoint commits). The agent can upgrade complexity mid-flight if scope is expanding.
See references/escape-hatch.md and references/iteration-planning.md (handoff file format and failure behavior). Triggered when complexity = large.
See references/artifact-ownership.md (iterate spec, spec.md, shipwright_events.jsonl, ADR, architecture.md, mini-plan).
CRITICAL: F0–F11 (incl. F3a, F5a, F5b, F5c) are MANDATORY. (→ Phase Timing: mark test at F0, mark finalize at F1 — see phase-timing.)
Order matters. F0.5 / F3 / F3a / F4 / F5 / F5a / F5b / F5c all write tracked artifacts and MUST run before F6 so a single atomic commit stages them. F5b's
work_completedevent lands in this worktree'sshipwright_events.jsonl, so F6 stages it and it ships in the PR (per-tree, PR-committed model — iterate-2026-05-29-events-jsonl-worktree-commit). F0.5 is the production-time E2E gate. F6.5 (SHA patch) and F7/F7b are SKIPPED in the normal worktree flow — they exist only for legacy / out-of-band (non-worktree, replay) event recording. Do not reorder.
See F0. Leak-guard (check_iterate_isolation.py --stage f0), then full test suite. STOP on any failure.
See F0.5. Mandatory at medium+. Safety-enforced at small with touches_io_boundary or UI. Advisory at trivial.
Four fail-closed conditions enforced by surface_verification.py (orchestrator) + the post-commit audit verify_iterate_finalization.py: (1) surface != "none" AND tests_run == 0; (2) non-zero exit_code after the 3-retry cap; (3) surface == "none" without a justification; (4) surface_verification block missing at medium+ without an opt-out. Non-zero exit at F0.5 = STOP.
Backend-affects-Frontend rule. If the diff touches API routes, store mutations, SSE/WS handlers, message contracts, or any code consumed by the UI — surface = web is mandatory even when no client/** file changed. The matrix always cell at medium+ subsumes file-path detection. Spec-only authorship counts as no test (tests_run = 0).
| Phase | Reference | One-liner |
|---|---|---|
| F1 | F1 | artifact_sync.py --ref "HEAD~1..HEAD"; update specs if drift |
| F2 | F2 | Architecture update; triggers: new route/component/schema/service/write-surface/read-surface/convention |
| F3 | F3 | write_decision_drop.py keyed by run_id; ADR-NNN assigned at /shipwright-changelog release; field cap 1-3 sentences / 500 chars |
| F3a | F3a | Reflection — append learnings per references/reflection.md |
| F4 | F4 | write_changelog_drop.py → one bullet per AC under CHANGELOG-unreleased.d/<category>/ |
| F5 | F5 | Latest-run state under iterate_latest in shipwright_test_results.json — incl. the test_completeness ledger block (small+) |
| F5b | F5b | finalize_iterate.py — records work_completed (with commit="") into this worktree's events.jsonl BEFORE compliance regen + handoff; F6 stages it (ships in the PR) |
| F5c | F5c | append_iterate_entry.py → .shipwright/agent_docs/iterates/<run_id>.json atomically; 50-entry retention |
| F6 | F6 | Commit (Conventional Commits). Explicit git add per-path list — incl. shipwright_events.jsonl when tracked. NEVER -A. Footer: Run-ID: {run_id} + Co-Authored-By: Claude <[email protected]> |
| F6.5 | F6.5 | SKIP in worktree flow — event ships with commit="". Legacy/non-worktree only: finalize_iterate.py attach-commit … |
| F7 | F7 | Legacy/out-of-band record_event.py. Skip unless replaying / non-worktree. ADR-059 FR-gate applies to ALL iterates incl. BUG |
| F7b | F7b | commit_event_followup.py — seals an out-of-band F7 main-tree append only (not the worktree flow; idempotent noop otherwise) |
| F11 | F11 | Leak-guard (--stage f11), ensure_current.py refresh-if-behind (integrate+regenerate before arm), push + gh pr create against origin/<default>, arm fail-soft gh pr merge --auto --squash (iterate/* only; deferred under campaign SHIPWRIGHT_ITERATE_AUTOMERGE=0 — orchestrator merges each PR in turn, interleaved-serial), update handoff, run verify_iterate_finalization.py, then watch_pr_delivery.py — delivered = MERGED + green (no shoot-and-forget) |
| F12 | F12 | Count pending drops; prompt for /shipwright-changelog once PR merges; print summary banner |
See references/degraded-mode.md (no sync config, stale mappings, no visual-guidelines, browser-verify failure, code-reviewer unavailable, external review opt-out, pipeline handoff failure, no designs). Record degraded conditions in shipwright_test_results.json.degraded[].
See references/error-handling.md (test failures: 3-attempt circuit breaker; pre-commit hook failures: auto-fix, never --no-verify; missing sync config: TBD/conservative; session handoff: see references/iteration-reviews.md).
npx claudepluginhub svenroth-ai/shipwright --plugin shipwright-iterateGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.