Skip to content

Repository files navigation

The incident coordination guide describes continuous ownership, full-path rehearsal, evidence-based replanning and quiet waits. The compact orchestrator loads specialized procedures only when needed. Live qualification distinguishes public tool discovery from project actions and correlates publication IDs independently of nested governance references. Cortex lifecycle policy findings are advisory: hooks do not veto host tool calls.

Cortex logo

Cortex

Reliable multi-agent coordination for complex software engineering work in Codex.

Cortex turns a large task into durable, evidence-backed coordination. It preserves tasks, advisory governance, one Markdown pipeline per task, and reports in local storage. The coordinator owns delegation, evidence assessment, user steering, and completion.

Cortex 1.15.9 Python 3.11+ Codex Desktop and CLI Markdown files and SQLite metadata

Install with Codex β€” recommended

Important

⚑ Copy the prompt below into a new Codex task. It tells Codex to read this repository's current installation guide, install Cortex from the GitHub Marketplace main branch, install and configure Codebase Memory MCP, configure Codex, and verify the result.

Install and configure the Cortex plugin for this Codex environment.

First, read the complete installation instructions and requirements in this
repository's README. Treat it as authoritative:
https://github.com/igovet/codex-cortex-orchestrator/blob/main/README.md

Then complete the setup end to end:

1. Check every prerequisite required by that README (including Codex plugin and
   multi-agent support, Python 3.11+ with tomllib, Git, and Bash). Install every
   missing prerequisite with the supported package manager for this operating
   system. Do not install unnecessary packages or Python dependencies.
2. Install and configure the Codebase Memory MCP server as `codebase_memory`,
   following the README's **Codebase Memory MCP** section and its linked
   official upstream instructions. Install its required dependencies, register
   it with Codex, enable automatic indexing when supported, and verify that
   Codex can use it for this exact project root. Restart Codex if its
   instructions require a restart.
3. For a fresh installation, add the Cortex Marketplace from the main branch
   exactly with:
   codex plugin marketplace add https://github.com/igovet/codex-cortex-orchestrator --ref main --json
   If the `cortex` Marketplace is already registered, refresh it with the
   documented update flow instead of adding a duplicate. Then install the
   plugin (or use the README's documented remove/reinstall update flow) with:
   codex plugin add cortex@cortex --json
4. Preserve existing global $CODEX_HOME/config.toml (normally ~/.codex/config.toml)
   and model preferences while applying the required Cortex provider and
   compaction settings below. Verify native
   subagent support; enable multi_agent_v2 only when needed by the installed host.
   Cortex does not require changing agents.default_subagent_model.
   Keep user approval review enabled; do not enable Ask for me / Approve for me.
   Follow **Automatic provider and compaction paths** after both installation
   and update: start the installed Cortex MCP so it verifies the gateway and
   applies the global provider and compaction configuration automatically.
   Installing the plugin alone is not proof that this initialization ran.
   Inspect the effective global config and verify all of the following:
   - model_provider = "cortex";
   - model_providers.cortex points to the verified loopback listener, with
     wire_api = "responses", requires_openai_auth = true and supports_websockets = true;
   - features.context_management = false;
   - features.remote_compaction_v2 = true.
   Preserve unrelated settings and the generated backup/route journal. If a
   later user override prevents these settings from applying, explain the
   conflict and resolve that choice with the user instead of silently replacing it.
   Do not add proxy environment variables or a CA certificate. Verify a fresh
   model request through the gateway after Codex reloads configuration. If a new
   task or restart is still needed, report that explicitly and preserve active
   work. Do not claim compaction routing is verified without observing an actual
   compaction request and its routed model/effort.
5. Confirm the plugin catalogue includes the 23 `cortex:worker-*` specialist
   skills. Verify complete native skill loading or exact advertised SKILL.md reads;
   catalogue discovery alone is insufficient. Do not read TOML or server internals. See the current
   host compatibility limitation below. Start a fresh task after updating the plugin.
6. Confirm that the installed package exposes exactly the seven documented
   storage tools and includes the documented local lifecycle hooks. Run the relevant
   verification checks and start a new Codex task.

Use only the instructions and commands documented in that README. If an
elevated system permission, an interactive desktop confirmation, or a material
choice is required, explain exactly what is needed and ask me before proceeding.

Cortex is activated only when you explicitly select it. An ordinary complex requestβ€”or merely mentioning orchestrationβ€”does not create a Cortex session.

Table of contents


Installation

1. System requirements

Component Requirement Why it is needed
Codex Desktop or CLI with Plugins and multi-agent support Loads the plugin, skills, MCP server, and advisory agents
Python 3.11+, with the standard-library tomllib module Runs the local Cortex MCP server and validators
Git A current version Fetches and refreshes the GitHub Marketplace source
Bash 3.2+ Runs repository development and local-source synchronization scripts
Operating system macOS or Linux; WSL is recommended on Windows The MCP server launches through python3 and repository tooling uses Bash

Report storage uses the Python standard library. The enabled Model Gateway automatically installs its hash-locked Python dependencies in a private Cortex directory; Python must have pip available. The current gateway wheel set and process verification target Linux CPython 3.11/3.12; macOS gateway qualification is pending. Confirm that the required tools are available:

python3 --version
python3 -c 'import tomllib; print("tomllib: ok")'
git --version
codex --version

Choose a project root

Use a specific existing repository or worktree, for example /workspace/my-service. The host supplies its absolute canonical directory. Each task stores that exact project boundary; do not use a broad system or home directory as the project.

Task documents and the private SQLite metadata index are both project-local: .codex/cortex/<task>/ and .codex/cortex/cortex.sqlite3. The active Codex home's state_5.sqlite locates native source records and validates the thread's canonical project; it is not the Cortex store. Task/report association is checked on every read. Keep the project's SQLite file and task directories together for offline backups. The installed MCP configuration invokes python3 directly, so its launch environment must resolve Python 3.11 or newer.

macOS-specific installation notes

The Plugins workflow is the same on macOS, but the local runtime may require a separate Python 3.11+ installation:

  • macOS does not guarantee a suitable Python 3.11+ runtime.
  • macOS ships /bin/bash 3.2, which the repository helper scripts support.
  • Homebrew uses /opt/homebrew on Apple Silicon and /usr/local on Intel; use brew --prefix instead of hard-coding either location.
  • Apps opened from Finder or the Dock do not necessarily inherit shell startup files such as ~/.zprofile, ~/.zshrc, or ~/.bashrc.

Install the prerequisites with Homebrew:

# Install Apple's command-line tools first if they are not already present.
xcode-select --install

brew install python@3.11 git

Resolve and verify the installed runtimes:

"/bin/bash" --version
"$(brew --prefix python@3.11)/bin/python3.11" --version
"$(brew --prefix python@3.11)/bin/python3.11" -c 'import tomllib; print("tomllib: ok")'

For Codex CLI sessions, make sure Homebrew is initialized before running codex. Homebrew prints the exact shellenv command for the machine:

eval "$(brew shellenv)"
export PATH="$(brew --prefix python@3.11)/bin:$PATH"
python3 --version
codex

For Codex Desktop, ensure its launch environment resolves python3 to the same Python 3.11+ installation. A Desktop app opened from Finder or the Dock may not inherit the shell PATH; configure the application launch environment or start Codex from a shell where python3 --version is correct. Fully quit and reopen Codex afterward, then start a new task.

The packaged MCP server uses the host-resolved python3 -B command. Cortex does not hard-code /usr/bin/python3; -B prevents runtime bytecode from changing the content-addressed package. If CLI and Desktop behave differently, compare their Python versions and launch environments. Bundled lifecycle hooks use the host’s ordinary review and trust flow.

Required Codex configuration

Important

Configure Codex before the first Cortex 1.15.9 orchestration, then start a new task. Cortex requires available native subagents. It does not require Luna or a change to the user's global default subagent model.

On hosts where it is not already enabled, the current V2 route uses:

[features]
multi_agent_v2 = true

Use only settings supported by the installed Codex version. Preserve unrelated configuration. An omitted worker model override inherits the actual host model; intentional overrides use exact available model identities and supported effort. Do not silently switch native interfaces or register personal agent profiles.

For clearer coordinator explanations and full plain-text question/answer context, the recommended top-level Codex setting is:

model_verbosity = "high"

This setting is recommended rather than required. Apply it before starting a new task so the task inherits the configured response style.

You may also approve all tools exposed by the local Cortex MCP server:

[plugins."cortex@cortex".mcp_servers.cortex]
default_tools_approval_mode = "approve"

The MCP setting affects Cortex storage tools only. It does not authorize shell commands, patches, external messages, destructive actions, scope expansion, or tools from other plugins. Keep those decisions routed through Codex or the user's configured approval policy.

Warning

Keep external and destructive approvals with the user

Cortex governance is advisory. It is not an approval system and cannot replace Codex/user authorization for destructive, external, privileged, or materially scope-expanding actions.

Marketplace specialist delivery

All 23 specialist profiles are distributed as cortex:worker-* skills through the standard plugin manifest. Each native worker loads its complete selected skill before project work: use an attached body or read the exact SKILL.md path supplied in the host's available-skills catalogue. Needed declared Markdown references load on demand. An already attached live tool schema can be used directly; Cortex does not require a separate catalogue bootstrap, a particular first-call order, or fixed batching. Generated worker skills use exact generated bytes and a final completion marker, so a successful partial range cannot be mistaken for a complete file. This is normal Codex progressive skill loading, including in the plugin cache; it does not authorize reading agent TOML or server internals.

Marketplace installation needs no personal agent registration, setup hook, custom loader or profile selector. After an update, start a fresh task for the current catalogue. Missing automatic skill injection in an inter-agent message does not prevent loading the advertised skill file. See host compatibility and the completed 12-trial decision.

Generated TOML exports remain available for explicit personal custom-agent use, but Cortex orchestration always uses the packaged worker skills. The optional scripts/cortex_setup.py --install manages only those personal exports and refuses conflicting user files. It is not part of marketplace or dev preparation.

Required post-install verification

Start a new task after installation and confirm that Cortex advertises exactly create_task, set_governance, create_draft, read_draft, write_report, list_reports, and read_report. All seven operations are available to the coordinator and native workers. The package includes local lifecycle hooks for source memory, observation and exact file-integrity checks; they do not approve actions or decide task completion.

Confirm the required native-agent configuration and Python runtime. A small explicitly selected task should create one pipeline, delegate bounded work, read selected reports and save its result. Actual CLI and Desktop observations are distinct from source validation; see release evidence.

2. Install on Codex Desktop

Codex Desktop and Codex CLI use the Plugins Marketplace system. The general user workflow is documented in the official OpenAI plugin documentation.

Add the GitHub Marketplace and install Cortex

Important

Cortex is not published in the public plugin directory. Add this GitHub repository as a Marketplace source before looking for Cortex in Desktop.

  1. Open the Plugins tab in Codex Desktop.

  2. Select Manage in the upper-right corner of the Plugins page.

  3. Open the Marketplace tab under Manage extensions.

  4. Select Add marketplace.

  5. Complete the Add plugin marketplace dialog:

    Field Value
    Source https://github.com/igovet/codex-cortex-orchestrator
    Git ref main
    Sparse paths Leave empty; the Marketplace manifest is at the repository root
  6. Select Add marketplace and wait for confirmation. The source should appear in Manage β†’ Marketplace as cortex.

  7. Return to the Plugins directory, open Personal, and find Cortex. Do not search for it in the public directory.

  8. Open the Cortex details page and select + / Install.

  9. Review the requested permissions and bundled seven-operation MCP server.

  10. Verify the required configuration.

  11. Start a new Codex task. Existing tasks do not load newly installed skills, MCP tools, profiles, or a different multi-agent adapter.

  12. Open Skills, select Cortex Orchestrator, and describe your goal.

Update on Desktop

  1. Open Plugins β†’ Manage β†’ Marketplace.
  2. Find cortex and select Upgrade marketplace. To refresh every configured Git Marketplace, use Upgrade all marketplaces.
  3. Return to Plugins β†’ Installed β†’ Cortex.
  4. Install the available newer Cortex version. If the UI offers only uninstall and install actions, uninstall Cortex and install it again from Personal.
  5. Confirm the seven storage operations and the bundled lifecycle hooks, using normal host trust.
  6. Recheck native subagent availability and the host's actual model/effort support.
  7. Start a new Codex task. An existing task may retain the previous plugin cache and catalog.

3. Install on Codex CLI

Register the GitHub Marketplace first. Cortex is not available in the public plugin directory:

codex plugin marketplace add https://github.com/igovet/codex-cortex-orchestrator --ref main --json

Then start the interactive Codex CLI:

codex

Open the plugin browser:

/plugins

Then:

  1. Switch to the newly added cortex Marketplace tab.
  2. Open Cortex and install it.
  3. If needed, press Space to enable the installed plugin.
  4. Confirm the seven storage operations and the bundled lifecycle hooks, using normal host trust.
  5. Verify the required configuration.
  6. Exit the current CLI session and start codex again.
  7. In the new session, invoke $cortex:orchestrator or open /skills.

For a direct, non-interactive installation after adding the Marketplace, run:

codex plugin add cortex@cortex --json

Update on CLI

Open /plugins, select the cortex Marketplace, and install the newer version. To refresh and reinstall it entirely from the terminal, run:

codex plugin marketplace upgrade cortex --json
codex plugin remove cortex@cortex --json
codex plugin add cortex@cortex --json

After every update, verify the required configuration, exit the current session, and start a new one.

4. Orchestration commands

Cortex exposes one explicit entry point with several routes. On Desktop, select Skills β†’ Cortex Orchestrator or mention the skill in chat. In the CLI, use $cortex:orchestrator or /skills.

Command Purpose Example
$cortex:orchestrator <task> Start ordinary Cortex 1.15.9 coordination $cortex:orchestrator Find the race condition and fix it with tests
$cortex:orchestrator help Show read-only help without changing the project or task storage $cortex:orchestrator help
$cortex:orchestrator harvest Update missing or stale source-backed project knowledge $cortex:orchestrator harvest
$cortex:orchestrator harvest-refresh Re-audit and rebuild project knowledge documentation $cortex:orchestrator harvest-refresh
$cortex:orchestrator clear 7 days Delete this project's tasks and artifacts older than seven days, protecting active tasks $cortex:orchestrator clear 7 days
$cortex:orchestrator normal Leave the active Cortex route $cortex:orchestrator normal

Example tasks:

$cortex:orchestrator Design and implement secure API-key rotation,
including migration evidence, tests, and residual-risk documentation.

$cortex:orchestrator Review the current change, identify regressions,
and synthesize independently verified findings.

$cortex:orchestrator harvest-refresh

Existing repositories: use harvest when needed

Important

Knowledge maintenance is an explicit route, not a lifecycle prerequisite

Run $cortex:orchestrator harvest when an existing repository needs a source-backed knowledge baseline. Cortex 1.15.9 never blocks ordinary coordination because harvest has not run or project documentation is incomplete.

Start the knowledge update with:

$cortex:orchestrator harvest

The resulting baseline uses the established project layout:

docs/project/index.md
docs/project/conventions.md
docs/project/verification.md
docs/project/decisions.md
docs/project/gotchas.md
docs/features/index.md
docs/features/<feature>/index.md

harvest-refresh rebuilds inventory from current source, audits every in-scope page, independently checks completeness and performs a second no-change planning comparison. Harvest preserves manual material outside generated blocks. The coordinator reads necessary user sources and bounded evidence pages; workers own index-driven routing, source discovery, documentation edits and checks. Workers receive mandatory requirements directly and select only useful reports. Missing indexes do not force harvest during an ordinary task.

Documentation impact is assessed after verified tasks

Before accepting an ordinary completed task, the coordinator reviews verified changes for durable project-knowledge or public-documentation impact. Missing inspection is not evidence of no impact. When impact is supported, the coordinator assigns the appropriate documentation owner to load/apply the bundled documentation-sync skill, gives that owner exact documentation ownership, and requires affected knowledge updates plus proportionate verification before completion. The coordinator does not read another role's SKILL.md; after the owner's published documentation report, it uses only Cortex report/public-evidence reads to compare owner-cited documentation hashes and check results before acceptance. Any additional project inspection, file read/hash or command verification is delegated to an appropriate worker and returned in a task-bound report; the coordinator does not rerun project checks itself. When sufficient evidence supports no impact, the coordinator records a concise conclusion without token edits or an extra worker. This advisory review does not activate the explicit-only harvest route. If inspection is partial or inconclusive, it gathers bounded missing evidence or withholds acceptance until synchronization or sufficient no-impact evidence exists. Source, tests and executable configuration outrank prose.

Never put secrets, personal data, private reports or diagnostic logs into public documentation.


Completed assignments can retain their context for explicit bounded follow-ups. Each follow-up publishes a new immutable report. A handoff must identify that latest report; useful links to the same worker's earlier reports are allowed. Coordinators record acceptance in the pipeline and answer the user directly; a worker-authored synthesis artifact is optional, not an extra completion requirement.

Workers send progress, questions, blockers and verification updates only through the host's native parent/subagent channel. They never use codex_app.send_message_to_thread or other app task-messaging tools, including for messages addressed to their coordinator. Completed work returns through the automatic native final handoff; no app-message approval is needed for worker updates.

The coordinator tracks native workers spawned through collaboration.spawn_agent only with collaboration.wait_agent, collaboration.list_agents, collaboration.send_message and collaboration.followup_task. Codex app thread tools such as create_thread, read_thread, wait_threads and send_message_to_thread are reserved for explicit user-owned task management, never for orchestration-worker tracking.

For an active Cortex task, the bundled PreToolUse hook denies both the canonical mcp__codex_app__send_message_to_thread call and its direct alias before dispatch. Tool-event payloads may not establish whether the caller is a worker, so this is a task-wide denial that also applies to a coordinator. The native parent/subagent route remains available for worker communication.

The isolated CLI/Desktop observer also recognizes direct, quoted-bracket and simple static-alias worker calls to send_message_to_thread, including those in known functions.exec wrappers, as forbidden orchestration outcomes and fails its audit. This is bounded static inspection, not exhaustive JavaScript evaluation. A qualification guard based on the host's observed call boundary cannot remove an app connector that the host exposes. The installed Desktop provider is injected dynamically as the codex_app MCP server; the candidate [mcp_servers.codex_app] disabled_tools=["send_message_to_thread"] override fails bootstrap with invalid transport, so the launcher does not claim a per-tool filter or shadow the provider.

Preferred worker route: Codebase Memory MCP

Coordinators read bounded evidence for decisions; specialists own unknown-code discovery. Do not duplicate their investigation. Unavailable or unsuitable graph coverage permits a documented native fallback, never a runtime veto.

A known filename or symbol does not establish its implementation: workers resolve unknown code through Codebase Memory first, including in small repositories. Retained current source and purely non-code text edits do not need redundant graph discovery. The shared protocol names codebase_memory explicitly. Workers discover its needed operations separately from Cortex report tools; a Cortex-only catalogue lookup does not establish whether the graph tools are available. Every delegation starts with the exact assigned worker-skill token and requires a complete worker-attributable skill/assignment receipt before tool discovery or project work; a coordinator read never satisfies that worker route. From the worker's first action, plugin/cache/candidate/agent-registry probes are forbidden. Live work uses one bounded command per wrapper with a complete exit/result receipt. An approved skill read that returns a complete error is failed receipt acquisition, not project work; it never credits the worker, and later Cortex/project actions remain blocked until the exact worker receipt is observable.

Workers use available graph tools before filesystem searches for definitions, callers, dependencies and impact. They match list_projects to the exact workspace, resolve symbols with search_graph, trace relationships with trace_path, and read selected implementations with get_code_snippet. Scoped get_architecture and schema-grounded query_graph serve broader questions; literal/configuration/docs searches can use search_code or ordinary text search directly.

Workers check relevant index coverage, handle pagination and confirm consequential facts in current source. Duplicate project names, stale/partial indexes and empty results are not proof that code is absent. When several indexes share the same root, workers compare health and relevant coverage: a ready index may exclude the assigned subsystem. Missing indexes may be built for the authorized workspace; watched indexes are not rebuilt for every task. A missing or insufficient MCP produces a concrete limitation and scoped source fallback. See knowledge routing.

Warning

Use Codebase Memory MCP for preferred project structural discovery

DeusData/codebase-memory-mcp builds a local graph of functions, classes, calls, routes, and dependencies. Cortex workers can use it for architecture discovery, impact analysis, and end-to-end tracing, especially in large monorepos.

Codebase Memory is a preferred worker route: every native worker uses it when available before structural project-code discovery. If the MCP is missing, denied, timed out, erroneous, unusable, or insufficient, the worker records that bounded limitation and uses exactly one safe assignment-scoped ordinary-repository fallback. There is no silent or chained fallback. The coordinator delegates both structural discovery and documentation-index routing to workers, keeping the main context focused on pipeline state and report previews.

Quick install on macOS/Linux:

curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash

Review the remote installation script before running it. For Windows, manual installation, and package-manager options, see the official Codebase Memory README.

After installation:

  1. Restart Codex so it loads the MCP server.

  2. Ask Codex to index the exact project root, or enable automatic indexing:

    codebase-memory-mcp config set auto_index true
  3. Confirm that the indexed root matches the exact absolute project_root.

Codebase Memory is an evidence source and preferred worker capability, not a Cortex storage capability. Its absence allows one bounded safe fallback; only inability to establish the assigned surface after that fallback is a worker blocker. Reports can preserve that limitation and support an honest final answer.

The live observer records Codebase Memory calls as ordinary worker tooling. A successful or failed external provider call, Git/rg diagnostic, or other non-Cortex command is not an orchestration violation by tool name or exit status. Workers have a separate private-Cortex boundary: they never shell, search or probe .codex/cortex/ task-cache paths. Assignment-relevant immutable reports are selected by exact acknowledged ID and read only through bounded mcp__cortex__read_report pages (at most 4,000 characters, continuing only with the returned cursor). Missing or insufficient evidence is reported as a gap; it is never filled by scanning the private cache. The observer keeps this cache hard stop fail-closed. For a literal rg/grep command, a quoted search pattern or glob containing .codex/cortex/ is a static mention, while a path operand, direct reader, or shell-ambiguous form remains an unauthorized hard stop; unquoted filename globs (*, ?, []) and brace expansion ({}) are ambiguous, while quoted literals remain static. Path-policy findings retain only safe provenance and target classes; only an explicitly classified unauthorized target, Cortex/transport contract breach, or task-impacting failure can enter the orchestration acceptance gate.

The trusted PreToolUse hook provides a deny-only execution guard for this boundary. It rejects worker shell, file, and patch operands that resolve inside the confirmed task-private root before dispatch, including relative paths, cd/variable-expansion forms, and existing symlink routes. The guard emits only a sanitized denial and does not open or log the target. It intentionally leaves bounded mcp__cortex__read_report reads and ordinary workspace, Git, Codebase Memory, and external MCP diagnostics available. This preflight is defense in depth; the observer's fail-closed hard stop remains authoritative for any observed unauthorized event. Only an observed complete attributable PreToolUse PERMISSION_DENIED with the explicit denied_before_dispatch status is a prevented-attempt diagnostic: it neither proves host execution nor becomes accepted evidence. Missing or unknown semantic status fails the audit closed. A dispatched unauthorized target remains acceptance-critical. When a tool event omits agent_id, worker scope is established only from a matching child-thread/parent-session provenance receipt validated against the durable binding. Running worker command receipts retain their effective working directory and command-session ID, allowing a later write_stdin to apply the same guard. Unproven session-scoped events remain compatible with coordinator and system tooling rather than being globally denied.


How orchestration works

Optional context-selected guidance

When relevant, the coordinator may use three advisory cues: map each fresh completion claim to relevant evidence and list unrun checks; separate facts from hypotheses and name one discriminating check before a nontrivial repair; and, before parallel dispatch, declare independence, mutation surface, shared resources, dependencies, and expected output. These cues are optional and do not create mandatory stages, approval gates, fixed report sections, or automatic acceptance.

At a work transition, it may also consider one bounded senior consultation only when both a consequence trigger and an uncertainty trigger apply. Consequences include material architecture/public-tool/storage/security/release/migration or multi-owner decisions, hard-to-reverse external/scope/compatibility choices, contradictory repair-to-acceptance evidence or broad claims, and replanning after repeated failure or surprise. Uncertainty includes material alternatives, fact/hypothesis conflict or an untested critical assumption, no discriminating check/evidence boundary, or a fresh view likely to change the decision. Routine, reversible/deterministic work, ordinary tests, already-decided detail, phase/time/report existence, executor-evidence requests, unchanged packets, consultation chains/sign-off/fixed counts and active incident recovery are excluded. The advice is optional, may run concurrently when safe and never blocks by rule or transfers planning, steering, evidence, acceptance or communication. The compact packet and coordinator record contain only the bounded question, context, selected report/artifact identities, alternatives, facts/hypotheses, attempts, ownership, decision and next check; no copied bodies or private data. Quality and overhead are evaluated against the unchanged baseline.

Select $cortex:orchestrator explicitly. Cortex then retains a task through ordinary follow-ups; normal leaves coordination and source capture without deleting its archive. Help is read-only. Naming the repository or asking a complex question never activates Cortex by itself.

The coordinator preserves the user's selected model, interprets requirements, answers short questions, reads necessary user sources and evidence, delegates the main technical work, and decides acceptance. A worker can investigate, implement, verify and document one bounded result. Additional specialists are useful for specific expertise, independent evidence or parallel work, not mandatory stages. Shared files, browsers, devices, ports and applications have one active owner. A timeout does not release that ownership.

The coordinator may inspect project evidence through read-only file access or a literal bounded read. Project mutations remain owned by the continuous worker. Private Cortex storage still uses the public report interfaces. Reuse the owner's verification evidence rather than repeating it for reassurance.

Markdown pipeline and readiness

A task has one real pipeline.md, with its newest complete edition first. It contains active requirements, cancelled conditions, decisions, assignments, resource owners, unfinished actions and evidence references. Original messages remain separate immutable reports. Source revisions and checked artifact versions make the basis of a report visible. A new message or observed file change signals possible stale evidence; the coordinator decides whether more verification is needed. Bounded independent discovery can precede the first edition. The coordinator records useful durable state before making dependency, shared-resource or acceptance decisions; pipeline publication is not a fixed stage before every delegation.

Pipelines keep three model-owned descriptions separate: implementation_state for changed artifacts and implementation evidence, delivery_state for observed report, Git, CI, deployment, rollout, or production receipts at an exact artifact revision, and acceptance_state for the coordinator's user-boundary judgment. A delivery receipt never implies acceptance, and a Git/CI/deployment/production claim without the matching observed receipt and revision remains unverified. Review or verification reuse has the identity (artifact_revision, acceptance_boundary, check_identity); unchanged work needs new evidence or a concrete rerun reason before repetition.

Report templates also expose optional structured model-authored evidence fields: delivery_state, acceptance_boundary, causal_model_delta, predecessor_rollout, retry_discriminator, and receipt_references. The runtime can retain bounded/null-safe warnings when one is absent and can diagnose an exact duplicate review/verification identity without fresh evidence or a rerun reason. These findings are advisory metadata only: they never route work, require approval, change coordinator acceptance, or change a successful command exit. Scalar advisory values are serialization-safe: booleans are retained, integers are limited to the JSON-safe 53-bit range, finite floats are bounded to 1e308, and arbitrary-magnitude or non-finite numbers are omitted and diagnosed as missing.

When a repeated live attempt is consequential, the coordinator may record an adaptive cross-layer acceptance contract and predecessor-rollout comparison: outcome/boundary, revision, relevant context, safety/rollback posture, observed receipts, and a discriminating check. Material architectural expansion and distinct failures are reconciled through outcome/scope, causal-model, or replan deltas, including bounded failed-canary evidence where useful. These records are guidance, not mandatory stages, approval machines, server state, automatic routing, or acceptance gates.

The coordinator and workers can read the source and report pages needed to recover requirements. A page is limited to 4,000 Unicode characters; the available context is not. Catalogue entries and opening decision briefs support selective retrieval. An unavailable attachment remains a visible gap with its recovery reference when one is known. An unavailable host journal does not close existing report access; receipts describe source-capture completeness.

Native workers and results

Assignments name a specialist skill, expected result, mandatory constraints, ownership, checks and necessary references. They do not paste a long startup protocol. Workers load their complete advertised skill normally and use applicable skills for documents, spreadsheets, research, designs or applications. Verification must establish the user's requested result, not automatically just passing code tests.

Workers reason and communicate only in English from their first response, including progress updates, skill-loading commentary and context recovery. Assignments carry this requirement before the worker loads its skill. Workers publish immutable English reports and return their handoff once through the native final response. The coordinator uses the user's own language for updates, questions and final answers, unless the user explicitly requests another response language. English evidence, forwarded agent messages and recovery summaries do not change that choice; requested product language remains independent. The coordinator owns pipeline editions. Reuse a completed suitable context for a bounded continuation; use a fresh context when independent evidence is warranted. A confirmed terminal failure permits recovery from saved reports, unfinished drafts and actual project state. Missing results are not completion.

The coordinator never emits a terminal final answer while an assigned owner is active or a required report/check remains outstanding. A wait timeout means only that no new evidence arrived, so the same owner receives another bounded native wait. Before acceptance or a final answer, the coordinator reconciles pipeline assignments with native worker state and required evidence; terminal failure or user cancellation must be explicit and recorded. Interim updates must say clearly that work remains active.

When evidence and model-owned state are unchanged, it waits silently. A timeout, pending worker, elapsed time, or unchanged poll alone is never a user-facing update; updates require a new evidence/state delta, genuine blocker, required user decision, or material next-action change.

Storage, receipts and Markdown files

The seven MCP operations remain create_task, set_governance, create_draft, read_draft, write_report, list_reports and read_report. Their advertised schemas contain argument, provenance, binding, change-query and retry contracts. Host thread metadata resolves the task; the model never guesses task identifiers. Each canonical project has its own SQLite store at .codex/cortex/cortex.sqlite3; projects never share a Cortex database. SQLite holds metadata and relationships, while report bodies live under project .codex/cortex/<task>/. Editable drafts live under .cortex/ because Codex protects ordinary writes to project .codex/. Requests for one project serialize through that project's store while unrelated projects use independent stores.

The server streams full UTF-8 drafts, verifies original file identity, atomically publishes files and commits metadata. Exact retries return the accepted receipt. New drafts default to server-generated delivery identities, so a worker's later assignment does not depend on remembering earlier report keys. An uncertain unkeyed creation is recovered through the caller's unfinished-draft catalogue; repeating it creates another draft. Explicit keys retain exact-retry protection. Only the bound coordinator can create a pipeline draft; worker pipeline requests are rejected before allocation, while ordinary worker report drafts remain allowed. Worker report creation still supplies the required template argument explicitly; ordinary worker reports use general, and an empty draft-creation argument object is invalid. The coordinator treats the create_draft Markdown and its exact replaceable_markers list as authoritative: every listed marker is replaced in the same draft before write_report, and document kind matches ownership (pipeline for the coordinator, non-pipeline report for a worker). A draft_guidance_remaining rejection is corrected in place and retried once with the same request key and metadata; it does not create a competing draft or replay an acknowledged publication. This is workflow guidance, not an approval gate. When a coordinator must provide request_key, it uses a literal valid UUID or stable literal key in the tool arguments. Runtime expressions such as crypto.randomUUID() are not used inside wrappers because the host may not expose that JavaScript global before Cortex receives the call. Pipeline recovery and retention stay inside the affected task, so a corrupted neighbour does not block another archive. Validated file identities and page offsets avoid repeated full reads of unchanged reports; changed files are revalidated.

Storage format 11 requires the separate offline 10β†’11 migration and a backup with access stopped. Migration changes metadata only and leaves Markdown bytes intact. A legacy shared v11 store can be split into a fresh project-local store with plugins/cortex/scripts/cortex_split.py; the split also requires stopped access, a new backup, and leaves the source and Markdown unchanged. See storage and migration.

Lifecycle hooks

The bundled hooks call one short python3 handler and share storage/validation services with MCP. Active tasks capture follow-up source messages and compact receipts; inactive conversations are not archived. Resume and compaction receive a bounded recovery reminder through SessionStart, with repeated unchanged reminders suppressed. Subagent binding uses explicit native receipts rather than treating a parent session_id as the child identity. The recovery reminder repeats the project-access boundary. When a host explicitly identifies the coordinator on a command/file event, PreToolUse denies that route before dispatch; events without actor identity remain observable and are rejected by the audit if they show coordinator project access.

UserPromptSubmit can only mark a pending follow-up because that event has no unique native message identifier; publication waits for an authoritative typed receipt. Stop observations are advisory, and the host may not expose the boundary of a reused worker assignment.

On the observed CLI host, Bash hooks receive stdout without an exit code or running session receipt. Cortex therefore keeps those hook outcomes unverified, even when the text resembles JSON or a command wrapper. Native command receipts remain the source of execution status.

Hooks record observations and diagnose unfinished work. They do not select models, assign work, approve actions, accept results or force endless continuation. Patch checks and the pre-dispatch app-thread-message denial cover only their exact routes; text merely mentioning a protected path is not a mutation. Hook coverage is partial, and hook failures remain visible. Passive observation, logging, telemetry, and diagnostic serialization use a narrow value-free fail-open boundary: a failure may emit only a bounded error class/code and continue with evidence_admissibility set to unverified. The boundary never wraps storage, authorization, binding, publication, cleanup, or audit work, and never turns a protected or uncertain action into success. See lifecycle hooks and the official hook reference.

Profiles and model routing

The coordinator reads as many bounded source or evidence pages as the decision requires and uses previews to select relevant reports. Reuse a completed context for an appropriate continuation; independent verification uses a fresh context when required by the risk. See comparative evaluation.

Cortex includes 23 advisory specialist profiles:

Area Profiles
Discovery and planning explorer, planner, architect, database_architect
Implementation frontend_dev, backend_dev, fullstack_dev, mobile_dev, data_engineer, devops_engineer, general
Diagnosis and improvement debugger, refactorer, performance_engineer, ux_designer, accessibility_auditor, accessibility_fixer
Quality control qa_engineer, code_reviewer, security_auditor, build_verification
Consultation senior_consultant
Documentation technical_writer

The host-supplied orchestrator skill contains a routing table for all profiles. The coordinator names the exact packaged worker skill and supplies the complete English assignment and constraints with fork_turns: "none". The worker loads its complete skill through host attachment or the exact advertised SKILL.md path before applying it to project work. For senior_consultant, the coordinator supplies the complete skill and publication reference as attached instructions or verbatim bodies; the consultant does not run commands to load guidance. The native assignment is named senior_consultant for observable role attribution. Missing tool declarations are discovered individually; publication uses only the live declaration's fields and a complete call whose receipt is inspected. Already attached live schemas need no catalogue round trip. Neither role explores the installation or reads profile TOML, manifests or server internals. No custom loader is needed.

Profiles have structured role, input, workflow, quality, reporting and recovery sections. The 22 executors share one source protocol; the consultant has a separate report-only protocol. These protocols and 23 specialization fragments generate 23 self-contained worker skills and matching optional Agent v2 TOML exports. A byte-for-byte test prevents profile drift. Each profile also fixes its default draft class:

Draft template Profiles
planning planner, architect, database_architect, ux_designer
investigation explorer, debugger
implementation frontend_dev, backend_dev, fullstack_dev, mobile_dev, data_engineer, devops_engineer, refactorer, accessibility_fixer
verification qa_engineer, code_reviewer, security_auditor, build_verification, accessibility_auditor, performance_engineer
documentation technical_writer
general general
general senior_consultant

Choose the report class that fits the assignment’s result. A profile default does not require another worker for a suitable different class. Optional report examples for planning, investigation, implementation, verification, documentation and final synthesis. Examples guide content without imposing exact report headings.

Codex supplies the selected orchestrator skill and the worker skill catalogue. The host supplies required skills through Codex's normal procedure only when relevant. Workers use exact advertised skill paths and declared references; they do not enumerate the installation. Tool discipline requires checking live tool declarations, complete arguments and actual results; it forbids guessed calls and unexplained mutation replays. Profiles do not authorize tools or select models. Discovery first lists tool names, then opens one selected complete declaration; a name-only result cannot supply an input contract. Calls include every required field; declared defaults apply only to optional controls. After compaction, actors reload the next needed declaration and preserve the full command result, including exit status or a running handle, from the first recovery read onward. New workers receive self-contained assignments and selected evidence without the coordinator's conversation history. Report publication follows its own live key requirements, which differ from draft creation. The required draft identity line is registration metadata and must not be treated as an unfilled guidance marker.

Adaptive model policy

Preserve the user's coordinator model and effort. Worker routing follows an explicit policy: Luna (gpt-5.6-luna) at medium/high owns fact gathering, exploration, known checks, ordinary implementation and plans of known steps. Terra (gpt-5.6-terra) at medium/high handles coupled implementation and complex ordinary review. Sol (gpt-5.6-sol) medium handles consequential architectural, contract, migration and planning decisions; high handles conflicting requirements, difficult rollback, data-loss or security-boundary risk. Astra (gpt-6-astra) is only medium, for exceptional consequential system decisions with a concrete reason Sol is insufficient. Role names, timeouts and production labels alone never raise the model. Sol/Astra consume bounded evidence gathered by Luna; implementation returns to Luna/Terra. These are advisory model-selection rules, not runtime gates.

The opt-in senior_consultant route answers one bounded coordinator question from selected published reports. Standard consultation is Sol (gpt-5.6-sol) at medium; narrow questions stay medium, harder questions use high. gpt-6-astra only at medium is reserved for a justified deeper escalation after Sol evidence remains unresolved. The consultant cannot read project sources or indexes, run commands/tests/network/environment checks, edit project files, launch agents, accept tasks, or alter the coordinator plan. Its only write is its own Markdown report. Each packet carries one question, goal/constraints, requirements revision, exact report IDs and artifact versions, attempts/results, and facts versus hypotheses; repeated consultation requires new evidence or a clarified question. Insufficient evidence must produce an exact data request and recommended executor profile. The coordinator records the consultation and decision in the current pipeline; the recommendation never replaces executor verification or acceptance.

The coordinator supplies the consultant's complete instructions alongside its compact evidence packet, without inherited conversation. Its separate protocol keeps the 22 executor profiles unchanged. See the consultation cycle and access limits.

Reviews and verifications use the permitted model and effort routes without automatic escalation from the implementation they inspect. Assignments record the implementation model and effort when relevant to the review. Every worker request states its model and effort explicitly. Other models or efforts are forbidden for coordinator-selected work unless the user directly requested that override; the exact request is recorded and preserved. The review label records work kind and does not select a model; absent an explicit complexity or security classification, it follows the ordinary route.

The isolated Desktop live-test launcher makes this provenance concrete: every spawn_agent call must include model, reasoning_effort, and fork_turns explicitly (gpt-5.6-luna with medium/high and none for ordinary workers; the selected consultant route records its own permitted values). The observer retains strict matching whenever requested fields are visible. If both are unavailable because the assignment carries the exact assignment_content_unavailable=true marker, it can verify only a complete, unique native child/path/parent-edge/Luna/effort/fork/skill join; it never fills missing fields from host defaults. Missing, conflicting or duplicate evidence remains unverified. Native SubAgentActivity evidence coalesces one started and one completed lifecycle record for that same child/path; repeated phases or a path resolving to different children remain ambiguous and fail closed. Valid declared Markdown-reference reads do not count as a second complete worker-skill receipt. The observer also recognizes a quoted rg/grep exclusion marker in a simple discovery pipeline as a static mention; direct private paths, unquoted globs, and opaque shell syntax remain unauthorized. Exact Python -c and quoted-heredoc audit comparisons may likewise contain a private marker only as a direct literal comparison operand; Python assignments, file/process calls, comments, interpolation, malformed programs and private working directories remain denied. A worker's native final names only its own assignment publication; input and predecessor report IDs stay in the report body. Desktop calls, MCP events, hooks, open resources, and usage are attributed only to the submitted coordinator and its native descendants. Every present native thread/parent identity must agree with that tree; mixed identities fail closed. A second recent root, duplicate edge, self-parent, cycle, or malformed recent edge is reported as an overlap/topology failure rather than merging or hiding sessions. Usage accounting consumes that same validated inventory and returns an explicit invalid_topology result instead of silently dropping a multiply-owned child. The coordinator cache exception covers only the exact advertised orchestrator SKILL.md; worker skills, other skills, and references remain forbidden to it. The c4 follow-up parity experiment uses a fresh mktemp -d directory initialized with git init for both hosts, avoiding historical task roots without turning the clean-project setup into a general product stage.

Obtain missing facts and tools directly; model escalation does not repair their absence. Never change a worker merely for a slow response or one timeout. Compare full task cost, including all participants, retries and cached input separately. User requirements remain mandatory.

Offline Phase 4 telemetry can preserve bounded/null-safe advisory planning signals for rollout, review, recheck, delivery-error, and wait observations. They are not cost estimates or quality scores and never rank workers, select models, route work, gate delivery, or determine acceptance.

The coordinator owns model selection. The server and hooks do not silently select agents or rewrite model requests; the isolated live observer audits actual worker model/effort receipts and reports policy violations. The new four-scenario pilot compares protocol configurations; unrun or unavailable measurements are explicit, never treated as zero.


Developing Cortex

End users install through the Marketplace flow above. Repository development prepares only the isolated candidate; it never updates the stable user plugin.

Runtime boundary

The complete installable product lives under plugins/cortex/. Root-level scripts/, tests/, docs/ and AGENTS.md are development support.

Path Purpose
plugins/cortex/scripts/cortex.py Seven-operation MCP entry point
plugins/cortex/.mcp.json Direct Python server startup
plugins/cortex/scripts/cortex_runtime/contracts.py Advertised schemas and limits
plugins/cortex/scripts/cortex_runtime/host_source.py Read the current host thread’s typed user input within its project boundary
plugins/cortex/scripts/cortex_runtime/store.py SQLite metadata and real Markdown storage
plugins/cortex/scripts/cortex_runtime/project_storage.py Native project binding and project-local store routing
plugins/cortex/scripts/cortex_runtime/server.py Bounded stdio transport and private errors
plugins/cortex/scripts/cortex_clear.py Explicit host-side retention command
plugins/cortex/scripts/cortex_split.py Stopped-access split from a legacy shared store
plugins/cortex/profiles.json 23 advisory specialist descriptions
plugins/cortex/skills/orchestrator/SKILL.md Coordination and model selection
plugins/cortex/skills/cortex-control/SKILL.md Shared worker reporting protocol
.agents/plugins/marketplace.json Repository Marketplace
scripts/cortex_package.py Complete payload hashing and candidate validation
scripts/sync-cortex.sh Read-only source validation or isolated candidate preparation
scripts/cortex-dev Prepare candidate and launch ordinary interactive Codex
scripts/cortex-desktop-dev Actual Desktop with a disposable profile
cortex-dev Repository-root forwarding launcher

Isolated candidate runtime

./scripts/cortex-dev creates or reuses the exact $HOME/.cortex-dev candidate, sets its own HOME and CODEX_HOME, prepares the content-stamped package through the supported sync path and launches ordinary Codex in the caller's project. It does not create tmux or modify the stable installed plugin. The packaged MCP manifest forwards the isolated dependency directory so cached MCP startup can launch the gateway with the same hash-locked dependency set. The Desktop helper derives and validates that prepared owner-only directory after --prepare-only, overwriting any conflicting ambient value before launching Electron.

./scripts/cortex-dev --prepare-only
./scripts/cortex-dev
# Equivalent interactive entry point:
./cortex-dev

The interactive CLI driver exposes the same complete observation gates. Its default preserves the isolated codebase_memory configuration, including explicit opt-out. Neither helper silently disables the graph nor changes the stable profile: ./scripts/cortex-live-smoke calls and ./scripts/cortex-live-smoke audit. Run both before accepting or stopping a live session.

On a current host that does not provide the typed pre-dispatch capability, an explicit MCP-first start uses an observational contract. It never accepts a caller receipt, environment value, local inference, or generic shell bootstrap as host authorization. Instead, it can return observational_accept only after complete capture/calls/events/terminal/exit/audit evidence proves the constrained public workflow; host_enforcement_state remains unverified.

./scripts/cortex-live-smoke start --workdir /absolute/existing/test-project \
  --bootstrap-route mcp-first

It records bootstrap_route=current_host_mcp_first and host_enforcement_state=unverified; those are observer metadata, not a host attestation. The launcher persists one immutable native user-turn root receipt; the child coordinator must directly complete public mcp__cortex__create_task first with that exact child-thread identity plus project, task, original-request, and native-result bindings before any project-target action. Missing, competing, or later-replaced root identities invalidate the attempt. That one successful, non-replayed direct public receipt is the pre-binding-to-bound transition. An observable current-host functions.exec transport label does not change it into a wrapper when it contains only that literal MCP member call; aliases, multiple nested calls, failed calls, or replays remain invalid. Launcher tmux/process/capture setup is launcher_transport, never qualification evidence. The only observed-current-host discovery exception is a complete bounded read of an exact advertised coordinator SKILL.md or public .mcp.json/ .codex-plugin/plugin.json declaration from the isolated bundled release; it cannot use a directory, glob, runtime/state/registry file, arbitrary cache path, or mutation. The separately observed text(ALL_TOOLS) envelope is permitted only as a value-free, bounded public catalogue label with a complete receipt; filters, queries, paths, content extraction, mutations, nested calls, and mixed wrappers are not this exception. If an opaque current-host assignment omits the early worker profile hint, one exact manifest-bound leaf from the closed registered worker SKILL.md set may be read first. It remains usable only after the later native result exactly matches the read profile and assignment digest; cross-profile or arbitrary cache leaves remain BLOCK. When worker Cortex MCP is unavailable on the current host, the only observational fallback is a closed cortex-native-worker-result-v1 final body correlated to one native spawn, terminal wait, parent/task, registered profile, and assignment digest. The coordinator then writes an ordinary report titled Delegation evidence: native_worker_result; it must state evidence_source=native_worker_result, worker_mcp_unavailable=true, and host_enforcement_state=unverified. Worker artifact hashes remain asserted until independently receipt-bound. Missing, duplicate, truncated, replayed, or competing evidence blocks qualification. In this observational mode only, a complete correlated native worker result and delegation-evidence report retain missing assignment/worker-skill receipts and a worker action preceding that separate receipt as diagnostics rather than a host gate. Likewise, a complete public MCP result plus exactly one later same-thread publication may explain a missing separate server event. This does not authorize dispatch, infer host enforcement, or relax any failed, truncated, private, mutating, duplicate, or ambiguous operation. When an installed interactive host cannot emit bootstrap attestation, assignment or skill receipts, a separate server event, or a process self-exit marker, that absent signal is not_applicable/diagnostic rather than a BLOCK. observational_accept still needs exactly one direct task binding, one terminal native worker, one task-bound worker report, exact coordinator artifact-hash reconciliation, complete non-truncated evidence, no pending work, and either owned exit=0 or a verified idle composer followed by exact owned cleanup. The route remains host_enforcement_state=unverified. A redundant worker-final report-ID omission is also diagnostic only after one unique task/parent/profile-correlated worker publication and exact coordinator artifact reconciliation supply that identity. Likewise, one completed, non-mutating read_report invalid_arguments lookup is harmless only when that separate valid publication/reconciliation evidence exists. It does not excuse a failed write, missing or ambiguous publication, mutation, private target, mismatch, replay, or truncation. If this installed host omits a public task ID or native-result body, the observer uses only one expected child root, one parent-bound native worker/report, and one exact non-replayed coordinator artifact reconciliation as opaque root/report binding. It never infers an ID: missing, duplicate, replayed, or mismatched root, worker, report, or artifact links remain BLOCK. One or more exact-equivalent denied-before-dispatch errors from the bounded registered worker SKILL.md read are diagnostic only after that same full outcome proof. They must share exact worker/profile/manifest-bound static-read identity; differing, replayed, private, project, mutating, dispatched, truncated, or ambiguous reads remain blocking and none credits a skill receipt. The installed interactive transport may place that sole exact worker leaf read in one literal bash -lc envelope. Cortex unwraps and revalidates the payload with the same closed static-read grammar; nested shells, extra commands, directories, globs, adjacent cache paths, and writes remain forbidden access. When the host serializes this read through functions.exec, the observer accepts only one direct-call form with a safe JavaScript identifier, for example const result = await tools.exec_command(...); text(result); or an equivalent const output = ...; text(output); form. The identifier must be bound once and forwarded unchanged exactly once. Aliases, property access, extra JavaScript/API/tool calls, missing or partial forwarding, and mixed wrappers remain fail-closed. For current_host_mcp_first only, the exact unsupported-host labels worker_assignment_policy_unverified and mcp_first_bootstrap_unverified are always printed as unsupported_by_current_host, not_applicable diagnostics. The installed current host cannot emit either attestation, so neither may become an integrity invalidator or a hard blocker; neither supplies evidence, score, or host enforcement. This does not relax supported task/report/hash/pending failures, replay/ambiguity/truncation, unsafe private or project mutation, or any other policy finding, and it does not apply outside that route. The helper reapplies this exact two-label normalization at the final audit boundary, after all collection and classification paths have run, so no parser spelling can restore either unavailable attestation as an integrity invalidator. That final normalization changes no other policy finding and provides no outcome proof. Generic pre_binding_host_action is never demoted by this outcome partition: it lacks strict actor/profile/path proof and can describe an unsafe dispatch. The sole coordinator setup exception is an observer-proven manifest-bound, bounded, read-only literal skills/orchestrator/SKILL.md read carrying the active-skill marker; the separate exact-equivalent registered-worker static-SKILL-read predicate can retain independently complete, read-only denied records as diagnostics. Neither exception admits directories, globs, another skill, unknown provenance, mutation, dispatch, truncation, replay, ambiguity, or private/project targets. The current-host audit returns exit 0 only for printed observational_accept with valid evidence and exclusively explicit retained diagnostics/not-applicable signals. It keeps those diagnostics in output, but returns exit 1 for any hard failure, remaining policy violation, pending/open state, mismatch, mutation, truncation, ambiguity, replay, or missing outcome proof. A pre-binding wrapper, shell, terminal, file, patch, or private probe outside that exact static exception; an MCP failure; or an ambiguous/wrong binding invalidates the CLI attempt, permits no shell fallback, and leaves Desktop locked.

For parity qualification, this CLI audit is the gate: only a CLI ACCEPT with clean audit evidence may unlock Desktop on the same unchanged candidate and payload. If CLI fails, is rejected, unavailable, or unverified, end and audit that CLI attempt, retain its complete evidence tails, stop its exact session, and do not start Desktop as a diagnostic substitute.

Actual Desktop uses the same prepared candidate and a disposable Electron profile:

./scripts/cortex-desktop-dev start --workdir /absolute/existing/test-project \
  --prompt-file /absolute/TASK_PROMPT.txt \
  --expected-result-path README.md \
  --expected-result-sha256 EXACT_RESULT_SHA256
./scripts/cortex-desktop-dev status
./scripts/cortex-desktop-dev send
./scripts/cortex-desktop-dev events
./scripts/cortex-desktop-dev calls
./scripts/cortex-desktop-dev audit
./scripts/cortex-desktop-dev stop

CORTEX_DESKTOP_BINARY can select the actual Desktop executable. send verifies the isolated window PID, preserves the URI-prepared composer focus without clicking a guessed coordinate, waits for that exact owned window to stay focused across two observations after a three-second URI hydration interval within one monotonic 60-second readiness budget, submits one plain Return, and records success only after exactly one new task receipt appears. It refuses a second acknowledged submission while leaving a prompt retryable when no receipt appears. calls emits the full run by default and correlates every coordinator and worker wrapper, nested host invocation and actual Cortex MCP event while retaining only argument/result digests and safe routing metadata. audit reads the same complete history and fails on MCP or host errors, truncation, missing command outcomes, forbidden role or file access, calls made by a worker after successful publication without an explicit successful parent follow-up after final handoff, oversized document pages, or a command session without a terminal result. Every observed error is retained chronologically in tool_error_history and fails the run even when a later retry succeeds. resolved_host_failures explains a later correction but never makes that run acceptable. Pre-dispatch wrapper syntax errors are separated from nested calls that never executed. This exposes redundant or misplaced operations without commands or report bodies. Inspect the visible result too. CLI and Desktop qualification requires consecutive successful scenarios on one unchanged payload. Any installable edit invalidates earlier live results.

When xdotool windowactivate --sync returns the exact XGetWindowProperty[_NET_WM_DESKTOP] failed (code=1) warning, send records the bounded warning and uses one windowfocus --sync fallback only after rechecking the launched PID. It then requires getactivewindow to name that same window and rechecks its PID before any input. Other activation errors, ownership changes, failed focus, or an active-window mismatch fail closed; the existing composer and exactly-one-receipt gates still decide delivery.

Recommended development loop

python3 -B scripts/cortex_package.py stamp
python3 -B scripts/validate-cortex-marketplace.py
./scripts/sync-cortex.sh --check
PYTHONDONTWRITEBYTECODE=1 python3 -B -m pytest -q
git diff --check
./scripts/cortex-live-smoke start --workdir /absolute/existing/test-project

Stamp before release-sensitive checks after every installable edit. Run package, tests and sync checks sequentially in one checkout. Normal sync is allowed only through cortex-dev in the exact isolated environment; --check and --dry-run are read-only source checks. Observe the interactive composer and candidate receipt before submitting an ordinary product workload.

Operator maintenance

$cortex:orchestrator clear 7 days deletes only this project's tasks and all their artifacts whose latest recorded activity is older than seven days. Active task identifiers are protected using the coordinator's native-host knowledge. This explicit instruction authorizes the bounded deletion without another confirmation.

The coordinator delegates the installed scripts/cortex_clear.py host command, obtaining its usage from --help. It is not an MCP operation and does not create a cleanup task. Committed deletion intents recover interrupted cleanup. The operation does not remove project source or other projects' tasks. Back up SQLite and task directories together while storage access is stopped.

Versioning

This release uses semantic version 1.15.9 per the current release instruction. The manifest and MCP server advertise 1.15.9+codex.sha256.<digest-prefix>, computed from the complete installable payload. Regenerate the suffix whenever that payload changes. Different bytes must not reuse a stamp. The package validator and candidate preparation verify it; the server is not a workflow compatibility layer.

The current source candidate is 1.15.9+codex.sha256.121a79864903aeee (payload SHA-256 121a79864903aeee34a37ab762da360c3449bfd4f8eb14ee190e8384d18d7750). After each successful native spawn, the coordinator must use a successful exact native wait_agent recorded after that spawn until the owner’s terminal handoff/report is consumed; qualification rejects a spawned worker without this post-spawn wait/reconciliation. Pending or unchanged worker state is waited on silently, with commentary reserved for material transitions, blockers/questions, and completion. This is model-owned guidance: lifecycle hooks are diagnostic and cannot resume a stopped host turn. If a host omits wait target metadata, an owner-bound completed wait is supported only when it is post-spawn; supplied target metadata must include the spawned worker. The recorded final CLI/Desktop qualification (r_648c4f40dcf9) belongs to the superseded e4f332d43bf38024 payload and is historical evidence only; it does not qualify this changed payload. Package, sync, full-suite, and real-host qualification remain required before any delivery or acceptance claim. The user cancelled the Phase 2 outcome comparison; it is non-blocking and non-scoring, and Cortex makes no efficacy-comparison claim for this release.

Development agreements

  • Keep one authoritative bundled orchestrator and exactly seven public operations.
  • Keep all 23 profiles with a shared free-form Markdown reporting workflow.
  • Keep model selection, delegation, steering and completion in the coordinator.
  • Store one latest-first pipeline file; ordinary reports remain immutable.
  • Keep tool argument contracts in advertised schemas, not model instructions.
  • The repository defines a typed, fail-closed host functions.exec dispatch contract; it is not proof that an installed Codex host invokes that contract. The shell-wrapper path is contained until the host attests its typed pre-dispatch capability. The explicit --bootstrap-route mcp-first current-host fallback instead admits only a complete direct public Cortex task receipt before project actions, remains host_enforcement_state=unverified, and fails closed on any observed pre-binding host action; it neither simulates host enforcement nor unlocks Desktop on failure. Each host-authenticated actor kind has exactly one semantic role (native_coordinator/coordinator or native_worker/worker); a mismatch denies before nested operation parsing or dispatch.
  • The bundled capability-manifest-v1 is a closed, versioned P1 policy input. It binds a verified profile, canonical semantic operation/resource, route, target, phase, task/assignment, artifact revision, payload, acceptance boundary, and check identity to a bounded receipt, together with policy/profile/actor and the canonical capability/operation/resource identity. It rejects aliases, encoded, opaque, mixed, or unknown descriptors and keeps denied or mismatched evidence inadmissible; missing, unknown, truncated, or replaced receipts also fail closed. It is not a token, filesystem/process/egress sandbox, or proof that a host performed enforcement. Local receipts can be only policy_declared or policy_observed; a supplied host_enforced label is unverified until a separate trusted host boundary verifies an exact binding.
  • Advisory failed-canary, review, and cost metadata is bounded, null-safe, strict-JSON-safe replanning input only, including nested values. Oversized strings are truncated, out-of-range integers and non-finite/oversized floats are omitted as null, and unsupported values are omitted as null. It does not select an agent, route work, impose a threshold, retry, or accept a result. Unchanged state/evidence produces no wait message or event. When semantic policy and path-boundary diagnostics both apply, they keep one stable call identity with two labels, not two synthetic calls.
  • Passive diagnostic failures are a separate execution-continuity lane. The bounded helper may catch only observation, logging, telemetry, or diagnostic serialization failures; it emits value-free type/code metadata when possible and retains evidence_admissibility=unverified. Passive telemetry storage and permission errors also continue; real integrity, binding, provenance, replay, truncation, publication, cleanup, and audit failures remain fail-closed and are never demoted.
  • Live acceptance additionally requires native completion of every Desktop participant. An existing output file or successful initial pipeline publication is not completion. Real check failures remain non-accepted in CLI and Desktop audits, without stopping the running orchestration.
  • Preserve help, harvest, refresh, clear, index routing and context rereading.
  • Verify storage integrity without interpreting Markdown completion claims.
  • Never retain compatibility routes, mandatory stages or approval machines; lifecycle hooks remain local storage and integrity helpers.
  • Update affected documentation and record actual evidence and unrun checks.
  • Refresh only the isolated candidate; never alter stable installation for tests.
  • Never commit private task reports, credentials or diagnostic logs.

Support Cortex πŸ’œ

Cortex remains open source. If it is useful to your work, you can support its continued development and maintenance through GitHub Sponsors. Sponsorship helps fund testing and experimentation with multi-agent coordination, plus the tooling, documentation, skills, and MCP integrations that make it better. Sponsorship is entirely optional.


Verification and diagnostics

The Model Gateway lifecycle and provider patch behavior are documented in Model Gateway lifecycle. Marketplace MCP startup enables the gateway by default through the global CODEX_HOME configuration; set gateway.enabled = false for explicit storage-only mode. The isolated launcher installs and version-checks a clean dependency target from the hash-locked Linux wheel set with pip --require-hashes, then invokes the prepared Marketplace cache's own gateway control entrypoint; runtime health binds the lock manifest digest, installed dependency-byte digest, exact stamped payload, and entrypoint invocation. If the explicit gateway configuration is changed to gateway.enabled = false, the launcher ensure path drains the owned child and waits for runtime-state removal before reporting it stopped. A reload to the disabled state stops the child and request handling rejects any race rather than forwarding; if reload cannot signal or drain the owned child, it returns failure and the control command exits nonzero. Draining health is not readiness. After readiness, Cortex automatically selects its local Codex provider at http://127.0.0.1:8787/backend-api/codex (or the configured fixed loopback listener). It uses Codex's existing OpenAI authentication and preserves model choices, reasoning effort and unrelated configuration. It selects the remote summary compactor with remote_compaction_v2 = true and context_management = false; both feature edits are journaled and reversible. No proxy variables, local CA certificate or special product launcher are needed. The proxy has no request-count or connection-slot admission limit: active-request tracking exists only for controlled drain, and a full historical 32-request count does not produce a capacity 503, Retry-After, or an admission queue. Body, timeout, protocol, policy, and cancellation checks remain in force. Candidate preparation uses the isolated listener (normally 18787) and never changes the stable 8787 runtime. Provider backups are published create-only so concurrent configuration cannot overwrite the first recovery point. Gateway configuration and its control directory are private owner-only paths; unsafe existing entries fail closed. Provider updates use a locked descriptor/content compare-and-swap and refuse to overwrite unrelated concurrent edits. When a requested listener is occupied by an older same-user Cortex gateway, startup verifies its complete command and packaged manifest, sends a controlled stop, waits for the listener to drain, and retries. An unrelated process is never terminated. The packaged dependency installer keeps its progress output off MCP stdout so it cannot corrupt the JSON-RPC handshake. Compaction rewriting covers V2 compaction_trigger (auto compaction) and the legacy /backend-api/codex/responses/compact JSON path (manual compaction). Recognized legacy JSON is routed in-call to the supported V2 path because the production upstream retired /responses/compact; opaque legacy bytes retain their original path and bytes. The HTTP compaction routes force the upstream- required store: false and stream: true values. The optional WebSocket transport inspects only uncompressed direct response.create compaction messages and rewrites only model and reasoning.effort, preserving the message's other fields; it does not apply a separate HTTP store rewrite.

Automatic provider and compaction paths

After installation or update, the first startup of the installed Cortex MCP applies these settings to the global $CODEX_HOME/config.toml (normally ~/.codex/config.toml), not a project-local config. Marketplace installation by itself does not run this setup; MCP initialization must occur. Model traffic uses the new settings when the client next loads configuration.

Automatic setup selects Codex's remote summary compaction mode. The experimental context_management mode can reset a context window locally without asking a model to summarize it; there is no summary request for a proxy to reroute in that case. Cortex sets features.context_management = false and features.remote_compaction_v2 = true on connection. These choices take effect on the next configuration load, apply to native workers as well as coordinators, and restore their previous values on disconnect if still unchanged. Subsequent user feature overrides are preserved; opting back into context management also opts out of this guarantee of remote summary routing.

Cortex's first MCP startup verifies the owned gateway and updates the effective user config.toml with a local cortex model provider. HTTP/SSE and Responses WebSocket requests use the same fixed loopback listener. The gateway establishes TLS to chatgpt.com and keeps authentication in transit only. WebSocket framing and handshakes are separate on each leg, with compression disabled; message content, application headers, ping/pong and close behavior are relayed.

Codex applies the route when it next loads configuration. Installing a plugin does not guarantee that MCP has started or that an existing task has reloaded its provider. A new task or Desktop restart can still be necessary; Cortex does not interrupt active tasks. A healthy gateway alone does not prove client routing: verify fresh model-request outcomes from that exact client.

Automatic setup requires the normal OpenAI provider. It refuses to replace a custom provider or custom upstream. Subsequent user provider edits take precedence. A private route journal records the fields Cortex owns, and config.toml.cortex-backup preserves the original file. Disabling the gateway or the recorded Marketplace entry restores matching owned fields and drains the gateway; unrelated later edits survive. Plugin removal is observed while the independent gateway is running. If it was forcibly killed first, its observer cannot perform cleanup. Configuration already loaded by an active client changes only on that client's next configuration load.

Codex's installed source markers identify the remote V2 compactor in core/src/compact_remote_v2.rs and its WebSocket request builder in codex-api/src/endpoint/responses_websocket.rs, with the request schema fields response.create, input, reasoning, store, and stream. When that V2 request is sent as an uncompressed direct response.create message containing an input item whose type is compaction_trigger, the gateway receives the bounded message and rewrites only model and reasoning.effort. store, stream, and all other JSON fields are preserved. A direct HTTP V2 request with the same trigger follows the existing HTTP policy, which also applies its upstream-required storage/stream normalization.

The upstream Codex sources make the automatic route more precise: core/src/compact_remote_v2.rs sets CompactionTrigger::Auto for run_inline_remote_auto_compact_task, while core/src/compact_remote_v2_attempt.rs appends ResponseItem::CompactionTrigger {} and calls ModelClientSession::stream. The shared codex-api/src/endpoint/responses_websocket.rs serializes that request as ResponsesWsRequest::ResponseCreate and sends it as a WebSocket text message. Thus automatic compaction reaches the same outbound response.create WebSocket handler as other V2 requests; it does not use /backend-api/codex/responses/compact. The installed binary is stripped, so these source links establish the trigger and handler shape while its exact threshold branch remains unverified locally.

Automatic compaction and a standalone /compact action can converge on the same remote V2 response.create/compaction_trigger wire shape. The gateway therefore identifies the protocol trigger, not the origin story: its bounded log records auto_compaction for the HTTP V2 classifier and websocket_compaction for the WebSocket frame classifier. To distinguish automatic from standalone behavior without another submission, correlate those sanitized entries with local lifecycle telemetry: a preceding native /compact user message indicates standalone steering, while a threshold-driven compaction has no such user message. Network evidence alone cannot make that distinction, and a failed helper receipt must not be retried for this purpose.

For Marketplace installation, the gateway starts by default. The packaged Python entrypoint creates the private config, installs the hash-locked runtime into $CODEX_HOME/cortex/deps/<lock-digest>, and ensures the cached gateway and provider; failures abort startup. A verified dependency tree is reused by subsequent MCP processes, including workers. Set gateway.enabled = false in $CODEX_HOME/cortex/config.toml for explicit storage-only mode. scripts/cortex-dev remains the isolated developer launcher, uses the same automatic provider code in its disposable profile. The proxy accepts only loopback listener authorities and the fixed upstream. Logs contain bounded model/effort, request-kind, and status metadata only: cookies, authorization values, request bodies, and WebSocket payloads are never written to diagnostics.

The /backend-api/codex/responses/compact handler is retained solely as a compatibility mapping for older manual callers: decodable JSON is routed to the supported V2 path, while opaque legacy bytes remain byte-for-byte pass-through. It is not a second WebSocket route or a fallback retry. The HTTP proxy module serves HTTP, health and WebSocket traffic on the provider listener. Every proxied request emits bounded, secret-free model/effort and request-kind telemetry to the private rotating gateway log; malformed ordinary or opaque legacy bytes remain unchanged. The proxy preserves path/query, body bytes, and all non-authority header pairs; it rewrites only the local incoming Host authority to the configured upstream authority on the upstream wire so Cloudflare virtual-host routing succeeds. This is transport metadata, not a semantic body rewrite. Compaction alone rewrites model and reasoning.effort. The outbound HTTP client does not inject an Accept-Encoding header when the caller omitted it, preventing an unsolicited encoded model catalogue; an explicit caller value is forwarded unchanged. Automatic response decompression remains disabled, so upstream response headers and body bytes are streamed to the caller as received.

Run release-sensitive checks sequentially on one stamped checkout:

python3 -B scripts/cortex_package.py stamp
python3 -B scripts/validate-cortex-marketplace.py
./scripts/sync-cortex.sh --check
PYTHONDONTWRITEBYTECODE=1 python3 -m pytest -q
git diff --check

Source tests cover storage, schemas, recovery, source capture, hook behavior, profile generation and the observer. They cannot establish model behavior, host hook coverage or task quality. Keep raw source messages, reports, logs and host transcripts outside repository documentation.

Interactive tmux live-dev workflow

Phase 2 status (2026-09-11): CANCELLED by the user. The outcome/efficiency comparison is non-blocking and non-scoring for the stable 1.15.9 release. Do not start a Phase 2 comparison or claim efficacy, scoring, or promotion; the adapter details below are retained as historical/offline reference.

Use only ./scripts/cortex-live-smoke start --workdir PATH for the exact cortex-markdown-smoke session on the default tmux server. Inspect capture and status, visibly confirm trust before one explicit enter, and confirm the composer. Compare the passive initialization receipt with the isolated candidate and seven-tool catalogue. Workloads begin with $cortex:orchestrator followed by ordinary product work. send --prompt-file FILE pastes once, waits five real seconds and sends one named Enter; it requires an ordinary before/after native input receipt plus the immutable ordinary start binding and a current exact tmux server/session/pane/PID/start-tick check, but no Phase 2 control or trust receipt. The sealed Phase 2 adapter injects an explicit control marker and selects the stricter trust/send protocol; incidental or missing session fields never switch or weaken either mode. Ordinary send is also single-use: a non-null first-submission timestamp refuses before any composer/receipt inspection, state write, paste, or Enter. A resumed session observes and continues its existing task without replaying that request.

Each new CLI smoke run uses the exact project-local store at PATH/.codex/cortex/cortex.sqlite3. A --resume-last run reuses that same canonical project store and rejects a missing or mismatched store. stop keeps the project store for resume and removes only the session and observation streams. For a new evaluation cell, add --evaluation-fresh-store: the opt-in Linux-only CLI guard requires a supported architecture/syscall and same-filesystem staging, builds the complete owner-private .codex/cortex hierarchy in an external same-filesystem stage, and installs it once as the project .codex destination with no-replace semantics. Unsupported, unavailable, raced, or otherwise unproven conditions fail closed before canonical project mutation; uncertain loser stages are retained outside the project rather than removed by pathname. Git/config readiness is completed before that commit. It requires the project-local SQLite target to be absent and non-redirected, leaves database creation to the normal initializer, and records only privacy-safe path/check/digest provenance. It never deletes, truncates, migrates, overwrites, or accepts an existing store. The flag does not alter ordinary starts or explicit --resume-last behavior. The sealed Phase 2 compatibility adapter additionally passes that exact empty project directory as CORTEX_DATA_DIR to both frozen launchers after removing any ambient value. This lets the format-10 baseline use the same isolated path that the format-11 candidate resolves from native project state; it does not expose or reuse the isolated home's unrelated Cortex database. The adapter also revalidates the selected archive's full normalized payload digest and exact embedded plugin version before every command. Preflight success cannot be reused after archive rebuild or mutation drift; an identity contradiction stops the cell before the launcher or fresh-store commit. Phase 2 cell evidence is collected through the adapter's single sealed collect-evidence --evidence-dir PATH command. It owns the bounded observer arguments, atomically records status, capture, events, calls, usage, and audit, and creates a final bundle receipt only after validation. Adapter-mediated stop requires that matching complete bundle, preventing partial capture from deleting the transient streams. The exact invocation is documented in docs/project/phase2-external-evaluator.md.

The control also seals one common cortex-desktop-dev observer beside the common harness and applies it to both archived arms. Its minimal runtime bundle contains the exact profiles.json plus the complete dynamically addressable skills/ tree; the control records every canonical relative path and file hash as one trusted aggregate. Preparation, independent audit, and adapter preflight reject missing, changed, extra, symlinked, non-private, or relocated dependencies before live transport. Participant usage is content-free and scoped to the single observed coordinator root; an unavailable usage status remains availability evidence and is never converted into a quality score. Compound command failures name the executable identified by the shell's command-not-found receipt, rather than the first command in the compound string. The observer preserves the raw exit-1 receipt while classifying only a simple rg/grep search, or an exactly proven pwd && rg/grep search, with empty stderr and empty search output as semantic no_match. That expected search absence is excluded from host-failure and tool-error quality gates. Exit 2+, stderr, extra shell segments, mismatched pwd output, and every other failure remain blocking; only an exit-127 availability failure may be corrected by a later family success. The shared audit classifies evidence integrity before quality: truncated, unbound, assignment-unverified, contaminated, or topologically ambiguous rows make a cell unscoreable, while complete attributable failures remain visible as quality findings in an otherwise valid bundle. Raw failure and policy receipts are always preserved, and the same decision table applies to both arms and hosts. Every cell's sealed start owns a bounded trust/composer transition and returns ready-for-begin before begin-cell --cell-id cell-NNN. It waits through an early loading placeholder, sends at most one named Enter only while the exact trust prompt is active, seals the control/session result, and proves the exact empty composer before cell authorization can be issued. A separate accept-trust is idempotent receipt verification only and emits no input. Empty means the latest rendered β€Ί input row is the exact placeholder; a historical placeholder above active unsent text is never readiness evidence. Once tmux has returned the exact owned pane identity, start captures one immutable, control-scoped session-binding receipt and marks the lifecycle started. Begin-cell refuses before that transition or after receipt/pane-field rotation. Cell authorization files are scoped by both control digest and session receipt, so a fresh control cannot inherit a prior UID-global or cross-control authorization; an unconsumed authorization for the current session remains exclusive. That boundary issues a one-time nonce and binds the later submission, evidence bundle, and stop to the current workdir, store, session receipt, coordinator thread, control, and arm. Cross-cell replay, duplicate submission, and duplicate stop are refused even when control and arm are unchanged. The adapter durably changes the authorization from issued to submitting before transport. Only an observed exact root-thread native user-turn receipt can atomically promote it to submitted, with the prompt digest, thread ID, user-turn source/line hashes, finite submission timestamp, and nonce-bound receipt recorded together. The native source must be the single rollout file held open by the exact owned Codex descendant after tmux, pane-PID, and process-start revalidation. The harness reads the inode identified by that descriptor and requires a second identical descriptor/process/session snapshot immediately before acceptance; added, removed, retargeted, or ambiguous rollout FDs fail closed. Same-workdir/time rows alone cannot match. A bounded resolve-send can reconcile a delayed accepted receipt without sending input. Failed or uncertain sends remain non-resubmittable, and submitted-or-later reads revalidate timestamp/receipt and transport-state consistency before collection or cleanup. An unchanged pre-submit trust prompt or a proved empty composer after an unaccepted send has one separate abort route. The adapter requires the exact control/session binding, two stable owned process/activity snapshots, either a null request or the matching no-submit prompt digest, null submission receipts, and no task, worker, foreign call, or open exec state before persisting a one-time abort receipt and issuing exactly one exact-target interrupting stop. The cleanup helper receives the sealed tmux server PID, session name/ID/creation time, pane ID/PID/process-start identity, control digest, and session receipt; it revalidates them at the cleanup boundary and addresses only the sealed pane/session IDs. It is not orphan recovery; any uncertainty is non-retryable, and any submitted session is refused. The collected authorization also seals the canonical evidence-directory path and its device/inode, owner, and private mode. Stop refuses copied, renamed, symlink-aliased, or non-canonical directory paths even when bundle bytes match. Normal Phase 2 stop remains bundle-gated. Normal collection accepts a stable idle interactive composer only when its exact owned Codex process and task trees match, all workers and the coordinator are terminal, the final call/event join has the same owned report and draft identities, each independently validated as a nonempty typed r_[0-9a-f]{12} or d_[0-9a-f]{12} receipt before equality, the recognizable composer footer matches model, effort, and workdir, no tool/exec/wait/session activity remains, every wait has an explicit successful completion receipt, and repeated status, process, capture, events, calls, and audit snapshots are identical. This normal path needs no exit marker; bundle-authorized stop --interrupt then closes only that accepted idle session through the same exact-target helper. A replaced server, renamed/recreated session, replacement pane, or reused pane PID is refused before signaling, and a failed exact stop does not consume the cell authorization. The retained bash path still requires one successful Cortex live-dev exit=N marker and no descendants. The distinct recover-orphan route is limited to exact owned issued/submitting sessions with no submission receipt, requires explicit one-time authorization, and captures terminal status/output, calls, events, and audit. Every live pane is refused. A retained dead bash pane must have a matching Cortex live-dev exit=N marker, no active work, and the same session receipt, status, process snapshot, and marker capture at a final pre-stop recheck; both evidence generations are hashed. Submitted, receipt-less, repeated, raced, or foreign sessions are refused. It writes an external consumed cleanup receipt before a new disposable cell may start. If the whole tmux server is already gone, gc-absent-runtime is the only stale-state path. It inventories recognized control transactions, session bindings, authorizations, saved session state, and invalidation receipts; refuses unknown or foreign generations; proves tmux and every sealed process identity gone; and requires retained calls/audit evidence with no active task, tool, wait, or session; both audit open-state fields must be present as literal empty lists, and simultaneous saved-session files are refused. The strict state-root allowlist accepts only canonical filenames derived from the selected control/session/cell provenance; any extra JSON, backup, hidden/temp, case variant, alternate suffix, duplicate, or unrecognized entry refuses before mutation. The binding's exact events path must be the canonical direct child of the state root. After runtime loss it may be absent; if present it must be an owner-owned mode-0700 nonsymlink directory with stable device/inode identity and no children. A file, symlink, wrong owner/mode, opaque or valid-looking row, hidden file, nested entry, or any other content refuses. Event rows are never accepted as GC evidence. It repeats the complete tmux/session/PID/start-tick/activity/inventory/hash proof immediately before every archive rename and before consumption. A durable prepared-to-consumed receipt makes the same nonce idempotent and permits only a byte-identical, fully revalidated partial-archive resume. Existing or ambiguous runtimes are never garbage-collected. The same command has a distinct pre-binding failed-launch branch. Only paired failed transactions and paired unusable failure receipts with session_cleanup: stopped qualify, and their control/workdir identities must match canonical project markers. It proves the project store, binding, authorization, submission, and runtime events absent; accepts only an empty capture plus one sealed launcher-provenance row; and archives the seven exact kind/digest-sealed entries with full rechecks. Partial, successful, mixed, extra, malformed, active, or raced generations refuse. Validated consumed archives are inert history during classification, so a later bound stale generation routes to normal GC. An exact old nonce replays only its matching consumed receipt; simultaneous live bound and failed-launch markers remain an ambiguous refusal. The successful atomic hierarchy commit is the fresh-store acceptance boundary. Git-root and other rejection-prone launch checks run before it. A no-workload tmux preflight creates, verifies, configures, and removes the exact isolated session first, using the same sealed new-session arguments as the real launch except for its bounded command. Server/session/pane provenance comes from one exact-target list-panes result, avoiding target-type-dependent empty format values. Probe and launch configuration use the returned session ID, pipe and dispatch use the returned pane ID, and identity rechecks refuse recreation before mutation or cleanup. Before rename, independent control/workdir transaction journals are durably prepared outside the project and the same transaction is embedded as a committing marker in the staged hierarchy. A crash or failure writing later receipts therefore still leaves fail-closed reuse evidence. Post-commit failures are reported as the explicit non-qualifying post_commit_launch_failure; diagnostic failure receipts and an unusable marker are best-effort redundant records, not the sole guard. The sealed control and workdir cannot be resubmitted, and any newly created tmux session is stopped by its exact returned session ID. No evaluation acceptance is recorded; the next attempt requires a new control and a different disposable workdir. The CLI helper requires --workdir to already be the root of a Git repository and does not initialize it or write Git identity settings. For an isolated run, create a fresh empty directory with mktemp -d and run git init explicitly first. A worker Git probe in an uninitialized workspace remains advisory observer noise.

Inspect complete calls and events, including after a discovered fault, and run audit before stopping. A command wrapper must expose its exit status or running session receipt. Collect the sealed evidence bundle from either the proven idle composer or the owned idle bash with its successful exit marker, then stop only that exact session; use bundle-authorized stop --interrupt for the idle composer or after a failed run. Ordinary CLI cleanup seals a receipt-bound immutable pre-stop capture/calls/events/hooks/terminal bundle. Every ordinary start first creates an owner-private cortex-live-session-binding-v1 receipt from the exact tmux server/session/pane identity and pane start tick, exposes only its opaque receipt in the start result, and retains it in the transient session state. Normal stop revalidates that binding before sealing; missing, mismatched, stale, or foreign receipts refuse cleanup. It also re-queries the current tmux server, session, pane, creation time, PID, and pane start tick immediately before sealing and again before killing; a restarted, replaced, or reused identity remains untouchable. Binding creation uses no-replace semantics, so a concurrent creator cannot be overwritten. A post-stop no-session probe uses its distinct diagnostic path and never overwrites that bundle. A normal successful stop requires the observed owned-bash Cortex live-dev exit=0 marker. Never kill the tmux server. Resume uses the same workdir and --resume-last, with the existing task confirmed.

Real Desktop uses scripts/cortex-desktop-dev start --workdir PATH --prompt-file FILE and the same isolated candidate in a disposable Electron profile. Confirm the prepared composer, then send focuses that exact window, submits with one plain Return and requires one new task receipt. Review its calls, events and audit too. The Desktop helper applies the same existing-repository validation without initializing the directory or writing Git identity, and treats a worker Git probe without a repository as advisory. Use ordinary hook trust; never bypass it for qualification. CLI/Desktop parity requires CLI ACCEPT before Desktop, then consecutive successful runs on one unchanged payload. A failed, rejected, unavailable, or unverified CLI ends that attempt; its Desktop counterpart is not run as a substitute. Unavailable hosts and unrun checks remain unverified.

The offline Phase 5 adaptive overlay remains advisory and fail-closed: candidate evidence must join selected report metadata, malformed proposals retain the static baseline, and recommendation reason/JSON sizes are bounded.

See verification, host compatibility, lifecycle hooks, comparative evaluation, and Phase 4 telemetry, and Phase 5 adaptive selection, and current release evidence.

Live development uses Luna/high for the coordinator and Luna at medium/high for native workers. The isolated helpers layer this user-requested test policy and audit actual participant/selector receipts. Heavy live-test models are rejected. This does not change stable settings or the plugin's general user-selected model policy.

Workers keep routine checks non-destructive: Python checks use the inherited PYTHONDONTWRITEBYTECODE=1 setting, and workers do not use recursive cache cleanup, git clean, reset/checkout, or similar commands just to remove residue. Existing residue is left in place and reported as a blocker when it prevents a check; host permissions remain native and no guidance auto-approves a destructive command. After a pending or timed-out wait_agent, the coordinator repeats a bounded wait for the same owner and may inspect status or selected evidence internally, but does not send send_message/followup_task solely because the wait produced no evidence. Only an inbound same-owner handoff reply, direct user steering/clarification, or an intentional follow-up after reconciling terminal worker evidence is a legal transition.

Governance and specialist responsibility

The coordinator owns the overall outcome; specialists own bounded assignments. Nontrivial changes use independent checking rather than calling developer self-tests an independent review. Current minimal/light/full governance is exposed by public tools and recovery hints and guides work depth; it is not a runtime prohibition, automatic heavy-model route or fixed agent pipeline. See incident coordination.

Live qualification repair β€” 2026-09-13

The compact coordinator retains public task binding before project work and the initial/final report protocol. The observer recognizes exact linked orchestrator reference reads after binding; unlinked or modified cache documents remain invalid. Current-candidate live CLI and Desktop acceptance is recorded in incident outcomes, not inferred from unit tests.

About

Cortex - Reliable multi-agent orchestration for complex software engineering work in Codex.

Topics

Resources

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Sponsor this project

Contributors

Languages