Preserve selected development and portability history, correct current UI consumers, and scope owner-authorized red-test eligibility to the official v7.7.0 tag while preserving actual conclusions and strict signed artifact proof. Retain native/full-QA limits and deferred advisory findings.
185 KiB
6. Agent Core
Lifecycle, tools, route evidence, authored context/source recovery, review authority, delegated custody, planning, common story and budgets. loop.py runs tasks, direct turns and wakes; reviews/post-task work settle separately.
Task lifecycle
Workers run OuroborosAgent (§5); direct chat owns an agent and DirectActivityRegistry (§3). agent_task_pipeline.py freezes contract/context, runs the loop, stores results/artifacts (the store row is the lifecycle authority, read by get_task_result / query_data; task_results/<id>.json is import input and export output), runs root post-work (post_task_synthesis.py, post_task_checkpoint.py) and publishes. Admission, completion, satisfaction, verification, review and artifact finality stay separate. task_result_schema.py admits rows (§11); usage owns money/tokens. A crash is failure.kind="runtime"; lost capture is unknown. finalization_timing.py times delivery, sharing child projections per pass until a model wait; lookups use task/root/queue-seed lineage (task_store). Test spies count reads. supervisor/cognitive_operations.py keeps typed operations off the idle rail; deadlines, budgets and cancellation stay active.
The loop transcript is append-only: OpenAI-family caching requires the previous request as a byte-prefix (§6 Prompt caching). transcript_prefix.py records breaks without blocking sends and identifies deliberate compaction. model_execution records the last accepted ordinary solve response, keeping requested, routed and provider-reported models distinct; empty, forced, review and post-task responses cannot replace it. After a host model change following tool work, the successor gets one recovery round to resume authorship; a second tool-less response degrades as authoring_handover_incomplete.
loop_delivery.py retains the complete DeliveryCandidate before verification or review; later failures cannot erase useful work. outcomes.py combines execution, objective, review, artifact, child-absorption and custody facts, substituting none for another. Host receipts and exact artifact references prove effects; declarations do not. Failed tools alone do not degrade an answer; an unevaluated objective retains residual_tool_errors_without_review. The unconditional FINAL ANSWER: latch survives review, nudges and forced finalization though only task_contract.answer_protocol="final_answer_line" prompts the marker. A best-effort result may have lifecycle completed with an unaccepted objective. Stored reason codes stay unchanged; current owner wording is projected at read time (§3 Task cards, errors and reason lines).
Host disclosures stay beside the answer: terminal_host_notice carries plan/orphan limits; the owner's typed terminal_custody_notice row omits empty categories. CLI labels these as host status; Presence speech excludes them. A notice changes neither answer bytes/hash nor verdict; identical text never revives superseded approval. Child-result and plan-evidence hashes include notices: a changed limitation voids an old parent disposition. Host salvage is visibly labelled Preserved intermediate output (not a final answer):; the durable preview is bounded; get_task_result and stop receipts keep the whole copy.
A first reply without a selection episode is a plain final. After substantive host continuation, Main selects complete retained bytes with finish_task(action="finish"|"stop", answer=...|answer_sha256=...); compaction withdraws unavailable selectors. Finish checks children, skills/handover, owner sources, material, services, configured review and admission. Stop retains the selected unfinished work without buying criticism or another answer, cancelling descendants or claiming approval; evidence-only changes cannot undo it. Undispositioned direct children hold finish; reminders and custody disclosures never decide it. Presence completes a send only with host-confirmed delivery. Acceptance keeps reviewed and delivered identities distinct.
Provider death salvages text but ends failed/infra_failed with provider_unavailable (or resource_refusal_no_resend) and an immediate not-completed owner notice. One forced model call runs only while a call can land; wait expiry and loop_llm_call.provider_no_call_source forbid another paid window. terminal_provider_notice quotes the provider's own words beside the result, never recommends blind replay. The finalization sink stamps model_final, host_notice (host words) or host_salvage (model output kept after provider death); a forced reply still requesting tools is incomplete. Finalization controls are typed mailbox entries. Descendant activity is not the task's own progress; an unkillable process stays visibly running: even a zero, final cost cannot settle delegated_runs_unreconciled custody.
Task acceptance
Task acceptance advises work; commit review is separate. Auto needs root nomination (deferred_to_host_acceptance, authoritative=false); Required also admits observed effects or retained produced material. Requirements, inputs, checkpoints and queue status prove no production. acceptance_material.py retains selected final_answer_line bytes, verified outputs, baseline-attributed changes and OSWorld GUI-input receipts before eligibility; packet and subject reuse them. Empty/stale/failed sources grant nothing; GUI execution proves no goal success. Neither prose/tool counts nor automatic child panels qualify (skipped_child_advisory).
task_acceptance_review nominates work; Main authors criteria. Off forbids new root panels, manual/historical included, never paid/unknown collection, cap-only amendment, code or child critics. A child picks one configured reviewer_slot_id. Historical requests need new owner chat/quiz/mail: amend_cap changes only the original-root cap; review judges frozen terminal work. acceptance_history.py retains skipped roots/retries, gaps and separate historical_author_inputs; old premises direct nothing; host-authored terminals mint no debt (emitted_delivery_authorship). Spend, Stop/Panic, prohibitions and deadlines bind; Hurry/Wrapup stop unstarted automatic work, never paid collection. Partial delivery leaves the goal open; sufficient work needs no embellishment.
queue_transitions.py proves subtree quiescence and fences child admission before payment; unanswered fences buy no round. Delivery seals again. Pooled fences bind attempt/PID: unanswered begins release, ended owners retire at handoff; consumed Resume rebinds direct/pooled park fences. The canonical budget_drive_root packet retains verbatim owner directives, criteria, deliverables, terminal children, verification receipts, service teardown (shown to the author; whole logs as read_file text, not tails), artifact references and an omissions_manifest. repo_diff_capture.capture_repo_diff produces preview and exact source from one read: failed, cut or undecodable capture is a gap, never a clean tree. Exact bytes stay private in observability CAS; public sections are redacted before cutting, withholding unsafe partial diagnostics. Shedding preserves repo_diff_source_ref; immutable-core overflow is explicit. review_source_closure retains named sources and host-attested refs under source_handles/review_inputs/<request>/ before paid binding. Missing/corrupt sources refuse unpaid; oversized first sends use an exact-source work order; changed session bytes degrade. Packet, session and native rows keep their own delivery contracts (§6 Review delivery).
acceptance_preparation.py binds a local preparation incident to material and criteria, not exception wording. Unchanged material needs an exposed failure and explicit source-bound acceptance_retry (material_change|repair_evidence|owner_retry) for one more try. Unknown evidence revokes approval, keeping the answer as unverified, and invents no reviewer or finding. An unresolved preparation terminal is unfinished in Blocking, best-effort with a stated caveat in Advisory.
acceptance_paid_identity binds the semantic subject and substantive obligation dispositions. Narration, forensic hashes and ingress counters alone buy no panel; an identical paid identity replays free with its actual verdict. task_pacing.review_launch_allowed requires cycle capacity, money admission and more than OUROBOROS_ACCEPTANCE_REVIEW_EST_SEC above the finalization reserve before evidence building; that floor predicts no duration and gates no author improvement. The first physical send claims task_results.task_acceptance_review_accounting; an unrecoverable claim remains unknown, never resend authority (§6 Paid stamp and owner custody). A launched review cut by its deadline is DEGRADED, not a free skip.
review_operation.ReviewOperation owns the immutable request, paid roster, waits and controls past the author turn. Recovery verifies stored ownership/binding; collect_recorded_acceptance_run parses locally at $0 with no model. Worker death is unknown. announce_acceptance_settlement mails each reviewer's verdict at quorum and final settlement; only typed owner/control input grants an owner revision. Its sole publisher, settle_acceptance_operation, owes one System card_row="reviews" via the durable outbox and a host mark in its room only the mind releases (late_review_marks.py, also a late plan reply or a left change wave), reporting time and reviewed identity, authorizing no continuation; an unplaced notice or mark stays owed. Cold execution facts come from final_attempt_facts (§6 Session identity).
Adaptive quorum is two of N for N≥3, both for N=2, and one disclosed single_reviewer_no_diversity for N=1. Failed or malformed rows are infrastructure evidence, never negative judgments; pre-send refusal is not_dispatched. PASS/FAIL/DEGRADED belong to reviewers; only loop_acceptance._set_acceptance_decision writes accepted, revision_requested or finalized_unaccepted. A clean criterion needs exact full-packet evidence_refs; claim support resolves through acceptance_support_refs to passing host receipts. Unresolved refs keep the audit but lose their clean contribution, preventing self-certification by repeating the expected outcome. Minority findings remain feedback without quorum.
Stable obligations retain author and critic positions; valid rebuttals retire findings, invalid ones reopen them. Reading bounded, unhashed acceptance_dialogue_history buys nothing. Informed Advisory finish binds exposed feedback and current evidence, not a separate rationale; Stop requires one. Paid-run lookup, not latest feedback, decides clean reuse; replay refusal cannot shadow a new explicit act. Author and critic hashes stay separate; Blocking requires fresh approval. Cyber retains BIBLE P0/P3 authority without rewriting verdict, money or custody; dialogue_status never chooses the author's stop.
Default pending_review=wait keeps the same operation in every mode through mail, rewrites and partial settlement without empty author polls; settled feedback, PASS included, precedes the next author decision; finish prose never waives it. Nonblocking modes allow explicit pending_review=finish, apart from criticism, with no Cyber improvement-counter veto. Once that feedback reached Main, a text-only rewrite with matching premises/material is accepted as previous_revision_accepted (fork 1=B; a rewrite Main nominated gets its own panel), granting no candidate, commit, plan or skill PASS. Forced finalization keeps the tool envelope but runs no tool or extra round. A dangling revision becomes finalized_unaccepted with revision_unavailable_on_forced_rail, preserving terminal decisions; deadlines or unread mail certify no subject.
Headless finalization and workspace patch capture
Workspace completion diffs against preflight task_constraint.base_sha, including local commits; unborn repos use Git's empty tree. A moved HEAD refuses only self_worktree; shared trees use reverse-patch verification. workspace_patch_capture.py streams tracked binary changes and admitted untracked files under workspace_patch_rules.py, disclosing exclusions. Oversized/binary untracked outputs use manifest+ZIP. Project .gitignore, not host directory names, governs generated output; credentials are excluded per file (sensitive_blocked). Every finalization writes workspace_patch.json, including no-change/failure; only ready_with_changes writes workspace.patch (CLI: §1). Forked/empty drives use data/state/headless_tasks/<task_id>/data; results return to the canonical root, artifacts to data/task_results/artifacts/<task_id>/. Late copy-back preserves terminal results; adoption drops child state/code_intel.
headless selects drive names in bounded batches using task_store.drive_retention_facts: the writer's exact effective date avoids rereading young bodies; legacy NULLs classify lazily, directory mtime stays layout-local. Fresh strict body/age checks precede task_custody.settle_child_drive, which alone deletes: the supervisor must prove every occupant inactive, the row settled and every obligation canonically held. Missing/mismatched material stays until restoration converges. Projection and first-parseable date semantics: retention.py, PERSISTENCE.
Owner routing verbs
start_task, move_to_project and tell_task use the existing token-matched receipt rail; internal event and receipt names stay unchanged. Admission is not completion. start_task creates separate new work without predecessor selection. Its complete intent and token are durable before emission; a failed write emits nothing. Boot with prior custody proved gone marks only proven unadmitted intent not_started, with explicit retry; possibly admitted work stays held. No automatic replay occurs. Rejection keeps its typed reason; UNCONFIRMED means no matching receipt, never license for a duplicate; new-head manifests and the own-act observer expose saved admission separately.
The issuer records capability provenance. tell_task(task_id, note, quote) sends one atomic relay: selected host-held owner rows retain their exact words, attachments and authority; the note is context. Held handles and unanswered return addresses survive pause, compaction and Continue. Any room may address an independent root; Presence binding and publication ceilings remain. The source annotation names the recipient and room, then changes on saved read acknowledgement. send_user_message(reply_to_relay=...) returns there; empty selects the single open relay, omission keeps ordinary sending. forward_to_worker remains tree mail. The bounded [INDEPENDENT_ROOTS] roster discloses omissions.
update_focus is dated model context, never authority or inherited authorship. live_works.py projects independent roots' id/title/room/state, questions, holds, focus and start time for new heads outside the cached prefix. Sources use get_task_result(include_focus_source=True, focus_source_sha256=…); store errors stay unknown. No TTL or project-wide focus.
Routing failures use project_dialogue.ROUTING_REFUSAL_CAUSES and one durable refusal writer. Tool-issued acts return facts for the model to narrate; host-issued acts publish a System task_not_started or task_start_unconfirmed, and an undelivered owner steer is steer_not_delivered. Failed genesis provisioning never falls back to the system repo. An exact system-repo workspace_root becomes the disclosed workspace="none" sentinel; its subfolders and the data drive refuse. start_task reports its admitted destination; it neither adopts origin siblings nor transfers the caller's planning obligation.
Routing context offers registry folders and bounded recent/live root facts, never raw answers. list_projects and receipts read the canonical registry; shared origin is provenance, never new-work identity. Placement: §6 Project placement. The technical Continue door retains its own contract (§6 Continue).
Explicit starting effort of a root
settings_scales.choose_effort: model-named level wins, then owner pin, then requested effort within the helper bounds; Cyber accepts the request over a pin. Auto children default to primary clamped into those bounds; Auto reviewers, evolution and wakes start at their top. Main/root primary is independent (§7). _initial_effort_for prefers model-named, then stored reasoning_effort, then the role default. API/CLI/owner schedules and Continue carry validated owner pins. start_task/follow-up effort applies only in Cyber. switch_model moves a child, evolution or wake within its captured bounds; ordinary Main keeps its level. New children, delegates and review waves read the room's current values; existing actors keep theirs through cold Resume. owner_wait.continuation_state.cognition retains only composer choices, separately from actual rendered mode and route; legacy checkpoints keep their prior fallback.
Tool capability and execution
tool_capabilities.py owns tool classes/child ceilings; tool_policy.py selects initial capabilities, ToolRegistry dispatches, loop_tool_execution.py owns timeouts/concurrency/evidence/results. Policy, mode, contract disables, credentials, resources/bindings and profiles independently narrow execution. Discovery names omissions or CAPABILITY_UNAVAILABLE/policy_hidden_reason; _name_miss_result stays namespace-local. list_available_tools reads schemas() in every mode: residency is not callability. _fit_route_tool_ceiling follows provider_models.tool_schema_limit, prioritizing core/meta/loaded schemas; overflow remains callable via enable_tools.
ouroboros/tools/query_data.py reads JSON/JSONL/store/blobs with batches, selectors, filters and bounded tails, naming caller/child/canonical/native-pin planes. Default queues use their owner; child selection stays local. Cross-plane blob fallback needs absence, never denial/corruption; file admission covers loose/pack sources, never new grants. Native pins cannot reach live data; SQL/logs/advisory scope stays. save_as: exact bytes, equal reuse, collision refusal, link-free temp/replace. UTF-8 canonical JSON flags reconstruction. query_data_sql.py supervises read-only facts/money/packs SQL with authorizer, interrupt,128MiB heap and SQLite errors. evidence_packs.open_index rebuilds sidecar caches under SQL locking; absent: no_packs. Money defaults to checked VACUUM INTO; facts hold COMMIT ≤ half its wait, allocations may outlast interrupts. Parent owns deadline/cleanup; full answers precede cuts.
ToolResult separates policy refusal from execution failure: user_files_path_blocked, cwd_blocked and artifact_output_undeclared are non-failure refusals; failed export is artifact_output_error. _EXACT_IDENTIFIER_CODES maps only invariant meanings. Branch-specific outcomes publish at their producer: missing service logs are unavailable, absent-service status remains an observation; partial discovery keeps its useful results. Review pending is an observation, new-dispatch refusal is blocked, lost custody unavailable; SkillReviewOutcome.dispatch_refusal_code carries live admission refusal through _outcome_payload, never from historical verdict/prose. None settles prior effects. Admitted misses (LIST_FILES_NOT_FOUND, SEARCH_NOT_FOUND, image FILE_NOT_FOUND) follow confinement/runtime/protected checks. Delegate substrate refusal (SUBSTRATE_REFUSAL_CODE) does not degrade execution; malformed calls (AGENT_FAULT_CODE) do; reading a failed/cancelled leaf is successful observation. _publish_tool_result binds metadata to identical returned text; wrappers preserve it with append_published_text. Wake ACK uses its supervision_wake_id, never the tool name.
Tool API v2: canonical get_tools() names and path-based file ABI. Joined foreground editors share edit_ops._edit_mutation_block; _ROOT_ARG_REPO_WRITE_TOOLS owns repo-write fencing. body_relative_path recognizes admitted body copies, not foreign roots. verify_and_record shares process pre-execution guards, then writes task_results/artifacts/<task_id>/verification_receipts.jsonl; only afterward does meta.verification carry the criterion verdict beside unchanged call status. Only evaluated comparisons have a Boolean matched: new receipts use null otherwise, published facts omit it. Old records stay unchanged. The loop, compact model view, acceptance and tool_call_log.replay_evidence preserve both axes. Replay carries each observation's time; replayedEvidenceTs keeps legacy carrier fallback, never inventing a missing start. Handled FAIL adds no tool error; failed receipt custody stays one. Card semantics: DESIGN “Conversation activity block”.
Resource roots and physical file identity
Filesystem results name root:path; run_command/run_script echo resolved cwd. A Project room selects one folder for files, process cwd, VCS and delegation; governance stays at system_repo. A missing folder keeps its address and availability note, never falling back to Ouroboros source; a folderless task uses task_drive scratch without workspace or write authority. Resolution keeps physical identity: absolute paths inside a selected base normalize to it, rootless ones bind to their permitted base, outside ones refuse before safe_relpath could rename them. Every redirect, payload paths included, shares the guards' and handlers' resolver (ToolContext.repo_path/drive_path). Docker aliases (workspace_executor.map_backend_path) bind files and process cwd only inside active_workspace, after a real host path; only BackendPathNoMatch falls back. Identity mounts retain ordinary host-root checks, not new rights.
Roots: user_files for owner-visible files under home (repo/runtime control plane refused); task_drive for task scratch; artifact_store for lazy data/task_results/artifacts/<task_id>/ audit copies of user_files or process outputs (§1); subagent_projects and deliverables for read/list/search only. The matrix (tool_access_types._POLICY) is closed under read⇒list,search and write⇒edit. tool_access_reads.inherited_read_roots gives ordinary native foci canonical runtime_data READ aliases in every mode, including settings: absolute and omitted-root paths reach the original; relative paths keep execution-drive bytes. Only children inherit recorded ancestor workspaces. Presence retains its selected roots; task restrictions, protected artifacts and project-store guards still bind. Read aliases grant no writes, commands or publication. Continuations and schedules read their named predecessor/origin's task_drive/artifact_store (one hop, read-only; tool_access_reads.scheduled_origin). Process admission: §6 Safety and runtime mode. tools/shell_audit.py observes only: failure adds bounded output_audit_unavailable and retains exit, signal, timeout and runtime facts.
Credential mutation and diagnostic redaction
Credential, Bible and identity mutation fences use physical owner locations (credential_shapes.owner_credential_locations), source operands and actual VCS metadata; ordinary project names (tokens.json, credentials.json, .well-known) identify no host store, so attachment ingest, export/Deliverables, user_files mutations and Git never reject a word or suffix beyond the exact-name/dotenv rules, and Git capture checks content through workspace_patch_capture.pem_private_key_reason. Unlisted stores keep ordinary root access. Read, search, query and media results preserve source content for every mode and actor, without token/PEM replacement, and keep source_masked=false so exact-source review receipts stay verifiable; command, diagnostic/log, Settings-placeholder, capture and skill-publication redaction are independent of that read path. Runtime-data reads are gated by core_file_tools._runtime_data_read_check over core_secret_paths.runtime_data_roots.
Web access mechanisms (three distinct paths — do not conflate)
search_routes.py resolves built-in Source/Model (Auto or a strict source), separate from skills, MCP and browser. With Anthropic pinned, native per-call ids apply; only saved bare ids retain legacy defaults. Settings encodes edited Anthropic ids as anthropic::model, preserving untouched values. The three paths differ in reasoning, fetch authority and evidence:
| path | reasoning model | fetch authority | evidence |
|---|---|---|---|
| Main-loop native search (provider server tool, attached only if the main-loop setting allows) | the solve model decides whether to search; no second model enters the scaffold | provider-side | citations and request counts fold into llm_usage and the task's host-attested retrieval fact (acceptance context, never a criterion alone); the host never sees the provider-side query |
web_search function tool |
a provider-backed call may add a second model and its own cost | the built-in Source/Model (search_routes.py), run by ToolRegistry |
arguments, tried legs and bounded results in tools.jsonl; never native-search usage on the answering call |
Browser tools (browse_page, browser_action) |
the main loop | a local stateful Playwright session that can fetch or act on arbitrary pages | arguments and result previews as tool evidence; browser state equals neither retrieval path |
Ordinary delegated profiles, local-readonly and acting alike, keep the URL, route, private-range and control-plane guards (browser_policy.py, §6 MCP and browser-facing external tools); a Cyber-effective acting child inherits the selected access minus explicit task restrictions. Their non-loopback private origins need host-established resource_policy.allowed_origins, named by Main/root scheduling in schedule_subagent and only inherited or narrowed by delegated and external Presence callers (tools/control_subagent_spec.py); among delegated profiles only a valid acting child may run JavaScript evaluate, on its current page. The separation is methodological authority: an evaluation or acceptance claim must name the path used.
Context fitting, retry, and compaction
config.get_context_mode() sizes Main; get_owner_context_mode() retains owner intent/P3 (context_mode_compat.py). SYSTEM/BIBLE stay full tier-0. Max inlines Architecture; Development is inline for body work, otherwise a pointer, with context_requires_development/context_requires_self_body_docs overrides. Low/Nano and children get physical chapter navigation (context_layout.book_navigation), never composed offsets. Children do so in all modes contrary to P1 (issue #1026); Low/Nano ignore the self-body flag (issue #1019). Own-body Main/API children, planners/consilia and declared-input ones included, get DESIGN headings/ranges in dynamic_head after knowledge (context_layout.task_design_navigation). Provenance/body_fact selects the source; a prepared candidate or flag covers folderless self work. Foreign work gets no DESIGN rules; missing sources are disclosed. The mind selects original sections: a map proves no content delivery, reading or application.
llm_local.py takes capacity from confirmed serving_context_evidence (--n_ctx), not model metadata; unknown capacity skips compaction, implying no failed health or cloud fallback. Its tier-0 compactor can still cut BIBLE's principle bodies (issue #1018); a request still too large raises LocalContextTooLargeError.
context_fit.py: immutable Max/Low/Nano core; targets inform, never gate. Max keeps books until size refusal; Low/Nano and lowered starts keep sizing, owner mode/P3 unchanged. Startup memory fits known W. Rebind keeps the sent view and its floor note naming the W it was cut for while the request fits W or W is unknown; otherwise it narrows by W alone, never unfolds. Nano substitutes an input pointer only when W fits that pointer but not the input. loop_messages.py appends round/route/view facts: input, reply reserve, window/target room, largest parts, spend, quota, prior usable cache and cached exact-route tariffs: unknown stays unknown, no fetch/advice. context_health: task-start invariants.
context_compaction.py checkpoints sources; actor notes start at the first replaced unit; position/lineage persist unless merged. Guidance: SYSTEM/working_note. restore_unit_refs appends labelled sources without note/helper/rewrite. Human words, outward dialogue (tools/owner_delivery.py), assignment, new arrivals and opaque protocol stay whole; owner_wait retains pending speech without resend. Exposure uses usable Main pre-redaction evidence (model_send_seal.py), not call IDs or understanding. Helpers replace only fully covered units with smaller signed views; failures stay raw. No predictive helper. review_history_view/loop_round_limits receipts distinguish request failures from stale inherited selections; detail alone exceeding fit becomes count/retained source.
After actual size refusal, loop_model_call.py tries context_source_view.py: obsolete host snapshots collapse to one exact checkpoint address, then oldest confirmed-exposed tool bodies become sources until the measured goal. Helper, coarser memory and task-local book navigation follow. Late disclosed source-only rescue handles unconfirmed exposure before configured fallback and refusal with Continue. Outcomes and current facts survive; addresses prove no understanding. Changed rungs get one strict-shrink retry; Stop, deadline, money and unknown custody bind. send_clock stamps before measurement/pricing/sealing; rejoins retain bytes.
tool_result_delivery.py measures each completed Main batch whole (adopted route/schemas, host additions, one reserve). Unasked bodies share B's low-water eighth (B: smaller known target/window W) of room requested forms leave; only a known W cuts those: the mind chose and folds them. Full sources precede head+tail views; remeasurement names an unfit minimum. Unknown B keeps all bodies. tool_capabilities.tool_result_limit sizes producer pages; no tool/path escapes the frame. read_file(start_char, max_chars) uses Unicode characters after universal-newline decoding.
tool_result_record.py binds canonical outcomes to invocation and logical text digest across neutral cache wrappers; changed/opaque content stays unknown. Empty outputs stay exact (seals skip them; send-only padding is route-owned); private metadata stays off the wire. delegate_output.py credits each consumer's actual ranges of the exact recorded file (retained, or legacy own delegated_runs/<run>.json; never previews): Main's batch, native review's sent prefix, consolidation's accepted prefix or a direct reader's window. Invocation-local metadata prevents parallel/abandoned read confusion; receipts retain source-byte hash and reader identity.
llm_attempt.bound_reply_allowance caps sends at the fresh route maximum (response_limits.py) apart from the window; unknown or stale never caps. Low/Max ceilings and Nano capacity/targets still apply; fit, memory and compaction reserve the cap; summaries it cuts keep raw sources. In capability_evidence.json, response_limit_refresh_failures holds exact-route failed-refresh timestamps for the negative TTL without changing expired positive records; owner acknowledgements win.
local_model.local_artifact_key binds local maxima to the expanded file path or hf:<repo>:<full repo-relative path>, shared by settings and serving cache paths. Basenames use the downloader's _resolve_hf_path metadata resolver, never a download or dropped subfolders. The serving artifact outranks pending settings.
Canonical history is provider-neutral and function-shaped; send copies adapt at the exact route: direct-OpenAI Chat's custom/function/none ladder (openai_chat_custom.py) never changes API surface; anthropic_native_custody.py retains native assistant replay only for its route; llm_openai_compatible.py sends OpenRouter strict: false and omits neutral tool_choice. request_wire_recovery.py repairs shape on the same credential-free route/profile and never chooses a provider or model; only normalized success bound to the settled physical capture teaches state/request_wire_compatibility.json, and error prose cannot reroute. usage.request_wire describes compatibility, usage_store.py / state/usage.sqlite owns money.
Retry classes stay distinct: transient 429/5xx and empty/incomplete replies may retry within deadline; auth, quota, permanent bad requests, confirmed oversize and output exhaustion never do. Compatibility exhaustion returns to configured fallback. LLMClient keeps leading system messages authoritative, later ones becoming user notices. A proven remote pre-dispatch failure (Claudexor not-started receipts too) releases at $0; configured alternatives run before loop_transport.py opens an interruptible network wait. Its network_wait facts spare the idle rail without cancelling cognition in flight; expiry never resends. Silence after kill, Panic, crash or hard Stop proves no terminal outcome.
provider_outcome_unknown keeps unresolved money and forbids a resend. loop_transport.new_generation_after_unknown needs ended receiving, no viable same-operation rejoin and host input binding the new attempt to the old identity, route and unknown charge. Every running turn, inline Presence included, uses configured routes then paced recovery within its existing controls. Earlier tool results stay in the transcript; only the accepted answer executes subsequent tools. Control-read loss rejoins the accepted operation; a live delegated leaf parks its nanny in supervised wait (delegate_hold.py).
Retry rails nest, each with its own owner and bound; the table shows their multiplication in one place (every physical send is its own execute_physical_attempt lifecycle, whichever rail asked):
| Rail | Owner | Bound | What it repeats |
|---|---|---|---|
SDK max_retries |
client construction (net_transport.py, llm.py) |
0 everywhere | nothing: the ledger sees every physical send |
| request-wire recovery ladder | request_wire_recovery.py inside one LLMClient.chat |
_MAX_COMPOSED_ACTIONS per call |
a rejected request in a corrected wire shape |
| configured-route walk | loop_model_call._run_cross_model_fallback_chain |
bounded attempts per binding per walk | the round on each other configured binding, the primary first when a fallback acts |
| transient burst | call_llm_with_retry |
OUROBOROS_TRANSIENT_RETRY_MAX attempts per call |
typed 408/429/5xx and empty/incomplete responses other than output exhaustion |
| round redial | loop_transport.py wait episode |
managed task: owner deadline, budget, Stop, absolute ceiling; direct-chat turn: OUROBOROS_TASK_IDLE_TIMEOUT_SEC from episode entry or a shorter explicit deadline |
the same round: released ($0), eligible unknown (new attempt), or chosen primary refusal (ordinary burst) |
| served-model redo | llm_substitution.py inside one chat_claudexor |
OUROBOROS_SERVED_MODEL_REDOS per call; none under a pin, an admitted candidate or a spent budget or window |
a round the engine says another model answered, as a new operation |
| review physical rail | review_substrate.py, review_native_episode.py |
review_native_episode.native_or_packet_attempt_rail bounds P3/acceptance packet or session sends; a native-retrieval slot carries no send count |
a released review send, never an unknown one |
net_transport.py gives OpenAI-compatible, no-proxy and web-search clients TCP keepalive on Linux/Darwin, detecting dead NAT/VPN mappings during silent reasoning; proxy routes, native Anthropic requests and other platforms lack it. The same seam merges OUROBOROS_EXTRA_CA_BUNDLE over certifi into state/extra-ca-bundle/<digest>.pem for first-party clients; an unreadable file raises ExtraCaBundleError, never silently changes trust. Typed cognitive-operation start/terminal facts keep model calls off the idle rail. OUROBOROS_LLM_TRANSPORT_READ_TIMEOUT_SEC bounds a dead socket, not reasoning; deadline, money, cancellation and absolute ceilings stay independent.
_usage_response.response_finish_reason reads provider length/max_tokens as output exhaustion, outside canonical history; an empty limited response without a body error opens the next ordinary round as llm_output_exhausted within existing limits, with no provider failure, cooldown, cache bypass or route walk. Overflow/body errors keep precedence; absent finish evidence stays a glitch.
Prompt caching
Prompt caching is stable-first: governance and task-stable contracts precede mutable evidence, review builders disclose the stable/dynamic boundary, untrusted payloads stay outside the governance cache block; context_fit.seal_task_transcript owns the one message-side breakpoint. OpenAI-family caches look a prefix up only at message ends, inside the leading system group only at its end, and a changed tool set is another prefix: that group plus the tools is one cache unit, changing runtime evidence stays outside it. The Main builder declares its stable prefix (host-only STABLE_PREFIX_BLOCKS_KEY, stamped by context_fit.ContextFitProjection.system_message); the OpenAI-family (llm_attempt.openai_family_route) and Claudexor (llm_claudexor._request, every model source) send A' (prompt, Bible, Architecture, a common book pointer), optional D (Development) and B (identity and the sealed story) as separate system items and carry C (knowledge, rooms, runtime facts) as one [SYSTEM NOTICE] user message with a byte-stable provenance header just before the task (placement: llm_messages.split_leading_system_prefix); on OpenRouter this family keeps message markers (llm_attempt.supports_message_cache_control), other families byte-identical wire. OpenRouter's sticky session follows the same family line (llm_routing._openrouter_session_identity): the OpenAI family shares one session per model + governance prefix, so a new task, child or wake gets the prefix its predecessors cached. Each call records the shape sent (usage["wire_layout"]); the Health Invariants cache-hit rate counts only rounds reporting cached_tokens (a provider without that telemetry is unmeasured, not a miss). Residuals: the shared family session pins a model's traffic to one OpenRouter endpoint while it lives; an idle install's cached prefix expires. Gateway response-cache recovery is reactive and narrow: only a main-loop provider_incomplete_response arms a fresh-response request; only the generic openai-compatible route renders LiteLLM's extra_body.cache.no-cache control.
Vision and local image evidence
analyze_screenshot and vlm_query call LLMClient.vision_query; view_image and the typed auto_attach_image opt-in attach pixels through vision.attach_local_image_to_context (auto-attachment failure is non-fatal). Main fits and adopts one old-plus-new image projection under the live-image cap. Local reads obey the Tool API policy matrix and protected-artifact rule; task contracts may withhold these tools. Owner images enter new tasks and drained running-task deliveries through context.build_user_content/build_incoming_user_content; ACK follows append. Shared image_preparation.prepare_image_bytes preserves detail within host budgets and known route limits. Originals remain at the source or in atomically written uploads/views; conversion/recovery notes reach VLM requests and host-owned tool results. Unusable files keep a note.
vision_routing.py projects send copies by Image Input mode (explicit VLM/caption calls: Inline) and owns same-route image-refusal recovery. vision_image_limits.py applies known limits without changing history. _original_image_url rebuilds pixels/notes on wait or switch; refusal/caption identity follows sent pixels. Losing all pixels refuses an image query before generation; Main keeps words and surviving images. provider_models.supports_vision reads complete, dated evidence: Claudexor's account catalog per call; API /models from task-start probes, kept in state/capability_evidence.json for _EVIDENCE_FRESH_SEC. Unknown sends pixels. Model names and refusals prove no capability: size, count, format and content-filter refusals look alike (DEVELOPMENT “External facts: unknown is not no”). Install presets set Vision to a confirmed image row or blank (inherits Main). Explicit Vision selections remain callable despite negative metadata.
Background consciousness and Evolution
Consciousness is Main's direct turn without speech; consciousness_wake.py renders prompts/CONSCIOUSNESS.md. Only it may finish_task(silent=true), not over owner rows after its last live text send (owner_reply_owed). Words stay internal; non-clean outcomes post a host notice. The clock uses last finish and a mind-chosen, owner-bounded interval. Conversation heads and wakes across carriers block admission; detached owner work does not. /bg stop finds pooled wakes. Events and update_letter.py are observations, never wake triggers. Boot floor, retry/backoff, allowance, Panic and due times remain. toggle_consciousness(status) reads persisted facts; start/stop are announced.
The wake sees Main's integrator view: identity/story, all marks, Main verbatim, other rooms' unsealed words, helper-retold memory and journal since the last accepted wake. Settled facts/answerable cards are evidence, not sealing duties; chronicle_write is the mind's choice. quiz_closed history survives canonical GC; bootstrap uses closed_at, actor/reason imply no answer, and both witnesses join once at consciousness_observation_boundary. It advances only after immutable-source readback, preserving mid-wake arrivals and the bootstrap lower bound until verified.
Origin, autonomy and money are separate. initiator="consciousness" follows spawned work and grants no owner voice. consciousness_authority.py enforces Observe (research, internal notes, own-child cancellation, narrow schedule management and read-only delegation), default Act (no evolution, restart, settings writer, own alarm or Presence configuration) and Full. Below Full the effective mode caps at Light; install restrictions may narrow it. Observe also narrows arguments and cancellation by lineage; read-only children cannot delegate mutation. tools/followup.py lets roots change schedules, children list and Presence do neither. Restrictions bind at dispatch, so schemas and cached prefix match an owner turn.
consciousness_allowance.py reads one rolling 24-hour allowance over wakes and root trees they start, not a separately started Presence cycle; an unreadable ledger yields allowance_unknown, refusing admission without claiming exhaustion. The alarm and supervisor/queue.py::enqueue_task admit on known spend with holds disclosed. Remaining allowance, capped by the owner's task cap, becomes root_cost_ceiling_usd; zero daily remainder blocks waking.
supervisor/evolution_lifecycle.py owns a campaign's objective and transaction/task claim; evolution_mode_enabled only projects scheduling. Dispatch, review, commit, publication and restart revalidate the claim; restored work without a live uncommitted claim is cancelled. Publication binds the reviewed SHA; state/pending_restart_verify.json binds restart verification even with auto-restart off. Abandoned/no-op cleanup restores the admitted base, keeping dirty/ahead work in recorded stash/refs. Identical blocked diffs replay review free; changed diffs use the shared cycle cap. evolution_checkpoints.py retains Git/memory identity, money, rounds and omissions. Agent-requested restart drains live heartbeat-fresh work within a bound, then refuses, never cutting it.
post_task_evolution.py is owner-gated and default-off: a worker's chooser reads the finished run's exact initial text and sealed package beside the complete authored backlog and may recommend one improvement; a split Project root reaches that chooser through agent_task_pipeline._run_global_backlog_promotion_only with a globalized view (sealed package and provenance, no project scope or initial text) under the same opt-in and cadence counter. Only the idle supervisor starts a normal campaign cycle; absorbing it never edits the backlog (its stated entry stays ledger evidence). Owner stop closes the campaign, clears requests and persists evolution_owner_stopped; autonomous work cannot reverse it. Light blocks evolution at start, idle enqueue and supervisor/worker_assignment.py; Advanced/Pro use normal tasks and review.
loop_messages.context_facts_line states room, money bounds, tool counts, protocol latch, round_clock_fact's execution/calendar clocks and nanny burn/request anchors—not strategy. task_pacing factual thresholds append to ordinary rounds, not extra calls. Tree/group allowance differs from shared headroom against its starting remainder; neighbors' spend counts. Notices/facts share a dated observation; changed reprepare refreshes it; unknown stays unknown. Periodic advice, self-checks and tool-less-output accusations are absent. Finalization can re-loop on host-held custody, readiness, verification, handover or protocol facts; controls remain. Hot-loop reflection broke caching and produced unusable records; understanding is authored via knowledge_write.
Safety and runtime mode
Tool dispatch uses the registered capability, the explicit task/resource contract and one prepared physical target. Explicit task resources and the actual Git target are host facts, distinct from any semantic judgment about the call; this is not an OS sandbox.
Runtime mode is effective Access and a self-modification ladder. Light refuses mutation of the Ouroboros repository and control plane (LIGHT_MODE_BLOCKED; skill payloads under their own root stay editable) while user deliverables outside them remain buildable, and Light cognitive writes go through update_identity, update_scratchpad or knowledge_write. Advanced evolves the application layer and built-in tools but not the protected set owned by runtime_mode_policy.py (SAFETY_CRITICAL_PATHS, frozen contracts, release/managed invariants; one policy shared by the registry, git tools and gateway guards, refusing typed CORE_PROTECTION_BLOCKED). Pro may write that set, announced by CORE_PATCH_NOTICE, and its commit still passes the normal review wave (both questions). Cyber authority derives from effective Access (runtime_mode_policy.mode_has_unrestricted_agency); a saved next-boot mode never rewrites a running task. In Cyber Pro, internal review and Safety findings are advice under BIBLE P0/P3: configured enforcement, independent assessments and the decision to proceed remain distinct facts.
Process admission preserves the original argv, resolved cwd and prepared physical target. Command words, quoted source or script examples and unknown interpreter effects show no write intent or forbidden action: shell_parse.py and tools/write_shape.py supply observed targets and syntax facts, never permission judgments. The Safety Supervisor (safety.py) judges each call on the light-model route from the complete retained owner directives, the task contract and constraint and the prepared resource target; a bounded recent-conversation view supplements that source, never replacing it. Coverage is OUROBOROS_SAFETY_MODE Full/Light/Off over each tool's TOOL_POLICY entry, else its ToolEntry.safety_policy (extension, MCP and unknown tools are checked): Light skips conditional checks, Off skips every Supervisor call; every waved-through check leaves a durable safety_mode_skip event. full → light → off is a decreasing coverage ladder, so outside Cyber Pro a downward step is owner-only (POST /api/owner/safety-mode). Each admitted process effect executes once; later settings or repository observations annotate the original result, never repeating or reverting it: a revert proves no causation. Settings-selected environment (env_from_settings) reaches commands, scripts and verification under service startup's Settings-selection authority; tools/process_facts.py resolves it once after admission and masks diagnostics before persistence.
Safety Supervisor outcomes
The first line of a Supervisor result is the typed outcome. SAFE passes silently; SUSPICIOUS allows the call with SAFETY_WARNING; DANGEROUS or an answer still unusable after one repair retry blocks with SAFETY_VIOLATION. Cyber records a negative or unavailable assessment as advice (SAFETY_ADVICE, durable safety_advisory event), never manufacturing SAFE. A provider 429 is an infrastructure fact about the Supervisor, not a verdict about the call: after one retry the typed non-verdict SAFETY_UNAVAILABLE blocks the call, telling the agent to retry the same call, not reword it; a confirmed storm arms a process-local latch (safety.py) that answers in-window checks without a provider call, since re-probing from the highest-frequency light-model consumer would amplify the storm it reports. A structured insufficient-quota refusal is a verdict and blocks. An over-budget subject is refused fail-closed (SAFETY_SUBJECT_TOO_LARGE_BLOCKED), never truncated: anything past a cut would run unreviewed. Only the no-backend cases fail open with SAFETY_WARNING, so a misconfigured runtime never hard-blocks every unknown tool: no provider key and no local lane; a remote key not covering the light model's provider, with no local lane; a local runtime chosen as fallback that fails or is rate-limited. An explicitly primary local runtime (USE_LOCAL_LIGHT) that fails is a real SAFETY_VIOLATION.
Outside Cyber Pro, read-only shell git is allowed everywhere; mutating shell git only when its resolved target lies outside the Ouroboros system repository and runtime data drives (git_shell_policy.py; git init/git clone are judged by destination). Acting self_worktree children stay read-only: patch capture requires an unmoved HEAD. The generic VCS tools (vcs_status, vcs_diff, vcs_pull_ff, vcs_restore, vcs_revert) default to root=active_workspace and accept explicit root=system_repo; protected Ouroboros path names constrain restore/revert only on that system target, so a project's own BIBLE.md or contracts/ is ordinary project content; preflight_review, commit_reviewed/vcs_commit_reviewed, vcs_rollback and promotion stay system-repository lifecycles. First-party PR helpers are ordinary built-ins under the same root policy, runtime mode, delegated-child constraints, credential rules and reviewed-publication authority. Outside Cyber Pro, a task contract may declare resource_policy.protected_artifacts[] as execute-only black boxes (protected_artifacts.py): reads, copies, hashes, static inspection and trace/debug wrappers over those paths are refused.
Review delivery
review_execution.py routes are api_chat/agent_session; vendor/harness is a target, not a kind. Preparation, health and dispatch share session_route_for_review_slot, frozen before send; no fallback (ReviewRouteUnavailable). API packets get at most two sends (interaction plus transport/empty-output recovery or acceptance-format repair), never after unknown dispatch. Hosted reviewers use one Claudexor session with instructions, pointers and tools, not an API pack; delegated transport owns custody/cancel/recovery/settlement (§6 Delegated subagents). review_execution_projection.review_actor_progress_text shows route, answer and observed harness/model/account or refusal. $0 refusal means unsent; requested effort/model is not observation. review_session_reads.session_read_facts extracts harness_observed ranges from the journal: diagnostics only, never paid-repeat, verdict or quorum authority.
Reviewer rights. ReviewSlot.session_access binds request and roster: full default, workspace_write, readonly (explicit or absent). Writable seats get git or skill copies; task folders are read in place (review_checking.py). Threads keep their copy and project turn geometry (review_thread_continuity); older engines refuse, never start afresh. A copy goes after its receipt; review_checking_prune retires the rest.
Native tool-round episode
review_native_episode.py::NativeToolRoundReviewExecutor serves API rows (delivery: native) and deep self-review. Each attempt binds reads to its data plane; budget/Pause keep canonical roots. Tools: read_file, list_files, search_code, query_code, query_data, vcs_status, vcs_diff, compact_context, under local_readonly_subagent with network off. Commit/change/preflight use two-part briefs; plan/skill/acceptance keep their contracts. The complete initial assignment, required-source manifest included, receives one cache marker through the existing cache policy.
P13 permits no round or serialized-character cap. Sends retain owner deadlines, inspection-tool timeouts, per-send ledger admission and provider limits. Initial layout hints choose inline versus exact paged sources, never execution permission. native_context records diagnostic serialized characters, the current typed window evidence, previous request usage with route/view identity and the output allowance, never current free tokens. compact_context preserves the reviewer's authored view and exact sources. native_read_coverage is diagnostic; native_tool_receipts record host-observed ranges from the reader's ctx.last_read_view and display_map, separating bounded reads from full coverage (§6 The coupling question).
Unavailable inspection schemas produce not_dispatched at $0; actual provider overflow keeps its existing failure path. Every episode leaves custody and actor usage; a paid send cannot be relabelled unstarted. Historical cap failures remain readable. triad_review.default_output_contract supplies the surface shape unless the request overrides it.
Late completion and typed refusals
Late completion stays in operation-addressed prompt/response CAS (review_substrate.py, review_custody.py). The manifest binds the complete outcome to task/attempt/slot/operation/subject/contract/roster; reconciliation verifies it and runs the surface reducer without another paid attempt. Pending, unreadable, mismatched and unknown retain custody. A delegated refusal before the paid stamp is not_dispatched by a positive fact (delegated_start_unrequested); an unproven start stays unknown. Readers use the writer's custody_root. Plan asks (through review_operation.collect_recorded_review_actor) and Skill Review share this; for skills review_job.review_wave reserves slot ids before dispatch; review_resume_of reaggregates only the preceding unsuperseded wave with identical material, recorded contract/roster/layout and RAW pre-POST chunk request (skill_review_passes). Late completion neither revives a job nor enables a skill.
Custody belongs to the review run, not its worker. After process loss, review_custody._rejoin_window uses the saved original window (first requested_at for unbound starts), floored at NESTED_SETTLEMENT_MARGIN_SEC; collection never extends it. review_operation.recorded_review_assignment supplies the recorded request and slot, not today's catalog. Released in_flight/custody_lost stays unresolved, not failed or answered. Observation failures keep polling until terminal or deadline; an unreadable deadline observation leaves in_flight (ReviewPollUnavailable), attach-only, never settled or resent. Deadline-observed succeeded is accepted paid evidence (late_success_accepted), not cancelled/failed. Terminal custody notices stand beside unchanged model text; later cancellation changes neither authorship nor answer hash.
A malformed catalog is refused at save (reviewer_slot_config.review_pool_save_error) and is a typed loud failure on every review surface (reviewer_slot_config_invalid); an empty pool (pool_empty) reviews on Main alone, one native seat main (review_pool_slots). The preflight and /review read no slot: each call names one enabled catalog row; an unknown or disabled row is a typed refusal, never a fallback, and no surface silently chooses the opposite route. Technical failure and commit permission are separate facts: producers keep a failure's origin beside the original status and findings; what each enforcement mode then permits is the protocol's rule (DEVELOPMENT "Review & Commit Protocol"), and neither changes quorum.
Usage ledger substrate vs. accounting policy
usage_store.py owns the monetary authority, state/usage.sqlite (one row per physical attempt, updated on every transition; Usage store) over store.py's shared SQLite core; usage_ledger.py is the shared vocabulary leaf that policy modules import and that imports none of them. usage_accounting.py is the one-way policy layer above them (pricing, reservations, settlement, scopes, budget fences, projections, admission). So a pricing or budget-policy change cannot redefine valid storage, nor a locking or repair change alter what an attempt costs; events, state mirrors, task fields and UI projections may carry attempt ids and derived totals but never become a second charge source. _usage_response.py normalizes provider usage: a received price, zero included, outranks error shape and survives later errors without proving the response complete. Only a pre-generation body error with explicit zero usage and no price settles free. Every provider adapter still reads the raw usage dict for its own envelope; there is no central read to consolidate.
Caller-owned subscription model calls
claudexor::<source>=<model> selects an owned-engine model operation, not an Agent Run. LLMClient routes sync/async calls through llm_claudexor.py before OpenAI-compatible filtering/retries; Ouroboros owns SYSTEM, BIBLE, messages and tools. Codex exposes raw models; other harnesses retain Agent capabilities and API keys their routes. cache_key_for_model shares the governance prefix across tasks, children and consciousness within one data-root/model.
ClaudexorGateway (gateways/claudexor.py) submits idempotent POST /v2/model-operations, generating at most once. Lost control rejoins; unknown outcomes cannot regenerate; eligible host continuations use a new operation. The official CLI refreshes the managed profile shared with Agent sessions: no relay, copied operator auth or public OpenAI-compatible endpoint. Metadata uses passive read_owned_gateway, calls/lifecycle actions ensure_owned_gateway. Unusable coherent terminals settle usage then raise non-repeatable stream_rejected (response_rejected). Only exact model_request_invalid at create proves no admission. Cash stays zero/known/estimated/unknown; subscription never proves zero. Receipts outlive bodies, preventing expiry-driven regeneration. Images use the selected account catalog (§6 Vision). Send copies drop foreign metadata (stop_reason) but retain refusal as assistant text, preserving bytes across cache-boundary changes. effort_evidence.py checks reported tiers without remapping; missing/malformed stays unknown, reports separate from requested options in Logs.
The receive loop emits changed model_activity: preparing, queued, dispatching, awaiting_response, response_ready, response_received, rejoining or unknown, with operation/invocation IDs and known admission blocker kinds. loop_llm_call.py binds main_llm_call_state observations to its call; supervisor.events updates pooled RUNNING or the direct registry for that attempt/execution/round/call only. Direct attempts use the same live TaskModelWait; observations open no quota wait and close no call lease. vision_process.py projects only operation_id, invocation_id, request_ref, request_manifest_ref into strict custody receipts, deduplicated after successful write (§3 presentation).
The live turn slot
Caller-owned llm_claudexor.ModelTurnState carries the opaque live-turn token through LLMClient.chat, outside history; neither compaction nor failed bodies reconstruct it from old assistant envelopes. A dispatched durable result replaces it, released invalid_continuation repair clears it, other outcomes retain it. One run_llm_loop invocation spans rounds, steering, acceptance and quota waits; the next loop/cold restart starts empty, leaving this transport ends it. Opt-in requires the last successful handshake to meet config.CLAUDEXOR_MODEL_TURN_STATE_MIN_VERSION. The token grants no generation and enters no usage/event/progress/task-card content.
Roles, accounts and context
OUROBOROS_MODEL_ACCOUNTS and OUROBOROS_MODEL_CONTEXT_WINDOWS bind roles (§7); identical model names prove neither identical roles nor accounts; reviewers and actors reuse route credentials. Auto uses the exact account's largest advertised window, never CLI compaction thresholds. Manual windows assert sizing, not provider/review authority; capacity, input and output reserve stay separate, unknowns included. Usage pairs submitted options and provider echoes; missing keys remain unknown. Account changes reprepare before dispatch; ordinary, wrap-up and forced-final sends share role/account, and final headers identify the responder. Review default_temperature is a route-resolved hint; raw operations use provider defaults; explicit temperature, including zero, stays explicit and may fail. Quota, interruption and unknown custody propagate through helpers without becoming a result or verdict.
Configured routes and primary return
model_slots.route_binding names model, locality and selected account or Auto. The primary (loop._initial_round_route) remains available if fallback fails. [ROUTE FACTS] names both routes, failure date and reset; primary_route_observation.py adds changed, dated, non-generating primary metadata at round boundaries. Cognition chooses stay, switch_model(primary="return") (logged apart from its outcome) or primary="wait". Return preserves primary role/fit, effort and Auto. Temporary 429/503 refusals exhaust ordinary retries, then loop_transport waits on that primary under Stop/deadline/budget bounds. Only a real answer ends this wait; metadata, clocks and resets never prove generation success (P5/P13). Direct API auth/billing waits offer Retry/Switch/Stop without a subscription observer.
Quota and auth waits
execution_timeout_sec / CLI --execution-timeout narrows the global ceiling via model_wait.execution_elapsed_seconds: queue, confirmed quota, Pause and sleep through Resume consumption are excluded once; tools/result waits count. No time is regranted; timeout_sec stays a calendar deadline.
llm_capability_policy.model_catalog negotiates includeAdmission; catalog_admits_model shares exact-model admission across waits and upstream recovery. Advisory absence permits an attempt without inventing a row; older engines keep membership semantics. Source/account/fingerprint/freshness checks remain; failed discovery is not empty success; admission proves neither generation nor the previous outcome.
model_wait.py holds quota/auth and engine-dated pool waits in the live call via the mailbox and /api/decisions family model_wait:<task>:<wait>. Dated non-mixed pools are unavailable, undated refusals use transport recovery, and only poolCause proves exhaustion. The engine alone places/deprioritises accounts; pins never rotate. Metadata cannot generate; result rows are projections, not a ledger. Another model's completed answer is retained/ACKed but rejected as the round; model_substituted means root fallback or exact-route-child failure, never requested-model cooldown (redo policy: §6 Context fitting, retry, and compaction). Resource refusals try configured fallback routes (§7) before owner wait on the retained refusal, naming needed sign-in. Inline Presence never waits (§12). Temporary switches affect only this wait; Settings, acceptance and task application stay separate, and Fallback Local is group-wide.
gateway/task_model_wait.py owns effects; task_decision.answer_decision serves Web/Host Service. supervisor/task_model_wait.py projects worker events/clocks; gateway/decision_contracts.py owns decision vocabulary. Worker/project-write ownership stays held (one worker means the queue waits); reviewers retain their operation through settlement (§6 Task acceptance). Browser closure preserves the wait; process stop ends that guarantee. Lost tracked VLM results (vision_process.py) remain unknown, never free. Review-operation decisions reach only the exact live review_operation_controller, not an ended author's mailbox. Consciousness (handle_wake_direct) shares owner-turn registration, model wait, Stop and unknown-outcome recovery.
Streams and transport waits
Main remote completions (llm_stream.py) assemble inside the physical send closure before settlement. Complete streams normalize like JSON; partial calls and answers never execute. Exact wire and partial assembly stay in private CAS (physical_stream, attempt id). A Chat call-name fragment equal to the accumulated name is suppressed and any other appended, both disclosed: this compatibility policy reads a,a as a, not aa; arguments and other payloads keep their deltas. Form anomalies appear in the stream receipt; shape is judged after terminal framing. Complete unusable bodies are provider errors (stream_rejected) with received usage; only unterminated streams enter unknown-outcome continuation. A complete response without final usage still has unknown money. Comments and pings set no cognitive deadline; HTTP phase bounds stay distinct from the logical wait.
After alternatives fail, cognition keeps one loop_transport.py episode (§6 Context fitting, retry, and compaction). A fresh non-generating upstream observation can admit a real task continuation with [SYSTEM NOTICE]; it proves connectivity, never the old outcome or future success. Subscription catalog evidence needs provenance="provider_http", an observedAt after the failure and a matching source/model/account fingerprint; cache reads never refresh that timestamp. Control-link, create, status and result-read failures (generic 404 included) rejoin the same operation or create key across endpoint rediscovery; they prove no non-dispatch and start no generation while it is recoverable.
Delegated subagents (Claudexor transport + the nanny)
Ordinary delegation requests no extra engine review panel. The start receipt's engine_version is the handshaken serving version; engine review outcome, execution success, the parent's integration decision and Ouroboros review gates stay separate facts.
Child coordination, registry and scheduling
Children coordinate through tree_note and tree_read; only the parent may use override_delegation_constraint. Read-only and acting children alike hold the descendant-scoped forward_to_worker, peek_task, cancel_task and discard_child_result; recursive delegation never widens filesystem, budget, depth, deadline, commit or owner authority. forward_to_worker also reaches any task in the same durable tree as context-only peer_task provenance: a shared root grants context, never ancestry (owner_mailbox.py). delegation_budget governs descendants; persisted admission facts outrank later Settings changes; a lower permitted depth is reported capability_reduced, never a silent flat tree.
Registry. configured_subagents.py owns OUROBOROS_SUBAGENTS: strict {enabled, items}, at most MAX_CONFIGURED_SUBAGENTS rows, each a hidden subagent_id, a route-handle name (§3 Available subagents), any-language recommended_use, a normalized API or session route, effort, account pin, access and row enabled. Off rows keep their configuration but leave the catalog, alternatives and reviewer resolution; selecting one returns subagent_disabled, distinct from global subagents_disabled and from live unavailability. Descriptions guide the LLM, never host ranking or keyword routing: exact selection starts that route or refuses without substitution.
Scheduling. schedule_subagent requires subagent_id, objective, expected_output. Blank roles stay empty in task/prompt/notices; explicit labels retain actor identity (§3). workspace_root selects the starting folder, else inherits. Acceptance claims never inherit implicitly. access=inherit keeps configured rights; readonly|workspace_write only narrow. write_surface owns mutation authority, not a model-visible lane. subagents.subagent_intent_fields carries intent through admission/worker/snapshot. choose_effort resolves requested effort (auto = omitted), recording level/request/source; leaves start there, nannies inherit the parent's. select_subagent_snapshot freezes the enabled row without rereading settings; its kind selects API child or nanny. main_context_authority keeps helper briefs idempotent with exact readers; late history enrichment uses resolve_task_lineage.is_root_task, not a role string. Shared/declared helpers retain briefs and their own review authority; blank-role/retry roots and exact get_task_result reads retain predecessor history.
Selected first-input sources. schedule_subagent(input_sources="declared") gives API children and configured sessions assignment/evidence, full SYSTEM/BIBLE, authority/tools, own observations and applicable DESIGN navigation. Default shared adds governance/book maps, identity, top-level life account (except nannies), room page/marks and verbatim owner origin (owner_words.py), never whole dialogue history. Children publish chronicle drafts signed with their focus (tools/chronicle.py); the integrating mind accepts or rejects them. context_input_selection.py composes/validates this core. Selection is no filesystem boundary, semantic independence, first-position gate or model/effort change; reads, tools and mail may broaden evidence.
Historical author inputs. context_input_selection.capture_historical_inputs retains the selected input after a usable ordinary response: the first immediately as immutable redacted JSON, the latest when an evaluator requests it; equal views deduplicate. Intermediate views remain in observability, so these anchors do not claim every input. Logical messages, verified physical projection or its gap, original Presence event and admission provenance stay distinct. Captured topic bodies are never reconstructed from today’s files, profile or room history; exclusions prove no exposure.
review_evidence.historical_author_inputs is a sibling of owner directives and terminal inputs, changing neither criteria, acknowledgement nor paid semantic identity. Native/session readers use existing source readers; packet-only evaluators receive labelled incomplete previews. Size/hash travel independently of reader placement. Anchors survive continuation and terminal recovery; missing original pins or changed bytes stay unavailable. Publication follows source storage in canonical and execution roots, and retention follows only anchor refs, never arbitrary event dictionaries.
Child handoffs and task waits
Waiting on children. get_task_result and a settled wait_task return the full child handoff with red/masked-first verification and exact omission counts; batch wait_tasks stays compact (_compact_child_projection: task, status, result hash, outcome, trace_summary, capability_delta when disclosable, nullable accounted_upper_bound_usd/cost_final; fields: §11.1). A nonterminal wait_task keeps delegated_runs, the task's own open non-review custody. Unreadable or racing supervision facts mean unknown, never liveness. Both task waits use task_status.SETTLED_STATUSES; a pending cancellation stays cancel_state: "pending". wait_expired_with_live_children gives the live IDs and the window, no advice. known_result_sha256[_by_task] compares join-ledger identity: a match returns result_unchanged, a mismatch the full handoff. Task waits end NESTED_SETTLEMENT_MARGIN_SEC inside the executor's emission, so an outer wait is never shorter than the inner operation it wraps (control_task_results._wait_window).
Delegated spend and token reads
What a delegated run costs. Claudexor reports cash per attempt (attemptExecution[].usageCost.cashUsd with cashKnowledge exact|estimated) and in summary.spendUsd/summary.spendEstimated; delegate_custody.disclosed_spend is the single reader, preferring the per-attempt figures, so the ledger row and the payload the nanny relays cannot tell different stories. Runs ask authPreference: subscription explicitly: the engine default falls back to a paid key invisibly. Four cases:
| disclosure | ledger | finality |
|---|---|---|
| disclosed settled zero | 0.0 (subscription_session row) |
cost_final=true — the proven free session |
| disclosed settled charge | the amount | final |
| estimated amount | the amount | cost_final=false — an estimated zero is not a proven free session |
| undisclosed | cost_usd: null, increments unknown_unmetered |
drops cost_final for the projection |
An undisclosed spend contributes 0.0 to known settled_usd and accounted_usd: a conservative bound would fabricate a number the harness never gave (BIBLE P1), so a TOTAL_BUDGET fence cannot stop spend it was never told about; the honest consequence is lost finality, not a guessed charge.
What a delegated run reads. Harnesses count input tokens with incompatible conventions, so settle_run copies the engine's normalized summary.inputTokenUsage onto the subscription_session row as the optional input_token_usage object; record_subscription_session is the one validator, and a partial object is unknown as a whole: a repaired counter reads exactly like a measured one. The object stays outside the idempotent row identity, so an engine that starts reporting never rewrites a session already settled without it.
Nanny, transport and custody
The nanny model. An agent_session child is an ordinary recursive nanny task supervising at most one active bounded external leaf. Task lineage, authority, deadline, money, acceptance, cancellation and descendants stay with the task; the harness is a nonrecursive tool leaf, and host-authored verification checks its claims. requested_depth is absolute root-depth telemetry, depth_remaining the narrowing cap. Targets and access profiles are opaque to core: no harness-name capability or fallback branch; login asymmetries stay in gateway/claudexor_accounts.py.
Transport. gateways/claudexor.py owns the descriptor, /v2 handshake and config.CLAUDEXOR_MIN_VERSION floor. trust_env=False keeps proxies from the /v2 bearer token. New work uses claudexor_daemon.ensure_owned_gateway and reviewed engine/Node pins, never PATH. Exit, kill and failed handoff/recovery attach only; only an admitted sweep may ensure and replay an unresolved START. Until recovery binds it, a remotely accepted run can remain unconfirmed; sweep cadence is no stop-time guarantee. OUROBOROS_CLAUDEXOR_BIN overrides the binary; contributor-only OUROBOROS_CLAUDEXOR_ATTACH_HOME attaches to its running engine, never spawning or falling back to the operator home. Stop, latch and failure: §9.
Durable custody. delegate_custody_current.py reduces each authoritative custody_runs row in the emitting state/current.sqlite transaction; its outbox appends forensic delegate_run_* events after commit, and import folds them once. Addressed readers select current rows by id, task or hold; bulky decoding follows their coherent raw snapshot and Python predicates decide. health_runs reads own, held and maybe-unread rows (non-json_valid facts pass), all rows after a failure; payload_snapshot reads payload runs and pending requests in one transaction, owner terminality after it, holders in run_id order; unreadable custody refuses. These JSON filters may scan all rows. Ownership stays OWNED/FOREIGN/UNKNOWN; unavailable storage is delegated_run_state_unknown:custody_log_unreadable, not absence. Each intended start mints an invocation UUID and Idempotency-Key: content hashes locate work, never identify reruns. retry_of and admitted sweep recovery use the same retained invocation/request/key; missing or corrupt sources keep that identity unknown without a POST (delegate_pending.py). Containment incidents remain recorded.
delegate_collection.py observes addressed held runs and publishes exact terminal/interaction sources before heavy work. The server retains full output, patches and supplied money without author attention. Unchanged collection debt retries on BODY_MAINTENANCE_INTERVAL_SEC; changed facts or explicit requests remain immediate. terminal_state/terminal_source/observation_seq describe execution, settled/ledger_recorded accounting. Separate bounded observer/collector jobs own their physical return: blocked capture cannot occupy another observer. Observation starts no daemon, retries no POST, answers no question and accepts/applies no work.
Foreground, body and orphan collection share collect_terminal: the nonblocking disposition lock rechecks run/continuation binding. Verified output returns before remote probes despite pending capture/money; missing output uses delegate_wait's quiet collection_in_progress wait without paid polling rounds. Retention sets no consumption, EOF or terminal ACK. Task/root/parent, invocation, route, target and billing identity remain the author's.
Orphan cancellation needs readable terminal owner-finish evidence; crash/provider/transport loss or unknown ownership keeps work live. Accepted cold owners stay (§6 The model's own sleep); reviewers remain panel-owned. One-shot roots register nothing. Proven pre-callable exits clean only fresh nonpersistent delegate/review registrations, even after START_REQUESTED; shared/persistent/thread/recovery and possibly sent starts remain retained. Actual daemon 4xx keeps prior typed-refusal semantics; failed cleanup preserves the cause with unconfirmed cleanup. delegate_continuation.still_continuable retains ordinary registrations with continuation rights or unknown authority. Failed ledger writes owe settlement; started_uncustodied needs positive absent/terminal proof.
No terminal/cancel claim without a verified receipt. delegate_cancel returns confirmed (terminal readback), requested, failed or containment_fault_run_may_still_be_live; the last two keep a durable critical incident until a receipt or settlement; a refused control never proves run state. daemon_says_absent accepts only an answering daemon's scoped 404, never a failed observation; delegate_run_closed_absent means unreachable, not settled, with no invented terminal, usage or spend.
Nanny verbs and continuation
Five nanny verbs (tools/delegate.py): delegate_start, delegate_wait, delegate_cancel, delegate_answer, delegate_message; no fake hurry. Start needs an exact session subagent_id or recovery-only retry_of; subagent_bootstrap starts the snapshotted leaf before the first model round; the model decides when to wait. delegate_message (delegate_interactions.py) requires the engine's /v2/operations catalog to advertise POST /v2/runs/:id/messages and a route liveInput other than none; the gate uses no harness-name branch. Outcomes mirror the engine's LiveMessageOutcome: delivered proves consumption, not obedience; steering is attempt-local, never re-injected by the host. An unreadable capability is capability_read_failed, not proof that live input is unsupported; a not_active refusal with interaction_pending may carry a fresh question observation and exact pending-interaction ids through the ordinary complete/preview artifact path; the refusal is preserved and nothing is auto-answered. A definite refusal needs a typed cause, no custody handle and either producer definitely_unrun or _DEFINITE_UNRUN_REASONS; it ends UNRUN at $0. Ambiguity wakes the model: uncertain live work cannot become a zero-spend terminal. Actor-replacement and zero-run fences exclude review_owned runs, while settlement, money, containment and registration see all runs.
Continuation (delegate_continuation.py): continue_from=<run_id> is the mind's new start, cap and key over a settled run, not recovery. Without live input, wait or verify cancellation/settlement; partial work may need repeating. The engine's continuity names its carrier; continue_carrier=packet forces re-briefing, absent continueFrom yields continuation_engine_unsupported. Durable checks require recorded task-line relations (not room/folder equality or panel ownership), settled and not already continued, no ambiguous apply, no wider access and an unchanged writer target. Same-tree custody also refuses continuation_snapshot_missing, continuation_snapshot_released and continuation_handover_busy. Cause, unread result, changed route/work order ride the started payload and child's prompt, never instructions: a resumed session may retain the first instructions.
Execution evidence. delegate_evidence.task_execution_evidence projects custody (§11.1). delegate_start_attempted includes blocked/uncustodied attempts, so refusal is not ignored delegation. applied_access_profiles uses SETTLED rows only; absent acceptance_patch_dispositions means no recorded disposition, not "reviewed clean".
Work orders. subagent_work_order.py sends the complete assignment in prompt, the normalized contract once in instructions (delegate_start_instructions.py); native/HTTP limits return actual failures. After root preparation, session_design_navigation appends own-body DESIGN headings, source path and byte SHA to final host instructions. Bytes come from the prepared source/copy, never a foreign target. START_REQUESTED retains them; retries replay stored bytes. Canonical work-order bytes/range selectors stay unchanged. Tool-less participants need relevant excerpts as declared evidence; incomplete coverage authorizes no PASS or apply (delegate_source_coverage.py).
Supervision, activity and recovery
Supervision. delegate_supervision.supervised_wait renews bounded transport windows without LLM calls; a meaningful event creates a coalesced durable wake replayed until ACK; deadline, ceiling, budget and cancel stay outer rails. Read-only coordination_context supplies intent, time, spend, descendants and acceptance capacity for the model's judgment, never thresholds (BIBLE P5). Polls are read-only of task state (the usage reader's bounded maintenance: §1 Platform substrate); quiet holes are observation_read_timeout (our bound expired on a live daemon), daemon_unreachable (no socket answered) and a DAEMON_BUSY_CODES answer to a GET. Wakes retain full tools; leaf_live_input is capability, not liveness. nanny_pacing reads current usage against round/cost request anchors; coordination resets neither. owner_wait retains both marks; older checkpoints disclose unknown anchors. Burn informs, never prompts advice.
Delegated activity. delegate_activity.py types the executor's message, thinking and problem parts in additive progress_meta.delegated_activity; host observation (narration=False) proves neither nanny authorship nor execution. gateways/claudexor_run_events.py reads GET /v2/runs/:id/events as bounded SSE keyed by run_id/seq, without a poll or retry loop. Redacted ranges live under source_handles/delegated_activity/, size/digest-bound with cuts_truncated/seqs_truncated disclosure. Ready results replay unshown ranges locally; cursor/gap rules: module docstring. Task-file ?source= reads: §4; UI and replay: §3.
A run's question belongs to its nanny. A new pendingInteractions entry wakes supervision as waiting_on_user; delegate_answer echoes the custody keys; a question beyond the nanny's authority escalates to the nearest live ancestor. continuation:same_session is paid per turn. A route without mid-run questions ends input_required; the answer is delegate_start(continue_from=<run_id>, prompt=<answers>), never an engine rerun outside task custody.
Recovery is exact and cause-specific, not generic task resurrection. A proven non-signal worker crash or a planned self-restart's typed handoff lets a successor adopt the exact run or pending invocation before any model call or new start; anything ambiguous returns typed recovery-required, never a duplicate mutator; owner restart, panic, signals, deadlines and cancellation are explicit no-resume causes (delegate_recovery.py). With no physical run and none startable, the model may finish only with a typed zero-run receipt (verify_and_record) after custody proves nothing is open; a session actor's clean terminal needs its own physical leaf or that receipt; a completed host child cannot substitute.
Dispatch, route health and history
Configured dispatch is exact. subagent_runtime.resolve_configured_actor_dispatch checks live availability at dispatch; a bad choice returns a typed cause, alternatives, reset time and host_fallback:false, never host ranking, first-healthy selection or session→API conversion. Selecting agent_session is the parent's LLM choice of harness execution: the host sets the truth, money and authorship floor, the model owns topology, decomposition and supervision (BIBLE P13/P5). For a configured subagent every fallback is an explicit LLM-selected start; a pinned selection whose delegate tools are invisible is blocked, not substituted.
Route health. subagents.route_health is the one health reader for dispatcher, nanny and review slots, and never guesses admission: the doctor status describes only the default credential store while the real accounts live in the engine's credential-profile pool, so admission is the engine's, whose start POST answers an empty pool with a typed credential_pool_exhausted at $0; only a disclosed resetsAt makes that refusal a timer-healing window. enabled is honored as route_disabled (the owner's switch, not an observation); the other structural refusals are the capability catalog, an access-profile mismatch, the delegated marker floor and positively proven quota exhaustion. Review slots inherit "the engine decides", never a silent fallback onto metered API spend. The model sees a facts-only catalog (model_visible_subagent_catalog); with no rows it offers Main alone (offered_subagents). Helper observations are history, not routing: state/subagent_last_delegation.json (subagent_history.py) feeds runtime context and the UI, never admission; a fallback's success never certifies the failed route, nor does a code or test failure condemn a provider.
Run shape and mutation authority
Read-only and writable session rows share one nanny transport. subagents.delegated_run_shape alone derives the run shape for tools/delegate._derive_authority, resolve_configured_actor_dispatch and every reviewer seat, so authority derivation cannot diverge.
| task authority | access | mode | isolation | execution.delegated |
|---|---|---|---|---|
acting subagent (valid write surface); ordinary root with a validated external workspace or selected Project room; top-level task selecting an exact skill payload (root="skill_payload"); research or reviewer seat without write authority (investigation) |
captured full or workspace_write |
agent |
live |
true |
explicit readonly, Observe research, a Presence ceiling without delegated write, a fail-closed subagent |
readonly |
ask |
envelope (default) | not sent |
Host-derived mutation authority (tools/delegate_integration._mutation_authority / _payload_mutation_authority) separately names the destination; never model-supplied:
| source | target_root derivation |
capture_mode |
|---|---|---|
acting_constraint |
the child's own task_constraint.write_root, required to equal the active workspace root |
delegated_snapshot |
external_workspace_root |
the root task's validated external workspace or selected Project room | delegated_snapshot |
skill_payload |
the exact payload the fresh skill_payload.write binding resolved |
delegated_snapshot |
readonly |
ordinary active root (nothing to write) | none |
investigation |
the active root, as provenance only | evidence |
subagent_worktrees.provision_payload_snapshot gives payloads standalone private Git snapshots; live payloads gain no Git. Whole-payload CAS in integrate_payload_patch: drift conflicts; identical content is idempotent; blocked_reserved_paths refuses whole; baseline-equal apply_no_op proves no write; other hashes leave mutated ambiguous pending intent. Success queues request_extension_reconcile and stales skill review; mode-only changes refuse unreviewable_metadata_change.
Snapshots, capture and disposition
Private snapshots. Native/API external_workspace shares its target: integration verifies current read/Presence/task authority without tree/index writes. self_worktree copies eligible Git inputs, dirty bytes included; parent integration needs current write/Presence rights. Delegated refs (refs/ouroboros/delegated/) and state/subagent_worktrees.json survive until disposition or custody-checked GC; unreadable custody retains them, missing copies refuse execution_snapshot_missing (PERSISTENCE). delegate_directory keeps Git subfolder starts in their clones and copies staged inputs for folderless investigation. Capture excludes/discloses nested repositories and credential-shaped files before hashing. scope.root grants reads; the bound execution.workspaceRoot grants writes.
Terminal collection reuses delegate_integration.capture_terminal_patch_for_drive and the existing Git, skill and engine-directory capture paths, independently of money. Baseline diffs stay in task artifacts; moved committed bytes disclose head_moved; only ready manifests earn patch_captured. Capture, continuation and disposition share the snapshot lock. Only explicit apply/reject or continuation takeover disposes a mutating snapshot. Git apply verifies touched baselines then stages without committing; payload apply uses whole-payload CAS. Unfinished delegate_run_patch_apply_started stays INTEGRATE_DELEGATED_APPLY_AMBIGUOUS until explicit acknowledgement. patch_verdict.py alone owns run_<rid> subjects; protected-path rules apply only to body targets.
Review/skill capture and provisioning share subagent_worktrees.stage_raw_payload_inventory / _RawBlobWriter: Python bytes → filter-free fast-import → index path/mode/blob check. Unindexable paths refuse; rename them. Kept packs avoid unpacking; the threshold bounds Git's blob memory, not Python file reads.
Terminal products. Terminal revisions keep their metadata, reader and hash across output retries; previews earn no EOF. Investigation evidence self-disposes as evidence_retained only after the full output and required sources survive, granting no product acceptance. undisposed_patches keeps run/target until PATCH_DISPOSED names disposed_by_task_id. Confirmed automatic retries may read settled delegated-run products, never inherit live control; shared roots, manual Continue, review-owned runs and CLOSED_ABSENT confer none. Snapshot takeover supersedes the predecessor; cumulative work integrates once. Orphan disposition needs proven owner terminality and the admitted target; reject needs no new write grant. Missing/unreadable/unreaped ownership retains custody indefinitely. Late sources re-owe their closing receipt transactionally; receipts retain the canonical source and published digest (delegate_terminal/context_health).
Custody disclosures heal from the write side. delegated_custody_unreconciled covers own undisposed runs; outcomes.custody_debt_axes warns without replacing earned axes. Readers never replay custody: delegate_terminal.py audit writers refresh facts; unknown clears nothing. Frozen delegated_runs_* counters stay; actual_substrate follows live custody. Provider death plus debt stays Failed with the custody reason; clean plus debt never increments evolution_consecutive_failures.
Disclosed delegated-isolation residuals: non-owner orphan verdicts live under the disposer's task, while capture directories and PATCH_DISPOSED keep owner ids, excluding those verdicts from owner acceptance packets. Task-drive-scoped Git locks let nannies interleave integrations into one external tree; drift makes the loser's apply a typed conflict. Child-created credential-shaped files fail the whole patch, never shipping a partial diff.
Native product succession. integrate_subagent_patch admits finished native direct-child products via hash-verified owner_continue.continuation_chain, with target/CAS/resource checks. Exact-result decisions stand; conflicts/refusals retry. Successor verdicts/marks keep original parent/child/hash, leaving lineage, evaluation and controls unchanged. Missing marks stay missing.
Access disclosure
Native access disclosure. Full access has no filesystem sandbox; snapshots own delivery. CLAUDEXOR_DELEGATED_MARKER_MIN_VERSION is a schema floor: route_health blocks incompatible mutating requests before spend; read-only delegation omits the marker. Attempt evidence alone determines isolation. Missing containment discloses delegate_run_unconfined without refusal: the child already has native shell access. Recorded harness_home_isolated:false or claimed isolated HOME equal to the operator's cancels as a breach; nested HOME is disclosed-unconfined; missing HOME evidence stays unproven. Applied-evidence readers, threat model/floors: docs/DELEGATED_ADMISSION.md.
Authority cannot widen. delegate_start: prompt, session subagent_id, max_seconds, lowering-only access, retry_of, continue_from/continue_carrier, payload selectors; no mode/isolation/scope. Retry keeps route/root/access/permissions; host instructions stay unforgeable. Native access never overrides task constraints or edit targets. _containment_breach checks every fetched detail's access/HOME, derived by Claudexor, never echoed. Wider access cancels (access_profile_widened); narrower is valid.
Vendor program maintenance
harness_maintenance.py serves Accounts and inspect_harness/maintain_harness (ouroboros/tools/control_maintenance.py); ouroboros/gateways/claudexor_maintenance.py transports negotiated engine operations. Claudexor owns selected installation, targets, durable request identity and before/after/partial-effect evidence. Lost replies reuse the same key; no host updater ledger, invented rollback or legacy reinstall labelled Update. Inspection never starts an engine. Mutation respects existing resources, verified Presence grants, Observe and Pause without another owner confirmation. Updates neither replay tasks nor change auth/accounts; unsupported engines return unavailable.
Own-body candidates
Ordinary body authors — a queued root, a direct turn, an evolution cycle — write a task-owned linked worktree of the serving repository, never the serving checkout, so unfinished self-change never enters serving imports. The candidate starts at the serving HEAD on branch candidate/<task> under the isolated worktree root, as a kind=body_candidate row of the worktree registry, which restores the binding across a retry, a Resume or a new worker. prepare_self_change prepares it explicitly; body writes, PR-integration verbs (git_pr.BODY_WORKTREE_TOOLS) and an acting self_worktree child reach the same preparation through body_candidate.authoring_seam before resolving any target; reads before preparation stay on the serving tree. Light mode, capped trees, subagents and the managed-update resolver get none; Cyber Pro may choose in_place; a body with no Git tree keeps in-place authoring.
Binding rewrites one fact — repo_dir, system_repo_dir and branch_dev of the tool context name the candidate — so every consumer, the review subject and commit_reviewed included, shares one identity under own-body policy; a candidate is never an external workspace, and serving_repo_dir keeps the running checkout for review governance, the restart marker and rollback. A process whose cwd is inside the candidate or its admitted own-body child copy runs in an isolated environment beside it (<candidate>.env, test_environment.isolated_environment: its own HOME and data root, no credentials or global Git config, pip only inside a venv), so a push, a provider call or a pip install outside a venv runs from a cwd outside the candidate; when it cannot be prepared the process is refused (CANDIDATE_ENVIRONMENT_UNAVAILABLE), not started with the serving one.
Ownership is the root task: a host-validated continuation inherits its predecessor's candidate, prepare_self_change(resume=…) selects one exact retained candidate, and either moves ownership only from a terminal owner whose ledgered processes are settled; nothing is inherited by room, name or date. Binding appends the candidate to the lineage's mutation baseline, so commit_reviewed stages what the task's own baseline attributes to it exactly as on the serving checkout; the commit is never auto-pushed. A candidate commit is version-neutral (every carrier span byte-identical to HEAD, no tag) or a numbered release (VERSION and every carrier in one diff, tagged); the release gate names the form from the diff, a partial carrier move is neither. Retention counts from last use: a candidate with no unique work expires; otherwise its files are captured on refs/ouroboros/candidates/<id> and the checkout is removed only when the capture is complete and the verdict still holds (body_candidate.verdict_holds); a nested OUROBOROS_RETAINED.txt marker keeps the process environment and source checkout.
Adoption is deliberate and restart-bound (body_adoption.py): request_restart(adopt_commit=<sha>), or an evolution cycle's own restart, authorizes one exact commit that builds on the serving HEAD, came through the commit gate (Cyber Pro records the exception), keeps the entry files and the package-init hook and changes no path where the serving checkout holds uncommitted work; a constitutional change needs a numbered release outside Cyber Pro. The old generation never writes the tree: the carrying restart re-verifies under the update lock, and its exit tail arms only on the stop owners' own evidence that the old readers are gone, reading the engine pin the next generation selects from the candidate's file (bound_candidate_file) before the owned daemon's fate is decided (§9). The owner's Restart and Panic never arm or wait: a stuck stop must not hold the owner hostage; evolution cleanup abandons only its own authorization, and crash recovery retains a reviewed candidate without authorizing adoption. The switch and its recovery are §2; settle_on_boot records adopted only for a generation that attested the switched tree before its imports, bootstrapped and is supervisor-ready.
Git and commit review
pr_merge(number, expected_head_sha, method) merges through the selected repository's gh identity at the exact head, never with force, admin or auto-merge; merge_receipts.py records intent before effect and keeps reviewed, current and merged apart (a committed base..head record named by review_record_id; a declared_only declaration never reads green). An unknown or queued outcome is observation-only — exit status alone, transport loss or 5xx proves no rejection — a missing review is loud, never a veto, and shell or web merges leave no receipt. Only proven pre-effect failures release intent, including the exact full gh pr merge stderr matching its canMerge refusal (before the display cut); recorded unknowns are never reclassified. list_github_prs preserves its bound gh pr list selection and reads exact counts in one node-ID GraphQL query on the returned URLs’ host; unavailable counts withhold the list, never invent zero.
mutation_attribution.py captures the root-task baseline and projects the clean-at-baseline delta plus an adopted predecessor's exact retained changes; a changed pre-existing dirty path, a stale baseline or a failed scan blocks automatic staging for the panel to weigh. commit_reviewed(paths=None) stages only that attributed candidate, explicit paths must be a subset, and an empty candidate is GIT_NO_ATTRIBUTED_CHANGES; managed update transactions keep their separate whole-tree authority; predecessor_adoption grants no review approval.
Commit, tag, post-commit tests and push each pass owner_pause.run_operation: Pause after review refuses an unsubmitted commit; an ordinary one handed off stays a success whose later steps report not started, and nothing resumes them: after Resume they are its author's explicit work, never a new commit. A managed merge keeps postcommit_resume; commit_reviewed rechecks its HEAD and a clean tree, then finishes its tests and smoke with no new commit or rollback (git_managed_postcommit.py).
A reviewed commit is bound to one staged fingerprint — the git write-tree SHA, ordered HEAD and MERGE_HEAD parents, indexed VERSION, expected v{VERSION} tag, any existing tag target and the binary staged-diff hash — re-read after the commit before success or push is recorded; an existing release tag is never silently accepted or retargeted. Every seat of the one wave inspects the same staged snapshot, any mutation stales the binding, and the author's early look (§6 Commit preflight) changes neither tests, wave nor binding. A managed-update resolution commit reviews the declared M0→S subject (tools/review_subject.py) while the gate binds S to the exact index write-tree. release_sync.sync_release_metadata projects version carriers during commit preparation; VERSION_CARRIER_SPANS / substitute_carrier_spans is the one span primitive the managed-update resolver and the packet's carrier cut share. BIBLE supplies review authority, CHECKLISTS the criteria and DEVELOPMENT the procedure; snapshot identity, the preflight fact, deterministic results, actor evidence and final Git identity describe one material.
Every Advisory or Cyber Pro outcome returns its complete result and exact review_reference before commit, tag or push. Continuation through commit_reviewed / vcs_commit_reviewed with that reference and author_disposition binds the current attributed candidate, reruns the independent preflight, tests and Git checks and dispatches no critic; a settled handback is reviewed/review_only, pending custody stays reviewing/late_wait and collectible, and Blocking gets no author override. Evolution receipts record the wave's actual aggregate (triad_scope_status), never a PASS inferred from a successful commit.
Commit review evidence
review_evidence.capture_commit_review_evidence freezes the selected browser and vision calls and same-round image attachments, unavailable-image gaps included, once per attempt — after free admission, before the look and the wave — as one canonical task source handle: native reviewers read its ranges under the canonical root, sessions receive byte-identical bytes in an ignored .review-drive/<task>/<sha>.txt, packet-only reviewers a bounded, disclosed partial view. The trace keeps exact redacted arguments and the next visible response of the same execution; adjacency never attests visual inspection. A pending rejoin restores the same source from the frozen request, and cleanup waits for physical custody.
Hermetic preflight proof
Only preflight_runner.py mints ctx._preflight_test_proof after green lanes/containment, binding HEAD/tree/index, pass specs, isolated env, Python and Node. test_selection.py selects floor, changed tests, direct importers and widening; release-only text normalizes EOLs. preflight_inventory.py reconciles executed IDs; records keep tier, base/policy, reasons/counts. Missing floor/execution blocks; verifier edits force full (DEVELOPMENT "The tiered commit and CI gates"). Unknown teardown retains tree/Git registration.
Selected proof never qualifies adoption, managed updates or evolution publication; adoption and publication accept only existing full evidence of the exact commit (preflight_qualification.py), never a new run. Only a complete full run (all lanes, two workers or the one admitted) writes state/preflight_receipts/<key>.json, unsigned, reusable across processes. Identity adds Git, Python metadata and load-pinned source; older code cannot mint/accept. A new HEAD requires a run; skips grant no proof. Forgery, other executables and unrecorded package edits stay outside its trust. Seats' hashed briefs carry the frozen preflight_execution; pending rejoins keep it.
Commit preflight
preflight_review(commit_message="...", deterministic_only=True, source="worktree" | "index") returns free diagnostics before sync, staging, review-state access, provider checks, tests or fingerprints. commit_admission.release_metadata_diagnostics evaluates the selected source's current VERSION, carriers and P9 limits. The release report identifies its source, status (clean, blocked, unavailable, not_applicable) and findings; it grants no review freshness and writes no history. A separate book_balance field labels its bytes as worktree (reference_books.py). Book growth never changes the release status or blocks a local commit; syntax and critic review do not run here.
The author's preflight is one look, not a pipeline: commit_reviewed(preflight_reviewer="<row>") names one enabled catalog row by id or handle, pool member or not (an unknown or disabled row is a TOOL_ARG_ERROR before staging, commit_gate.preflight_reviewer_error), and after the free checks and the tests the gate runs review_change(subject=worktree, surface=preflight, reviewers=[row]) on the system repository (commit_gate.run_commit_preflight), before the wave. The look informs and never gates: its record carries surface=preflight in its reuse key, so it never answers the commit panel, and the commit record's preflight fact names it — performed with record, row and aggregate, not_performed without the argument (a plain fact, not an audited bypass), skipped under skip_advisory_review=True; a row named beside the skip or an author continuation is a TOOL_ARG_ERROR. The look counts against review_change's paid-cycle cap and holds no commit custody; review_status reports the checkout's newest look (review_ledger.latest_preflight_record) and whether a later worktree edit staled it (stale_from_edit). preflight_review(reviewer=…) (tools/preflight_review.py, advisory_review alias) is the same look standalone, without tests or release-metadata sync.
The free checks (commit_gate.deterministic_preflight) run on every commit, a skip included: size headroom, the diff pulse and worktree readiness as information and warnings, then release metadata of the staged index and the syntax of staged .py files. Only release and syntax findings block; readiness lines go to the owner's progress and the events log. The diff pulse (review.diff_pulse: files, lines and new files since reference_books.contribution_base, touched modules against the 1000/1600 limits, the books' balance and one question; no threshold) ends every system-repository edit result and heads each non-managed body subject's brief. Tests run unless skip_tests (documentation has tests too), and always for a managed resolution. The reviewed-commit cycle (git_review_cycle) checks authorization and unresolved prior work before staging, binds the exact candidate before free-cycle and budget admission, and revalidates the index and worktree snapshot before the wave. review_status reports open debt from state/advisory_review.json (review_state.py) as a retry anchor, never an admission gate, and no surface projects a repo_commit_ready verdict from it.
Review stack
review_cycles.py owns the shared paid-cycle ceiling OUROBOROS_REVIEW_MAX_CYCLES (a positive integer or unlimited; anything else fails closed to the shipped default; §7). One number, three gate meanings (plans stand outside it): paid panel runs per task for acceptance, independently of author responses; paid review waves per root task for the commit gate, counted from the attempt ledger at dispatch, so the ceiling counts money and only undispatched attempts stay outside it; paid panel dispatches for skill review. Byte-identical material replays each gate's recorded verdict for free; a dispatched technical failure consumes capacity, an undispatched refusal or a collection does not. The last allowed panel still permits an author reaction; an explicit task-local max_improvement_passes=p keeps its p author responses and p+1 paid ceiling, and unlimited removes only the paid count, not the ordinary task rails (§10 invariant 17).
Review waiting has six independent axes:
| axis | bound |
|---|---|
| transport | dead-socket read bound |
| operation | typed active-operation lease |
| logical | slot/task deadline |
| policy | budget / cancellation |
| absolute | task ceiling |
| aftermath | late-result custody |
Physical custody
review_custody.py owns review_substrate.py workers, operation ids and the live map, without another scheduler or timing ledger. Deadline, budget, cancellation and ceiling still bind. API/thread calls disclose in_flight; late answers and settled terminal errors remain collectible, never erased or resent by siblings (§6 Late completion and typed refusals). Capture state, not a synthetic id, proves custody: dispatched|unresolved without terminal HTTP status is custody-lost/no-resend (usage_accounting). Only explicit __cause__ or typed transport metadata proves pre-dispatch, not inherited __context__. Transport defaults do not limit reasoning; timeouts narrow to owner deadline minus finalization reserve. Returned responses and typed terminal errors settle even when empty; post-dispatch socket death stays provider_outcome_unknown, never another paid route. A spent window refuses at $0 before fan-out; reviewed commits have no outer tool cutoff. Recorded commit/preflight/review_change calls join a live original operation's drain and remaining window (review_live_join), keeping unsent preparation and Pause/Stop controls; cold and acceptance collection stay nonblocking.
Paid stamp and owner custody
The paid fact behind the ceiling is recorded write-ahead at physical dispatch (review_dispatch.py): a gate installs one once-only ReviewPaidStamp for its wave and each delivery stamps at its own boundary: a packet row, a native episode's paid send, a session's replayable START_REQUESTED row. Assembly-only refusals exit before that seam, so a $0 attempt stays outside every ceiling; neither a worker outliving its caller nor a crash after dispatch loses the fact. The stamp is idempotent across the wave's concurrent deliveries, so each seat waits for the write's result before starting its transport; commit review, review_change and task acceptance treat a failed write as fail-closed, skill review only when resuming a wave, and other callers keep fail-open accounting. Task acceptance binds one exact-hash tree-wallet claim per panel to the same stamp (the paid identity is material, not route); a wallet or cancellation veto at the claim releases the reservation and no row's transport proceeds (the launch floor: §6 Task lifecycle). Residual: a compatibility transport that raises with positive physical capture before entering the canonical marker is stamped after the send, and when the tree's last paid cycle is consumed concurrently at that late stamp the wallet refusal replaces the captured exception and the substrate may resend.
Before the wave starts, one locked write records paid=True with the reserved seat roster and operation ids in the commit-attempt row; a delegated seat patches pending_invocation_id before the provider POST; a missing or mismatched operation on resume is custody_lost under every enforcement mode. The stamp records the server session and pid owning the reviewer threads (review_owner_custody.py): owner loss is proven by pid death, never by elapsed time: a TTL would convert waiting into resend authority.
Delivery is a catalog-row property read by reviewer_slot_config.review_pool_slots (§7 Review pool). The one shared session target is OUROBOROS_REVIEW_SESSION_ROUTE (review_execution.REVIEW_SESSION_ROUTE_ENV), an opaque harness[=model][:effort] spec that falls back to OUROBOROS_SUBAGENT_HARNESS when unset, so one delegated route is configured once; a set but unparseable value turns review sessions off with a warning, never silently re-routing them.
Surfaces and money admission
The review surfaces:
- Change review (
tools/review.py) — the pool's seats cover the layered Change Review Checklist (the Ouroboros Body Layer joins the universal core on the body;review_helpers.load_checklist_layers) with JSON findings underconfig.adaptive_quorum. A packet seat answers contract A (triad_review.REVIEW_JSON_ARRAY_CONTRACT, the findings array); a retrieving seat answers contract B (REVIEW_TWO_PART_OBJECT_CONTRACT:{change, change_clean, coupling}): one wave, two questions, one quorum over the seats that answered (review_ledger.reduce_verdict, shared by the gate and the record). - The coupling question (
tools/review_brief_coupling.py, Part 2 of the retrieving seat's brief) — intent, scope and coupling across the whole repository, asked of every retrieving seat of the same wave; there is no separate scope role (§6 The coupling question). - Parallel orchestration (
tools/parallel_review.py) — two-phase admission: the packet is fit-checked and every brief built before any reviewer dispatches, so a deterministic assembly block anywhere spends $0 (a seat paid while its sibling was doomed is real money for a half-verdict). Money admission (tools/review_admission.py:admit_commit_gate_wave) prices every paid seat, as disclosure, under its substrate's usage scope and admits the wave throughreview_wave_budget_gate(surface="commit_gate")while known spend is below the globalTOTAL_BUDGET, the root and the billing-group fences; a refused wave records$0 not_dispatchedon every seat plus onereview_wave_budget_insufficientevent naming thebinding_axis. Admission is a read-only pre-check — per-seat reservation stays the enforcement, so a fence reached mid-wave refuses the remaining seats with truthful custody — and an admission that raises is fail-open but loud (review_wave_admission_unavailable). An agent-session row rides the owner's subscription and is neither priced nor waited for.
A free refusal never wears the form of a verdict: a $0 exit is a typed not_dispatched fact with its reason, never a DEGRADED panel or a synthetic actor, and a request never sent is one seat with operation_state='not_dispatched' that stays in the denominator. Part 1 catches line errors; Part 2 catches cross-module contracts, from the same seat over the same staged snapshot (managed updates: M0→S), so one answer cannot hide the other. Task acceptance (§6 Task acceptance) shares quorum and transports, asks no coupling question and stores its verdict apart from the terminal result.
One pool, many subjects — who calls the wave and what each seat is asked:
| subject | caller | questions |
|---|---|---|
| the body's staged index (a commit) | commit_reviewed — the gate |
every pool seat: the change part, the coupling part on every retrieving seat; Cyber Pro composes from the pool and records the reason |
| the body's live worktree before a commit | commit_reviewed(preflight_reviewer=…) / preflight_review(reviewer=…) — the author |
one named enabled catalog row, the same two parts by its delivery; informs, never gates |
any root's index / worktree / base..head |
review_change — the mind, by judgment |
the same two parts under the root's layer; coupling_only critics answer [coupling] (review_ledger.seat_parts) outside the quorum |
| an intention | plan_task |
the Plan Review Checklist; ask='council' = every pool row, ask=[ids] = those rows; a body plan's first ask: every marked row |
| a skill payload | skill_review |
the Skill Review Checklist, every pool row |
| a task result | task_acceptance_review and loop acceptance |
the acceptance question only — a root: every pool row; a child: at most one (reviewer_slot_config.child_acceptance_slots) |
| the running system | /review — review_change(subject=system, surface=system) |
the deep self-review report from one enabled catalog row (default Main); no verdict question |
One organ per subject. An intention has one organ, the plan council (plan_task, §6 Plan construction and review), where nobody votes. A staged change (commit review, review_change) and a delivered result (task acceptance) are frozen subjects whose reviewers answer exactly that; no vote erases a finding and there is no consensus round. A blind-first cross-check of one panel (only the raising seat withdraws) reopens only on recorded evidence: a lone critical FAIL spending the cycles against a passing rest, defects found only in reviewer dialogue, a dominant false-critical cost. Children the mind schedules are its own work, never council members or seats; their reports may be evidence, never a verdict.
## Review. The mind sees the review pool its task's settings snapshot serves as one semi-stable block after ## Available subagents (subagent_runtime.review_facts_block), read through reviewer_slot_config.review_pool_slots, never the last execution. It states the source (structured; empty — a readable catalog with no marked row, pool_empty: true, main_self_review: true; error — a malformed catalog or the refused migration of this document), enforcement, enforcement_blocks, the runtime mode, one rule sentence, per seat its seat_id (the id records carry), subagent_id (the catalog handle, else the seat id), model, effort, delivery and cost_hint, and surfaces, who reviews where. coupling_unanswerable: true (no seat reads the repository, so every commit-gate review ends NOT_PERFORMED) is a block fact kept through any shrink; pool_without_credentials / no_pool_row_has_credentials carry what GET /api/review-pool and Settings → Agents show; migration_snapshot names the migration receipt that decided this document. ## Review records, the task's newest ledger records, rides in the changing part with a bounded omitted.records.
Subject operation
The review wave is parametric in its subject (tools/review_subject.py). A ReviewSubjectSpec names the root (system_repo or active_workspace), the kind (index, worktree, or base..head with base an ancestor of head), the surface and the checklist layer; freeze_subject pins it once as a FrozenSubject (the diff, its diff_sha, both trees). Governance is always the installed body's (governance_root: the serving checkout; a bound body candidate is a subject, never the source of its own rules), while the reading root is the subject's.
Only a synchronous wait reads a live root: the gate's own (is_gate_subject: the system repository's index against HEAD with no explicit base), through the gate's own capture (capture_staged_diff), so its packet, brief, seats and decision are byte-identical to the gate's. Every other subject, and a receptive wave (review_pause), is materialized by isolated_checkout: a detached worktree at the parent with the frozen patch applied to its index, under the install's data root (state/review_checkouts/<token>/repo) at the path of the task's round (checkout_token), so a rerun of the round reads the checkout an earlier wave's open custody retained; it is removed on exit unless custody stays open. Every delivery — packet, brief, the -U0 fit rung, the required-source manifest, the retrieving seats' checkout — reads the frozen subject, never a recapture of a live index. A frozen subject that is not the body's own index skips the body's release preflight: the core layer is a foreign root under the body's rules, not the body's release contract.
Three identities derive from the frozen subject, never from the live index of the running process. (a) The reuse key (review_reuse_key, review_ledger.reuse_key_digest) covers surface, subject, rules, layer, composition, enforcement, contract and the logical round; a settled, dispatched record with that key is returned at $0 (review_ledger.find_reusable; reused=true) unless this task's own operation of the round is still open, which is collected first; pending and NOT_DISPATCHED records are never reused. (b) The logical round (review_round_sha → review_ledger.round_sha_of) is what the author asked of these bytes — rebuttal, questions, goal, scope, base and head — so a new rebuttal or brief buys one more paid review; the identical-diff refusal (commit_gate.check_identical_verdict_refusal) lets a new rebuttal through once; the paid-cycle ceiling (check_review_cycles_ceiling) is common to the root task per (repo, tool), so a second subject under an exhausted root is refused, not reset. (c) The retry key (review_retry_key; the gate's has no round suffix) identifies the physical operation custody keys attempts by (review_custody._attempt_key), set before dispatch: a retry rejoins or replays it and never pays twice; a new round never receives the previous round's answers. The rejoin is durable (tools/review_change_custody.py): a rerun finds the write-ahead attempt row by retry key (pending_round_attempt) before the current pool, any reuse lookup, ceiling check or payment, restores its recorded panel and dispute input, and runs the gate's reconcile-only path (arm_rejoin: settled seats replay, the pending seat rejoins by its exact invocation, nothing new is sent, the record is revised), in this process or after a restart. A parametric wave's record names the frozen subject and carries fingerprints.reuse_key / fingerprints.retry_key.
Change review on any root
review_change (tools/review_change.py) is the commit gate's reviewer wave without the landing: one subject, at most one paid wave, one ledger record (surface="change"), nothing committed and no tests (tests.policy=NOT_RUN; the author attaches results). The mind calls it by judgment; nothing starts it. It reviews the active workspace (default), the system repository or a workspace_root admitted by the schedule_subagent folder policy, frozen once and read as §6 Subject operation says; a deterministic call error (incomplete base..head, unregistered folder, empty change) is a TOOL_ARG_ERROR before any payment. The checklist layer follows the root's body_fact (layer_for); treat_as_body raises only an unknown root. Composition follows the same fact: on the body outside Cyber Pro the owner's saved rows stand and reviewers only adds seats (a named subset records reviewers_subset_ignored); on the body in Cyber Pro and every other subject reviewers is the panel (composition=composed; omitted = full_pool) with reason recorded; a narrowed panel without one records reason_missing=true, not failing. Counted seats of a composed panel are marked pool rows; an enabled row outside the pool is an added critic (additional, outside the quorum); a composition naming no pool seat is a TOOL_ARG_ERROR. commit_reviewed(reviewers=…, reason=…) composes the commit panel with the same composer (commit_gate.compose_commit_panel), refused before staging; the composed seats reach the wave's pool readers as a context-local override (reviewer_slot_config.composed_review_pool): the gate's slot readers have no argument path, the one disclosed contextvar seam the plan-review rule excepts (DEVELOPMENT "Loop / State-Machine Changes"); a concurrent wave keeps the configured pool. reviewer_effort orders this wave's strength; author_questions reach brief and record verbatim (reuse and rebuttal: §6 Subject operation). Paid waves count against the shared cap per root task and (reviewed repository, review_change), apart from the gate's count; exhaustion is typed review_cycles_exhausted with a NOT_DISPATCHED record and meets only a new paid wave, never an open operation's answer. Enforcement is recorded on every root; only the body under Blocking records enforcement_blocks=true, so another root's FAIL is information, never a lock. commit_reviewed/vcs_commit_reviewed stay the only landing in the system repository: their root accepts only system_repo; any other root is a TOOL_ARG_ERROR pointing at review_change and ordinary git.
Review ledger record
review_ledger.py writes state/review_ledger/<record_id>.json: subject/brief, assigned/added seats, requested/observed routes, part answers/aggregate, sources, author decisions, tests/cost. review_wave_id binds paid attempts/actors; review_record_id binds attempt/review_reference/result/same-wave slots (load_record). Unknown models add no quorum diversity; pending is NOT_PERFORMED, free refusal NOT_DISPATCHED, author continuation no verdict. Settlement raises revision; stale writes lose. Canonical-root ledger mirrors typed results/aggregation, never gates.
artifacts.store_actor_source_bytes saves exact briefs/answers before state/review_ledger/index.jsonl; resolvable records/sources shed bodies. Segments rotate at INDEX_MAX_BYTES; unresolved rows stay whole (§10.1). review_projection sends primary/cleanup causes to task/UI; local failures stay local beside withheld rows. Seat usd survives failure/pending, even zero; absent/estimated stays null. Wave sums: known cost/unknown gaps, no final billing/verdict.
review_history.py, plan_review_artifacts.py and plan_record.record_history project decisions once, referencing known mirrors; unknown legacy fields and paid artifacts stay exact. review_history_view.py keeps the full operative spec and current/open/deferred/pending facts. compact_context.review_notes shortens exact decisions or groups selected history without closure or verdict changes; references bind observed versions. Task-result selection carries accounts/lineage through cold context, new packets and Continue, legacy singletons included. Reviewer prose carries ordered authored texts/provenance, not private capsule bookkeeping; Main and retention keep exact capsules. Invalid transfers retain bodies/reasons; selections act independently. Refresh keeps unchanged indexes, retiring superseded valid snapshots before fit. Missing sources remain gaps; no automatic author/read gate.
Session identity
Session reviewer identity comes from gateways.claudexor.final_attempt_facts: the unique final_attempt_id row of the engine-owned final/telemetry.yaml, bound to the requested run id, with model, harness and credential profile read from that same attempt. Summary fields echo requests and may borrow earlier-attempt facts, so none supplies a missing observation. Usage, last-execution views, delegated payloads and settlement keep known facts or explicit absence; the chosen custody and billing route stays the authority, separate from the observed actor, and no quorum rule or model-name mapping follows from the observation.
Structural gates
Structural gates measure code size (BIBLE P3). ouroboros/review.py::iter_gated_modules supplies the one inventory for smoke, codebase_health, census and the UTF-8 byte gate. ouroboros/size_ratchet_manifest.py is a generated, data-only debt register read as AST literals: exact module-line, function-line and byte debt plus the rationale band (the limits: DEVELOPMENT "Module Size & Complexity"). validate_size_ratchet checks live and staged exactness and shrink-only transitions against the committed manifest of HEAD or a parent, with no history replay; only readable absence bootstraps from the candidate tree, so a fork inherits no topology debt; an unreadable authority or staged tree keeps the live findings plus a partial: finding, never a clean pass. Official-repository CI blocks in the size_ratchet pytest lane; local surfaces warn on the same findings, and without branch protection a red lane is a signal, not a merge stop. Function totals are uncapped: counts penalize decomposition. Git blob reads use file-backed input to avoid mutual pipe writes.
agent_startup_checks.hot_store_growth_notes (surfaced by context_health.build_health_invariants and once per server generation and code version) stats the hot stores and archive chains it names against their thresholds in ouroboros/context_budget.py and emits a WARNING with a remediation pointer. The generated inventories under docs/inventories/ — frozen contracts (§11.1 with every owner path resolved), data layout (every row of the §1 tree probed), facades (the noqa: F401 re-export surface, domains from ouroboros/domains.toml) and UI control text — ride the same gen/verify discipline as the size manifest: scripts/regenerate_inventories.py writes them, and a stale inventory is red.
Prompt size, density and windows
review_helpers.REVIEW_PROMPT_TOKEN_BUDGET sizes packets (review, plan, acceptance, skill-review chunks). Retrieving seats and deep review use review_native_transcript_bound only for initial layout and reach exact sources through tools; a native acceptance source stays available above that hint. reviewer_window.window_scaled_reserves scales each surface's output reserve to the route's usable window and known maximum response.
usage_accounting.execute_physical_attempt stores settled (prompt_chars, prompt_tokens, route_fp) density in capability_evidence.json. Main uses the freshest exact-route, then exact-model witness, else neutral density. Reviews use the densest fresh exact-model witness, which may undercut COLD_START_TOKEN_DENSITY; stale, absent or cross-model evidence keeps that floor. calibrated_input_token_limit combines cap, density and absolute margin per call. Before refusing an irreducible cold packet, review_admission.density_probe_before_size_refusal sends one bounded slice on its exact model for one resize: pre-dispatch rejection cannot teach density.
reviewer_window.resolve_reviewer_window sizes routes without model-window tables or authority floors. Unknown API windows get ReviewerWindow.sizing_window's full-window default, raw subscriptions none; scope_window names provenance and its designated-default or conservative fallback. POST /api/owner/capability-ack binds a window or maximum response to one route fingerprint, sizing sends without reviewer authority. Failed sends supply no verdict; small windows alone remove no responding reviewer.
The coupling question (Part 2 of the brief)
The commit gate runs one wave with one role, the seat, and one quorum. Every assigned seat receives one brief by its parts (review_ledger.seat_parts): a packet seat [change] (contract A); a retrieving seat — native API or delegated session, in every context mode — [change, coupling] (contract B, one object {change, change_clean, coupling}); a coupling_only critic of review_change [coupling], outside the quorum. config.adaptive_quorum(len(assigned)) counts the seats that answered at least one asked part once, and review_ledger.reduce_verdict decides the aggregate for the gate and the record alike (per_question.change / per_question.coupling); an unperformed coupling question never permits aggregate PASS. A native API seat keeps its configured identity, route, account pin and effort while the surface selects inspection delivery.
review_admission.build_two_part_brief purely renders the frozen subject and intent. Part 1 carries intent, rebuttal, history, obligations, touched-path dispositions, the layered Change Review Checklist, task evidence and exact staged change; Part 2 the Coupling questions, shared governance tiers, repository index and required-source manifest. Stable governance precedes change-relative context for cache reuse. The diff stays inline within the layout hint (native_first_send_chars; sessions use SESSION_INLINE_DIFF_CEILING_CHARS); otherwise it becomes one exact paged source in the task artifact store, with a byte-exact .review-drive view for a delegated session (a skill payload: an index of its hash-bound copy, paged if large, read once beside packet chunks). Native size never refuses a brief. A real preparation failure appends review_brief_preparation_failed and blocks the wave as infra_failure at $0.
scope_required_sources.py declares the change-relative reading minimum: touched protected runtime, prompts and frozen contracts, protection-owned families (GIT_OPS_FAMILY_PATHS and tool-dispatch leaves) and declared Python/browser contract twins. An ordinary touched file needs no whole-body obligation: the diff carries its complete change. Each row binds the exact identity a read receipt stamps (source_revision, complete_sha256 / complete_chars). required_sources_ref and SCOPE_REQUIRED_SOURCES_POLICY bind the manifest into the review-contract fingerprint (commit_gate.commit_review_contract_fingerprint), so replay authority cannot survive a changed contract. The minimum never restricts further reading.
Coverage records what could be observed — native receipts match source identity and delivered ranges, sessions fold weaker journal evidence over the same rows — as complete, incomplete, declared_empty or unobserved; a changed source is a source_gap, and inline delivery never proves understanding. review_context_atlas.repository_index supplies orientation only: no bodies, no spend, no limit on what the reviewer may open. The reducer keeps received findings and counts responding seats through config.adaptive_quorum independently of coverage: reading gaps stay diagnostics that change no status, block no commit and buy no paid review, and the agent judges whether a gap needs more reading. Critical findings follow OUROBOROS_REVIEW_ENFORCEMENT; a defective coupling block is recorded against that question alone while the seat's change answer still counts, and oversize requests, route and candidate-binding failures never become PASS. Retrieval keeps the reading obligation proportional to the change instead of letting repository size decide whether review can occur; if the change cannot fit a reviewer, split the change, never weaken the reviewer.
Governance delivery
tools/governance_context.py supplies CODE/coupling briefs for change-review seats, preflight and deep review. review_body_fact.layer_for selects the layer; installed governance judges proposals. Native inspection binds system_repo to the installation, active_workspace/default reads to the candidate, even outside HOME. DESIGN maps name the exact source path. Body tier 1 inlines BIBLE, CHECKLISTS_ARCHIVE and executing CHECKLISTS surface/Shared Contract Ownership sections. Tier 2 budgets review protocol, web/ DESIGN and DEVELOPMENT chapters naming touched files; tier 3 adds ARCHITECTURE navigation/relevant packet sections within runtime_limits.REVIEW_GOVERNANCE_INLINE_SHARE. Non-inline DESIGN gets its canonical map; missing sources are explicit. Core/foreign review gets its universal checklist, body books not_applicable, subject_root navigation and no body-required sources. Retrieving seats may read named sources; tool-less packets disclose undelivered text/uncertainty. Maps prove neither reading nor application and add no gate.
The body predicate. review_body_fact.body_fact returns BodyFact(body ∈ {true, false, unknown}, how, detail); layer_for maps true to body, all else to core. how records the deciding git fact (order/cases: module docstring); branch, directory and remote-name patterns never decide (P5). treat_as_body may raise unknown to true, recorded in detail, never lower a recognized body. A plan is a body plan by its declared affected_paths, copies included (§6 Plan construction and review). review_checklist.checklist_fingerprint(layer) records the layered text's sha256 and rules_source = docs/CHECKLISTS.md at the installed blob.
Guaranteed-fit ladder
The review packet keeps its one-pass fit sequence in review_admission.fit_triad_prompt (evidence projection, touched-path note, then -U0), preserving every file and hunk identity and every added or removed line; the cold-density rung above may precede the sequence once. Briefs and packets share the disclosed span-only release-carrier cut; the packet also omits governance bodies byte-identical to its inline prefix; managed subjects keep full texts. Every omission is named, and an irreducible oversized packet is a typed refusal; a retrieving seat uses its paged exact subject instead, and a plan ask sizes its delivery and attachments per participant, keeping the constitutional pack a body plan requires.
Planning, deep review, post-task work, memory
Plan review, task acceptance, commit review and deep self-review weigh an intention, the delivered objective, a staged self-change and the whole system; none inherits another's authority, and post-task work and memory record execution but approve none of them.
Plan construction and review
plan_task (tools/plan_review.py) is the one organ for an intention (P3): a conversation with the reviewers the mind asks, never a vote; fields present decide the effect. A write (goal, done_when [{id, claim, support}] in task_contract's acceptance-claim grammar, affected_paths, prose plan) appends a free revision; omitted fields carry over, identical content records nothing. The first revision requires affected_paths ([] for no files; resolved against active_repo_dir_for, governance from the system repository). An ask (ask="council" or ids, message, attach, reviewer_effort) is the only paid act and carries the current revision. No arguments is a free read; waiting is that read or the mailbox wake. Old-form fields get PLAN_FORM_RETIRED; every typed PLAN_* refusal engages no gate and writes nothing but a no-route ask's attempt.
tools/plan_ask.py owns one ask. resolve_participants: ask="council" is the review pool (reviewer_slot_config.review_pool_slots, Main alone for an empty pool), ask=[ids] those pool seats or enabled catalog rows; an added row's objections never hold; scheduled children never participate. plan_is_body: the declared affected_paths reach the installed repository (plan_spec.resolve_constitutional, new files included; reads do not qualify) or a recognized body copy (review_body_fact.body_fact), or the task declares folderless research about the body (context_requires_self_body_docs=true with a task_design_source). Outside Cyber Pro a body plan's first ask includes every owner-marked reviewer, the host adding and naming those left out. reviewer_effort orders one ask by row_effort's rule (Auto clamped into the effort range, pins kept outside Cyber Pro; unordered, Auto reviews at its top); a weaker order discloses ordered_weaker.
The host builds delivery (tools/plan_packet.py); the mind never re-sends the plan. The stable part carries role, Plan Review Checklist, PLAN_REPLY_CONTRACT and, for body plans only, the constitutional pack (BIBLE/ARCHITECTURE inline for packet seats, mandatory reads for retrieving seats, absence failing assembly; DESIGN headings). Per-participant content follows the checklist; tools/plan_evidence.py resolves attachments against readable task roots with typed omissions. First asks run in parallel, blind; cross-talk adds peers' replies to earlier asks settled since the last delivery, marked late. Repeat participants continue by review_thread_id (session) or their last ask's retained texts (packet); unreadable source means a fresh send, shown as continued. Released seats settle via the review_custody hook settle_released_reply, late ones through attach_late_reply; mailbox frames count actual settlements. After task end, a reply becomes one room mark only the mind releases (late_review_marks), pointing at its ledger reply. Maintenance uses task_store's indexed plan candidates; the plan collector rechecks terminality/pending seats at $0, never granting authority through selection. The own-room snapshot (dialogue_evidence.py, plan_dialogue.py) is a redacted immutable task_source (chat:<id>@<sha256>, line ranges, gaps explicit).
Replies follow PLAN_REPLY_CONTRACT ({prose, objections[{id, text}], withdrawn[{id, why}]}; the first JSON object with one of those keys; bad items named in reply.ignored): only the raiser withdraws; omission keeps an objection (not_adjudicated); a foreign withdrawal or unparseable reply changes nothing; prose never holds.
Task-result key plan_record (ouroboros/plan_record.py, schema 3) is the plan authority: revisions (each text retained once as plan-revision-NNNN, inline while the record fits 1 MB), asks with their participants and each reply's typed projection, which the gate and readers fold (fold_objections, gate_projection, acceptance_view) without opening a ledger file. Exact texts, raw replies, costs and custody live in one review-ledger record per ask (surface="intention", NOT_PERFORMED). Plans stand outside OUROBOROS_REVIEW_MAX_CYCLES: money limits bound asks.
The gate is the task's normal final answer alone (owner_hurry.force_plan_decision over gate_projection); edits and commits never read plan state. Under Blocking, outside Cyber Pro and owner hurry, it holds any task while an objection stands from a participant that was an owner-marked reviewer of the ask it answered (Main when the pool was empty); the [PLAN_REVIEW_HOLD] reminder names its exits (withdrawal, finish_task(action='stop'), hurry, enforcement). Unavailability, refusals, silence, pending asks, added critics and a spent budget never hold; an unknown outcome (custody lost, a dispatch lost after hand-off) stays unresolved, never "nobody reached"; asking again may pay twice. Advisory and Cyber Pro never hold on objections: they become a typed result fact the mind states. An unmet Swarm force_plan (owner_hurry.unmet_force_plan_obligation) holds outside Cyber Pro: with no plan; under Blocking until an ask reaches a reviewer or none can.
Acceptance binds one route (review_evidence_sections._accept_effective_claims over acceptance_view): ingress claims win, else the latest revision's done_when, open objections or not, beside each revision's done_when text, the asks that saw it and the objections open at finalization; ingress never hides adopted plan promises. plan_record.import_legacy_v2 reads earlier-schema records through one loader (legacy_facts, naming an unreadable state): an in-flight task's open blocking findings hold as their seats' objections; reviewers owed at upgrade are one disclosed pending ask (legacy wave <fingerprint>) collected read-only as history, never approval of the current revision; selected claims bind with legacy provenance. The Plan panel renders the host fold (plan_objections). review_history_view.current_plan_history reads plan_record.record_history after earlier-schema waves for Reviews history, compaction and a Continue; plan_review_authority, context_health and predecessor envelopes read the record.
Deep self-review
The retained report (memory/deep_review.md) is historical evidence, not a current-tree verdict: its provenance header records generated_at; source_revision=unknown is explicit, as a delivery captures no frozen Git revision. Context carries a source pointer with those header facts (unknown without a header, never the file time) and a qualified reader address; dispatch decides access and the report stays intact.
/review is review_change(subject=system, surface=system) with one seat: the enabled catalog row the call names (pool member or not), else the direct Main row (reviewer_slot_config.main_review_row: Main's model, local flag and pinned account), so a bare /review runs where Main runs. The Web selector, /review <row>, a bare /review and request_deep_self_review(reviewer=…) queue that name; queue_deep_self_review_task refuses a row not enabled in the requester's chat before a worker is held, and the ack, the result and its record link return to that chat. A task with type=deep_self_review bypasses the tool loop and calls review_change.run_system_review, which re-resolves the row under the task's settings snapshot. The report is that seat's answer outside the verdict questions, so its one surface=system ledger record is never PASS; the record names the chosen seat even on a refusal, binds the live tree snapshotted before the reviewer reads (a tree that moves underneath is the degraded reason system_tree_moved_during_review) and carries the call's own goal, author_questions and reason beside the standing questionnaire. Every row retrieves under ReviewRequest(surface="deep_self_review"): an api_chat row as a NativeToolRoundReviewExecutor episode with the repository and real runtime data roots, an agent_session row through its harness with the same task and report contract (markdown, not an output schema; deliveries and header: the module docstring).
Memory is the subject of this review, so both deliveries inline the seven-file whitelist byte-exact (identity, scratchpad, registry, WORLD, full knowledge index, patterns, improvement backlog) and record each file's disposition in the task, in deep_review_memory usage and in the report header. Reading gaps are diagnostics and never invalidate a finished report. Typed deep_self_review_unavailable or deep_self_review_error failures return execution_status=infra_failed and leave the previous report intact; BudgetExceeded propagates to the budget-pause rail. Availability follows deep_review_route (an API row needs credentials for its routed model, a session row a healthy delegated route), never a window floor. These reviewers hold no candidate write authority and run no plan, acceptance or commit reviewers: the report is diagnostic memory, not implementation or publication authority.
Post-task work
Lessons, the Pattern Register and the improvement backlog are authored, never host-generated: each is an ordinary global note revised through knowledge_write (exact expected_revision, anchored edit, old/new history), so no automatic writer re-decides what an experience meant. Nothing after a task buys a reflection, rewrites the register, applies memory actions, or counts, reopens, ranks, grooms or closes backlog entries; a merged or absorbed change is evidence, not proof an authored intention is met. The accepted cost: with wakes off or after a crash an experience may stay an unrecorded fact.
A root's late phase records the free host_task_facts row, then runs memory_fallback.run_fallback_draft (one Light draft billed as consolidation, only with consciousness off), scratchpad compression and the owner-enabled chooser (§6 Background consciousness and Evolution). Roots own the phase; child replicas cannot regress its canonical running, paused or terminal phase. root_phase_checkpoint preserves completed stages across Restart; supervisor/terminal_delivery.py and terminal_projection.settle_terminal_projection own at-least-once delivery and Main/Project mirrors (§3, §5). terminal_time.py separates the attempt's end from later publication. A Pause an earlier version saved resumes its surviving stages: a retired stage is disclosed (stage_retired:skipped=…) and its saved outputs cause nothing, while completed steps never repeat.
logs/task_reflections.jsonl retains earlier automatic reflections and today's host rows. A late acceptance settlement appends one bounded row without a model call (plan_review_facts.py → reflection.append_reflection_routed; Project rows live in their store behind a canonical pointer). Integrating contexts render host rows whole and old automatic rows as one pointer dated by recorded ts. context._canonical_runtime_reader names read_file(root='runtime_data'), absolute across a fork; _project_reflections_reader names scoped journal_read(source='reflections'). Addresses obey Runtime context's tool/resource and Presence facts; dispatch owns permission. Without a tool context, access stays unknown.
The chooser reads a sealed durable package: answer, artifact manifest and completion_observations. Full redacted observations remain in canonical artifacts behind explicit get_task_result(include_completion_source=true) ranges; a pointer is not proof of reading. post_task_synthesis.capture_task_inputs freezes owner words, Q/A provenance and verification receipts before cleanup. files_rescued comes from the independent listing, so no salvageable text does not mean no files.
Post-work retains pooled custody apart from early answer delivery and the solve ceiling; Stop, deadline, money, per-call and idle rails remain. Confirmed running precedes paid stages; unpaid preparation failure releases its reservation. Final publication retries only bookkeeping, retaining computed results. post_task_synthesis.propagate_paid_interruption saves owner-Paused work; other paid interruptions skip later stages and degrade, ordinary errors stay local. Indexed recovery requires absent physical ownership and an unchanged phase/attempt. pending_once is replayable only with readable proof of no prior dispatch; paid or indeterminate work degrades without replay. Steady recovery preserves paused grants; startup revokes unconsumed grants. Registry access never waits on checkpoint accounting.
Project registry and lease
Projects are rooms of one mind (§6 Durable memory and project focus). projects_registry.py owns identity, room/folder, lifecycle (active|deleting|tombstoned), routing generation/incarnation and activity revision. project_lease.py serializes pooled roots per project, not subagent trees or folders. An exact cold holder retains its external writer's lane; the same saved task may return, another root may not. Ordinary cold sleep without such a writer releases it. Delete fences admission and quiesces before tombstoning; history/data survive.
project_admission.py captures execution authority at preparation (_project_admission, carried by snapshots and retries); the final committed registry read and the queue append hold queue lock Q together; the registry stays the only durable authority. Malformed or duplicate identity refuses all execution and writes. A committed witness makes a missing registry unknown to admission, and reconciliation rebuilds eligible rooms as new incarnations, never as old dispatch authority (docs/PERSISTENCE.md). Invalid bases or unreadable authority retain accepted rows under a restore hold; ordinary execution bases are never recaptured, and explicit placement is readmitted at its next execution boundary; release persists before dispatch, and an unknown dispatch stays held as project_dispatch_unconfirmed unless a carrier-free row's planned handoff is pre-adopted (§9). A refused admission keeps its result and origin notice as never_admitted without a completion card; unknown or missing ancestor results hold children, and missing or unreadable sources hold, never replay (§5).
Project placement
project_placement.move_task_to_project serves the mind and owner button. Durable exact-task binding wins; a bound task's requested name renames its room. Shared origin remains provenance. Preparation compares destination routing generation/incarnation before commit. Only PENDING rows are marked; RUNNING folder and writer lease stay unchanged. At the next execution boundary readmission checks the same active room incarnation, refreshes generation/folder and acquires its lease before folder access changes. Journal/workpad, knowledge tools and routing use the new binding immediately; one host notice names the room and deferred resources, with no automatic memory reload. Children keep inherited scope. Main row products retain the same task id.
Durable memory and project focus
memory_view.py renders each ViewSpec: B holds identity/story; C knowledge, marks, rooms, verbatim current dialogue and task facts. Pages seal row sets, not a frontier: earlier rows can stay open. working_sources_line derives children's Working sources from ViewSpec. memory_inventory.record_period derives source periods; account unions prove no continuous coverage. Unfolded retellings stay whole for story-carrying foci until selection or the floor, with no block privilege. memory_floor.py keeps horizon and owner Low/Nano policy; only physical limits relocate people's words/replies. Nannies keep their room without a common story.
chronicle_store.py appends authored account with frozen source IDs/revisions/hashes/draft states, changing no selection, seal, fold or room head. selection shows/withdraws it and names replaced records; latest wins. memory_view_account.py shows text/counts/periods and one composition reader; rooms keep detail. Corrections/rejections stay whole until a new selected account cites corrected direct versions. Editing/reselecting leaves old edges unchanged. Draft decisions, folds, gaps and nested changes stay explicit; parts claim no member revision. Sources remain reusable/foldable; memory_read(node_id=..., revision=...) reads exact versions and selection IDs.
context.py assembles static governance, semi-stable memory and dynamic task evidence. Recent activity uses each task's newest progress/tool/event rows (jsonl_tail.py, Memory.read_task_recent), never a starving filtered global tail; coverage names shown rows, window and unopened archives. Children read tools/events from their execution drive, progress from the canonical log. Beyond SCRATCHPAD_SECTION_BUDGET_CHARS, context retains newest whole blocks that fit, naming memory/scratchpad.md and the gap; no build retires blocks. The Development matrix and context_layout.py own resident reference forms.
Writers. tools/chronicle.py publishes exact-row pages, adjacent parts, notes, corrections, draft decisions, accounts and selections. Host stamps give outcomes, not reading proof. Children/nannies sign page/part drafts; the mind authors/selects accounts. Wakes off: memory_fallback.py drafts one unit/root, never accounts/overview. Parts retain prior accounts' attributed meaning, not fresh authority, or return non-failure kept_original. Exact input/route refusals, no-ops and rejected draft metadata skip to later eligible input; changed input/route is new work. Receipts: PERSISTENCE. Only trailing JSON and verified quotes enter records. consolidator.py owns Light transport/scratchpad events; dialogue_provenance.RoomLabelResolver labels chat identity, never lineage project identity.
knowledge.py owns note reads, revision-checked writes and active/archived/all navigation; tools/knowledge.py exposes them as the one writer. knowledge_write(mode="edit", old_str=..., content=...) replaces one body occurrence under the current revision; a missing or ambiguous anchor, an absent note or a stale revision writes nothing, and a stale write returns the current source. patterns and improvement-backlog take the same path; no automatic pass writes notes. History rows record the route that answered (knowledge.observed_route_stamp), never the configured route.
Archive/restore share the note lock, revision check and previous/next history. Lifecycle-owned archive: {at, reason} preserves body and path; ordinary writes preserve it, restore removes it from current text. Malformed whole YAML refuses lifecycle changes; malformed archive metadata remains visible. Active summaries stay resident; archived notes remain addressable and explicitly listable, including Presence topics. The mind first retains meaning and limits in linked active overviews, without a host backlink gate or automatic classification. overview, patterns and improvement-backlog stay active. Navigation reads current files without a cache; shelf-byte/count scaling and stale authored index prose remain disclosed limits. markdown_source.py projects titles without full source parsing.
Lifecycle publication first captures exact previous text in existing actor-source custody in canonical and execution reader roots (knowledge_previous_source.read via read_file on artifact_store): generic file tools cannot read project history. review_source_closure.py carries that host handle through child-source retention and cleanup. Source/history failure publishes nothing; index failure reports publication_incomplete; a retry with the current revision rebuilds it before success.
One Ouroboros spans Main, Projects and consciousness with unified dialogue. Project work prefers its thread, journal, workpad and knowledge. project_facts.py selects projects/<id>/knowledge; children inherit the root's resolved project id, never derive it. Identity/scratchpad stay canonical, not project copies. tools/project_journal.py owns curated journal.jsonl milestones and active workpad.md; context holds the whole workpad, recent journal and older-entry pointers. At root completion only high-signal blockers, questions and interface contracts pass from tree ledger to journal. Digests update recency; scheduled consciousness reads results, not digests.
Skills and extensions
Skill capability grows through independent gates, each with its own module: discovery and manifest parsing (skill_loader.py, contracts/skill_manifest.py), content-hash-bound review (skill_review.py / skill_review_runner.py), owner grants, dependency reconciliation (skill_dependencies.py, marketplace/isolated_deps.py), enablement, readiness (skill_readiness.py) and execution (tools/skill_exec.py). Discovery establishes identity, source, provenance (.self_authored.json), conflicts and hash, never trust. Review status, grants, enablement and dependency health stay independent durable facts under data/state/skills/<name>/; a UI toggle, a catalog hash or an old review never becomes execution authority; the gate sequence, payload buckets and marketplace/hub layer are §13's. skill_readiness_for_execution() composes review, hash, enablement, grants, dependencies and peer conflicts into phase-specific next actions and reads the mode-aware gate_for projection (executable_review), never a raw verdict string. The owner may attest their own skill, or a hash-verified official hub payload, to skip the LLM review (skill_owner_attestation.py); the deterministic preflight floor still gates it. list_skills and the per-turn Installed Skills section project the same live facts as /api/extensions; an enablement change appends a best-effort skill_enabled_changed event naming the actor. In Cyber, review failures are visible advice; visibility, successful execution and review PASS are different facts.
A skill may declare a reviewed presence: behavior profile: instructions, knowledge topics, runtime defaults and portable capability requests that installation-local selections resolve to exact targets. Admission requires the bound behavior skill installed, enabled, freshly reviewed and complete, then compiles one immutable positive capability ceiling copied through task_contract, so mutable skill/Settings state cannot broaden a live turn. An optional owner-local workspace_root (configure_presence or the Skills settings form; validated by workspace_admission.validate_workspace_root) changes the file/process target while keeping canonical shared memory; it neither derives Project scope nor forks the data drive, promotion or follow-up tasks keep the admitted folder, and a folder that has become unusable refuses the promotion typed (workspace_unusable). The Presence runner: §12.
extension_loader.py and the isolated-dependency layer load only a ready, hash-matching extension (in-process via PluginAPIImpl, isolated-dep/native ones as child-process proxies), and a review PASS alone proves neither dependencies installed nor a widget loadable. Per-skill health at data/state/skills/<name>/health.json is process-qualified (§1 extension_health.py). skill_lifecycle_queue.py (§13) exposes queued/running/succeeded/failed plus stale metadata; stale is recovery evidence, not a fake unlock of a still-running thread. Scheduled work is reconciled by resync_skill_schedules() and runs only after skill_readiness_for_execution() (§5). skill_payload_binding.resolve_skill_payload_base fills an omitted skill name or bucket from the selected TaskConstraint; explicit selectors must still resolve to the same physical payload. A selected-skill repair (skill_repair_admission.py, §13) is admitted against an immutable base_content_hash and verifies the observed expected_content_hash before each payload write; drift makes the repair STALE, with no long shell lock, no rollback, and other writers never blocked.
Skill publication
The passive installed-skill projection never launches Betterleaks and never claims the current bytes are publication-ready (skill_publish_eligibility.py). Selecting Publish calls POST /api/skills/{skill}/publish-preflight (gateway/skill_publish.py, read-only), which captures and scans one current payload, recomputes review staleness and returns exactly one backend-authored state (ready, warnings, needs_attention, repairable, hard_block); the browser only renders it; only hard_block prevents task creation. The authoritative flow is:
passive index (no scan) → selected preflight → explicit confirmation → ordinary managed task → immutable current capture with separate review provenance → payload scan → GitHub read-only planning → derived-output scans → first GitHub mutation → validated same-skill pull-request receipt → ordinary acceptance
Publication authority is skill_publish_eligibility.publication_author_acceptance: fresh publishable critic authority or qualified current Advisory author authority; owner attestation alone is not that chain, and catalog hashes and PR receipts never become review PASS. Every outbound byte derives from the capture (skill_publish_snapshot.py), never a reread live payload, so there is no time-of-check/time-of-use drift. Outside Cyber Pro, Betterleaks high findings (skill_publish_scanner.py) block the outbound call; lower or unknown confidence is a redacted warning; Cyber keeps scanner and review results as independent advice. Packaged installs resolve the bundled betterleaks-standalone; a source checkout installs the managed runtime explicitly with python -m ouroboros.betterleaks_runtime install — Publish never downloads it. A skill_publish task (tools/skill_publish.py) is accepted only when its pre-truncation metadata holds a validated pull-request receipt for the requested skill and configured Hub repository; the receipt proves the observed publication. A failed envelope (skill_publish_result.py) names the failed stage (reason_code), a repair_hint and the transport's sanitized error_detail.
Owner lifecycle actions share skill_lifecycle_actions.run_skill_action: grant/toggle run in the lifecycle lane, local delete uses skill_uninstall_state, and attestation keeps its deterministic floor. The host supplies actor identity and checks exact resource/revision plus an existing chat message, answered quiz or owner-mailbox record when owner intent is needed; the model interprets that source. A generated edit-and-review request confers no grant, attestation, deletion or enable authority: a client allow_enable flag authorizes nothing, Presence ceilings come first, a newer owner disable in enabled.json wins, and a Repair review never auto-enables; the model chooses toggle_skill. There is no permission ledger and no HTTP impersonation. skill_exec returns the revision captured before its script launch, and extension tool receipts carry the descriptor's content_hash only after physical dispatch; neither is review PASS or a semantic test verdict. Marketplace update, adopt rollback (install.PayloadRollbackSnapshot) and the publication-record owner (marketplace/provenance.py): §13.
MCP and browser-facing external tools
mcp_client.py owns HTTP/SSE and local stdio discovery/calls (gateway/mcp.py; names mcp_<server>__<tool>). HTTP/SSE validate URLs, legacy auth_header/auth_token and literal headers (mcp_headers.py). Shared secret_masking.py masks URL userinfo and tokens; nested secrets never migrate silently. ***set*** keeps a map value only for its saved canonical server and header name (any case); never a literal. Untouched legacy rows retain their storage/mask. Transport-owned headers may override literals (witnesses: tests/test_mcp_headers_loopback.py); credential-bearing cross-origin requests, HTTP→HTTPS too, stop before sending (MCP_REDIRECT_REFUSED). SDK transport/session logs redact secrets, not header values. mcp_import.py previews mcpServers/servers into a draft without I/O; explicit headers replaces the whole list, legacy pair included.
Stdio passes an executable command and exact string-list args without a shell. Optional cwd, literal env and env_from_settings (environment name → saved key) resolve identically for discovery/calls. Unknown fields remain with a not-applied warning; invalid known fields yield MCP_CONFIG_ERROR. Discovered tools join the initial capability envelope beside enabled/granted extensions; list_available_tools discloses discovery failures. MCPManager.resolve_tool_name precedes paid Safety: unlisted, disabled or (outside Cyber) allowlisted-out tools return UNKNOWN_TOOL/MCP_UNAVAILABLE/ACCESS_BLOCKED without Safety, transport or refresh. Hits recheck revocation before Safety. Descriptions/results stay untrusted; registry, resource, safety, timeout and result policies still apply. web=false alone disables neither MCP nor extensions; network=false and tool disables bind discovery and dispatch.
Thread-sticky Playwright/greenlet sessions bind their generation before Safety via browser_call_scope; only its replacements advance it. Timeout retires it; its owning thread closes it after settlement, and late calls cannot adopt/close newer sessions. Retirement overflow refuses BROWSER_BACKLOG_RETIRED_SESSIONS; synchronous hangs need the outer timeout (process isolation remains future work). The iframe.contentWindow stealth evasion is disabled: it broke srcdoc widgets. Page/screenshot/evaluate successes disclose actual engine/version/stealth beside clean producer_text, not anti-bot efficacy. Chromium is default; WebKit/device descriptors target Safari/iOS risks, not a universal matrix.
browser_policy.py admits owner-control from actual HTTP requests and three-valued service identity, not JavaScript text, per-request LLMs or a second policy engine. Cyber root/acting requests retain control/target reach; explicit readonly contracts still bind. Live state/server_port.bindings.json proves our endpoints; expectations (state/server_port, state/server_process.json, Host Service config, local-model custody) with unverified processes refuse as unknown, not foreign (server_process.runtime_service_identity). Other ports are ordinary; unclassifiable restricted DNS targets refuse BROWSER_POLICY_UNAVAILABLE before navigation. Redirect callbacks see only the first URL, so tools/browser.py rechecks redirected_from with that predicate before returning content. An allowed→blocked→allowed chain withholds content/actions, but the blocked request has already left: no pre-request or DNS-rebinding guarantee. Cookies, POSTs, service workers and native redirects remain unchanged; no proxy, CDP fork, pre-probe or refetch.
Budget tracking
usage_accounting.py owns reserved → dispatched → settled | unresolved, or proven unsent release. After dispatch, release needs typed engine proof of no complete inference request. Retries get new ids; unsent preparation keeps reservation, claim, consumer and paid stamp. Publication gaps and rolled-back StoreBusy(reason=contention) wait outside money/root/Q locks, then revalidate. Corruption, permission/resource failures and unknown handoffs never count as contention. queue_observation.dispatch_probe measures its read; _usage_wait.py charges that and publication sleeps, never nested storage waits. Sync/async never resend; cancellation/deadlines bind without a model-wait owner. Tree/post-work cost is counted once; opaque spend stays unknown. Abandoned sends retain unknown nonfinal cost and failure; exact late receipts may refine them. Prices/releases are final. OpenRouter reconciliation is explicit, never send/startup/maintenance (Usage store).
cost_projection.py owns amounts/openness: accounted_upper_bound_usd = settled+reserved+unresolved; COST_OPENNESS_FIELDS accompanies it. cost_presentation binds one scope (§11.1): reconstruct_task_cost owns own-cost; root terminal/heartbeat/checkpoint/synthesis use root-tree, never own zero for an unknown subtree. Only prices or retained bounds evidence zero; empty/unpriced rows do not. The post-task facts row reads a frozen ledger snapshot; the terminal checkpoint owns final cost. Failed reads stay unavailable/null. terminal_cost_reconciliation uses receipts then engine HTTP, retaining late-receipt rights. root_phase_checkpoint.accounting keeps cumulative observations/null on failure, not invoices. unknown_unmetered is no third accounting status. Threshold resource_facts carries tool counts, measured durations, ledger buckets and shared headroom equally to prompt/event; no argv/output/sleep classifier chooses behavior. swarm_rollup.py stores fan-out counts/gaps and a root-row cursor: finalization reads the suffix, legacy rows replay once. swarm_efficiency infers no waves or child-wait time.
Planning threshold (task_pacing.py). One unreserved CostCeiling (disabled, active, exhausted_soft_land, unknown) supplies loop checks and in_task_cost_ceiling. Ordinary tasks have no_default_cost_stop; explicit cost_hard_stop_pct selects the lesser of a global-remainder share and root-cap margin. A producer allowance, such as a wake's remainder, stops at its actual value. Descendants inherit the root's authority; cold restores re-read it and retain an unreadable policy as legacy_policy_unverified, never widen it. Monetary admission is separate.
loop_budget._check_budget_limits runs after unfinished spending rounds, with or without tools, but never adds a paid final after READY. Eligible tasks pause. Other actors use a priced terminal rail only when an explicit profile permits and money admission fits (budget_wrapup_unaffordable otherwise); producer or unverified limits end with an unpaid host notice. Unknown price fails open, unknown spend is not zero, and an affordability probe reserves nothing. _usage_cache_splits.py reuses settled exact-route cache observations for estimates. task_pacing.main_loop_wire_options owns the complete outgoing shape; pre-send identity drift refuses forced_candidate_drift, with one ledger-priced unpredicated terminal retry so the answer is not lost.
Exact budget pause and Resume
budget_pause.py parks pooled/direct work at one id, no paid final: fence → settle producers → save owner_wait.continuation_state → events_budget.install_exact_budget_pause. Money fences trees; unreadable billing/control authority parks one member (reason=authority, no auto-wake). Missing owner/stable save failure: exact_pause_unavailable. Positive seed-lock or rolled-back store contention retries the same seed/prepared source under Stop/Panic/deadline/cancel; ambiguous external publication holds. Money pauses need verified delegated stops; unknown coverage admits no competing writer.
restart_retention.conserve_unreadable_pending keeps exact/native work and Project holds on live/boot read gaps. Resume rechecks native authority, clears only read holds, grants no money. After death/idle/restart, worker_health, workers.kill_workers and queue_snapshot._park_pausing_running_rows re-park canonical saves or keep _budget_pause_hold. Boot completes a sourceless seed from the dead attempt's saved working checkpoint; without saved state, idle seeds retry and owner seeds keep unsaved_pause_intent. Stop forbids re-holding (§9).
queue_transitions/budget_resume: fresh global/root money, Stop/Panic/restart, time and ancestry. Stale/unreadable money grants nothing; money loss/restart revokes. Single-use generation-bound grants keep clocks/spend/rounds/review wallets. Dispatch holds unknown retry authority, revokes only proven stale selections.
events_budget separates lending from selection. root_resume_basis binds actor/grant/owner fence, not time; unbound owner choices borrow no grant under the same root latch. No-fence Resume supersedes bound choices and transactionally rebinds unbound carriers without reissuing exact grants. Warm grants serve current direct/pooled actors, not history; ambiguous legacy grants need reselection. continue_consumed_resume_selection keeps root own/upstream bindings without durable role reads; members retire superseded selections, never unselected holds. Root Resume checks writers; no fan-out. Dispatch holds unknowns and rejects supersession; owner_pause.consumed_member_resume repairs missed selection. resume_paused_loop saves before consumption, preserves unanswered calls and refuses spent/revoked/foreign grants. Failure holds. Only explicit graceful profiles permit a fitting final reservation; hard exhaustion needs an owner increase. OS handles do not return.
The model's own sleep
await_messages defaults to bounded in-slot waits; the model chooses warm/cold, senders, task/run terminals, own-service exits (warm only) and time. With no selectors, mail wakes; owner input and typed descendant escalations bypass filters. New questions from any ordinary own run wake too, never reviewer/foreign custody. Canonical check → install → recheck prevents lost wakes. A failed explicit source cannot hide another ready source/time; otherwise it raises. Pollers and implicit open-run question reads never wait on store contention; arming does. Refresh failure keeps a known reason. Task/engine terminal, collection, money and success differ. Services pin one start: exit reports its known code; loss/unreadability wakes as unknown. Cold retains no local services.
Warm sleep keeps stack, actor and lane via owner_wait, lending pooled capacity. Cold saves source/attempt/clocks. continue_in_background(reason) parks the same id after the completed batch, before unregister; admitted profile/ceilings stay. Services, delegated runs, running children and retained/unreadable custody refuse. Browser/REPL loss is disclosed; owner questions stay warm. Capacity/leases/holds govern readiness. Ordinary cold sleep may transfer exact runs via sleep_custody.py after dispatch closes and host acceptance commits; authorship and cross-carrier discovery stay.
A receipt binds sleep/pause identity/generation, attempt, source, runs and workspace; runtime identity is provenance. Restart rebinds before orphan recovery, preserving stop holds and external-run fate. Unconfirmed acceptance proves no host absence: awake return needs exact withdrawal of the unaccepted request and reopened fence. Acceptance wins its race; unknown withdrawal stays interruptibly held. Requests/readiness grant no release.
Warm, cold and native-handoff returns name their wake. Normal returns and ready tools expose exact question refs, concurrent questions included; control returns skip fresh question reads. Only delivered source notices or complete tool views update per-run exposure, also carried into restart-retained sleep; cold disclosure retries roll it back. No answer is inferred; absent legacy exposure may repeat a question. supervisor/sleep_wake.py records readiness off Q without HTTP. grant_exact_sleep_resume returns the SAME actor over live or terminal-but-unsettled accepted work; foreign/unbound custody, owner/money/deadline/capacity holds and single-use bindings still apply. No monetary Resume, Continue or new root is granted.
Warm and lane-retaining cold refuse selected queued roots needing their lane. Resume saves cognition before consuming grants, preserving model, effort, attempt, spend and execution time. Sleep is excluded once through consumption; calendar deadlines stand. Manual Restart/Panic hold sleep for Resume; else cold sleep wakes when ready unless held. Body custody grants neither stopped-work resume nor external-exit proof. Clock recovery matches task/attempt/grant/source, not nested root metadata, and grants no execution.
Owner Pause of a whole tree
pause_task shares POST /api/tasks/{id}/pause and install_fence; resume_task shares Resume grants. Mind records name actor="mind"/actor_task_id; self-pause refuses, Panic release stays owner-only. Live roots/current reciprocal retries qualify; Stop/cancel veto. Logical-lock grant reads let fresh Pause supersede Resume; repeats coalesce. Persist before ACK/latch; Q contention returns latch_pending, write failure refuses. Unknown identity grants no member authority. Started critics park warm, others exact. stop_task_owned includes accepted cold holders; requested/unknown proves no exit. Resume keeps history and checks both Stop ids, source/money/deadline/custody. Preparers recheck fences; crossing Resume waits, busy grants no launch.
Pure budget_pause.enter_owner_pause reads use owner_pause.wait_member_fence: only StoreBusy contention with rollback_confirmed not false waits on the same stack. Reads check ending controls off Q/launch/money locks; no effect repeats. The SPA renders control_store_wait by episode/phase as waiting/ended, never Paused.
run_tool_handler admits under root Stop/Pause/deadlines, then runs on the same worker off admission; queueing only prepares. Sticky tickets retain affinity; nested sends/skill starts take fresh gates. A phase mutex orders close/start without DB waits; refusals retain invocation entry/cause. _control_projection caches strict reads by current signature, decoding no unchanged body. Unknown refuses; unsent contention waits off Q/root/money locks with the same reservation/consumer, never replaying the handler.
budget_pause binds frozen Future root/task/attempt/invocation, caller pin and real holds; callbacks alone hold nothing. Host errors settle before completion; joins need no eager SQL claim. tool_custody.py retains escape/effect custody; return settles no independent duty. Exact idempotent settlement retries only contention in the store budget, off launch locks; never body replay or custody loss. Closed contexts refuse starts but publish old duties. MCP init failure discharges only method-unsent with clean transport/session join; live/possible sends stay unknown. Unbound fallback/legacy remain. Failed publication joins body/holds off locks/budgets before release. Direct Stop never kills threads; pooled termination/Panic remain independent.
Started reviewers finish (review_pause.py): review_episode arms only at first physical handoff under Pause's lock, permitting that attempt's later rounds. The paused author leaves PENDING in_flight, or unsent pending_dispatch latched not to send; live_detached_operations keeps it warm until settlement. New panels refuse at $0 as NOT_DISPATCHED, never PASS. finishing_reviews names critics; Resume collects unchanged work at $0 without waiting. Process stop converts warm to exact cold pause. Unconfirmed writers keep pausing; Resume binds custody/fence/member selections. Related schedule Restore uses recorded control identity, never fan-out or adoption.
Pause interrupts sync/async author waits (_usage_wait.receiver_abandonable): the sender settles late with unknown money until its receipt; the abandoned answer and tools are never adopted, and Resume names the attempts.
Owner Continue after a technical interruption
Continue admits one successor root in the predecessor's room/folder; helpers stay paused. owner_continue.py owns eligibility/source/CAS; supervisor/continuation_admission.py admits. continue_task uses that CAS with task/tool-call nonce and mind attribution. Recorded interruptions qualify, including completed rails; live/non-root tasks, unknown causes, owner Stop/Panic, author finish and hard deadline/money refuse.
A nonce claims its fully compared predecessor binding before effects. Replay returns it or continuation_identity_conflict; a new nonce returns already_continued. Original/later owner words govern every hop; predecessor output is an agent note, mail peer context. Missing owner sources refuse owner_source_missing. The successor's first Runtime input carries the bounded predecessor envelope, so the actor-free work order makes rereading optional; empty predecessors refuse authority_source_unavailable; checkout lines are dated observations. Snapshots retain deadline_at, billing group, explicit root reasoning_effort and stored context_requires_self_body_docs.
conflicting_writers holds continuation_writer_unsettled for open/paused late work, dispatchable children, delegated runs, model/tool invocations, services/processes, merge/control receipts and unreadable custody. Continue and selection of its held successor use CONTINUE_PURPOSE, excluding independent_review runs and reviewer-slot model attempts. Actual paused-task Resume, Pause, money and sleep keep the full census. Blockers name observed facts; only running work earns wait-or-stop. No diagnostic successor, second writer or timed release. tree_member_results reads the store's typed facts (task_store.task_facts) then strict authority; missing membership holds. retired_tool_invocations retain unknown effects after kill/cancel/crash without replay and keep late monetary receipt rights.
Continue/Resume/selection retires proven ENDED local owners (local_custody_repair.py): local_custody_witnesses or platform-qualified absence of recorded pid/birth (its docstring). Denied/failed lookups hold; passive reads write nothing (invariant 31: never ps lstart).
release_settled_continuations and manual Resume observe custody/money outside the queue lock, revalidate the exact candidate/fences/grant under it. Only proven unsent or paused_before_dispatch work is selectable; unknown stays held, newer Restart wins. Paid reviews keep their own waits/deadlines beyond the author (Pause: §6 Owner Pause).
main_context_authority follows named predecessors for selected accounts/decision lists and verified source readers: history, no current plan/finish authority. Its frozen Runtime prefix cannot be reauthored by current-task review_notes. A readable predecessor's unreadable plan source becomes plan_review_source_gap; the successor still starts.
Saved working state and application stops
working_checkpoint.py keeps one rolling state per attempt under source_handles/working/, written by its loop through owner_wait.continuation_state (atomic, no fsync) at its docstring's boundaries; an unwritable pre_effect save holds the batch, interruptible by Stop, Panic and deadline. A live park's newer source wins. Content mail is ACKed only once a saved state incorporates it (defer_content_ack).
Recovery freezes bytes into immutable _working_recovery sources; loading retires the mutable file. Invariant 31 binds replay; delegated runs remain facts and saved candidates buy no generation. Retries (worker_health same-ID crashes; task_reaper same/new-ID idle retries) keep eligibility, count and cadence. Idle retries drop spent grants/selections; dispatch revalidates surviving selections. New IDs borrow no acceptance/delivery authority; source reads follow retry lineage, own store first, verifying bytes without copying history, produced acceptance material excepted (PERSISTENCE).
UI Restart, planned restart and managed update name returns in one transaction (restart_retention.prepare_restart_returns); acknowledged (§9), next boot returns active roots, children, direct turns and the runnable queue once; unacknowledged or at other doors it holds saved_work_hold for Resume (invariant 31; snapshot age: §5).
During updates, retained_for_boot exempts stopped RUNNING from timeouts, not death checks. recover_aborted_update reuses pause parking and saved-work recovery at abort/release doors for captured attempts and eligibility after confirmed teardown. PENDING persists before writers reopen, releasing dead project leases; failed handoffs stay held. Pool startup alone grants no return.
Monetary authority and projections
Live global limit. One agent resolver reads saved settings, reparsed on change; a failure falls back to the environment without caching the failure. Workers refresh the environment at task start, and live file reads keep reservation/wallet TOTAL_BUDGET current; planning thresholds stay separate. Absent means the shipped default; non-positive means unbounded, silencing the loop's global axis. A run cap set by a launcher before settings load (OUROBOROS_REVIEW_RUN_CAP_USD, the isolated contributor review only) replaces the saved budget for that process tree, whose ledger starts empty; an unreadable cap is a zero allowance.
pricing.py uses bounded best-effort exact normalized-route catalog lookup, never manual tables, prefix/fallback prices or admission allowlists. Every limit refuses once known (settled) spend reaches it, at reserve and again at dispatch; holds and unresolved bounds are exposure, never spending, so concurrent or late charges can overshoot. Unknown price: reserve None, settle the reported cost or a later exact price, otherwise None/non-final. usage_admission.review_wave_admission admits a skill, plan, task or commit wave while known spend is below every global/root/group limit; the shared estimator's wave total is disclosure, and a managed update only records it (managed_update_wave_estimate); unpayable slots bypass without substitution, and unknown prices stay disclosed without disabling priced siblings.
Whole-work billing group. usage_admission.py separates task/root/parent ids from billing_group_id/billing_group_limit_usd. One store transaction checks global/root/group for successors and original-root late work too. Continue uses initial billing_group, else earliest live ledger authority, else configured cap (legacy_default). Review-wave binding_axis=group, pacing and strict Resume share it; only the group owner amends its cap. task_money_snapshot keeps root/group axes over shared spend. Unestablished authority refuses typed, never as money or a stand-in group/zero; late overruns bar admission without a bill guarantee; standalone UI/marketplace contexts declare a non-task role. Reservations retain applied global limit/unbounded, source and revision through transitions.
For roots, GET /api/tasks/{id} derives cost_breakdown from the store (own/child/unattributed/delegated costs, subscription sessions, unknowns, finality, authority); it is never persisted and never a third sum, and an unreadable or unattributable ledger omits it, never asserting zero. Review emits one llm_usage per physical send with wave/slot attribution (review_records.resolve_review_wave); skill_review_usage.py projects (review_skill, review_wave_id) without another ledger; delegated rows report their own route provider and resolved model, never inferred values. state.json, task results, llm_usage, /api/state and /api/cost-breakdown are compatibility projections.