# 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

```text
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

```toml
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

- `mcp` roles execute in isolated persistent app-server workers with mechanical admission, live control, transport recovery, scope, contract, goal/turn lifecycle, partial-evidence, and telemetry controls.
- `native` roles 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.
- `hybrid` profiles use both. With `native_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:

```toml
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:

```toml
[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 = true` and 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:

```bash
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:

```text
$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

```toml
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

```bash
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.
