
Rpi
- 1.3k installs
- 416 repo stars
- Updated August 5, 2026
- boshu2/agentops
rpi provides documented workflows for Run discovery, crank, validation. Triggers: "run rpi", "research-plan-implement one turn", "drive a turn through the operating loop".
About
The rpi skill run discovery, crank, validation. Triggers: "run rpi", "research-plan-implement one turn", "drive a turn through the operating loop". # /rpi - Full Lifecycle Orchestrator > Quick ref: `/discovery` -> `/crank` -> `/validate`, then report. Do not only describe it.** RPI is autonomous unless `--interactive` is set. The user touchpoint is after validation, or after a real blocked state exhausts retries. Read [references/autonomous-execution.md](references/autonomous-execution.md) when you need the full autonomy contract. **`--auto` means *pivot autonomously*, NOT *execute the initial plan to the letter*.** Autonomy is agility, not waterfall: between waves the orchestrator re-plans the remaining work and changes course on its own - refactoring, adding, dropping, reordering waves as evidence arrives - without the operator saying so (touched only at the terminal objective or a circuit-breaker trip). See [Agile Re-Plan Loop](#agile-re-plan-loop-the-anti-waterfall-rule). ## Loop position `/rpi` is the orchestrator across **every move** of the [operating loop](../../docs/architecture/operating-loop.md): BDD intent → vertical slices → conflict-free wave → bead acceptance →.
- **operating-loop-skill** - driving one bead end-to-end through claim, work, independent validation, closeout, and pers
- Create `.agents/rpi/`.
- Resolve `--from`:
- default, `research`, `plan`, `pre-mortem`, `brainstorm` -> discovery
- `implementation` or `crank` -> implementation
Rpi by the numbers
- 1,319 all-time installs (skills.sh)
- +28 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #235 of 2,064 Data Science & ML skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
rpi capabilities & compatibility
- Capabilities
- **operating loop skill** driving one bead end · create `.agents/rpi/`. · resolve ` from`: · default, `research`, `plan`, `pre mortem`, `brai · `implementation` or `crank` > implementation
- Use cases
- documentation · planning
What rpi says it does
# /rpi - Full Lifecycle Orchestrator > Quick ref: `/discovery` -> `/crank` -> `/validate`, then report.
Do not only describe it.** RPI is autonomous unless `--interactive` is set.
npx skills add https://github.com/boshu2/agentops --skill rpiAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.3k |
|---|---|
| repo stars | ★ 416 |
| Security audit | 2 / 3 scanners passed |
| Last updated | August 5, 2026 |
| Repository | boshu2/agentops ↗ |
How do I use rpi for the task described in its SKILL.md triggers?
Run discovery, crank, validation. Triggers: "run rpi", "research-plan-implement one turn", "drive a turn through the operating loop".
Who is it for?
Teams invoking rpi when the user request matches documented triggers and prerequisites.
Skip if: Skip when cached docs are missing, the request is a negative trigger, or another sibling skill owns the workflow.
When should I use this skill?
Run discovery, crank, validation. Triggers: "run rpi", "research-plan-implement one turn", "drive a turn through the operating loop".
What you get
Step-by-step guidance grounded in rpi documentation and reference files.
- implemented code changes
- validation learnings
- discovery notes
By the numbers
- Enforces 3 mandatory execution phases: discovery, implementation, and validation
- Supports a fast complexity mode that can skip the full three-phase rule
Files
/rpi - Full Lifecycle Orchestrator
Quick ref:/discovery->/crank->/validate, then report.
Execute this workflow. Do not only describe it. RPI is autonomous unless --interactive is set. The user touchpoint is after validation, or after a real blocked state exhausts retries. Read references/autonomous-execution.md when you need the full autonomy contract.
*`--auto` means pivot autonomously, NOT execute the initial plan to the letter.* Autonomy is agility, not waterfall: between waves the orchestrator re-plans the remaining work and changes course on its own — refactoring, adding, dropping, reordering waves as evidence arrives — without the operator saying so (touched only at the terminal objective or a circuit-breaker trip). See Agile Re-Plan Loop.
Loop position
/rpi is the orchestrator across every move of the operating loop: BDD intent → vertical slices → conflict-free wave → bead acceptance → evidence + learning capture. It delegates each move to the skill that owns it (/discovery, /plan, /crank, /validate, /forge//post-mortem), and enforces these loop-level invariants:
- Agile, not waterfall — the plan is a hypothesis. Every wave closes with a re-plan, not just a retry (the Agile Re-Plan Loop, autonomous under
--auto). - No move-skipping, but validation cadence is pawl-gated, not per-tread (docs/contracts/pawls.md). Strict delegation is on by default; phases never compress; the lifecycle objective is preserved across the loop. "Validation cannot be skipped" means the bead-acceptance pawl validates fully — NOT that every intermediate slice pays the heavy cross-family panel. The acceptance roll-up + heavy gates (full council,
/validate --mixed,/pre-land-refuters) fire once, at the bead-acceptance / merge-to-main pawl (the ratchet's lock). Intermediate slices are chaos: cheap local checks (build, TDD red→green, light inline wave-acceptance judges) run freely; the heavy panel never fires per slice. A pawl on every tread is the waterfall the ratchet exists to avoid. - The first failing test is the bead's contract. With
--test-firston (the default),/crankis invoked with the TDD-per-slice discipline;--no-test-firstis an explicit opt-out, not a fast path. - Acceptance examples close the bead, not activity. Validation FAIL re-cranks on the same objective up to 3 attempts; DONE requires the acceptance roll-up in the slice-validation template to be fully green.
- Ports stay visible. Preserve the Intent-to-Loop Hexagon boundary as the objective crosses
shape_intent,persist_intent,plan_slices,execute_wave,validate_acceptance, andrecord_evidence. - Context density survives phase boundaries. Apply the Context Density Rule to every phase handoff and final report: keep intent, boundary, evidence, decision, constraint, and next action; omit or link anything else.
Folded triggers (ag-s43tg): operating-loop-skill + operating-loop-workflow route here
- operating-loop-skill — driving one bead end-to-end through claim, work, independent validation, closeout, and persistence:
/rpi <bead-id>runs that exact arc. - operating-loop-workflow — installing or running the seven-move operating-loop Workflow for AgentOps plugin users and multi-agent orchestration:
/rpiis the in-session orchestrator of the same seven moves.
Core Contract
RPI delegates via Skill(skill="discovery", ...), Skill(skill="crank", ...), and Skill(skill="validate", ...) as separate tool invocations. Keep strict delegation on by default; do not compress phases, replace phase skills with direct agent spawns, or skip validation. Read ../shared/references/strict-delegation-contract.md for the full anti-compression contract. See references/isolation-contract.md for the four-lever model, phase-isolated skill transport, and the compression patterns scripts/check-skill-isolation.sh flags. See references/best-practices.md for the principle and anti-pattern citation table.
When the runtime supports phase isolation, keep /rpi visible in the main session and run each phase contract through isolated transport: phase skill name in, bounded handoff artifact in, phase artifact/verdict/next action out. The transport may be a daemon job, process runner, or subagent wrapper, but it must execute the declared phase skill contract rather than doing phase work directly.
RPI owns one lifecycle objective across all phases. Preserve the discovered epic_id when present; otherwise preserve the original goal and execution packet objective. A child bead or one ready slice is context, not a replacement objective. <promise>PARTIAL</promise> from /crank means retry Phase 2 on the same objective.
Route And Classify
1. Create .agents/rpi/. 2. Resolve --from:
- default,
research,plan,pre-mortem,brainstorm-> discovery implementationorcrank-> implementationvalidation,vibe, orpost-mortem-> validation
3. If the input is a bead and --from is absent, resolve it with br show:
- epic -> implementation with that epic
- child with parent -> implementation with the parent epic
4. Classify complexity:
fast: short/simple goal or--fast-pathstandard: medium goal or one scope keywordfull:--deep, complex-operation keyword, 2+ scope keywords, or >120 chars
5. Log RPI mode: rpi-phased (complexity: <level>).
Track state compactly:
rpi_state = {
goal: "<goal string>",
epic_id: null,
phase: "<discovery|implementation|validation>",
complexity: "<fast|standard|full>",
test_first: <true by default; false only when --no-test-first>,
cycle: 1,
verdicts: {}
}Complex-operation keywords include refactor, migrate, rewrite, redesign, rearchitect, overhaul, decouple, deprecate, split, extract module, and port. Scope keywords include all, entire, across, everywhere, every file, system-wide, global, and codebase.
Phase DAG
Enter at the routed phase and run every phase after it.
1. Discovery: invoke /discovery <goal> [--interactive] --complexity=<level> directly or through phase-isolated skill transport. On DONE, read .agents/rpi/execution-packet.json or the run archive and preserve its objective spine. On BLOCKED, stop with the discovery verdict. 2. Implementation: invoke /crank <epic-id> when the packet has epic_id; otherwise invoke /crank .agents/rpi/execution-packet.json, directly or through phase-isolated skill transport. Pass --test-first or --no-test-first through. On DONE, record ao ratchet record implement 2>/dev/null || true and continue. On PARTIAL or BLOCKED, retry the same objective up to 3 total attempts. 3. Validation: invoke /validate <epic-id> --complexity=<level> when an epic exists; otherwise invoke /validate --complexity=<level>, directly or through phase-isolated skill transport. Add --strict-surfaces when --quality is set. On FAIL, extract findings, re-run /crank on the same objective, then re-run /validate, up to 3 total validation attempts. On DONE, record ao ratchet record vibe 2>/dev/null || true. This Phase-3 /validate is the bead-acceptance pawl (docs/contracts/pawls.md) — once per RPI objective at acceptance, not per slice. The merge-to-main pawl fires regardless of complexity: any work crossing the shared-trunk door — fast/standard included — invokes the pawl gate `/pre-land-refuters` before push (pawls.md makes mutate-shared-trunk complexity-independent). Complexity scales the gate's DEPTH, never exempts it: every door gets at least the fresh-context default (≥1 fresh-context refuter, model-agnostic); higher-irreversibility doors are opted up to multi-model (≥2 distinct families), and full arcs (100+ files, factory regen, contract-test repoints, capability removal) get full council — neither skips the gate. REFUTED → AUTO-REDO: refuted findings re-crank like a validation FAIL, autonomously and with no human (the default self-correcting path); a human is escalated to only when a tunable circuit breaker trips (max-attempts — here the 3-attempt cap — time budget, cost/quota, or oscillation), per pawls.md "Escalation — the circuit-breaker model". The gate is the door, never per slice. 4. Re-plan (mandatory between waves; the loop's hinge). With remaining waves, run the Agile Re-Plan Loop before the next — a post-mortem/discovery delta that MAY mutate the remaining plan (autonomous under --auto). No remaining waves → straight to Report. 5. Report: summarize phase verdicts, the re-plan deltas taken, and epic status using references/report-template.md. With --loop, restart from discovery on FAIL while cycle < max_cycles. With --spawn-next, read .agents/rpi/next-work.jsonl and suggest the next command without invoking it. Before emitting the report, apply the Context Density Rule: every line should carry intent, boundary, evidence, decision, constraint, or next action.
Agile Re-Plan Loop (the anti-waterfall rule)
The initial plan is a hypothesis; each wave is an experiment whose evidence re-plans the rest. At every wave boundary (and after validation): reflect (a bounded /post-mortem + /discovery re-plan delta over what shipped/broke) → re-plan the REMAINING waves (refactor / insert / drop / reorder / re-scope / escalate, persisting the mutated plan so the next wave reads the current one) → proceed. Under --auto this is autonomous, bounded by the run's circuit breakers (budget / attempt cap / oscillation detection) and the ≥5-ship post-mortem checkpoint; the operator is touched only at the terminal objective or a breaker trip. /crank and /validate surface findings UP for re-planning (never a silent local retry); /discovery is the re-plan engine. Anti-patterns: waterfall (run the plan to the letter), retry-not-replan (re-crank forever instead of changing the remaining plan), permission-seeking (pause to approve a pivot --auto already authorizes). Full detail: references/agile-replan-loop.md.
Phase Data Contract
The execution packet carries the repo execution profile through contract_surfaces, done_criteria, and queue claim/finalize metadata. Keep the latest alias at .agents/rpi/execution-packet.json and read references/phase-data-contracts.md for schemas and archive paths.
Complexity-Scaled Gates
The pawl gates (pawls.md) fire at the irreversible doors — bead-acceptance and merge-to-main — never per slice/wave; chaos between pawls. The merge-to-main pawl fires regardless of complexity (see Phase 3); complexity below only scales the DEPTH of the gate, never whether it runs.
Complexity scales the gate's depth: low/fast and medium/standard → 2-judge minimum panel (inline / --quick); high/full → full council; max 3 total attempts. The gate still fires at the door at every complexity.
- Pre-mortem (planning-time, chaos-side — NOT a pawl):
high/full→ full council, 2-judge minimum; max 3 total attempts. Pre-mortem stress-tests the plan before work; it is not an irreversible door and carries no heavy gate of its own outside this optionalfull-arc depth. - Final Vibe (at the bead-acceptance pawl):
high/full→ full council, 2-judge minimum; max 3 total attempts. - Post-mortem (STEP 2, at the bead-acceptance pawl):
high/full→ full council; same scale as above.
Flags
| Flag | Default | Purpose |
|---|---|---|
--from=<phase> | discovery | Start at discovery, implementation, or validation |
--discovery-artifact=<path> | unset | With implementation start, convert an existing artifact into the handoff packet |
--interactive | off | Human gates in discovery/validate |
--auto | on | Fully autonomous default — pivots between waves on its own (re-plans remaining work; not a fixed-plan/waterfall executor). See Agile Re-Plan Loop |
--loop --max-cycles=<n> | off / 3 | Iterate when validation fails |
--spawn-next | off | Surface follow-up work after reporting |
--test-first | on | Pass strict-quality preference to /crank |
--no-test-first | off | Explicitly opt out of strict-quality |
--fast-path / --deep | auto | Force fast or full complexity |
--quality | off | Make validation strict surfaces blocking |
--dry-run / --no-budget | off | Report only, or disable phase time budgets |
Examples
User says: /rpi "add user authentication" Run discovery, implementation, validation, then report.
User says: /rpi --from=implementation ag-23k Resolve the bead scope, run implementation and validation, then report.
User says: /rpi --deep "refactor payment module" Use full council gates across the lifecycle.
Read references/examples.md for resume, interactive, loop, and artifact-mode examples.
Troubleshooting
| Problem | Response |
|---|---|
| Discovery BLOCKED | Stop and report discovery's manual-intervention reason |
/crank returns PARTIAL | Retry /crank on the same objective; do not narrow to a child slice |
| Validation FAIL | Re-crank with findings, then re-validate, up to 3 total attempts |
| Packet shape unclear | Read references/phase-data-contracts.md |
| External executor fails | Read references/codex-executor.md, run direct Codex validation, and only create follow-up work for reproducible source failures |
Related skills
- `/using-atm` — out-of-session ATM substrate for running whole
/rpiloops over a bead queue.
Reference Documents
- references/agile-replan-loop.md — the anti-waterfall rule: inter-wave re-plan,
--auto-pivot bounds, anti-patterns - references/rpi.feature — Executable spec: strict ordered phases, validation-never-skipped, context-density across handoffs (soc-qk4b.2)
- references/orchestrator-compression-anti-pattern.md — Phase-skipping failure mode; rationalizations to reject
- references/autonomous-execution.md
- references/installed-plugin-version-not-repo-head.md —
/rpiloads from~/.claude/plugins/cache/, not the repo working tree; verify which version is active before measuring - references/complexity-scaling.md
- references/context-windowing.md — OPT-IN large-repo mode (
--large-repo); NOT part of the default RPI path. Default discovery/research does not generate.agents/rpi/context-shards/latest.json. - references/codex-executor.md
- references/discovery-artifact-mode.md
- references/error-handling.md
- references/examples.md
- references/gate-retry-logic.md
- references/gate4-loop-and-spawn.md
- references/phase-budgets.md
- references/phase-data-contracts.md
- references/report-template.md
- references/troubleshooting.md
Agile Re-Plan Loop (the anti-waterfall rule)
The initial plan/wave-sequence is a hypothesis. Each wave is an experiment that produces evidence; that evidence re-plans the remaining waves. This is what makes --auto autonomous rather than blind.
At every wave boundary (and after the validation phase)
1. Reflect — run a bounded post-mortem/discovery delta over the wave just completed (delegate to /post-mortem then /discovery's re-plan, isolated; do not inline). Input = what shipped, what the gate/refuters said, what broke, what the wave taught that the plan didn't know. 2. Re-plan the REMAINING waves — the delta may, autonomously:
- refactor a downstream wave's scope (split, merge, narrow, widen),
- insert a new wave the evidence revealed is needed,
- drop a wave the evidence made unnecessary,
- reorder waves as the critical path shifts,
- re-scope / re-prioritize / re-sequence beads,
- escalate (circuit-breaker) when the evidence invalidates the objective itself.
Persist the mutated plan (the execution packet / plan doc is rewritten, not appended-to-blindly) so the next wave reads the current plan, not the stale one. 3. Proceed to the next (possibly new/changed) wave.
Bounds (so agility ≠ thrash)
Re-planning shares the run's circuit breakers — token/time budget, the attempt cap, and oscillation detection (if the plan flips the same decision back and forth across waves, stop and surface it). Honor the autonomous-session scope (CLAUDE.md): at ≥5 ships in one session, the post-mortem checkpoint is mandatory and may itself end the session. The operator is touched only at the terminal objective or a breaker trip — never just to approve a pivot.
Anti-patterns this rule kills
- Waterfall: executing the initial wave list to the letter because "that was the plan."
- Retry-not-replan: re-cranking a failed wave on the same objective forever instead of asking whether the remaining plan should change.
- Permission-seeking: pausing to ask the operator to approve a pivot that
--autoalready authorizes.
How the phase skills feed this loop
/crank (implementation) and /validate surface their findings up to the orchestrator for re-planning — they do not swallow a finding into a silent local retry. /discovery is the re-plan engine; /post-mortem is the reflect step.
Autonomous Execution Rules
The Three-Phase Rule
RPI has THREE mandatory phases (unless complexity == fast). You MUST run all three — discovery, implementation, AND validation — in a single session. Do NOT stop after implementation. Do NOT ask the user if they want to commit after Phase 2. Phase 2 completing is NOT the end — it is the midpoint. Validation (Phase 3) is where learnings are captured and the knowledge flywheel turns. Skipping it breaks the flywheel.
Fully Autonomous by Default
Unless --interactive is explicitly set, RPI runs hands-free from start to finish. Do NOT:
- Ask the user for confirmation between phases
- Ask "want me to commit?" or "should I continue?"
- Pause to summarize and wait for input
- Request clarification mid-execution
- Stop to ask about approach or strategy
The human's only touchpoint is AFTER Phase 3 completes. If something is genuinely blocked (3 retries exhausted), then and only then do you stop and report. Everything else runs autonomously. The user invoked /rpi because they want you to GO — not to narrate.
Anti-Patterns (DO NOT)
| Anti-Pattern | Why It's Wrong | Correct Behavior |
|---|---|---|
| Stop after Phase 2 and ask to commit | Skips validation — no quality check, no learnings, flywheel doesn't turn | Proceed directly to Phase 3 |
Call /validate directly instead of /validate | /validate is one sub-step; /validate wraps vibe + post-mortem + forge | Always call /validate from /rpi |
| Ask "want me to commit?" between phases | Interrupts autonomous flow — user invoked /rpi for hands-free execution | Commit only after ALL phases complete |
| Ask the user ANY question during execution | RPI is autonomous unless --interactive — questions break the flow | Make best judgment and proceed; report at end |
Run Phase 1 inline instead of delegating to /discovery | Loses brainstorm → search → research → plan → pre-mortem sequencing | Delegate via Skill(skill="discovery") |
| Summarize findings and wait after Phase 1 | Discovery output is an input to Phase 2, not a deliverable | Proceed immediately to Phase 2 |
| Pause to explain what you're about to do | Narration wastes time — the user wants results, not commentary | Execute, then report at the end |
Phase Completion Tracking
After each phase, log progress:
PHASE 1 COMPLETE ✓ (discovery) — proceeding to Phase 2
PHASE 2 COMPLETE ✓ (implementation) — proceeding to Phase 3
PHASE 3 COMPLETE ✓ (validation) — RPI DONERPI lifecycle best practices
Citation table extracted during research for soc-bcrn (RPI lifecycle sharpening). The lifecycle skills (/rpi, /discovery, /crank, /validate) MUST reference principles by # from this file — they MUST NOT duplicate the body content here. When a principle is wrong or stale, update this file and the citations fix themselves.
Source research: .agents/research/2026-05-07-rpi-lifecycle-sharpening.md §Objective 4.
Table A — Principles to encode
| # | Principle | Source citation | Encode in |
|---|---|---|---|
| 1 | Explicit done criteria | docs/context-lifecycle.md (Gap 1) | discovery, plan, validation |
| 2 | Strict delegation over compression | skills/shared/references/strict-delegation-contract.md, .agents/learnings/2026-04-19-orchestrator-compression-anti-pattern.md | rpi, discovery, crank, validation |
| 3 | Fresh context per worker (Ralph Wiggum) | docs/scale-without-swarms.md | crank, swarm |
| 4 | Isolation + waves + gates (3–5 workers/wave) | docs/scale-without-swarms.md | crank |
| 5 | Evidence-based gates, not vibe | docs/context-lifecycle.md Gap 1 | validation, vibe |
| 6 | Test-first when feasible | skills/crank/SKILL.md (test-first mode) | crank |
| 7 | Atomic changes compose | docs/brownian-ratchet.md | crank |
| 8 | Reconcile, don't push | PRODUCT.md design principle (K8s control loops), docs/cdlc.md | rpi, evolve |
| 9 | Agent fungibility + filesystem results | PRODUCT.md operational principle #5, skills/agent-fungibility-philosophy/SKILL.md | rpi, crank, swarm |
| 10 | Chaos + filter + ratchet (Brownian) | docs/brownian-ratchet.md | rpi, evolve |
| 11 | Structured handoffs over freeform | skills/rpi/SKILL.md (execution-packet contract) | rpi, discovery, validation |
| 12 | Knowledge flywheel closure | docs/context-lifecycle.md Gap 3 | rpi, post-mortem, forge |
| 13 | Information flows + rules + self-organization (Meadows) | PRODUCT.md design principle #1 | rpi (top-of-skill framing) |
| 14 | DevOps Three Ways (flow, feedback, learning) | docs/the-science.md, PRODUCT.md design principle #2 | rpi (top-of-skill framing) |
Table B — Anti-patterns to forbid
| # | Anti-pattern | Source citation | Forbid in |
|---|---|---|---|
| 1 | Compression of strict delegation (inline phase work) | .agents/learnings/2026-04-19-orchestrator-compression-anti-pattern.md | rpi, discovery, validation |
| 2 | Massive uncoordinated swarms (60+ unbounded) | docs/scale-without-swarms.md | crank, swarm |
| 3 | Magic-claimed compounding (without a scheduled out-of-session loop) | PRODUCT.md mission section | dream, evolve |
| 4 | Vibe-based gates without rubric / separate-context grader | PRODUCT.md Gap 1 | validation, vibe |
| 5 | Vendor memory follows the chat (context must reload from disk) | PRODUCT.md mission | rpi (orchestrator persists; phase workers DO NOT carry chat memory) |
| 6 | Coverage-padding tests | .claude/rules/go.md, .claude/rules/python.md, skills/standards/ | crank, test |
How to cite
When a phase skill (or sibling) wants to invoke a principle, write a single line referencing the row by number:
See [best practices](references/best-practices.md) #2 (strict delegation) and #5 (evidence-based gates).Do not paste the principle body. Citations stay short; the source-of-truth is here. Anti-patterns are cited the same way: See [best practices](references/best-practices.md) Table B #1 (compression).
Mechanical enforcement
- Principle #2 + Anti-pattern #1:
scripts/check-skill-isolation.shlints phase-skill SKILL.md bodies for compression patterns (introduced insoc-bcrnUW2). - Principle #5 + Anti-pattern #4:
skills/validate/SKILL.mddefines the per-criterion verdict shape (introduced insoc-bcrnUW1; folded from the retiredvalidationskill). - Principle #11:
schemas/execution-packet.schema.json($defs/Criterion) is the canonical handoff shape.
Codex Executor Path
Use this reference when an RPI run fails because the external agent harness failed, while the repo checks or slice behavior are still recoverable through Codex direct execution.
Decision Rule
If Claude Code or another executor fails with process pressure, missing worktree, or session-runtime errors, do not classify that as a code regression until Codex direct checks reproduce a source-level failure.
Codex Recovery Steps
1. Identify the clean branch worktree and avoid the dirty canonical root. 2. Use the source-built CLI explicitly:
AO_BIN=/Users/bo/go/bin/ao
"$AO_BIN" rpi status3. If the RPI run worktree is missing, treat the run as an executor artifact and continue from the branch worktree. 4. Run the program or slice validation bundle directly from Codex. 5. If validation fails for source code, create or update a bead with the failing gate and fix it test-first. 6. If validation passes, record acceptance evidence and do not re-open the already-satisfied bead.
Non-goals
- Do not resurrect missing temporary RPI worktrees.
- Do not invoke Claude Code as the executor for the recovery run.
- Do not convert a runtime artifact into a source-code failure without a
reproducible gate.
Complexity Scaling
Automatic complexity detection determines the level of validation ceremony applied to each RPI cycle.
Classification Table
| Level | Issue Count | Wave Count | Ceremony |
|---|---|---|---|
| low | ≤2 | 1 | fast-path: --quick on pre-mortem, vibe, post-mortem |
| medium | 3-6 | 1-2 | lean: --quick on pre-mortem, vibe, post-mortem (same as low — inline review is sufficient for most work) |
| high | 7+ OR 3+ waves | any | thorough: full council on pre-mortem and vibe, standard post-mortem |
Design rationale (2026-02-18): --quick (inline single-agent structured review) catches the same class of bugs as full multi-judge council at ~10% of the token cost. The value of multi-judge consensus scales with stakes, not linearly with issue count. Medium-complexity epics (3-6 issues) don't benefit enough from multi-agent spawning to justify the 5-10x cost multiplier. Full council is reserved for high-stakes work where cross-model disagreement has real ROI.Detection
Complexity is auto-detected after plan completes (Phase 2) by examining:
- Issue count:
br children <epic-id> | wc -l - Wave count: derived from dependency depth
Flag Precedence (explicit always wins)
| Flag | Effect |
|---|---|
--fast-path | Forces low regardless of auto-detection |
--deep (passed to /rpi) | Forces high regardless of auto-detection |
| No flag | Auto-detect from epic structure |
Existing mandatory pre-mortem gate (3+ issues) still applies regardless of complexity level.
Large-Repo Context Windowing
OPT-IN — large-repo mode only. Context-shard generation is gated behind an
explicit --large-repo mode and is NOT part of the default RPI path. The defaultdiscovery/research phase does not produce .agents/rpi/context-shards/latest.json.scripts/rpi/generate-context-shards.py,run-shard.py,init-shard-progress.py,
and context-window-contract.sh are opt-in tooling for large repositories — invokethem only after explicitly entering --large-repo mode, never as a default-path step.Use this mode when the repo is too large for stable single-window analysis.
Why
Trying to read everything in one pass causes context collapse and unstable decisions. Deterministic shards let /rpi process all files incrementally with bounded load.
Setup Contract
scripts/rpi/context-window-contract.shThis verifies:
GOALS.yamlis valid- shard manifest generation works
- shard progress state initializes and validates
- shard runner can traverse shard 1
Generate Shards
scripts/rpi/generate-context-shards.py \
--max-units 80 \
--max-bytes 300000 \
--out .agents/rpi/context-shards/latest.json \
--checkInitialize Progress State
scripts/rpi/init-shard-progress.py \
--manifest .agents/rpi/context-shards/latest.json \
--progress .agents/rpi/context-shards/progress.json \
--checkRun One Shard (Bounded)
scripts/rpi/run-shard.py \
--manifest .agents/rpi/context-shards/latest.json \
--progress .agents/rpi/context-shards/progress.json \
--shard-id 1 \
--limit 20 \
--mark in_progress \
--notes "phase-1 analysis start"Operating Pattern
1. Generate shard manifest once per material repo change. 2. Process one shard at a time. 3. Write concise shard summaries to .agents/rpi/phase-*.md. 4. Mark shard status (todo, in_progress, done). 5. Continue until all shards are done.
This keeps CPU and context budgets bounded while preserving full-file coverage.
Discovery Artifact Mode (--discovery-artifact=<path>)
Purpose: Skip Phase 1 (/discovery) when discovery has already been done — for example, by an upstream /council --evidence --commit-ready validation, a hand-written plan, or a mid-session pivot where the agent has already produced a sound execution packet.
The problem it solves
The default /rpi flow runs /discovery as Phase 1: brainstorm → design → search → research → plan → pre-mortem. This is expensive (several skill invocations, potentially spawning council judges) and redundant when the caller already has a validated scope document. Without this flag, the only way to skip Phase 1 was --from=implementation, which requires an existing epic ID in the bead tracker. That left a gap: how do you resume RPI mid-session with a council-validated plan but no bead?
When to use
Use --discovery-artifact=<path> when any of the following is true:
1. An upstream /council --evidence run just produced a consolidated report with the scope, risks, file manifest, and test matrix you need for implementation. 2. A prior session wrote a plan to docs/council-log/ or .agents/plans/ that is still valid and you want to act on it now. 3. You are mid-session, discovered scope via ad-hoc research, and want to formalize the handoff into an execution packet without re-running discovery's gates. 4. The scope is small enough that a full /discovery invocation would cost more than the implementation itself.
Do NOT use for fresh, un-validated goals. Discovery exists to catch premature implementation; skipping it on a goal that hasn't been vetted recreates the very failure mode /rpi is designed to prevent.
What the artifact must contain
The /rpi orchestrator reads the artifact and extracts the following fields into .agents/rpi/execution-packet.json:
| Field | Required? | Source in typical artifact |
|---|---|---|
goal | yes | Heading or first paragraph |
scope.in_scope | yes | A "scope" / "what ships" / "file manifest" section |
scope.out_of_scope | recommended | An "out of scope" or "not shipping" section |
scope.loc_estimate | optional | LOC estimate from the plan |
abort_gates | recommended | Any "abort if X" / "stop and escalate if Y" conditions |
tdd_matrix | recommended | A list of test assertions (especially for --evidence artifacts) |
risks | optional | A "risks" / "unknowns" section |
If the artifact is a markdown file without explicit sections, /rpi falls back to treating the entire document as the goal and running with empty scope — this degrades gracefully but is less safe. Prefer structured artifacts.
The canonical format is the `/council --evidence --commit-ready` output. Those artifacts have all the required fields by construction.
How it works
/rpi --auto --from=implementation --discovery-artifact=docs/council-log/2026-04-11-validate-m8-assumption-validation.mdStep by step:
1. Validate artifact path. If the file doesn't exist or isn't readable, emit <promise>BLOCKED</promise> with reason discovery-artifact not found. Do not proceed. 2. Parse the artifact. Extract goal, scope, abort gates, tdd matrix, risks. For council reports, look for the consolidation section and the findings with test assertions. 3. Write execution packet. Produce .agents/rpi/execution-packet.json with the extracted fields, the artifact path under discovery_artifacts, and phase: "implementation". This is the same shape a normal /discovery run produces. 4. Log Phase 1 completion. PHASE 1 COMPLETE ✓ (discovery) — artifact: <path> 5. Proceed to Phase 2 (crank). Pass the execution packet to /crank exactly as if Phase 1 had run normally. 6. Phase 3 (validation) is unchanged — it still runs vibe + post-mortem + retro + forge.
Gate behavior
The pre-mortem gate that normally runs at the end of /discovery is assumed to have been passed by whatever upstream process produced the artifact. This is the core trust trade-off: you are skipping the gate in exchange for the work done upstream. To preserve safety:
- The orchestrator requires the artifact to contain at least one of: an explicit verdict (e.g., "PASS with HIGH confidence"), abort gates, or a test matrix.
- If the artifact is empty or lacks any of the above,
/rpidowngrades to treating it as an informational hint and runs/discoveryanyway. Do NOT silently skip gates when the artifact is too thin to validate.
Example: continuation from in-session council
The 2026-04-11 na-h61 M8 session used this pattern:
1. Session started with /council --tdd validating the scope of a deferred bead (the bead description had collectLearnings listed against a nonexistent file). 2. Council returned a consolidated report with: corrected scope (~300 LOC not 395), file touch inventory, test matrix (T1-T6), and an abort gate (">5 broken existing tests"). 3. Report was written to .agents/council/2026-04-11-m8-assumption-validation-consolidated.md. 4. User invoked /rpi --auto. The orchestrator recognized the artifact as the discovery output, declared Phase 1 complete, and proceeded directly to crank. 5. Phase 2 implementation landed with 1 commit, under the abort gate. 6. Phase 3 validation passed inline.
With this flag, the pattern becomes explicit instead of improvised:
/rpi --auto --from=implementation \
--discovery-artifact=.agents/council/2026-04-11-m8-assumption-validation-consolidated.mdSee also
skills/council/SKILL.md+skills/council/references/evidence-mode.md— the upstream source of high-quality discovery artifactsskills/discovery/SKILL.md— the Phase 1 orchestrator that this flag bypassesdocs/council-log/README.md— where committable council artifacts live
Error Handling
| Failure | Behavior |
|---|---|
| Skill invocation fails | Log error, retry once. If still fails, stop with checkpoint. |
| User abandons at sub-skill gate | /rpi stops with checkpoint (only in --interactive mode) |
| /crank returns BLOCKED | Re-crank with context (max 2 retries). If still blocked, stop. |
| /crank returns PARTIAL | Re-crank remaining items with context (max 2 retries). If still partial, stop. |
| Pre-mortem FAIL | Re-plan with fail feedback, re-run pre-mortem (max 3 total attempts) |
| Vibe FAIL | Re-crank with fail feedback, re-run vibe (max 3 total attempts) |
| Max retries exhausted | Stop with message + path to last report. Manual intervention needed. |
| Context feels degraded | Log warning, suggest starting new session with --from |
RPI Examples
Full Lifecycle
User says: /rpi "add user authentication"
1. /discovery "add user authentication" — brainstorm, research, plan, pre-mortem -> epic ag-5k2 2. /crank ag-5k2 — implement all issues 3. /validate ag-5k2 — vibe, post-mortem, forge
Resume from Implementation
User says: /rpi --from=implementation ag-5k2
1. Skips discovery 2. /crank ag-5k2 3. /validate ag-5k2
Interactive Discovery
User says: /rpi --interactive "refactor payment module"
1. /discovery "refactor payment module" --interactive --complexity=full — human gates in research + plan 2. /crank <epic-id> — autonomous 3. /validate <epic-id> — autonomous
Gate and Retry Logic
Detailed retry behavior for each gated phase. All gates use a max-3-attempts pattern (1 initial + 2 retries).
Pre-mortem Gate (Phase 3)
Extract verdict from council report:
REPORT=$(ls -t .agents/council/*pre-mortem*.md 2>/dev/null | head -1)Read the report file and find the verdict line (## Council Verdict: PASS / WARN / FAIL).
Gate logic:
- PASS: Auto-proceed. Log: "Pre-mortem: PASS"
- WARN: Auto-proceed. Log: "Pre-mortem: WARN -- see report for concerns"
- FAIL: Retry loop (max 2 retries):
1. Read the full pre-mortem report to extract specific failure reasons 1a. Extract ALL findings with structured fields (group by category if >20):
For each finding, extract:
FINDING: <description> | FIX: <fix or recommendation> | REF: <ref or location>
Fallback for v1 findings: fix = finding.fix || finding.recommendation || "No fix specified"
ref = finding.ref || finding.location || "No reference"2. Log: "Pre-mortem: FAIL (attempt N/3) -- retrying plan with feedback" 3. Re-invoke /plan with the goal AND the failure context including structured findings:
Skill(skill="plan", args="<goal> --auto --context 'Pre-mortem FAIL: <key concerns>\nStructured findings:\nFINDING: X | FIX: Y | REF: Z\nFINDING: A | FIX: B | REF: C'")4. Re-invoke /pre-mortem on the new plan 5. If still FAIL after 3 total attempts, stop with message: "Pre-mortem failed 3 times. Last report: <path>. Manual intervention needed."
Store verdict in rpi_state.verdicts.pre_mortem.
Implementation Gate (Phase 2)
Check completion status from crank's output. Look for <promise> tags:
- `<promise>DONE</promise>`: Proceed to Validation (Phase 3)
- `<promise>BLOCKED</promise>`: Retry (max 2 retries):
1. Read crank output to extract block reason 2. Log: "Crank: BLOCKED (attempt N/3) -- retrying with context" 3. Re-invoke /crank with epic-id and block context (include --test-first by default; omit only when --no-test-first is set) 4. If still BLOCKED after 3 total attempts, stop with message: "Crank blocked 3 times. Reason: <reason>. Manual intervention needed."
- `<promise>PARTIAL</promise>`: Retry remaining (max 2 retries):
1. Read crank output to identify remaining items 2. Log: "Crank: PARTIAL (attempt N/3) -- retrying remaining items" 3. Re-invoke /crank with epic-id (it picks up unclosed issues; include --test-first by default; omit only when --no-test-first is set) 4. If still PARTIAL after 3 total attempts, stop with message: "Crank partial after 3 attempts. Remaining: <items>. Manual intervention needed."
Validation Gate (Phase 3)
Extract verdict from council report:
REPORT=$(ls -t .agents/council/*vibe*.md 2>/dev/null | head -1)Read and extract verdict.
Gate logic:
- PASS: Auto-proceed. Log: "Vibe: PASS"
- WARN: Auto-proceed. Log: "Vibe: WARN -- see report for concerns"
- FAIL: Retry loop (max 2 retries):
1. Read the full vibe report to extract specific failure reasons 1a. Extract ALL findings with structured fields (group by category if >20):
For each finding, extract:
FINDING: <description> | FIX: <fix or recommendation> | REF: <ref or location>
Fallback for v1 findings: fix = finding.fix || finding.recommendation || "No fix specified"
ref = finding.ref || finding.location || "No reference"2. Log: "Vibe: FAIL (attempt N/3) -- retrying crank with feedback" 3. Re-invoke /crank with the epic-id AND the failure context including structured findings:
Skill(skill="crank", args="<epic-id> --context 'Vibe FAIL: <key issues>\nStructured findings:\nFINDING: X | FIX: Y | REF: Z' --test-first") # default strict-quality path
Skill(skill="crank", args="<epic-id> --context 'Vibe FAIL: <key issues>\nStructured findings:\nFINDING: X | FIX: Y | REF: Z'") # only when --no-test-first opted out4. Re-invoke /validate on the new changes 5. If still FAIL after 3 total attempts, stop with message: "Vibe failed 3 times. Last report: <path>. Manual intervention needed."
Store verdict in rpi_state.verdicts.vibe.
Gate 4 Loop and Spawn Next Work
Post-Validation Loop (Optional) -- Post-mortem to Spawn Another /rpi
Default behavior: /rpi ends after Validation (Phase 3).
Enable loop: pass --loop (and optionally --max-cycles=<n>).
Gate 4 goal: make the "ITERATE vs TEMPER" decision explicit, and if iteration is required, run another full /rpi cycle with tighter context.
Loop decision input: the most recent post-mortem council verdict.
1. Find the most recent post-mortem report:
REPORT=$(ls -t .agents/council/*post-mortem*.md 2>/dev/null | head -1)2. Read REPORT and extract the verdict line (## Council Verdict: PASS / WARN / FAIL). 3. Apply gate logic (only when --loop is set). If verdict is PASS or WARN, stop (TEMPER path). If verdict is FAIL, iterate (spawn another /rpi cycle), up to --max-cycles. 4. Iterate behavior (spawn). Read the post-mortem report and extract 3 concrete fixes, then re-invoke /rpi from Phase 1 with a tightened goal that includes the fixes:
/rpi "<original goal> (Iteration <n>): Fix <item1>; <item2>; <item3>" # default strict-quality path (test-first on)
/rpi "<original goal> (Iteration <n>): Fix <item1>; <item2>; <item3>" --no-test-first # explicit opt-out pathIf still FAIL after --max-cycles total cycles, stop and require manual intervention (file follow-up bd issues).
Spawn Next Work (Optional) -- Post-mortem to Queue Next RPI
Enable: pass --spawn-next flag.
Complementary to Gate 4: Gate 4 (--loop) handles FAIL->iterate (same goal, tighter). --spawn-next handles PASS/WARN->new-goal (different work harvested from post-mortem).
1. Read .agents/rpi/next-work.jsonl for unconsumed entries (schema contract: `docs/contracts/next-work.schema.md`). Filter entries by target_repo:
- Include if
target_repomatches the current repo name, ORtarget_repois"*"(wildcard), OR the field is absent (backward compatibility). - Skip if
target_reponames a different repo. - Current repo is derived from:
basenameofgit remote get-url origin, or failing that,basename "$PWD".
2. If unconsumed, repo-matched entries exist:
- If
--dry-runis set: report items but do NOT mutate next-work.jsonl (skip consumption). Log: "Dry run -- items not marked consumed." - Otherwise: claim the current cycle's item first (item
claim_status: "in_progress",claimed_by: <epic-id>,claimed_at: <now>) - Only after the cycle finishes PASS/WARN and clears the regression gate: finalize that item (
consumed: true,claim_status: "consumed",consumed_by: <epic-id>,consumed_at: <now>) - If the cycle fails, regresses, or is interrupted: release the item claim (
claim_status: "available", clearclaimed_by/claimed_at, keepconsumed: false) - Task failures may also stamp item
failed_at; that is retry-order metadata, not a stop condition - Report harvested items to user with suggested next command:
## Next Work Available
Post-mortem harvested N follow-up items from <source_epic>:
1. <title> (severity: <severity>, type: <type>)
...
To start the next RPI cycle:
/rpi "<highest-severity item title>"- Do NOT auto-invoke
/rpi-- the user decides when to start the next cycle
3. If no unconsumed entries: report "No follow-up work harvested. Flywheel stable."
Note: Phase 0 read is read-only. Mutating queue state follows a claim/finalize lifecycle so failed cycles can safely release work back to the queue without blacklisting sibling items in the same harvested batch.
Repo-Scoped Filtering (target_repo)
Both Phase 0 and --spawn-next filter next-work entries by target_repo:
target_repo value | Behavior |
|---|---|
| Matches current repo | Included |
"*" (wildcard) | Included — applies to any repo |
| Absent / null | Included — backward compatible with pre-v1.2 entries |
| Different repo name | Skipped — intended for a different rig |
The current repo name is resolved as: basename $(git remote get-url origin 2>/dev/null) with .git suffix stripped, falling back to basename "$PWD" when no remote is configured.
This prevents cross-repo pollution when .agents/rpi/next-work.jsonl is shared or synced across rigs.
Claim / Release State Machine
| State | Required fields | Meaning |
|---|---|---|
| available | item consumed=false, item claim_status="available" | Ready for /evolve or --spawn-next to pick |
| in_progress | item consumed=false, item claim_status="in_progress", item claimed_by, item claimed_at | Currently being worked |
| consumed | item consumed=true, item claim_status="consumed", item consumed_by, item consumed_at | Successfully completed and retired from the queue |
Entry-level lifecycle fields are aggregates for dashboards and legacy readers. Never mark an item consumed at pick-time. Claim first, consume on success, release on failure.
/rpi Runs The Installed Plugin's Skills, Not The Repo Working Tree
Before metering, testing, or measuring skill behavior via /rpi (or any Skill() call), verify which plugin version is actually active. The harness loads skills from ~/.claude/plugins/cache/agentops-marketplace/agentops/<version>/, which can lag the repo and — when multiple cached versions are present — can resolve to a stale one even though installed_plugins.json pins the latest.
A measurement that assumes "repo HEAD has the new path, therefore /rpi runs the new path" will silently measure the old path.
When This Fires
- Token-budget measurement comparing skill paths
- Behavior test of a recent skill edit before reinstall
- Any
Skill(skill="x")invocation expected to use post-edit code - Plugin cache contains 2+ versions of
agentops-marketplace installed_plugins.jsonwas updated but plugins were not pruned
The Diagnostic
# 1. What's in the cache?
ls ~/.claude/plugins/cache/agentops-marketplace/agentops/
# Expect ONE version. Multiple = drift risk.
# 2. What does installed_plugins.json pin?
jq '."agentops-marketplace".version' ~/.claude/installed_plugins.json
# 3. What does Skill resolution actually load?
# Read the "Base directory for this skill:" line in the skill-load output.
# Compare to repo:
wc -l skills/<n>/SKILL.md
# vs the loaded base dir's SKILL.md.If the loaded base dir's SKILL.md line count doesn't match the repo, the harness is reading a stale cache version.
Evidence (anchored)
"During the soc-etwf.6 clean-room RPI token measurement, the
agentops:rpi Skill loaded its machinery from~/.claude/plugins/cache/agentops-marketplace/agentops/2.41.0/ — thepre-#275 baseline (crank 689 lines, swarm 783, discovery 241) —
even though the repo HEAD (f77e8b22) carried the post-#275 billboardskills (crank 210, swarm 292, discovery 121). The plugin cache held
four versions (2.38.0,2.39.0,2.41.0,2.41.1).
installed_plugins.jsonpinned2.41.1, yet the Skill resolver
loaded2.41.0. Pruning the cache to2.41.1-only forced the correct
resolution."
— .agents/learnings/2026-05-15-rpi-loads-installed-plugin-not-repo-head.md (soc-etwf.6)
The mismatch: cache pinned 2.41.1, but the resolver picked 2.41.0. A measurement run with this drift will label "new path" results that are actually the baseline. Pruning the cache was the only reliable fix.
How To Apply
Before any skill-behavior measurement
1. Verify the active plugin version. Read the "Base directory for this skill:" line in the skill-load output (it's the first line of the skill content delivered to the agent). 2. Compare against the repo. wc -l <base-dir>/SKILL.md vs wc -l skills/<n>/SKILL.md. Mismatch → cache drift. 3. Prune the plugin cache. Keep only the version pinned in installed_plugins.json:
PIN=$(jq -r '."agentops-marketplace".version' ~/.claude/installed_plugins.json)
find ~/.claude/plugins/cache/agentops-marketplace/agentops/ -mindepth 1 -maxdepth 1 -type d \
| grep -v "/$PIN$" \
| xargs -r rm -rf4. Re-verify. Reload the skill; the base dir should now point at the pinned version.
To measure the repo working tree specifically
Two options:
1. Reinstall from the repo first. Make the cache point at the working tree's state, then run via Skill(). 2. Read the repo files directly. Follow the repo SKILL.md files inline rather than via the installed Skill tool. Loses the harness-mediated execution but isolates the test from cache state.
Failure Mode
A measurement claims "new path performs X" but actually measured the old path. The fix isn't to re-run the measurement; it's to verify the cache state, prune, then re-measure. Otherwise the published number is wrong with a green-looking process.
See Also
~/.claude/installed_plugins.json— the version pin source of truth~/.claude/plugins/cache/agentops-marketplace/agentops/<version>/—
where skills are loaded from at runtime
references/autonomous-execution.md— broader autonomous-loop rules
that interact with skill versioning
Phase Skill Isolation Contract
How RPI keeps phase skills (/discovery, /crank, /validate) from compressing each other's work into one agent context while preserving strict delegation and operator visibility.
Declaration vs enforcement
Declaration. `PRODUCT.md` operational principle #5 (two-tier execution) declares that phase skills own their own phase artifacts, gates, and retry policies. /rpi owns the lifecycle objective and phase order, not the internals of discovery, implementation, or validation.
Enforcement. This document plus `scripts/check-skill-isolation.sh` enforce the authored contract by detecting compression patterns in phase-skill SKILL.md bodies. Runtime isolation is a separate transport concern: when a runtime supports phase-isolated transport, the orchestrator gives a phase runner only the lifecycle objective, the bounded execution packet path, and the phase skill name. The runner executes that declared phase contract and returns only the phase artifact, verdict, and next action.
Important distinction. A subagent, daemon job, or spawned process may be a transport for a declared skill contract. It must not become a replacement for the skill. "Run /discovery in an isolated phase context" preserves strict delegation. "Skip /discovery and have an agent research/plan directly" is compression.
The companion `shared/references/strict-delegation-contract.md` gives the human-readable rationale and the canonical anti-pattern catalogue. Read this file for the mechanical contract; read that one for the philosophy.
Four levers
These are the four mechanical levers available to keep phase contexts bounded. They are listed in increasing strength, with the recommended posture last.
| Lever | Description | Mechanical strength |
|---|---|---|
| A | Text contract in SKILL.md and this reference | Weak - relies on agent compliance |
| B | Static lint via scripts/check-skill-isolation.sh | Medium - catches authored compression |
| C | Artifact-only handoff via .agents/rpi/execution-packet.json and phase summaries | Strong - limits what crosses phases |
| D | Phase-isolated skill transport | Strongest - phase context can die after the artifact returns |
Recommended posture: D with A-C always on. Layered enforcement keeps the contract durable when any single lever weakens. Text drifts, lint only sees source files, artifact handoffs can be overstuffed, and transport can be implemented incorrectly. Together they preserve the narrow waist: phase skill contract in, bounded artifact out.
Compression patterns (what NOT to do)
The lint script (scripts/check-skill-isolation.sh) flags the following patterns inside phase-skill SKILL.md bodies (skills/{rpi,discovery,crank,validation}/SKILL.md):
1. Cross-phase first-person verbs. Phrases like I will research, I will plan, I will crank, I will validate (case-insensitive). A phase skill should not describe itself as doing another phase's work. 2. Inline research vocabulary. Phrases like let me grep, let me read, let me search, I'll grep, I'll read, I'll search (case-insensitive). These signal that the agent intends to inline research-phase work into the current context instead of delegating. 3. Phase-skill calling another phase skill. A Skill(skill="research"), Skill(skill="plan"), Skill(skill="crank"), or Skill(skill="validate") callsite inside a phase-skill SKILL.md, except for the legitimate orchestration patterns:
/rpilegitimately orchestratesdiscovery,crank,validation(this is its core contract). It should NOT callresearchorplandirectly — those are discovery's sub-skills./discoverylegitimately orchestratesresearchandplan. It should NOT callcrankorvalidation— those are downstream phases./crankshould NOT callresearch,plan,crank, orvalidation— phase 2 is sealed./validateshould NOT callresearch,plan,crank, orvalidation— phase 3 is sealed.
False-positive guard
Citations and reference reads are not compression. The lint explicitly excludes:
- Markdown reference links:
See [research](../research/SKILL.md)(lines beginning withSee [). - Reference document reads:
Read references/foo.md(lines beginning withReadfollowed by a path). - Lines inside fenced code blocks (between triple-backtick fences) — code fences may legitimately quote a
Skill(...)call as an example without invoking it.
When the lint script needs to evolve, prefer narrowing the trigger over widening the guard — silencing a real compression pattern with an over-broad allowlist defeats the purpose.
Mechanical enforcement
Three surfaces, layered:
1. Lint. `scripts/check-skill-isolation.sh` walks skills/{rpi,discovery,crank,validation}/SKILL.md (or any path passed positionally) and exits non-zero on the first compression pattern. Run with -q / --quiet to suppress diagnostic output and rely on exit code only. The script ships a --self-test mode that injects a known violation into a tmpdir and asserts the lint catches it. 2. Artifact handoff. `phase-data-contracts.md` defines the bounded files that may cross phase boundaries. Discovery hands implementation an execution packet, implementation hands validation a phase summary and changed surfaces, and validation hands RPI a verdict. Raw reasoning does not cross phases. 3. Phase-isolated skill transport. When the runtime can isolate phase execution, RPI should run each phase contract in a fresh phase context and keep the main orchestrator visible. The transport may be a daemon job, a process runner, or a subagent wrapper, but its contract is the same: load the declared phase skill, execute it against the bounded handoff, write the expected artifact, and return only artifact path, verdict, and next action.
Cross-references:
- `PRODUCT.md` — declaration (operational principle #5)
- `shared/references/strict-delegation-contract.md` — companion contract with rationale and anti-pattern examples
- `scripts/check-skill-isolation.sh` — current mechanical enforcement
- `phase-data-contracts.md` — artifact-only phase handoff contract
See also
- `docs/learnings/orchestrator-compression-anti-pattern.md` — the 2026-04-19 live compression that motivated the layered enforcement approach
- `skills/rpi/references/phase-data-contracts.md` — how phases pass data via filesystem artifacts (the contract isolation depends on)
Orchestrator Compression Anti-Pattern
Mirror of docs/learnings/orchestrator-compression-anti-pattern.md (thecanonical promoted version, authored 2026-05-03). Copied here per
CI's no-symlinks rule so /rpi can reference it via the skill-link rule.Summary
Top-level orchestrator skills (/rpi, /discovery, /validate) are vulnerable to compression: the agent inlines sub-skill work instead of delegating via separate Skill() calls. This happened live in the 2026-04-19 MkDocs rebuild session: the agent explicitly chose to compress RPI into three direct phases, then never called Skill(skill="discovery"), Skill(skill="crank"), or Skill(skill="validate"). Phase 3 validation was skipped entirely until the user asked whether post-mortem validation had happened.
The compression passed a strict MkDocs build and an inline two-judge vibe review, so it looked mechanically successful. The knowledge flywheel did not turn: no forged learnings, no post-mortem artifact, no retro, and no structured council verdict.
Detection
Look for these phrases in live sessions or transcripts:
- "I'll compress this into one pass"
- "I'll do discovery inline"
- "I already know what to do"
- "Nested
Skill()calls waste context" - "Tests pass, so validation is done"
- A claimed
/rpicompletion with no distinct
Skill(skill="discovery"|"crank"|"validation") invocations
Positive detection: an /rpi session should show distinct Skill() tool calls at phase boundaries, each producing its own completion marker. Anything less is compressed.
Corrective Action
1. Delegate to Skill(skill="discovery", args=...), wait for completion, then delegate to Skill(skill="crank", ...), then delegate to Skill(skill="validate", ...). 2. Do not substitute Agent() for Skill(). Agent() spawns parallel work; Skill() invokes a declared workflow contract. 3. Honor phase gates. Phase 2 to Phase 3 is mandatory. Phase 3 failure returns to implementation, then retries validation. 4. Use supported escapes for speed: --quick, --fast-path, --no-retro, or --no-forge. These scale gate depth or scope; they do not skip phases.
Rationalizations To Reject
| Rationalization | Why It Is Wrong |
|---|---|
| "I know what discovery would say." | Delegation produces a written artifact future sessions can read. |
"Nested Skill() wastes context." | Context is cheaper than losing the artifact chain. |
| "The sub-skill is just instructions I can follow inline." | The sub-skill owns an artifact, gate, and retry policy. |
| "This is a small task, full RPI is overkill." | Use --fast-path; it still delegates. |
| "The user wants speed." | Time-box gates with --quick; do not skip phases. |
Why This Lands In /rpi
/rpi is the most-compressed orchestrator surface in practice. The 2026-04-19 session was an /rpi invocation that compressed all three phases. The other orchestrators (/discovery, /validate) face the same risk but are usually invoked AS sub-skills of /rpi, so the compression happens at the /rpi layer.
Read this before invoking /rpi in a session that is also tempted to "do things inline." If you catch yourself rationalizing compression, the rationalization is the smell.
Cross-References
skills/rpi/SKILL.md— the phased contract this anti-pattern violatesskills/discovery/SKILL.mdskills/validate/SKILL.mdskills/shared/references/strict-delegation-contract.md(if present)skills/evolve/references/long-loop-discipline.md— the same
disk-truth principle applied to long-running loops; compression is the orchestrator-layer version of "trusting conversation context"
Phase Budgets Reference
Time budgets for each RPI phase, scaled by complexity level. Prevents sessions from stalling in research or planning without producing actionable artifacts.
Budget Tables
Fast Complexity
| Phase | Budget | Rationale |
|---|---|---|
| Research | 3 min | Quick keyword search + 2-3 file reads |
| Plan | 2 min | Single epic, 1-3 issues, no deep decomposition |
| Pre-mortem | 1 min | Inline check, no council spawn |
| Implementation | unlimited | Crank wave limits apply (MAX_EPIC_WAVES=50) |
| Validation | skipped | Fast complexity skips Phase 3 |
Standard Complexity
| Phase | Budget | Rationale |
|---|---|---|
| Research | 5 min | Explore agent + knowledge lookup + file analysis |
| Plan | 5 min | Epic decomposition, 3-6 issues with dependencies |
| Pre-mortem | 3 min | Quick council (2 judges) |
| Implementation | unlimited | Crank wave limits apply |
| Validation | 5 min | Quick vibe + post-mortem |
Full Complexity
| Phase | Budget | Rationale |
|---|---|---|
| Research | 10 min | Deep exploration, multiple Explore agents, cross-file analysis |
| Plan | 10 min | Complex decomposition, 7+ issues, multi-wave dependency graph |
| Pre-mortem | 5 min | Full council (3+ judges), deep risk analysis |
| Implementation | unlimited | Crank wave limits apply |
| Validation | 10 min | Full vibe + comprehensive post-mortem |
Why Implementation Is Always Unlimited
Implementation (crank) has its own backpressure mechanisms:
- MAX_EPIC_WAVES = 50 (hard limit)
- Per-wave acceptance checks (Step 5.5)
- Per-task validation contracts
- Retry limits on blocked/partial status
Adding a time budget on top of these would create competing constraints that are hard to reason about. The wave limit is a better control than wall-clock time for implementation work.
Worked Examples
Example 1: Research Phase Expires
RPI mode: rpi-phased (complexity: standard)
Phase: research (budget: 300s)
[0:00] /research "add user authentication"
[1:30] Explore agent returns relevant files
[3:00] Knowledge lookup finds 2 prior learnings
[4:45] Reading auth middleware patterns...
[5:00] BUDGET EXPIRED — research phase time-boxed at 300s
Writing [TIME-BOXED] marker to .agents/rpi/phase-1-summary-*.md
Auto-transitioning to plan phase with partial research artifacts.
Note: Research produced file list + 2 learnings. Plan phase proceeds
with available context. This is NOT a retry — attempt counter stays at 0.Example 2: Budget Expiry vs Retry Gate
Phase: pre-mortem (budget: 180s, attempt: 1/3)
[0:00] /pre-mortem spawns council
[2:30] Council returns verdict: FAIL (3 critical risks)
[2:30] Verdict is FAIL → triggers retry gate (attempt 1/3)
[2:30] Re-running /plan with findings context...
[4:00] /pre-mortem attempt 2 spawns council
[5:00] BUDGET EXPIRED at 300s (cumulative across retries)
Writing [TIME-BOXED] marker. Auto-transitioning to implementation.
Pre-mortem verdict was FAIL but budget expired — proceed with WARN.
Attempt counter: 2/3 (budget expiry does NOT count as attempt 3).Example 3: Custom Budget Override
/rpi --budget=research:180,plan:120 "quick API endpoint"
# Result: research gets 3 min, plan gets 2 min
# Other phases use complexity-derived defaults
# Implementation remains unlimitedInteraction with Other Controls
| Control | Scope | Relationship to Budgets |
|---|---|---|
| Retry gates (3 attempts) | Per-phase | Orthogonal — budget expiry is not a retry |
--fast-path | All phases | Sets fast budgets regardless of classification |
--deep | All phases | Sets full budgets regardless of classification |
--no-budget | All phases | Disables budgets entirely |
--budget=<spec> | Named phases | Overrides specific phase budgets |
| Crank wave limit | Implementation | Separate backpressure mechanism |
| Council timeout | Within phase | Council has its own per-judge timeout |
Phase Data Contracts
How each consolidated phase passes data to the next. Artifacts are filesystem-based; no in-memory coupling between phases.
| Transition | Output | Extraction | Input to Next |
|---|---|---|---|
| → Discovery | Goal string + repo execution profile contract | Goal from the /rpi invocation; repo policy from docs/contracts/repo-execution-profile.md, repo-execution-profile.schema.json, and repo-execution-profile.json when present | repo_profile state is loaded before research/planning begins, including validation lane mutation metadata |
| Discovery → Implementation | Epic execution context or file-backed objective + discovery summary + execution_packet | phased-state.json + .agents/rpi/phase-1-summary.md + .agents/rpi/execution-packet.json (latest alias) or .agents/rpi/runs/<run-id>/execution-packet.json (run archive) | /crank <epic-id> when epic_id exists; otherwise /crank .agents/rpi/execution-packet.json with repo policy, contract surfaces, validation bundle, and validation_lanes already normalized |
| Implementation → Validation | Completed/partial crank status + implementation summary + execution_packet | br children <epic-id> or file-backed implementation state + .agents/rpi/phase-2-summary.md + .agents/rpi/execution-packet.json (latest alias) or .agents/rpi/runs/<run-id>/execution-packet.json (run archive) | /validate <epic-id> when epic_id exists; otherwise standalone /validate with the same repo execution profile fields, validation lanes, and done criteria |
| Validation → Next Cycle (optional) | Vibe/post-mortem verdicts + harvested follow-up work + queue lifecycle fields (claim_status, claimed_by, claimed_at, consumed, failed_at) | Latest council reports + .agents/rpi/next-work.jsonl | Stop, loop (--loop), suggest next /rpi (--spawn-next), or hand work back to /evolve |
Execution packet v1 should remain additive. Recommended fields:
schema_versionrun_idobjectiveepic_id(optional when the tracker cannot mint an epic)plan_pathcontract_surfacesvalidation_commandsvalidation_lanes(repo profile lane metadata:read_only,writes_artifacts,isolated_agents_home,release_only,mutation_escape_hatch)tracker_modetracker_healthdone_criteriapre_mortem_verdicttest_levelsranked_packet_path
Execution packet retention rule:
.agents/rpi/execution-packet.jsonis the mutable latest alias for the current objective.agents/rpi/runs/<run-id>/execution-packet.jsonis the durable per-run packet archive whenrun_idexists
Validation lane selection rule:
- implementation and fast closeout phases prefer lanes where
read_only=true,writes_artifacts=false,release_only=false,cost_classischeaporstandard, andauto_selectisdefaultor matches the changed surface - lanes with
cost_class=expensive,auto_select=explicit, orauto_select=release-onlyrequire an explicit operator request, a named plan acceptance criterion, or a release-readiness objective - every selected lane should honor
timeout_seconds; when a lane times out, record[TIME-BOXED]and continue with narrower evidence unless it was the only code-surface proof - lanes with
isolated_agents_home=truerequire isolated agent state before execution - lanes with
writes_artifacts=trueorrelease_only=trueare release/audit lanes; run them only when the packet objective or operator explicitly asks for release readiness - lanes with a non-null
mutation_escape_hatchrequire the escape hatch name in the validation report or handoff - unclassified commands containing
go test -race,-shuffle,-count=NwhereN > 1, eval runners, retrieval bench, headless runtime smoke, or release gates are explicit-only
Queue lifecycle rule:
- post-mortem writes new entries as available: entry aggregate
consumed=false,claim_status="available" - consumers treat item lifecycle as authoritative inside
items[]; omitted itemclaim_statusmeans available /evolveand/rpi loopclaim an item before starting a cycle: itemclaim_status="in_progress"- successful
/rpi+ regression gate finalizes that item claim: itemconsumed=true,claim_status="consumed",consumed_by,consumed_at - failed or regressed cycles release the claim back to available state and may stamp item
failed_atfor retry ordering - consumers may rewrite existing queue lines to claim, release, fail, or consume items after initial write
- the entry aggregate flips to
consumed=trueonly after every child item is consumed
Canonical schema contract: `docs/contracts/next-work.schema.md` (v1.4)
Rollback discipline
When changing phase-boundary logic, ship phase-3 (closeout) updates FIRST and remove phase-2 (handoff) logic SECOND. This keeps a working closeout path in place during the transition window — if phase-3 ships broken, you can revert before phase-2's removal lands.
Pre-mortem F3 of soc-bcrn (.agents/council/2026-05-07-pre-mortem-rpi-lifecycle-sharpening.md) called this out as the primary rollback risk for the consolidated daemon epic (E3).
Worked example: cli/cmd/ao/rpi_cleanup.go:preserveWorktreeCommits (phase-3 commit-preservation logic) was added BEFORE the phase-2 cleanup-removal as part of E3.S3. The order matters: orphaned worktree commits that previously fell into git fsck dangling now land on codex/preserve-<runID> branches before the worktree is force-removed. If preservation had been wired in the opposite order, a regression window would have lost commits during the transition.
Final Report Template
After all phases complete, summarize the entire lifecycle to the user.
Summary Report
## /rpi Complete
**Goal:** <goal>
**Epic:** <epic-id>
**Cycle:** <rpi_state.cycle> (parent: <rpi_state.parent_epic or "none">)
| Phase | Verdict/Status |
|-------|---------------|
| Research | Complete |
| Plan | Complete (<N> issues, <M> waves) |
| Pre-mortem | <PASS/WARN/FAIL> |
| Crank | <DONE/BLOCKED/PARTIAL> |
| Vibe | <PASS/WARN/FAIL> |
| Post-mortem | Complete |
**Artifacts:**
- Research: .agents/research/...
- Plan: .agents/plans/...
- Pre-mortem: .agents/council/...
- Vibe: .agents/council/...
- Post-mortem: .agents/council/...
- Learnings: .agents/learnings/...
- Next Work: .agents/rpi/next-work.jsonlFlywheel Section
ALWAYS include the flywheel section (regardless of --spawn-next flag):
## Flywheel: Next Cycle
Post-mortem harvested N follow-up items (M process-improvements, K tech-debt):
| # | Title | Type | Severity |
|---|-------|------|----------|
| 1 | ... | process-improvement | high |
Ready to run:
/rpi "<highest-severity item title>"The --spawn-next flag controls whether items are marked consumed in next-work.jsonl. The suggestion is ALWAYS shown. This ensures every /rpi cycle ends by pointing at the next one -- the flywheel never stops spinning unless there's nothing to improve.
# Executable spec for the /rpi skill — one turn's lifecycle executor (BC3 Loop).
# /rpi runs Research → Plan → Implement as strict, non-compressing phases that
# preserve the lifecycle objective end to end: phases never skip, validation is
# never bypassed, and context density survives every phase handoff. Hexagon:
# supporting; consumes: crank, discovery, domain, ratchet, validation;
# produces: .agents/rpi/*.md. (soc-qk4b.2)
Feature: RPI runs one turn's lifecycle without skipping moves
As the loop's lifecycle orchestrator
I want Research, Plan, and Implement run as strict ordered phases
So that the objective is preserved across the whole turn, with validation enforced
Background:
Given a goal, bead, or execution packet entering the rpi lifecycle
@covered-by:tests/e2e/rpi-phased-domain.sh
Scenario: Phases run in order and never compress
When /rpi executes
Then it runs Research, then Plan, then Implement in order
And no phase is skipped or merged into another (strict delegation is on by default)
@covered-by:tests/e2e/rpi-phased-domain.sh
Scenario: Validation cannot be skipped
When /rpi reaches the end of Implement
Then validation runs before the turn is considered done
And the lifecycle objective is preserved, not silently dropped at a phase boundary
@covered-by:tests/e2e/rpi-phased-domain.sh
Scenario: Context density survives phase handoffs
When one phase hands off to the next
Then intent, boundary, evidence, decision, constraint, and next-action carry forward
And anything else is omitted or linked, not pasted wholesale
@covered-by:tests/e2e/rpi-phased-domain.sh
Scenario: Autonomous run produces durable phase artifacts
Given /rpi --auto
Then the full lifecycle runs without per-phase human approval
And it writes phase artifacts under .agents/rpi/*.md
RPI Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| Discovery BLOCKED | Pre-mortem failed 3x | Review .agents/council/*pre-mortem*.md, refine goal, re-run /rpi --from=discovery |
| Crank retries hit max | Epic has blockers | br show <epic-id>, fix blockers, re-run /rpi --from=implementation |
| Validation retries hit max | Vibe found critical defects repeatedly | Apply findings, re-run /rpi --from=validation |
| Missing epic ID | Discovery didn't produce a parseable epic | br list --type epic --status open |
#!/usr/bin/env bash
set -euo pipefail
SKILL_DIR="$(cd "$(dirname "$0")/.." && pwd)"
PASS=0; FAIL=0
check() { if bash -c "$2"; then echo "PASS: $1"; PASS=$((PASS + 1)); else echo "FAIL: $1"; FAIL=$((FAIL + 1)); fi; }
check "SKILL.md exists" "[ -f '$SKILL_DIR/SKILL.md' ]"
check "SKILL.md has YAML frontmatter" "head -1 '$SKILL_DIR/SKILL.md' | grep -q '^---$'"
check "SKILL.md has name: rpi" "grep -q '^name: rpi' '$SKILL_DIR/SKILL.md'"
check "references/ directory exists" "[ -d '$SKILL_DIR/references' ]"
check "references/ has at least 3 files" "[ \$(ls '$SKILL_DIR/references/' | wc -l) -ge 3 ]"
check "SKILL.md mentions research phase" "grep -qi 'research' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions plan phase" "grep -qiE '/plan|plan' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions pre-mortem phase" "grep -qi 'pre-mortem' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions crank phase" "grep -qi '/crank' '$SKILL_DIR/SKILL.md'"
check "SKILL.md mentions vibe phase" "grep -qiE '/vibe|vibe' '$SKILL_DIR/SKILL.md' '$SKILL_DIR/references/phase-data-contracts.md'"
check "SKILL.md mentions post-mortem phase" "grep -qi 'post-mortem' '$SKILL_DIR/SKILL.md'"
check "RPI docs mention next-work handoff metadata" "grep -q 'queue claim/finalize metadata' '$SKILL_DIR/SKILL.md' '$SKILL_DIR/references/phase-data-contracts.md'"
check "phase-data-contracts documents claim lifecycle" "grep -q 'claim_status' '$SKILL_DIR/references/phase-data-contracts.md' && grep -q 'release the claim back to available state' '$SKILL_DIR/references/phase-data-contracts.md'"
check "gate4-loop-and-spawn documents claim before consume" "grep -q 'claim the current cycle' '$SKILL_DIR/references/gate4-loop-and-spawn.md' && grep -q 'Never mark an item consumed at pick-time' '$SKILL_DIR/references/gate4-loop-and-spawn.md'"
check "RPI docs mention repo execution profile" "grep -qi 'repo execution profile' '$SKILL_DIR/SKILL.md' '$SKILL_DIR/references/phase-data-contracts.md'"
check "RPI docs mention execution packet" "grep -qi 'execution packet' '$SKILL_DIR/SKILL.md' '$SKILL_DIR/references/phase-data-contracts.md'"
check "RPI docs mention contract_surfaces" "grep -q 'contract_surfaces' '$SKILL_DIR/SKILL.md' '$SKILL_DIR/references/phase-data-contracts.md'"
check "RPI docs mention done_criteria" "grep -q 'done_criteria' '$SKILL_DIR/SKILL.md' '$SKILL_DIR/references/phase-data-contracts.md'"
check "phase-data-contracts documents execution packet" "grep -q 'execution_packet' '$SKILL_DIR/references/phase-data-contracts.md' && grep -qi 'repo execution profile' '$SKILL_DIR/references/phase-data-contracts.md'"
echo ""; echo "Results: $PASS passed, $FAIL failed"
[ $FAIL -eq 0 ] && exit 0 || exit 1
Related skills
How it compares
Pick rpi for enforced end-to-end three-phase autonomy; use crank when the work is epic-scale wave execution with swarm parallelism.
FAQ
What does rpi do?
Run discovery, crank, validation. Triggers: "run rpi", "research-plan-implement one turn", "drive a turn through the operating loop".
When should I use rpi?
Run discovery, crank, validation. Triggers: "run rpi", "research-plan-implement one turn", "drive a turn through the operating loop".
What are common prerequisites?
--- name: rpi description: 'Run discovery, crank, validation.
Is Rpi safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.