MD-OS

MD-OS Cortex Agentic Shell

./cortex is the repository-local interactive entrypoint for MD-OS. It preserves the real host-shell experience and fuses it with the native Codex agent loop. It is not a browser console, a simulated filesystem, or a one-command text generator.

The operating rule is intentionally small:

valid native input -> real host shell -> bounded observation
natural language   -> full Codex loop for the current workspace

The first path stays immediate. The second path can understand the repository, load AGENTS.md, reason, inspect files and state, plan, use workspace-bounded tools through the APFC action gate, observe effects, correct its plan, verify the result, answer, and preserve the Codex thread.

Codex provides the plastic reasoning-and-tool loop. MD-OS provides the persistent identity and Operational Context as Filesystem: method, memory, semantic commitment gates, policy, bounded authority, executors, sensors, verifiers, and ledger readback. cortex is where these layers meet the real interactive shell.

Prerequisites

Start

No installation or PATH modification is required. From the checkout root:

./cortex

Run ./cortex from the checkout root. From another directory, use the explicit path to that checkout, for example /path/to/MD-OS/cortex.

On Linux, macOS, and BSD when tmux is available, an interactive invocation attaches to one shared Cortex session derived from the Git workspace. Running ./cortex from a local terminal, an SSH login, or WebSSH while inside the same repository therefore displays and controls the same REPL, App Server, active turn, and Codex thread. Multiple clients may remain attached simultaneously. Outside Git, the resolved current directory is the session boundary.

The complete startup message is:

MD-OS cortex agentic shell
Native commands run directly; natural language enters the full Codex loop.
Use exit or Ctrl-D to leave.

Then type ordinary commands and natural language in the same interface:

ls -la
cd ~/projects/project-a
what did we establish here in the previous session?
inspect the repository, verify the failing test, fix it, and run the checks

No quotes, apostrophes, prompt prefix, or special chat command are required. Use exit or Ctrl-D to leave. The compatibility inputs quit, /exit, and /quit also remain accepted even though the minimal startup text omits them.

Cortex enables terminal bracketed-paste mode. A single-line paste that fits the current terminal row remains visible literally. For multiline or longer text, Cortex stores the complete content in volatile memory and inserts [PASTED BLOCK 1] at the cursor. The operator may continue typing before or after that placeholder. On submission, Cortex replaces the placeholder with the original text before sending the request to Codex; the label itself is never sent. No special command, .end, or Ctrl-D is required. /paste remains only as a compatibility fallback for terminals that remove bracketed-paste events.

During an active Codex turn, Cortex keeps input canonical but disables terminal echo. This prevents partially typed steering text from being interleaved with streaming assistant or tool output. Pressing Enter prints a separate confirmation containing the complete short input or [paste] for a long input, then forwards the unchanged text through turn/steer.

One-shot natural-language input also uses the native Codex loop:

./cortex "explain the architecture of this repository"

The deterministic MD-OS runtime remains under the same command:

./cortex health
./cortex graphify status
./cortex replay

cortex dispatches known deterministic subcommands to md-os/os/mdos.js. Running cortex without arguments opens the agentic shell; other free-form input goes to the shell engine. mdos remains a deprecated command alias, while mdos-console remains the compatibility engine name and is not the public name.

Exact interactive flow

For every complete input line:

human input
├── cd / chdir / Set-Location
│   └── change the persistent parent REPL directory
│       └── update PWD, OLDPWD, prompt, completion, and observation queue
├── first token resolves to a native executable
│   └── execute immediately in the detected host shell
│       └── preserve bounded command/output/exit readback
└── natural language
    └── resolve current cwd and Git workspace
        └── APFC dynamic input filter
            ├── load the bounded invariant baseline
            │   └── identity, bootstrap, core, orientation, active work,
            │       continuity, and generated context-pack catalog
            ├── load portable_state.json only if every declared hash verifies
            ├── hash every loaded baseline source into a typed context contract
            ├── treat lexical matches as advisory task-routing hints
            ├── require dependency resolution before nontrivial claims/actions
            └── expose selected paths, omitted paths, and sufficiency status
        └── reuse only the live in-process binding for the same workspace
            or thread/start -> a fresh persistent Codex thread by default
            or explicit /resume -> thread/list then thread/resume
        └── turn/start with the current cwd
            ├── native AGENTS.md discovery
            ├── reasoning and planning
            ├── repository and state exploration
            ├── workspace-bounded tool use
            ├── deterministic APFC approval decisions
            ├── streamed tool and agent readback
            ├── correction and verification
            └── final answer and Codex-native session persistence

While a Codex turn is still running, the REPL continues polling terminal input. Type another message and press Enter to forward it to the active turn through the same APFC dynamic input filter and App Server turn/steer. It becomes additional user direction for that same turn; it is not held as a separate later request and does not restart the App Server. This steering path is enabled for a real interactive TTY, not redirected one-shot stdin.

baseline = ready means that stable orientation and the routing catalog were loaded; it does not mean that the current task is fully understood. A nontrivial turn must still identify its dependency edges, inspect the required canonical sources and current readback, and then act or state that context is insufficient. Merely loading every file is neither required nor proof of semantic understanding.

Pressing Esc while a turn is active sends App Server turn/interrupt immediately, without requiring Enter. At the ordinary prompt, Esc aborts the current editable line like Ctrl-C; neither action exits the Cortex REPL.

Codex slash commands

Cortex reserves every currently documented Codex slash-command name, so slash input is never misrouted as an ordinary model prompt. /help prints the live catalog. Protocol-backed or deterministic adapters cover /goal, /compact, /rename, /fork, /new, /resume, /clear, /status, /model, /diff, /review, /exit, and /quit. Commands that require a Codex TUI picker, clipboard, IDE, desktop app, account dialog, or Windows-only setup remain recognized and return an explicit capability notice instead of pretending the operation occurred.

There is no Python keyword classifier for natural language and no mandatory AGENT: os / AGENT: answer routing header on this primary path. The final assistant message is text; it is never silently re-executed by the parent shell. Real model-selected actions happen through Codex tools constrained by the APFC turn frame, workspace sandbox, and ordinary tool-result events.

The APFC input filter is contextual rather than lexical: it does not classify requests from a fixed phrase list and does not rewrite the human statement. For each ordinary input and steering message, it loads the bounded invariant baseline and the generated context-pack catalog, then adds any advisory relevance-selected health readback. Local last_turn.md and last_summary.md files remain inspectable runtime artifacts but are never injected automatically; they require an explicit task-directed read. Loaded, missing, selected, and omitted sources are declared inside the context sent to Codex. This makes the APFC causally present before turn/start and turn/steer; it is not claimed to be an infallible safety classifier or an output gate.

The pre-model selector uses only the current human request as its advisory relevance query; invariant baseline presence does not depend on lexical overlap. Cortex does not infer or persist a semantic theme or focus at this stage because such an unverified label can misframe unrelated later turns and interfere with Codex-native thread continuity. The complete dynamic context is capped at 12 KiB. Explicit goals, capabilities, inhibitions, source paths, the context-sufficiency contract, and the verification contract remain inspectable in the frame. A legacy local attention.json, if present, is ignored and is not recreated.

Explicit legacy JSON/Markdown programs and MDOS_CODEX_BACKEND=exec retain the older tagged-output protocol only as compatibility paths. They do not define the normal interactive architecture.

Workspace-bound continuity

The App Server process starts lazily on the first natural-language request and stays alive until the REPL exits. Native-only use therefore pays no model startup cost.

The REPL also keeps the Python shell engine loaded for its lifetime. Changes to md-os/shell/bin/mdos-console therefore require a process restart: exit the shared Cortex REPL and run ./cortex again. build:all, graph rebuilds, and replay refresh generated files but do not hot-reload the running shell engine. After restart, the next natural-language turn must expose the current APFC frame schema and the context-sufficiency contract; an older frame is evidence that an older process is still attached.

Interactive Cortex processes are first bound to one shared terminal session by Git workspace on POSIX systems with tmux. This makes local, SSH, and WebSSH entrypoints converge on the same live process rather than merely opening the same directory in separate processes. Set MDOS_SHARED_SESSION=never only when an intentionally isolated interactive process is required; set it to always to require tmux rather than falling back when it is unavailable.

Codex threads are also bound by current Git workspace, falling back to the exact current directory outside Git. On ordinary process boot, cortex starts a fresh thread and does not list stored conversations. Later turns reuse that live thread only while the process remains in the same workspace. Moving to another repository starts another fresh thread.

This is the default isolation boundary:

cd ~/projects/project-a
-> fresh Codex thread + identity + private folder chronology when present

cd ~/projects/project-b
-> fresh Codex thread + identity + project-b private chronology when present

Codex’s session store remains available only as optional chat history. /resume explicitly enables one lookup and resume of the latest matching thread. /new and /clear close the current App Server and force the next request through thread/start. Fresh threads normally receive a bounded recent tail from md-os/ops/local/cortex/conversation.ndjson. Cortex appends each successful exchange to this private hash chain; it stores human inputs and the final assistant response, not hidden reasoning, tool traces, model ids, or Codex thread ids.

The private file has a different transport rule from the repository sources: a physical copy of the whole folder carries it, while Git ignores it. Therefore cp -a, rsync -a, or a full archive can preserve the conversation across directories or computers, but git push and git clone cannot. The versioned md-os/continuity/portable_state.json remains a privacy-reviewed operational summary without a transcript. Set MDOS_PRIVATE_CONVERSATION=off to disable local conversation persistence.

Git privacy and network privacy are separate. Hydration sends the selected private excerpt to the configured model provider as inference context. A local model is required if the transcript must not leave the machine at all.

The ordinary context compiler also excludes host-local last_turn.md and last_summary.md. They can be inspected only when the current human request explicitly calls for historical diagnosis; they are not implicit identity or continuity inputs.

Git-clone-carried operational continuity comes from md-os/continuity/portable_state.json. Cortex imports it only after checking its self-hash, identity-source hashes, evidence hashes, schema-level field boundaries, and non-authoritative policy. A rejected capsule is shown as rejected and contributes no working-context content.

If explicit /resume finds that another process owns the stored thread, Cortex stops with attach guidance. Ordinary fresh boot does not depend on that thread and therefore does not encounter this conflict.

Shell observations

Valid native commands bypass the model completely, but the REPL retains a bounded observation of their command, directory, exit code, and normalized terminal output. Those unconsumed observations are attached to the next Codex turn as operating data, then cleared only after successful delivery.

The volatile queue retains at most 32 events, at most 16 KiB of output per event, and at most 64 KiB in one turn. It is not written into the repository. Tool output deltas are rendered without flattening their newlines, so tables, process lists, test output, and compiler diagnostics retain terminal shape. The default full trace also renders the Codex reasoning summaries made available by the protocol, plan updates, commands and command input/output, file changes and diffs, MCP progress, web searches, approvals, and agent messages. It does not expose private hidden chain-of-thought that Codex does not publish. Set MDOS_CODEX_TRACE=compact to hide reasoning/plan/diff detail, or MDOS_CODEX_TRACE=quiet to keep only essential output and prompts.

Every interactive semantic turn also receives a compact live-legibility contract. Nontrivial work announces its object and reason before using a tool, then reports only material doubts, failed assumptions, changed hypotheses, decisions, or a progress heartbeat when work lasts longer than 60 seconds. When a material doubt exists, Cortex asks the critical question within the same turn, tests the hidden premise or failure case, and revises the answer before committing to it. These messages are streamed from the same ordinary turn. They do not start an inner-voice process, a background call, a timer, or a second turn. Simple answers remain direct. The result is operational transparency rather than a fabricated transcript of private chain-of-thought.

Safety and authority

The two action paths have different authority:

The APFC gate fails closed without an active turn frame. It rejects external working directories, network authority, destructive commands, and additional permission requests. It may approve bounded local commands and workspace file changes without interrupting the human. Explicit native commands remain a separate human-controlled path and retain ordinary host-shell authority.

Do not print credentials, private keys, tokens, or other secrets before a natural-language turn: bounded shell output may be sent to Codex as context. No shell observation or raw chat is promoted into canonical MD-OS memory without a separate semantic commitment gate.

Preserved shell behavior

Codex configuration

The shell inherits the model and reasoning effort from the user’s Codex configuration by default. Optional overrides are explicit:

Variable Meaning
MDOS_MODEL select an explicit Codex model; default: inherit Codex configuration
MDOS_SHARED_SESSION auto (default), always, or never; control the POSIX per-workspace shared tmux session
MDOS_REASONING_EFFORT select a supported effort; default: inherit Codex configuration
MDOS_CODEX_BACKEND app-server (native persistent path) or exec compatibility mode
MDOS_CODEX_BIN override the codex executable, primarily for testing
MDOS_CODEX_TRACE full (default), compact, or quiet event rendering
MDOS_CODEX_COLOR auto (default), always, or never for Codex event and answer colors
MDOS_PROMPT_COLOR auto, always, or never
NO_COLOR disable automatic prompt and Codex colors

The implementation uses Codex App Server’s documented thread lifecycle and streamed structured items. ANSI colors are rendered locally from item type and status because the protocol does not supply the Codex terminal client’s already rendered byte stream. See the official Codex App Server documentation.

Bootstrap versus cortex

The bootstrap still exists and has a separate role:

./bootstrap-md-os-codex.sh
  -> opens the ordinary interactive Codex client in this repository

./cortex
  -> opens the MD-OS shell from any directory
  -> native input stays shell-native
  -> natural language enters a workspace-bound ordinary Codex agent thread

The bootstrap is not called once per shell turn and is not replaced by the agentic shell. Both paths use Codex as the host runtime while MD-OS carries the persistent identity, method, semantic gates, and Operating Filesystem.