23 KiB
Profile format: MMO generation 8
A profile is a static, non-executable composition pack. It declares roles, exact route-qualified model bindings, delegation/action graphs, goal/turn lifecycle, permissions, trust, resources, contracts, Tool MCP grants, and smoke tasks. The runtime supplies Unix app-server hosting, isolated writer worktrees, lineage, admission, root/native/MCP control, result disposition, integration, pause/continue/detach/stop/cancel lifecycle, gateways, and durable history/telemetry.
Only MMO schema 8 is valid. Profiles, smoke files, catalog overlays, and evaluation definitions use that same active generation. Earlier packs are not migrated, rewritten, normalized, or read through a compatibility layer. A profile's version must exactly equal the package version; it does not evolve independently during active development.
Pack layout
profile-id/
├── profile.toml
├── README.md optional
├── LICENSE optional
├── catalog.toml optional generation-8 route/model fragment
├── smoke.toml optional generation-8 live tasks
├── agents/*.md optional role instructions
└── contracts/*.json optional result contracts
Only those top-level members are allowed. Packs reject executables, scripts, symlinks, special files, escaping paths, unsupported suffixes, and missing explicitly named files. Unknown fields and wrong TOML scalar/container types fail; booleans are not accepted as integer schema versions.
Minimal profile
schema_version = 8
id = "review-pair"
version = "8.0.0"
display_name = "Review Pair"
description = "One active engineer and one fresh reviewer."
tags = ["review"]
maturity = "lab"
root = "lead"
smoke = "smoke.toml"
[agents.lead]
kind = "root"
description = "Critical-path engineer and sole canonical writer"
model = "codex_chatgpt_builtin__gpt_5_6_terra"
reasoning = "high"
plan_reasoning = "high"
permissions = "workspace-write"
can_spawn = ["reviewer"]
execution_mode = "goal"
goal_token_budget = 600000
max_goal_token_budget = 1000000
stall_warning_seconds = 3600
finalization_grace_seconds = 1800
max_active = 1
trust = "high"
verification = "risk_based"
requires_modalities = ["text"]
instructions = "agents/lead.md"
[agents.reviewer]
description = "Fresh read-only correctness reviewer"
model = "opencode_zen_anthropic_messages__claude_sonnet_5"
reasoning = "high"
permissions = "read-only"
backends = ["mcp"]
can_spawn = []
execution_mode = "turn"
stall_warning_seconds = 1800
finalization_grace_seconds = 900
max_active = 1
allowed_task_kinds = ["review", "verification"]
trust = "adversarial_reviewer"
verification = "root_adjudication"
contract_enforcement = "strict"
output_contract = "contracts/review.json"
instructions = "agents/reviewer.md"
[agents.lead.controls.reviewer]
actions = ["inspect", "trace", "steer", "interrupt", "pause", "continue", "detach", "stop", "finalize", "compact", "respond", "set_effort", "fork"]
[coordination]
mode = "actor_critic"
orchestration = "mcp"
max_active_agents = 2
max_depth = 1
max_children_per_agent = 1
max_active_writers = 0
reject_ancestor_role = true
wait_policy = "dependency_only"
write_conflict_policy = "reject"
contradiction_policy = "primary_evidence"
result_visibility = "ancestors"
Profile fields
| Field | Required | Meaning |
|---|---|---|
schema_version |
yes | Exactly 8 |
id |
yes | Stable lowercase ID |
version |
yes | Exactly the active package version; included in snapshot identity |
display_name |
yes | Product-facing name |
description |
yes | Practical purpose and composition |
tags |
no | Search/classification labels |
maturity |
yes | featured or lab |
root |
yes | The one agent whose kind = "root" |
catalog |
no | Relative generation-8 fragment; implicit catalog.toml when present |
smoke |
no | Relative generation-8 smoke file; implicit smoke.toml when present |
Coordination
| Field | Default | Contract |
|---|---|---|
mode |
rooted_team |
Descriptive policy label, not a scheduler plugin |
orchestration |
mcp |
mcp, native, or hybrid |
max_active_agents |
5 |
Agent-MCP admission ceiling including the root; also bounds compiler feasibility and defaults the separate native thread cap |
max_depth |
1 |
Root is depth zero |
max_children_per_agent |
4 |
Simultaneous children per caller unless role-overridden |
max_active_writers |
2 |
Concurrent MCP writer jobs; each uses an isolated worktree |
reject_ancestor_role |
true |
Prevent a role already in the lineage from recurring |
wait_policy |
dependency_only |
The only supported policy; historical modes are rejected |
write_conflict_policy |
reject |
Overlapping canonical scopes are rejected |
contradiction_policy |
primary_evidence |
primary_evidence, designated_judge, or root_adjudication |
result_visibility |
ancestors |
ancestors or session |
default_result_chars |
12000 |
Default result retrieval ceiling |
max_result_chars |
30000 |
Hard result retrieval ceiling; full artifacts remain on disk |
native_max_concurrent_threads |
derived | Codex native ceiling, excluding the root slot |
native_interrupt_message |
true |
Codex native completion interruption behavior |
native_nested_delegation |
false |
Explicitly opt into advisory native-to-native nesting |
The compiler rejects declarations that exceed its derived concurrency, writer, resource, and depth ceilings. For every shared resource lock it reserves any root units, expands each reachable role's max_active slots at that role's resource_units weight, and counts the cheapest combination that can fit. No role, including the root, may request more units than its resource capacity. Evaluation ablations reuse this same derivation after pruning their graph. This is an exact active-resource ceiling, not a promise that every task can realize it: delegation edges, per-caller child limits, provider behavior, and task dependencies can lower observed concurrency. Terminal workers release admission capacity, so sequential delegation does not consume a lifetime quota. dependency_only compiles active-root guidance and the evaluator observes waits/activity events, but MMO cannot prove cognitive productivity between events.
Agent fields
| Field | Default | Meaning |
|---|---|---|
kind |
participant |
root or participant |
description |
empty | Capability exposed to callers |
model |
required | Exact route-qualified catalog key |
reasoning |
high |
Must be supported by the model/route; none omits the selector |
plan_reasoning |
unset | Root planning effort, when applicable |
permissions |
read-only |
read-only or workspace-write |
can_spawn |
[] |
Directed child-role allowlist |
controls |
{} |
Per-target tables with an exact actions allowlist for root, native, or MCP runs |
max_active |
1 |
Simultaneous instances of the role across the stable profile ID |
max_children |
coordination default | Simultaneous children for one caller instance |
write_scope_required |
true |
Require canonical scope declarations for MCP writers |
trust |
normal |
low, normal, high, or adversarial_reviewer |
verification |
material_changes |
always, material_changes, risk_based, or root_adjudication |
allowed_task_kinds |
analysis, other |
Exact Agent-MCP admission categories |
min_task_chars / max_task_chars |
12 / 12000 |
Free-form task bounds for normal roles |
execution_mode |
turn |
turn, or durable Codex goal for roots and MCP-only participants; native-capable participants must use turn because native delegation exposes no mechanically owned goal lifecycle |
goal_token_budget |
unset | Required for goal; 10,000–100,000,000 host-observed total tokens |
max_goal_token_budget |
unset | Required for goal; controller extension ceiling, at least the initial budget |
stall_warning_seconds |
1800 |
Silence interval before an operator warning; 60–86,400 seconds and never an interrupt |
finalization_grace_seconds |
900 |
Host boundary for an explicitly requested terminal serialization/repair; 30–3,600 seconds |
allowed_reasoning_efforts |
initial reasoning only |
Exact role-specific allowlist for controller changes; every value must be supported by the bound model |
requires_modalities |
text |
Required model and route input modalities |
requires_output_modalities |
text |
Required model and route output modalities |
requires_tool_images |
false |
Require preservation of image-bearing tool results |
requires_documents |
false |
Require file/document transport |
attachments_allowed |
false |
Permit validated attachments |
network_access |
false |
Permit sandboxed shell networking |
web_search |
disabled |
disabled, cached, indexed, or live |
output_contract |
unset | Relative contracts/*.json member |
contract_enforcement |
warn |
warn or strict; native-only roles cannot claim strict enforcement |
resource_group |
route/model default | Weighted capacity pool |
resource_units |
1 |
Units held while active |
instructions |
unset | Relative agents/*.md member |
approval_policy |
never |
Codex app-server untrusted, on-request, or never; never is autonomous inside the compiled sandbox and denies escalation, while other policies expose approval as controller-answerable pending input |
backends |
profile-derived | mcp, native, or both when compatible |
native_name |
generated | Optional Codex custom-agent name |
tool_mcp_servers |
{} |
Grants into the operator-owned Tool MCP registry |
max_active limits simultaneous executing instances of a role, not how many instances may ever be created during a session. A terminal, cold-paused, or suspended worker releases its role, route, resource, child, and writer admission slots, so an authorized caller may launch later follow-up work. Continuation performs current admission again before restoring the same durable thread. Reattaching a detached session preserves its live leases; continuing a paused or suspended session preserves identity and evidence but reacquires leases. A terminal root session cannot be resumed.
Every session and job records the creating MMO package version, and live runners additionally record their package version plus runtime-file digest. Inspection exposes whether that runner matches the installed artifact. A record from any other schema or package generation is rejected at load time; historical evidence must be kept outside active MMO state rather than adopted or rewritten.
Every root and supervised MCP worker has a persistent Unix app-server host. turn runs have no profile task deadline. Root and MCP-only goal runs use Codex's cumulative token accounting and may be continued with a larger total budget only up to max_goal_token_budget; compilation rejects goal mode on a native-capable participant because Codex native delegation does not expose an independently owned goal lifecycle. stall_warning_seconds emits an operator-visible warning without interruption; silence and provider/model slowness never cause evidence deletion. Models are never instructed to track time or emit clock-based checkpoints. External smoke/evaluation wall limits detach or stop through the normal lifecycle and are not profile execution policy. Native subagents share the root host's app-server history; their strict scope/contract guarantees remain advisory where Codex does not expose an interception hook.
When a strict Agent-MCP role has an output contract and its resolved model declares
structured-output support, MMO projects the shape-compatible portion of that contract into
app-server turn/start.outputSchema. Closed objects and required properties are preserved.
Optional properties are omitted from the transport projection because Codex strict schemas require
every advertised property; this avoids forcing a value where the original contract permits
omission. Validation-only keywords unsupported by Codex are removed only from the transport
projection. The complete original contract remains in the task and is always parsed, validated,
and mechanically correlated after generation. If the first result is malformed, the same
persisted agent thread receives one tools-discouraged shape-only repair turn. There is no separate
JSON-fixer role, and a repair may not manufacture missing evidence.
Backend boundary
mcproles execute in isolated persistent app-server workers with mechanical admission, live control, transport recovery, scope, contract, goal/turn lifecycle, partial-evidence, and telemetry controls.nativeroles use Codex custom-agent machinery. Their model/instructions can be generated, but scope leasing, strict contract validation, and complete spawn telemetry are not externally intercepted.hybridprofiles use both. Withnative_nested_delegation = false, any child reachable from a native participant must have an MCP path.
All featured bundled native roles are read-only. A native-only role with contract_enforcement = "strict" is rejected.
Control graph
controls is separate from ancestry and can_spawn. Each [agents.<caller>.controls.<target>] table contains only actions = [...]. The target may be the root, a native run, or an MCP run; the runtime resolves an opaque agent_run_ref inside the caller's one active session/run and checks the target role plus the requested action. Low-trust roles cannot control anything. Each mutating command carries the current control_revision returned by inspection; a stale revision fails before delivery.
The available actions are inspect, filtered paginated trace, active-turn steer, interrupt, cold goal pause, same-thread continue (optionally extending a goal within its token ceiling), client detach, full stop, evidence-only finalize, durable-thread compaction, response to pending user input/MCP elicitation/approval, reasoning-effort change within allowed_reasoning_efforts, and persisted-thread fork. A supervised MCP pause persists partial evidence and retires its host; native pause is logical because native threads share a root host. Mutating controls are serialized per target across compare-and-swap revision assignment and delivery. If delivery began but the reply was lost, durable status is delivery_unknown; callers inspect before retrying rather than treating the request as failed. Control authority permits reading and stopping the target, but it does not itself grant successful-result accept/reject or patch integration; those remain lineage/result-lifecycle authorities.
Low-trust roles and literal_task
trust = "low" requires all of the following mechanically:
permissions = "read-only"
backends = ["mcp"]
can_spawn = []
controls = {}
max_active = 1
verification = "always"
contract_enforcement = "strict"
network_access = false
web_search = "disabled"
attachments_allowed = false
resource_units = 1
It also requires a strict output contract, a single-slot resource group, a brief ceiling of 2,500 characters, no control authority, and task kinds drawn only from locate, references, extract, and summarize_supplied.
A caller cannot send low-trust free-form prose. It must submit the typed literal_task object advertised by Agent MCP. The runtime validates paths/ranges, reads or hashes the requested input, and synthesizes a non-interpretive prompt. The weak role may return literal evidence; it may not architecture, debug ambiguously, write, delegate, or adjudicate.
Tool MCP grants
Tool MCP is separate from the Agent-MCP backend:
[agents.researcher.tool_mcp_servers.firecrawl]
required = true
enabled_tools = ["search", "fetch"]
The server ID must already exist under ~/.config/codex-mmo/tool-mcp.d/*.toml. A grant can only narrow the operator’s finite allowlist. It cannot define or change a command, URL, credential mapping, timeout, transport, or approval policy. mmo_mesh is reserved.
Model and route validation
For every role the compiler checks:
- exact model key and route namespace;
agent_compatible = trueand tool calling;- reasoning selector support;
- model input/output modality plus complete route transport;
- tool-image/document preservation when required;
- executable driver rather than catalog-only service;
- resource group and requested backend;
- trust/backend/contract consistency.
Rebinding reruns the same checks and changes snapshot identity:
codex-mmo run \
--profile adaptive-engineering \
--bind implementation_specialist=opencode_go_openai_chat__deepseek_v4_pro
No unqualified model ID, old provider key, or alias is accepted.
Output contracts
Contracts use a deliberately small, offline JSON Schema subset:
$schema, $id, title, description
type, properties, required, additionalProperties, items
enum, const
minLength, maxLength, pattern, format
minimum, maximum
minItems, maxItems, uniqueItems
oneOf, anyOf, allOf, not, if, then, else
Supported string formats are absolute RFC 3986 uri, RFC 3339 date, and timezone-bearing RFC 3339 date-time. Leap seconds and lowercase t/z are accepted where RFC 3339 permits them; malformed percent encodings and URI references are rejected. Unsupported keywords fail pack validation. No remote references or vocabularies are loaded.
Strict enforcement fails the job when JSON extraction, schema validation, or mechanical correlation fails. Objects containing command plus exit_code must correlate to a parsed captured command event with the same exit code. Objects containing relative_path plus sha256 must name a regular non-symlink file inside the delegated tree whose bytes match the hash. Literal evidence is also correlated to the runtime-generated operation, path/range, and input hash.
These checks establish shape and evidence identity, not semantic correctness. A valid security verdict or architectural claim still requires independent evidence and root adjudication.
Result and patch lifecycle
An Agent-MCP result begins unread. agent_result makes it read. It returns a complete strict JSON value when that value fits the requested page, otherwise contiguous text identified by cursor, total_chars, and next_cursor; callers must follow next_cursor until null. agents_wait returns compact lifecycle state, not a result transport. Callers pass the exact observed progress_revision map for every requested job as after_revision to wake on the first durable change and opt into bounded terminal previews only when useful. A truncated, valid agent_trace record carries its exact raw-line record_cursor; agent_trace_record returns the complete private-reasoning-filtered JSON text in contiguous checksummed pages. Malformed records remain bounded because their raw content cannot be structurally filtered. The authorized caller must then use agent_result_accept or agent_result_reject with a reason. Accepted isolated-writer output may be passed to agent_patch_integrate; integration verifies patch identity, canonical scope, and lease before applying it. States are monotonic and audited; rejection cannot be reversed and reading never applies a patch.
A controller/transport failure yields suspended plus a bounded partial result, authoritative trace/history, and patch; an authorized controller may continue the exact thread. stopped, failed, and cancelled are terminal evidence states and cannot be accepted as successful results. Partial evidence is intentionally labeled non-final and never satisfies a strict output contract.
Writable workers execute in isolated Git worktrees. Out-of-scope changes, unsafe artifacts, or patch-boundary failures taint the session and fail the job rather than mutating the canonical checkout.
Smoke files
schema_version = 8
[[tasks]]
agent = "reviewer"
backend = "mcp"
task_kind = "review"
mode = "read-only"
wall_timeout_seconds = 300
required_mcp_tools = ["repository.search"]
task = "Inspect the repository and return directly observed evidence."
Optional write_scope, attachments, and wait_seconds fields use runtime boundaries. wall_timeout_seconds belongs only to the smoke harness: a root first detaches with partial evidence and the smoke runner then fully stops that test session; an unfinished worker is cancelled at the harness boundary, retaining its partial evidence. Neither boundary changes the role's goal token budget or warning-only stall policy. For a goal-mode root, the harness appends an explicit update_goal(status="complete") lifecycle requirement after all task evidence is ready; merely emitting a final message would leave Codex's goal continuation active. A low-trust smoke task uses literal_task = { ... } instead of task/task_kind. Root success requires a successful root turn; MCP success requires a completed job; native success requires a native-role behavioral marker. Smoke tests consume live provider access and are distinct from offline tests.
required_mcp_tools is an optional list of server.tool names. A name may identify a Tool MCP grant or a runtime-owned mmo_mesh tool mechanically available to that task's role. A task passes only when every named tool has a successful direct MCP call in that task's Codex event stream. Contract-valid output, prose claiming that a tool ran, resource discovery, and failed tool calls do not satisfy this assertion.
Installation identity
Installation accepts only the active package/profile version. Reinstalling byte-identical content is an idempotent no-op. Different current-generation content requires --replace; it is staged, validated, and atomically swapped. There is no upgrade, downgrade, or migration comparison between profile versions.
Compilation
codex-mmo profile install ./review-pair
codex-mmo profile validate review-pair
codex-mmo profile compile review-pair
codex-mmo profile use review-pair
Compilation resolves the generation-8 catalog, route availability contract, Tool MCP grants, model bindings, spawn/action-specific control graph, goal/turn lifecycle, resources, instructions, contracts, native files, generated Codex homes, and Switchyard routes into a content-addressed immutable snapshot. It also derives one exact AGENTS.md per role and, whenever any role can spawn or control, a profile-wide mmo-profile-orchestration/SKILL.md that documents the complete admitted lifecycle. Profile packs do not carry handwritten copies of these generated files. Their exact bytes participate in snapshot identity. A spawn- or control-capable role's generated home materializes the skill at Codex's standard skills/mmo-profile-orchestration/SKILL.md path and enables that exact file through skills.config; true leaf layers explicitly disable the inherited path. Credential values never become snapshot content. Current-generation sessions continue using their exact snapshot when profile files are replaced.