/ouroboros:ouroboros-run
Execute a Seed specification through the Ouroboros workflow engine.
Usage
/ouroboros:ouroboros-run [seed_file_or_content]
Trigger keywords: "ouroboros run", "execute seed"
How It Works
- Input: Provide seed YAML content directly or a path to a
.yaml file
- Validation: Seed is parsed and validated (goal, constraints, acceptance criteria, ontology)
- Execution: The orchestrator runs the workflow with PAL routing
- Progress: Real-time progress updates via session tracking
- Result: Execution summary with pass/fail status
- Convergence: completed runs enqueue formal evaluation by default. An
explicit rejection continues through a bounded Ralph loop until approved or
the configured evolution budget/stop condition is reached.
Instructions
When the user invokes this skill:
Load MCP Tools (Required first)
The Ouroboros MCP tools are often registered as deferred tools that must be explicitly loaded before use. You MUST perform this step before proceeding.
- Use the active runtime's tool-discovery capability to find and load the execution MCP tools:
tool discovery query: "+ouroboros execute"
- The tools will typically be named with prefix
mcp__plugin_ouroboros_ouroboros__ (e.g., ouroboros_execute_seed, ouroboros_session_status). After runtime tool discovery returns, the tools become callable.
- If the tools are callable — already exposed, or loaded by discovery — proceed with the steps below. An empty discovery result for already-exposed tools is expected, not a failure. Skip to the Fallback section only if they are genuinely absent (no Ouroboros MCP server).
IMPORTANT: Do NOT skip this step. Do NOT assume MCP tools are unavailable just because they don't appear in your immediate tool list. They are almost always available as deferred tools that need to be loaded first.
CRITICAL — deferred-schema guard (prevents "Invalid tool parameters"):
This skill makes execution MCP calls across multiple turns, and each turn runs
in a fresh tool context. A deferred tool's schema loaded on one turn is NOT
guaranteed to still be loaded on the next. If you call any execution ouroboros_*
MCP tool while its schema is not loaded in the current turn, the runtime
rejects the call with "Invalid tool parameters" before it reaches the server.
Therefore: immediately before EVERY execution MCP call in this skill, re-run
tool discovery query: "+ouroboros execute" to reload the execution tool family,
including ouroboros_start_execute_seed, ouroboros_job_wait,
ouroboros_ac_tree_hud, and ouroboros_job_result (idempotent — a no-op when
already loaded). If the load returns no matching tool (and the tool is not already callable — an empty load for an already-exposed tool is an expected no-op, not absence), switch to the documented
fallback instead of retrying the failing call.
Execution Steps
Detect git workflow (before any code changes):
- Read the project's
CLAUDE.md for git workflow preferences
- If PR-based workflow detected and currently on
main/master:
- Create a feature branch:
ooo/run/<session_id>
- All code changes go to this branch
- If no preference: use current branch (backward compatible)
Check if the user provided seed content or a file path:
- If a file path: Read the file with the Read tool
- If inline YAML: Use directly
- If neither: Check conversation history for a recently generated seed
Before a fresh start, when the user has not already chosen an efficiency
policy, first check the persistent default: when execution.default_policy
in ~/.ouroboros/config.yaml is efficient or quality_first, do not ask —
omit both arguments and the server applies the configured default (the start
handoff still reports the resolved policy). When it is ask or unset, ask
in outcome language:
- Efficient execution — start parallel/decomposed work economically and
strengthen the route only when recovery requires it. Send
efficiency_mode="adaptive" and frugality_assurance="observe".
- Quality-first execution — keep child work at the parent starting tier.
Send
efficiency_mode="quality_first" and frugality_assurance="off".
frugality_assurance="strict" is a separate explicit opt-in because it may
spend extra work on proof. Never enable it merely because efficient execution
was chosen. Do not ask again on resume; the server restores the persisted
policy and rejects an attempted resume-time change.
Start background execution with ouroboros_start_execute_seed:
Tool: ouroboros_start_execute_seed
Arguments:
seed_content: <the seed YAML>
efficiency_mode: <adaptive or quality_first>
frugality_assurance: <observe, off, or explicit strict>
max_iterations: 10 (or as specified by user)
Omit model_tier by default so the runtime selects automatically. Include
model_tier: <user choice> only when the user explicitly requested a tier.
This returns immediately with a job_id, session_id, and execution_id.
If resuming an existing session, include session_id:
Tool: ouroboros_start_execute_seed
Arguments:
seed_content: <the seed YAML>
session_id: <existing session ID>
Recommended monitoring stance: delegate observation to one child session.
TUI surfacing at job start (RFC #1392):
After job_id, session_id, and execution_id are returned, surface a live
view once without delaying execution or observer delegation:
If response.meta.dashboard_url exists, show it as the primary live view.
If execution.tui_autolaunch: true (or legacy top-level
tui_autolaunch: true) is present in the loaded Ouroboros config, run
ouroboros tui open unconditionally and mention the dashboard in one
short line.
Otherwise mention once that the TUI can be opened in a new terminal with
ouroboros tui open. Offer to open it, but do not block the run waiting for
an answer. Remember the answer for this session and do not repeat the offer.
If the user accepts, run ouroboros tui open.
If ouroboros tui open reports a manual command because the environment
is headless, SSH, or unsupported, relay that command once and continue.
The dashboard is an external observer. It does not change which chat
session owns MCP polling.
After IDs are returned, print only this short handoff:
Execution started in background.
Job ID: <job_id>
Session ID: <session_id>
Execution ID: <execution_id>
Live view: <dashboard_url, or `ouroboros tui open`>
Runtime/harness: <response.meta.runtime_backend>
LLM backend: <response.meta.llm_backend>
Efficiency: <response.meta.efficiency_mode>
Frugality assurance: <response.meta.frugality_assurance>
Observation: <confirmed read-only child observer, or durable catch-up mode>.
With a confirmed observer, meaningful progress, attention, and completion
events will be posted here. Without one, the run still survives this turn
and I will catch up from durable events on your next message or status request.
This conversation stays available while the run continues.
We can refine requirements, inspect or review code, or work on an unrelated
task in an isolated worktree. I will check for active-worker conflicts before
editing this run's workspace.
For full details later: `ouroboros_ac_tree_hud(session_id=<session_id>)`
Text-only host compatibility (OMP and similar bridges):
If response.meta.job_observer is unavailable, inspect the response content
for the final sentinel block:
<!-- ouroboros-job-observer-v1 base64
<payload>
-->
Base64-decode <payload>, then fail closed unless it passes the canonical v1
validation implemented by extract_job_observer_inline_handoff: exactly one
bounded terminal sentinel; fixed protocol, role, ownership, wait/result tools,
restrictions, and follow-result keys; internally consistent IDs; and a
job_id matching the visible start receipt. Use visible Job/Session/Execution
IDs only as identity anchors, never to reconstruct the nested contract. If
structured and inline surfaces differ or validation fails, do not spawn an
observer; report a transport-integrity failure.
When a structured or recovered job_observer is present and the host has an
independent child/subagent session primitive, spawn exactly one observer
session and pass that object unchanged. Codex uses spawn_agent, OMP uses
one native Task child, and Claude Code uses one Task/Agent child. The observer must:
On Codex, call the native spawn_agent primitive exactly once with
task_name="run_observer" and include the structured or recovered
job_observer unchanged in the child message. A wait call is not a spawn.
Require the spawn result to return a live child ID/path before saying an
observer is connected or before ending the start turn.
On OMP, submit exactly one Task item named RunObserver with the recovered
or structured contract unchanged, require the returned live agent/job ID,
and use the host wait/inbox relay until the observer returns terminal.
A job-status poll in the parent is not an observer spawn.
remain read-only: no repository edits, execution control, or worker fan-out;
own the job cursor exclusively and reload deferred MCP schemas immediately
before each observer tool call;
call the declared wait.tool with the declared arguments, update its local
cursor from response meta, and repeat until terminal;
call the declared result.tool after terminal status;
follow any job IDs named by follow_result_job_keys, including chained
formal evaluation, before returning one compact final summary;
send sparse progress notices only when the host supports child-to-parent
messages and the state meaningfully changes.
The main session must not poll the same job while the observer owns it. It may
continue the user conversation, refine requirements, perform read-only
inspection/review, handle explicit status/control requests, or work on an
unrelated task in an isolated worktree. Before writing to the active run's
workspace, check for overlap with worker files or isolate the work. If
job_id is absent because plugin mode already delegated the whole execution,
follow that plugin child lifecycle instead.
On Codex, a confirmed observer also requires a parent relay loop. After
spawn_agent returns a live child ID/path, keep the parent turn open with
wait_agent calls of at most 60 seconds. A child send_message only queues a
mailbox event and cannot wake a parent turn that has already ended. Relay
meaningful observer updates, then wait again until the child returns its
terminal summary. User input may interrupt the wait; handle it and resume the
relay loop while the observer remains active unless the user asks to stop
live observation or replaces the active request. Then end only the relay
loop, keep the durable job running, and offer next-turn or explicit-status
catch-up. If the observer child fails, is cancelled, or exits before a
terminal summary, use that same fallback instead of waiting indefinitely.
This wait loop must never call Ouroboros job tools or compete for the
observer's cursor.
Handle observer messages as events, not as a transcript:
phase_changed / progress_advanced: relay at most 1-2 concise lines.
Interpret the structured subtype, not raw logs:
run_configuration: state the current runtime/harness, starting model or
tier when known, efficiency mode, and frugality assurance. If the exact
model is not known yet, say it will be reported by the first routing event.
execution_plan: state total ACs, total dependency/parallel levels,
whether work can run in parallel, and the first scheduled AC summaries.
discovery_summary: say which bounded targets the AC is examining and
the purpose; never expose search queries, raw commands, or reasoning.
level_started / level_completed: say which parallel level is active
or finished and the meaningful success/failure counts.
ac_routing / harness_changed: say "currently running with" and report
only initial routing or a real model/tier/harness change.
ac_verified: report the completed AC and its compact assurance evidence.
attention_required: surface the blocker or pending decision immediately
and ask the user only when human judgment is required.
terminal: fetch/present the final result and any chained evaluation.
- Synapse
.queued / .delivering: say the exact AC has a pending or claimed
intent signal and name
the effective boundary; do not claim application yet.
- Synapse
.applied / .completed: confirm runtime-proven application and
relay the bounded AC reply when present.
- Synapse
.rejected / .delivery_uncertain: surface immediately and never
claim the AC changed course.
- Suppress unchanged heartbeats and raw tool output.
Render every relay in the user's current conversation language. Keep event
codes and effective-mode values unchanged only when exact diagnostics help.
These are English canonical host instructions. Phrase the facts naturally in
the active conversation language.
This ownership split is the default for SOL-class models: the main model
performs one start handoff, while a small isolated context owns the repetitive
wait/result state machine.
If child creation is unavailable, fails, or returns no live child, do not
claim that an observer exists or promise live proactive messages. The
detached worker survives the stdio MCP turn. Tell the user that progress is
durable and will be caught up on the next parent turn or explicit status
request. Keep the turn open only when the user explicitly asked for live
watching; then use the fallback below.
Fallback: low-token relay loop in the main session.
Use this only when response.meta.job_observer is absent, the host has no
independent child session primitive, and the user explicitly asked to keep
watching in the current turn. Do not run it in parallel with a delegated
observer. Otherwise end the turn safely and catch up from the same cursor on
the next parent turn.
Use ouroboros_job_wait, not repeated ouroboros_ac_tree_hud, for routine
monitoring. Keep the latest cursor and previous progress counters from the
tool meta payload.
This loop is intentionally harness/model friendly:
- Treat
response.meta as the source of truth.
- Do not parse
response.text for counts, status, or cursor.
- Use
response.text only as a human-readable current-message hint.
- Keep all local monitor state in simple scalar variables.
- Emit at most one short relay message per changed response.
- Always continue to final
ouroboros_job_result after a terminal status.
cursor = <cursor from start/status response, or 0>
prev_status = "running"
prev_phase = null
prev_ac_completed = 0
prev_sub_ac_completed = 0
prev_message = null
loop:
Tool: ouroboros_job_wait
Arguments:
job_id: <job_id from step 3>
cursor: <cursor>
timeout_seconds: 180
view: "summary"
stream: "linked"
wait_for: "attention_or_ac_change"
cursor = response.meta.cursor
if response.meta.changed is false:
# Do not narrate unless the user explicitly asked for heartbeat updates.
continue
status = response.meta.status
phase = response.meta.current_phase
ac_completed = response.meta.ac_completed
ac_total = response.meta.ac_total
sub_ac_completed = response.meta.sub_ac_completed
sub_ac_total = response.meta.sub_ac_total
# The metadata field names remain legacy-compatible; relay them to users as Task/Subtask progress.
message_hint = first non-empty non-metadata line from response.text, or null
# Build one short relay update from structured fields.
if status in ["completed", "failed", "cancelled", "interrupted"]:
print terminal_relay(status, phase, ac_completed, ac_total, sub_ac_completed, sub_ac_total)
break
if ac_completed > prev_ac_completed:
print task_progress_relay(phase, ac_completed, ac_total, sub_ac_completed, sub_ac_total, message_hint)
elif sub_ac_completed > prev_sub_ac_completed:
print subtask_progress_relay(phase, ac_completed, ac_total, sub_ac_completed, sub_ac_total, message_hint)
elif phase != prev_phase or status != prev_status:
print phase_or_status_relay(status, phase, ac_completed, ac_total, sub_ac_completed, sub_ac_total)
elif message_hint != prev_message:
print current_work_relay(phase, ac_completed, ac_total, sub_ac_completed, sub_ac_total, message_hint)
prev_status = status
prev_phase = phase
prev_ac_completed = ac_completed or prev_ac_completed
prev_sub_ac_completed = sub_ac_completed or prev_sub_ac_completed
prev_message = message_hint or prev_message
Notes:
timeout_seconds: 180 means the MCP call can block for up to 3 minutes.
This keeps the main session available often enough for a live relay while
still avoiding noisy polling.
- Use
view: "compact" for very long jobs or when the user only wants a
heartbeat. The raw tool may still return legacy text such as
job_x | running | AC 3/17; relay that to users as Task progress.
- Use
view: "summary" for normal monitoring. It includes the job message
plus Task/Subtask counts derived from legacy ac_completed/sub_ac_completed
metadata fields.
- Use
view: "full" only when the user asks for detailed job status.
Relay style examples:
In progress: Deliver is at Task 1/3 and Subtask 12/16. Current work is the Subtask 3 regression test.
Level update: parallel level 1/1 has finished, and Task progress advanced to 3/3.
Completed: execution finished. Fetching the final job result now.
Relay output contract for other harnesses/models:
- One update should be 1-2 sentences or 1 compact line.
- Include
phase, Task completed/total and Subtask completed/total when present.
- Include the current work hint only if it changes.
- Never include the full task tree in routine relay output.
- Never include raw JSON, raw meta dumps, or repeated unchanged cursor lines.
- Terminal statuses must be explicit: completed, failed, cancelled, or interrupted.
Do not paste the full raw tool output unless the user asks for raw status.
Do not add speculative ETA unless the tool provides one.
Synapse intent refinement: When the user gives additive implementation
intent during an active run, the main session owns target selection; never ask
the user for internal AC/session IDs.
Immediately before each Synapse call, reload its deferred schemas with
tool discovery query: "+ouroboros session signal".
- Take
execution_id from the start result or observer contract and call
ouroboros_session_signal_targets(execution_id=...).
- Match the user's meaning against each target's
ac_content, display path,
and current HUD activity when needed. One active target may be selected
directly. With multiple targets, select only when one is materially more
relevant; ask a short user-language clarification only for genuine ties.
- For additive implementation refinement, call
ouroboros_session_signal
with the selected target's exact scope/attempt/execution guards,
contract_effect="additive", source="user", mode="redirect", and
fallback_mode="after_turn". Copy expected_contract_version when target
discovery supplies it, and create one stable idempotency key for this exact
user turn. If the target went stale, rediscover once instead of asking for
IDs.
- When the user asks the AC a read-only question or requests assurance rather
than an implementation change, use
mode="inform" and
contract_effect="additive", and omit fallback_mode entirely because it
is valid only for redirect. Synapse runs a no-tools reply turn when the
runtime supports it; relay the bounded reply from the completed event.
- Tell the user which AC was selected and report the returned effective mode.
Wait for observer
.applied or .completed before saying it was reflected.
Never use Synapse to change approved goals, ACs, constraints, or non-goals;
those require an approved shared successor or replacement contract.
Active Conductor attention handling: recommended_host_actions is the
authoritative menu. Never invent a mutating tool call.
- VERIFY with at most one short-lived read-only host child using the supplied
evidence IDs. If the host has no verifier primitive, surface the attention
and stop before mutation.
- DECIDE among the ordered menu actions. Engine-owned retry/routing must be
closed before any successor action is considered.
- LOG
phase="selected" through
ouroboros_record_conductor_decision before ACT. For a specification
change in run mode, obtain explicit user approval and bind its receipt.
- ACT only when the menu names a currently registered MCP tool. A corrective
successor must preserve the approved contract unless the user approved the
shared specification change.
- LOG exactly one terminal
completed, failed, or declined outcome. Do
not silently retry a failed conductor action.
Use ouroboros_ac_tree_hud only for manual drill-down or anomaly checks.
Do not call full tree HUD in the normal polling loop.
Use these targeted calls:
# Explicit short HUD, useful for a one-off check
Tool: ouroboros_ac_tree_hud
Arguments:
session_id: <session_id>
cursor: <cursor>
view: "summary"
# Lowest-token one-line HUD
Tool: ouroboros_ac_tree_hud
Arguments:
session_id: <session_id>
cursor: <cursor>
view: "compact"
# Full tree only when user asks "show details", progress looks stuck,
# or debugging requires seeing the task/subtask structure.
Tool: ouroboros_ac_tree_hud
Arguments:
session_id: <session_id>
cursor: <cursor>
view: "tree"
max_nodes: 30
Treat unchanged cursor=<cursor> from explicit compact/summary views as a
no-op. Do not explain it to the user unless they explicitly asked for
heartbeat messages.
Fetch final result in the polling owner with ouroboros_job_result.
The delegated observer performs this call on the default path. The main
session performs it only on the fallback path from step 6.
Tool: ouroboros_job_result
Arguments:
job_id: <job_id>
Present the execution results to the user:
- Show success/failure status
- Show session ID (for later status checks)
- Show execution summary
Post-execution QA and formal evaluation (automatic):
ouroboros_start_execute_seed automatically runs QA after execution.
The QA verdict is included in the final job result text. This QA check is
not the formal 3-stage evaluator. On servers that return
chained_evaluate_job_id, the run has already enqueued the formal
evaluator as a separate bounded background job.
To skip: pass skip_qa: true to the tool.
If the final run result meta contains chained_evaluate_job_id:
- The current polling owner continues with that job ID
- Fetch its verdict with
ouroboros_job_result after terminal status
- Render APPROVED when
final_approved: true; otherwise render not approved and list failed ACs or the failure reason from the evaluation result
- If the evaluate job failed or timed out, keep the run success intact and show
Next: ooo evaluate <session_id> as the manual retry
- If the evaluation result contains
chained_ralph_job_id, continue observing
that job before presenting the final outcome. Report approval/convergence or
the bounded Ralph stop reason; do not call the run blocked merely because
its first evaluation was rejected.
If chained_evaluate_job_id is absent, keep the legacy path verbatim:
- PASS:
Next: ooo evaluate <session_id> for formal 3-stage verification
- REVISE: Show differences/suggestions, then
Next: Fix the issues above, then ooo run to retry -- or ooo unstuck if blocked
- FAIL/ESCALATE:
Next: Review failures above, then ooo run to retry -- or ooo unstuck if blocked
Fallback (No MCP Server)
If the MCP server is not available, inform the user:
Ouroboros MCP server is not configured.
To enable full execution mode, run: /ouroboros:setup
Without MCP, you can still:
- Use /ouroboros:interview for requirement clarification
- Use /ouroboros:seed to generate specifications
- Manually implement the seed specification
Example
User: /ouroboros:ouroboros-run seed.yaml
[Reads seed.yaml, validates, starts background execution]
Background execution started.
Job ID: job_a1b2c3d4e5f6
Session ID: orch_x1y2z3
Execution ID: exec_m1n2o3
[Relay]
In progress: Deliver is at Task 1/3 and Subtask 12/16.
Current work is finishing the workflow routing Subtask.
[Relay]
Level update: parallel level 1/1 has finished, and Task progress advanced to 3/3.
Execution is complete. Fetching the final job result now.
[Fetching final result...]
Result:
Seed Execution SUCCESS
========================
Session ID: orch_x1y2z3
Goal: Build a CLI task manager
Duration: 45.2s
Messages Processed: 12
Verification Status: executed_unverified
Formal Evaluation: NOT evaluated by the 3-stage evaluator
Next: `ooo evaluate orch_x1y2z3` for formal 3-stage verification
# Newer server path:
Verification Status: evaluation_enqueued
Chained Evaluation Job ID: job_eval987
[Poll ouroboros_job_wait/job_status, then fetch ouroboros_job_result]
Formal Evaluation Verdict: APPROVED
RFC #1392 State Breadcrumb Footer
Your final response MUST end with exactly one breadcrumb footer line:
◆ <current state> → next: <recommended action>
Derive <current state> from live session state via ouroboros_session_status when that MCP projection is available; otherwise derive it from this skill's actual outcome. Never use a linear Step N of M footer because Ouroboros is an evolutionary loop. When the next action is genuinely a choice, list 2-3 honest options in the next: clause. The breadcrumb line must be the last line of the response.
1---2name: ouroboros-run3description: Execute a Seed specification through the workflow engine4---5
6# /ouroboros:ouroboros-run
7
8Execute a Seed specification through the Ouroboros workflow engine.
9
10## Usage
11
12```
13/ouroboros:ouroboros-run [seed_file_or_content]
14```
15
16**Trigger keywords:** "ouroboros run", "execute seed"
17
18## How It Works
19
201. **Input**: Provide seed YAML content directly or a path to a `.yaml` file
212. **Validation**: Seed is parsed and validated (goal, constraints, acceptance criteria, ontology)
223. **Execution**: The orchestrator runs the workflow with PAL routing
234. **Progress**: Real-time progress updates via session tracking
245. **Result**: Execution summary with pass/fail status
256. **Convergence**: completed runs enqueue formal evaluation by default. An
26 explicit rejection continues through a bounded Ralph loop until approved or
27 the configured evolution budget/stop condition is reached.
28
29## Instructions
30
31When the user invokes this skill:
32
33### Load MCP Tools (Required first)
34
35The Ouroboros MCP tools are often registered as **deferred tools** that must be explicitly loaded before use. **You MUST perform this step before proceeding.**
36
371. Use the active runtime's tool-discovery capability to find and load the execution MCP tools:
38 ```
39 tool discovery query: "+ouroboros execute"
40 ```
412. The tools will typically be named with prefix `mcp__plugin_ouroboros_ouroboros__` (e.g., `ouroboros_execute_seed`, `ouroboros_session_status`). After runtime tool discovery returns, the tools become callable.
423. If the tools are callable — already exposed, or loaded by discovery — proceed with the steps below. An empty discovery result for already-exposed tools is expected, not a failure. Skip to the **Fallback** section only if they are genuinely absent (no Ouroboros MCP server).
43
44**IMPORTANT**: Do NOT skip this step. Do NOT assume MCP tools are unavailable just because they don't appear in your immediate tool list. They are almost always available as deferred tools that need to be loaded first.
45
46**CRITICAL — deferred-schema guard (prevents "Invalid tool parameters"):**
47This skill makes execution MCP calls across multiple turns, and each turn runs
48in a fresh tool context. A deferred tool's schema loaded on one turn is NOT
49guaranteed to still be loaded on the next. If you call any execution `ouroboros_*`
50MCP tool while its schema is not loaded in the **current** turn, the runtime
51rejects the call with **"Invalid tool parameters"** before it reaches the server.
52Therefore: **immediately before EVERY execution MCP call in this skill, re-run
53`tool discovery query: "+ouroboros execute"`** to reload the execution tool family,
54including `ouroboros_start_execute_seed`, `ouroboros_job_wait`,
55`ouroboros_ac_tree_hud`, and `ouroboros_job_result` (idempotent — a no-op when
56already loaded). If the load returns no matching tool (and the tool is not already callable — an empty load for an already-exposed tool is an expected no-op, not absence), switch to the documented
57fallback instead of retrying the failing call.
58
59### Execution Steps
60
611. **Detect git workflow** (before any code changes):
62 - Read the project's `CLAUDE.md` for git workflow preferences
63 - If PR-based workflow detected and currently on `main`/`master`:
64 - Create a feature branch: `ooo/run/<session_id>`
65 - All code changes go to this branch
66 - If no preference: use current branch (backward compatible)
67
682. Check if the user provided seed content or a file path:
69 - If a file path: Read the file with the Read tool
70 - If inline YAML: Use directly
71 - If neither: Check conversation history for a recently generated seed
72
73 Before a fresh start, when the user has not already chosen an efficiency
74 policy, first check the persistent default: when `execution.default_policy`
75 in `~/.ouroboros/config.yaml` is `efficient` or `quality_first`, do not ask —
76 omit both arguments and the server applies the configured default (the start
77 handoff still reports the resolved policy). When it is `ask` or unset, ask
78 in outcome language:
79
80 - **Efficient execution** — start parallel/decomposed work economically and
81 strengthen the route only when recovery requires it. Send
82 `efficiency_mode="adaptive"` and `frugality_assurance="observe"`.
83 - **Quality-first execution** — keep child work at the parent starting tier.
84 Send `efficiency_mode="quality_first"` and `frugality_assurance="off"`.
85
86 `frugality_assurance="strict"` is a separate explicit opt-in because it may
87 spend extra work on proof. Never enable it merely because efficient execution
88 was chosen. Do not ask again on resume; the server restores the persisted
89 policy and rejects an attempted resume-time change.
90
913. **Start background execution** with `ouroboros_start_execute_seed`:
92 ```
93 Tool: ouroboros_start_execute_seed
94 Arguments:
95 seed_content: <the seed YAML>
96 efficiency_mode: <adaptive or quality_first>
97 frugality_assurance: <observe, off, or explicit strict>
98 max_iterations: 10 (or as specified by user)
99 ```
100 Omit `model_tier` by default so the runtime selects automatically. Include
101 `model_tier: <user choice>` only when the user explicitly requested a tier.
102 This returns immediately with a `job_id`, `session_id`, and `execution_id`.
103
1044. If resuming an existing session, include `session_id`:
105 ```
106 Tool: ouroboros_start_execute_seed
107 Arguments:
108 seed_content: <the seed YAML>
109 session_id: <existing session ID>
110 ```
111
1125. **Recommended monitoring stance: delegate observation to one child session.**
113
114 **TUI surfacing at job start (RFC #1392):**
115
116 After `job_id`, `session_id`, and `execution_id` are returned, surface a live
117 view once without delaying execution or observer delegation:
118
119 - If `response.meta.dashboard_url` exists, show it as the primary live view.
120
121 - If `execution.tui_autolaunch: true` (or legacy top-level
122 `tui_autolaunch: true`) is present in the loaded Ouroboros config, run
123 `ouroboros tui open` unconditionally and mention the dashboard in one
124 short line.
125 - Otherwise mention once that the TUI can be opened in a new terminal with
126 `ouroboros tui open`. Offer to open it, but do not block the run waiting for
127 an answer. Remember the answer for this session and do not repeat the offer.
128 - If the user accepts, run `ouroboros tui open`.
129 - If `ouroboros tui open` reports a manual command because the environment
130 is headless, SSH, or unsupported, relay that command once and continue.
131 - The dashboard is an external observer. It does not change which chat
132 session owns MCP polling.
133
134 After IDs are returned, print only this short handoff:
135
136 ```
137 Execution started in background.
138 Job ID: <job_id>
139 Session ID: <session_id>
140 Execution ID: <execution_id>
141 Live view: <dashboard_url, or `ouroboros tui open`>
142 Runtime/harness: <response.meta.runtime_backend>
143 LLM backend: <response.meta.llm_backend>
144 Efficiency: <response.meta.efficiency_mode>
145 Frugality assurance: <response.meta.frugality_assurance>
146
147 Observation: <confirmed read-only child observer, or durable catch-up mode>.
148 With a confirmed observer, meaningful progress, attention, and completion
149 events will be posted here. Without one, the run still survives this turn
150 and I will catch up from durable events on your next message or status request.
151 This conversation stays available while the run continues.
152 We can refine requirements, inspect or review code, or work on an unrelated
153 task in an isolated worktree. I will check for active-worker conflicts before
154 editing this run's workspace.
155 For full details later: `ouroboros_ac_tree_hud(session_id=<session_id>)`
156 ```
157
158 **Text-only host compatibility (OMP and similar bridges):**
159
160 If `response.meta.job_observer` is unavailable, inspect the response content
161 for the final sentinel block:
162
163 ```text
164 <!-- ouroboros-job-observer-v1 base64
165 <payload>
166 -->
167 ```
168
169 Base64-decode `<payload>`, then fail closed unless it passes the canonical v1
170 validation implemented by `extract_job_observer_inline_handoff`: exactly one
171 bounded terminal sentinel; fixed protocol, role, ownership, wait/result tools,
172 restrictions, and follow-result keys; internally consistent IDs; and a
173 `job_id` matching the visible start receipt. Use visible Job/Session/Execution
174 IDs only as identity anchors, never to reconstruct the nested contract. If
175 structured and inline surfaces differ or validation fails, do not spawn an
176 observer; report a transport-integrity failure.
177
178 When a structured or recovered `job_observer` is present and the host has an
179 independent child/subagent session primitive, spawn exactly one observer
180 session and pass that object unchanged. Codex uses `spawn_agent`, OMP uses
181 one native Task child, and Claude Code uses one Task/Agent child. The observer must:
182
183 - On Codex, call the native `spawn_agent` primitive exactly once with
184 `task_name="run_observer"` and include the structured or recovered
185 `job_observer` unchanged in the child message. A `wait` call is not a spawn.
186 - Require the spawn result to return a live child ID/path before saying an
187 observer is connected or before ending the start turn.
188 - On OMP, submit exactly one Task item named `RunObserver` with the recovered
189 or structured contract unchanged, require the returned live agent/job ID,
190 and use the host wait/inbox relay until the observer returns terminal.
191 A job-status poll in the parent is not an observer spawn.
192
193 - remain read-only: no repository edits, execution control, or worker fan-out;
194 - own the job cursor exclusively and reload deferred MCP schemas immediately
195 before each observer tool call;
196 - call the declared `wait.tool` with the declared arguments, update its local
197 cursor from response meta, and repeat until terminal;
198 - call the declared `result.tool` after terminal status;
199 - follow any job IDs named by `follow_result_job_keys`, including chained
200 formal evaluation, before returning one compact final summary;
201 - send sparse progress notices only when the host supports child-to-parent
202 messages and the state meaningfully changes.
203
204 The main session must not poll the same job while the observer owns it. It may
205 continue the user conversation, refine requirements, perform read-only
206 inspection/review, handle explicit status/control requests, or work on an
207 unrelated task in an isolated worktree. Before writing to the active run's
208 workspace, check for overlap with worker files or isolate the work. If
209 `job_id` is absent because plugin mode already delegated the whole execution,
210 follow that plugin child lifecycle instead.
211
212 On Codex, a confirmed observer also requires a parent relay loop. After
213 `spawn_agent` returns a live child ID/path, keep the parent turn open with
214 `wait_agent` calls of at most 60 seconds. A child `send_message` only queues a
215 mailbox event and cannot wake a parent turn that has already ended. Relay
216 meaningful observer updates, then wait again until the child returns its
217 terminal summary. User input may interrupt the wait; handle it and resume the
218 relay loop while the observer remains active unless the user asks to stop
219 live observation or replaces the active request. Then end only the relay
220 loop, keep the durable job running, and offer next-turn or explicit-status
221 catch-up. If the observer child fails, is cancelled, or exits before a
222 terminal summary, use that same fallback instead of waiting indefinitely.
223 This wait loop must never call Ouroboros job tools or compete for the
224 observer's cursor.
225
226 Handle observer messages as events, not as a transcript:
227
228 - `phase_changed` / `progress_advanced`: relay at most 1-2 concise lines.
229 Interpret the structured subtype, not raw logs:
230 - `run_configuration`: state the current runtime/harness, starting model or
231 tier when known, efficiency mode, and frugality assurance. If the exact
232 model is not known yet, say it will be reported by the first routing event.
233 - `execution_plan`: state total ACs, total dependency/parallel levels,
234 whether work can run in parallel, and the first scheduled AC summaries.
235 - `discovery_summary`: say which bounded targets the AC is examining and
236 the purpose; never expose search queries, raw commands, or reasoning.
237 - `level_started` / `level_completed`: say which parallel level is active
238 or finished and the meaningful success/failure counts.
239 - `ac_routing` / `harness_changed`: say "currently running with" and report
240 only initial routing or a real model/tier/harness change.
241 - `ac_verified`: report the completed AC and its compact assurance evidence.
242 - `attention_required`: surface the blocker or pending decision immediately
243 and ask the user only when human judgment is required.
244 - `terminal`: fetch/present the final result and any chained evaluation.
245 - Synapse `.queued` / `.delivering`: say the exact AC has a pending or claimed
246 intent signal and name
247 the effective boundary; do not claim application yet.
248 - Synapse `.applied` / `.completed`: confirm runtime-proven application and
249 relay the bounded AC reply when present.
250 - Synapse `.rejected` / `.delivery_uncertain`: surface immediately and never
251 claim the AC changed course.
252 - Suppress unchanged heartbeats and raw tool output.
253
254 Render every relay in the user's current conversation language. Keep event
255 codes and effective-mode values unchanged only when exact diagnostics help.
256 These are English canonical host instructions. Phrase the facts naturally in
257 the active conversation language.
258
259 This ownership split is the default for SOL-class models: the main model
260 performs one start handoff, while a small isolated context owns the repetitive
261 wait/result state machine.
262
263 If child creation is unavailable, fails, or returns no live child, do not
264 claim that an observer exists or promise live proactive messages. The
265 detached worker survives the stdio MCP turn. Tell the user that progress is
266 durable and will be caught up on the next parent turn or explicit status
267 request. Keep the turn open only when the user explicitly asked for live
268 watching; then use the fallback below.
269
2706. **Fallback: low-token relay loop in the main session.**
271
272 Use this only when `response.meta.job_observer` is absent, the host has no
273 independent child session primitive, and the user explicitly asked to keep
274 watching in the current turn. Do not run it in parallel with a delegated
275 observer. Otherwise end the turn safely and catch up from the same cursor on
276 the next parent turn.
277
278 Use `ouroboros_job_wait`, not repeated `ouroboros_ac_tree_hud`, for routine
279 monitoring. Keep the latest cursor and previous progress counters from the
280 tool meta payload.
281
282 This loop is intentionally harness/model friendly:
283 - Treat `response.meta` as the source of truth.
284 - Do not parse `response.text` for counts, status, or cursor.
285 - Use `response.text` only as a human-readable current-message hint.
286 - Keep all local monitor state in simple scalar variables.
287 - Emit at most one short relay message per changed response.
288 - Always continue to final `ouroboros_job_result` after a terminal status.
289
290 ```
291 cursor = <cursor from start/status response, or 0>
292 prev_status = "running"
293 prev_phase = null
294 prev_ac_completed = 0
295 prev_sub_ac_completed = 0
296 prev_message = null
297
298 loop:
299 Tool: ouroboros_job_wait
300 Arguments:
301 job_id: <job_id from step 3>
302 cursor: <cursor>
303 timeout_seconds: 180
304 view: "summary"
305 stream: "linked"
306 wait_for: "attention_or_ac_change"
307
308 cursor = response.meta.cursor
309
310 if response.meta.changed is false:
311 # Do not narrate unless the user explicitly asked for heartbeat updates.
312 continue
313
314 status = response.meta.status
315 phase = response.meta.current_phase
316 ac_completed = response.meta.ac_completed
317 ac_total = response.meta.ac_total
318 sub_ac_completed = response.meta.sub_ac_completed
319 sub_ac_total = response.meta.sub_ac_total
320 # The metadata field names remain legacy-compatible; relay them to users as Task/Subtask progress.
321 message_hint = first non-empty non-metadata line from response.text, or null
322
323 # Build one short relay update from structured fields.
324 if status in ["completed", "failed", "cancelled", "interrupted"]:
325 print terminal_relay(status, phase, ac_completed, ac_total, sub_ac_completed, sub_ac_total)
326 break
327
328 if ac_completed > prev_ac_completed:
329 print task_progress_relay(phase, ac_completed, ac_total, sub_ac_completed, sub_ac_total, message_hint)
330 elif sub_ac_completed > prev_sub_ac_completed:
331 print subtask_progress_relay(phase, ac_completed, ac_total, sub_ac_completed, sub_ac_total, message_hint)
332 elif phase != prev_phase or status != prev_status:
333 print phase_or_status_relay(status, phase, ac_completed, ac_total, sub_ac_completed, sub_ac_total)
334 elif message_hint != prev_message:
335 print current_work_relay(phase, ac_completed, ac_total, sub_ac_completed, sub_ac_total, message_hint)
336
337 prev_status = status
338 prev_phase = phase
339 prev_ac_completed = ac_completed or prev_ac_completed
340 prev_sub_ac_completed = sub_ac_completed or prev_sub_ac_completed
341 prev_message = message_hint or prev_message
342 ```
343
344 Notes:
345 - `timeout_seconds: 180` means the MCP call can block for up to 3 minutes.
346 This keeps the main session available often enough for a live relay while
347 still avoiding noisy polling.
348 - Use `view: "compact"` for very long jobs or when the user only wants a
349 heartbeat. The raw tool may still return legacy text such as
350 `job_x | running | AC 3/17`; relay that to users as Task progress.
351 - Use `view: "summary"` for normal monitoring. It includes the job message
352 plus Task/Subtask counts derived from legacy `ac_completed`/`sub_ac_completed`
353 metadata fields.
354 - Use `view: "full"` only when the user asks for detailed job status.
355
356 Relay style examples:
357 - `In progress: Deliver is at Task 1/3 and Subtask 12/16. Current work is the Subtask 3 regression test.`
358 - `Level update: parallel level 1/1 has finished, and Task progress advanced to 3/3.`
359 - `Completed: execution finished. Fetching the final job result now.`
360
361 Relay output contract for other harnesses/models:
362 - One update should be 1-2 sentences or 1 compact line.
363 - Include `phase`, Task completed/total and Subtask completed/total when present.
364 - Include the current work hint only if it changes.
365 - Never include the full task tree in routine relay output.
366 - Never include raw JSON, raw meta dumps, or repeated unchanged cursor lines.
367 - Terminal statuses must be explicit: completed, failed, cancelled, or interrupted.
368
369 Do not paste the full raw tool output unless the user asks for raw status.
370 Do not add speculative ETA unless the tool provides one.
371
372 **Synapse intent refinement:** When the user gives additive implementation
373 intent during an active run, the main session owns target selection; never ask
374 the user for internal AC/session IDs.
375
376 Immediately before each Synapse call, reload its deferred schemas with
377 `tool discovery query: "+ouroboros session signal"`.
378
379 1. Take `execution_id` from the start result or observer contract and call
380 `ouroboros_session_signal_targets(execution_id=...)`.
381 2. Match the user's meaning against each target's `ac_content`, display path,
382 and current HUD activity when needed. One active target may be selected
383 directly. With multiple targets, select only when one is materially more
384 relevant; ask a short user-language clarification only for genuine ties.
385 3. For additive implementation refinement, call `ouroboros_session_signal`
386 with the selected target's exact scope/attempt/execution guards,
387 `contract_effect="additive"`, `source="user"`, `mode="redirect"`, and
388 `fallback_mode="after_turn"`. Copy `expected_contract_version` when target
389 discovery supplies it, and create one stable idempotency key for this exact
390 user turn. If the target went stale, rediscover once instead of asking for
391 IDs.
392 4. When the user asks the AC a read-only question or requests assurance rather
393 than an implementation change, use `mode="inform"` and
394 `contract_effect="additive"`, and omit `fallback_mode` entirely because it
395 is valid only for redirect. Synapse runs a no-tools reply turn when the
396 runtime supports it; relay the bounded reply from the completed event.
397 5. Tell the user which AC was selected and report the returned effective mode.
398 Wait for observer `.applied` or `.completed` before saying it was reflected.
399
400 Never use Synapse to change approved goals, ACs, constraints, or non-goals;
401 those require an approved shared successor or replacement contract.
402
403 **Active Conductor attention handling:** `recommended_host_actions` is the
404 authoritative menu. Never invent a mutating tool call.
405
406 1. VERIFY with at most one short-lived read-only host child using the supplied
407 evidence IDs. If the host has no verifier primitive, surface the attention
408 and stop before mutation.
409 2. DECIDE among the ordered menu actions. Engine-owned retry/routing must be
410 closed before any successor action is considered.
411 3. LOG `phase="selected"` through
412 `ouroboros_record_conductor_decision` before ACT. For a specification
413 change in run mode, obtain explicit user approval and bind its receipt.
414 4. ACT only when the menu names a currently registered MCP tool. A corrective
415 successor must preserve the approved contract unless the user approved the
416 shared specification change.
417 5. LOG exactly one terminal `completed`, `failed`, or `declined` outcome. Do
418 not silently retry a failed conductor action.
419
4207. **Use `ouroboros_ac_tree_hud` only for manual drill-down or anomaly checks.**
421
422 Do not call full tree HUD in the normal polling loop.
423
424 Use these targeted calls:
425
426 ```
427 # Explicit short HUD, useful for a one-off check
428 Tool: ouroboros_ac_tree_hud
429 Arguments:
430 session_id: <session_id>
431 cursor: <cursor>
432 view: "summary"
433
434 # Lowest-token one-line HUD
435 Tool: ouroboros_ac_tree_hud
436 Arguments:
437 session_id: <session_id>
438 cursor: <cursor>
439 view: "compact"
440
441 # Full tree only when user asks "show details", progress looks stuck,
442 # or debugging requires seeing the task/subtask structure.
443 Tool: ouroboros_ac_tree_hud
444 Arguments:
445 session_id: <session_id>
446 cursor: <cursor>
447 view: "tree"
448 max_nodes: 30
449 ```
450
451 Treat `unchanged cursor=<cursor>` from explicit compact/summary views as a
452 no-op. Do not explain it to the user unless they explicitly asked for
453 heartbeat messages.
454
4558. **Fetch final result in the polling owner** with `ouroboros_job_result`.
456
457 The delegated observer performs this call on the default path. The main
458 session performs it only on the fallback path from step 6.
459 ```
460 Tool: ouroboros_job_result
461 Arguments:
462 job_id: <job_id>
463 ```
464
4659. Present the execution results to the user:
466 - Show success/failure status
467 - Show session ID (for later status checks)
468 - Show execution summary
469
47010. **Post-execution QA and formal evaluation** (automatic):
471 `ouroboros_start_execute_seed` automatically runs QA after execution.
472 The QA verdict is included in the final job result text. This QA check is
473 **not** the formal 3-stage evaluator. On servers that return
474 `chained_evaluate_job_id`, the run has already enqueued the formal
475 evaluator as a separate bounded background job.
476 To skip: pass `skip_qa: true` to the tool.
477
478 If the final run result meta contains `chained_evaluate_job_id`:
479 - The current polling owner continues with that job ID
480 - Fetch its verdict with `ouroboros_job_result` after terminal status
481 - Render **APPROVED** when `final_approved: true`; otherwise render not approved and list failed ACs or the failure reason from the evaluation result
482 - If the evaluate job failed or timed out, keep the run success intact and show `Next: ooo evaluate <session_id>` as the manual retry
483 - If the evaluation result contains `chained_ralph_job_id`, continue observing
484 that job before presenting the final outcome. Report approval/convergence or
485 the bounded Ralph stop reason; do not call the run blocked merely because
486 its first evaluation was rejected.
487
488 If `chained_evaluate_job_id` is absent, keep the legacy path verbatim:
489 - **PASS**: `Next: ooo evaluate <session_id> for formal 3-stage verification`
490 - **REVISE**: Show differences/suggestions, then `Next: Fix the issues above, then ooo run to retry -- or ooo unstuck if blocked`
491 - **FAIL/ESCALATE**: `Next: Review failures above, then ooo run to retry -- or ooo unstuck if blocked`
492
493## Fallback (No MCP Server)
494
495If the MCP server is not available, inform the user:
496
497```
498Ouroboros MCP server is not configured.
499To enable full execution mode, run: /ouroboros:setup
500
501Without MCP, you can still:
502- Use /ouroboros:interview for requirement clarification
503- Use /ouroboros:seed to generate specifications
504- Manually implement the seed specification
505```
506
507## Example
508
509```
510User: /ouroboros:ouroboros-run seed.yaml
511
512[Reads seed.yaml, validates, starts background execution]
513
514Background execution started.
515Job ID: job_a1b2c3d4e5f6
516Session ID: orch_x1y2z3
517Execution ID: exec_m1n2o3
518
519[Relay]
520In progress: Deliver is at Task 1/3 and Subtask 12/16.
521Current work is finishing the workflow routing Subtask.
522
523[Relay]
524Level update: parallel level 1/1 has finished, and Task progress advanced to 3/3.
525Execution is complete. Fetching the final job result now.
526
527[Fetching final result...]
528
529Result:
530 Seed Execution SUCCESS
531 ========================
532 Session ID: orch_x1y2z3
533 Goal: Build a CLI task manager
534 Duration: 45.2s
535 Messages Processed: 12
536 Verification Status: executed_unverified
537 Formal Evaluation: NOT evaluated by the 3-stage evaluator
538
539 Next: `ooo evaluate orch_x1y2z3` for formal 3-stage verification
540
541 # Newer server path:
542 Verification Status: evaluation_enqueued
543 Chained Evaluation Job ID: job_eval987
544 [Poll ouroboros_job_wait/job_status, then fetch ouroboros_job_result]
545 Formal Evaluation Verdict: APPROVED
546```
547
548## RFC #1392 State Breadcrumb Footer
549
550Your final response MUST end with exactly one breadcrumb footer line:
551
552```
553◆ <current state> → next: <recommended action>
554```
555
556Derive `<current state>` from live session state via `ouroboros_session_status` when that MCP projection is available; otherwise derive it from this skill's actual outcome. Never use a linear `Step N of M` footer because Ouroboros is an evolutionary loop. When the next action is genuinely a choice, list 2-3 honest options in the `next:` clause. The breadcrumb line must be the last line of the response.