codex-chat is a safety-first Codex skill for coordinating a browser-based
external engineering collaborator without turning the user into a manual
copy-and-paste relay.
Codex remains the accountable engineering lead: it understands the request, inspects the repository, limits what source may leave the machine, delegates a bounded task, reviews the response, applies changes only through an isolated scratch copy, and independently runs the required tests.
The external collaborator is an untrusted senior engineer. It can research, challenge a design, review code, or return one tightly bounded patch. Its claims are never treated as proof that the implementation is correct.
Important
This is an experimental local workflow, not an official OpenAI product. Browser availability, account capabilities, usage limits, and model labels can change. The implementation deliberately avoids depending on a particular model or subscription name.
Complex engineering work benefits from separating implementation from acceptance:
| Role | Responsibilities |
|---|---|
| Codex | Product framing, repository inspection, authority boundaries, source selection, task decomposition, communication recovery, integration, testing, security review, and the final verdict |
| External collaborator | Deep research, design alternatives, implementation suggestions, adversarial review, and a bounded advisory or patch result |
| User | Defines the goal and authority; intervenes only for authentication, consequential product decisions, or an unrecoverable external blocker |
The separation is useful only if it remains an actual trust boundary.
codex-chat therefore assumes the collaborator can be mistaken, incomplete,
rate-limited, disconnected, or silently changed by its provider.
flowchart LR
U["User goal and authority"] --> C["Codex lead"]
C --> B{"Zero-egress browser gate"}
B -->|"Built-in Browser ready"| P["Preflight and atomic capsule preparation"]
B -->|"Primary unavailable; Ego ready"| P
B -->|"No transport ready"| X["Stop before source work"]
P --> S["Commit-last receipt and SHA-256 binding"]
S --> E["External collaborator"]
E --> R["Bounded result envelope"]
R --> Q["Quarantine and validation"]
Q --> I["Scratch-only integration"]
I --> T["Independent local tests"]
T -->|pass| A["Codex accepts"]
T -->|fail| F["Bounded correction turn"]
F --> E
The bundled CLI is a deterministic safety and evidence helper. It does not control the browser, inspect browser profiles, extract cookies, send messages, or call an API. Browser interaction uses the built-in Codex Browser by default or one isolated Ego task space after a conclusive pre-send primary outage. Both use a session authenticated by the user.
- Explicit invocation only. Source can leave the local machine, so the skill cannot activate implicitly.
- Authority never expands itself. Permission to edit locally does not imply permission to commit, push, publish, deploy, purchase credits, migrate data, or access production.
- Minimum necessary context. Files are selected explicitly. VCS internals, credentials, environment files, databases, runtime state, browser state, caches, and build output are denied.
- Scan and bind the exact egress. The serialized context sent to the
collaborator is identity-checked with
gitleaks, measured, and bound to a SHA-256 digest. The exact task envelope has its own digest, so context bytes cannot be confused with the actual outbound instruction. Parent gitleaks configuration is removed; inline allow directives and ambient ignore files are disabled in an isolated scan policy. - At-most-once automatic submission. A durable visible marker and idempotency record are created before sending. Ambiguity never authorizes a blind retry.
- Bind the exact response. Both the complete terminal response and the extracted result envelope are scanned and stored as create-once, content-addressed evidence. Review, import, and acceptance revalidate the receipt and reject changed bytes even when run, turn, and context identifiers match.
- Treat returned code as hostile. Results are quarantined and scanned. The MVP accepts either an advisory or a zero-fuzz patch for one existing UTF-8/LF file with an exact preimage digest.
- Apply only to scratch. The collaborator never writes directly to the working tree.
- Verify independently. Test claims from the collaborator are not evidence. Codex runs digest-pinned argument-vector commands locally without a shell. Coordinated acceptance re-hashes every required success receipt.
- Fail closed. Corrupt state, changed paths, missing scanners, exhausted usage, ambiguous sends, and malformed responses stop or suspend the workflow.
- Route by immutable identity. Multi-agent work binds workspace, coordinator, run, work unit, agent, conversation, and turn. Titles and visible model labels are never routing keys. A shared local registry leases both logical conversation identity and confirmed provider locator so active coordinators cannot interleave one conversation.
- Separate source from representations. Exact bytes, excerpts, OCR, page renders, summaries, formulas, displayed values, and crops have separate digests and provenance. Model visibility remains unknown until transport evidence proves otherwise.
- Fence cross-host writers. Multi-host participants connect to one durable authority that assigns coordinator epochs, rejects stale fences, compares exact distributed run heads, and partitions bounded mailboxes by immutable route.
- Choose one browser transport. The built-in Browser is primary. Ego is the only optional fallback, is checked once before source work, and remains bound for the complete run. A possible upload or send permanently closes the fallback window. A capability-protected local bootstrap lease prevents concurrent coordinators from entering Ego's account-level draft seam before the normal conversation lease exists. Ego's bounded browser observations and live cleanup identities are evaluated by a strict local executable decision core, not duplicated prose-only browser branches.
- Plan exact egress by size. A scanned transport manifest binds the context, task, transport, exact composer bytes, and optional ordinal-zero attachment before run creation. Small context is inlined; larger context requires an observed upload capability. The plan never authorizes action, resend, or a model-visibility claim.
- Commit capsules atomically. Context, task, and transport artifacts are content-addressed and scanned before a create-once capsule receipt becomes authoritative. Concurrent identical writers converge; divergent or interrupted writers cannot expose a mixed capsule generation.
- Decode protocols in one place. A strict versioned codec module owns canonical encoding, exact-key validation, version dispatch, size limits, and relational invariants for the complete outbound capsule family.
- Snapshot untrusted files through one gate. Outbound inputs and durable evidence use one no-follow, byte-bounded reader that verifies regular-file type, optional private mode, descriptor/path identity, and unchanged metadata before returning bytes.
- Register each operational command once. One validated command registry owns the handler, required and optional options, repeatable options, dispatch, and machine-readable help. Unknown or misspelled options fail before any command side effect.
- Report collaboration state mechanically. A route-bound outcome command separates transport readiness, capsule authority, possible egress, submission, response availability, and accepted verification. Local Playwright or staging evidence remains independent Codex evidence and can never be described as an external-collaborator transport fallback.
The complete rules live in
SKILL.md, with detailed protocol and
security contracts under
references/.
The v2 context sidecar keeps every representation explicit. Original code, text, images, rendered pages, OCR, excerpts, summaries, spreadsheet values, and formulas each carry their own digest, byte count, fidelity, locator, and transformation provenance. A derived representation cannot silently stand in for its source.
Transport evidence is separate from context provenance. A delivery receipt
binds one representation and attachment ordinal to the exact coordinated run
head, route, conversation, turn, provider observation, and scanned raw
evidence. Provider acceptance still leaves modelVisible: "unknown".
Concurrent work is isolated by immutable workspace, coordinator, run, work unit, agent, conversation, and turn identities. Each run has its own compare-and-swap ledger; hardened turns lease the provider conversation across all runs in one state directory; and overlapping writers serialize behind target-specific locks. Before an Ego run has a conversation identity, a separate expiring bootstrap lease assigns the shared local browser profile to one coordinator. Its hashed capability and takeover generation reject stale renewal or release, and ownership overlaps the later conversation lease.
When participants span hosts, the opt-in control-serve process becomes one
authoritative coordination seam. It persists monotonic coordinator epochs and
fencing tokens, an exact distributed run head, provider-conversation claims,
and bounded partitioned mailboxes with visibility redelivery,
capacity-neutral availability peeks, exact peek-to-claim binding,
acknowledgement, cancellation, and finalized-payload pruning. The local run
ledger remains the richer browser-workflow and acceptance-evidence record.
See
coordination-v2.md
and
distributed-coordination-v1.md
for the distinct local and multi-host contracts.
- Codex in the ChatGPT desktop app with the built-in Browser capability
- An authenticated ChatGPT browser session for the external collaborator
- Optional fallback: Ego Lite with its
ego-browserskill and CLI already installed and the user logged in - Node.js 22 or newer
gitleaksavailable onPATH
Ego is not installed or configured automatically. Installation, authentication, account selection, CAPTCHA, passkeys, passwords, and two-factor verification always remain human actions.
Clone the repository and start Codex from inside it. The skill is already in
.agents/skills/codex-chat, the standard repository-scoped skills location.
git clone https://github.com/xicv/codex-chat.git
cd codex-chatFrom a clone on main, install the exact committed skill at
~/.codex/skills/codex-chat and expose its CLI as
~/.local/bin/codex-chat:
npm run sync:local:installThis also configures repository-local Git hooks. Whenever the local main
reference changes, the committed skill is synchronized automatically. A
pre-push guard synchronizes once more and rejects a push to remote main
unless it comes from the exact local main object. Dirty and untracked files
are never copied.
For a one-off synchronization without installing the hooks, run:
npm run sync:localEnsure ~/.local/bin is on PATH, then verify the installed bytes, executable
modes, CLI link, and hook configuration without changing them:
npm run sync:local:checkCodex detects skill changes automatically. An already-open task may retain the skill inventory it started with; open a new task if the updated skill does not appear, and restart Codex only if a new task still cannot discover it.
Codex keeps repository and personal skill scopes separate. When this authoring
repository and the personal installation are both visible, two codex-chat
entries can appear because equal skill names are not merged. Keep the
auto-updated personal installation as the canonical entry and disable only the
repository-scoped authoring copy in ~/.codex/config.toml:
[[skills.config]]
path = "/absolute/path/to/codex-chat/.agents/skills/codex-chat/SKILL.md"
enabled = falseRestart the ChatGPT desktop app after changing this setting. The repository
source remains checked in, and the Git hooks continue synchronizing its
committed main bytes to the personal installation.
Open a Codex task and invoke the skill explicitly:
$codex-chat
Work in /path/to/project.
Task:
Fix the intermittent duplicate-processing race in the background worker.
Acceptance criteria:
- Add a deterministic regression test.
- Preserve the public job payload contract.
- Unit, contract, and local E2E tests pass.
Authority:
- Read and modify local source and run tests.
- Do not commit, push, create a PR, deploy, migrate data, purchase credits,
or use paid API fallback.
Codex should then:
- inspect the project and its instructions;
- prove the JavaScript tool transport, browser binding, and authenticated external-collaborator composer without typing, attaching, uploading, or sending;
- select and scan only the necessary context;
- reserve and send one bounded external turn;
- monitor without duplicate submission;
- import and review the exact returned result;
- run local acceptance gates;
- send precise correction evidence when necessary; and
- report what is local, committed, pushed, published, or deployed as separate states.
The MVP was developed by applying its own responsibility split:
- Codex established the product boundary, wrote the implementation, and packaged an exact scanned review capsule.
- The external collaborator found concrete flaws in crash recovery, idempotency binding, terminal-result integrity, scanner impersonation, and destructive output handling.
- Codex reproduced those findings, added regression tests, and corrected the implementation.
- After an external
GO, Codex's own dogfood import found another integration defect: an advisory result from an early durable run attempted to canonicalize a missing source root. - Codex fixed the defect test-first, imported the exact external result, sent one final bounded recheck, and reran every local gate.
- A continuation run then examined typed multimodal context and multi-coordinator isolation. The external advisory led to run-head-bound, immutable delivery slots with scanned raw evidence and idempotent replay.
Current local evidence:
| Gate | Result |
|---|---|
| Unit tests | 238/238 |
| Contract tests | 41/41 |
| Chaos/recovery tests | 5/5 |
| Local E2E tests | 3/3 |
| Aggregate test gate | 287/287 |
| Independent scratch verification | Passed |
| Repository source scan | Clean |
| Installed skill parity / secret scan | Exact / Clean |
This example is intentionally not presented as production proof. It demonstrates local orchestration, recovery, correction, and verification.
The executable entry point is:
.agents/skills/codex-chat/scripts/codex-chat.mjs
Run it directly with Node:
node .agents/skills/codex-chat/scripts/codex-chat.mjs --help
node .agents/skills/codex-chat/scripts/codex-chat.mjs preflight \
--root "$PWD" \
--include src/example.mjs
node .agents/skills/codex-chat/scripts/codex-chat.mjs prepare-capsule \
--root "$PWD" \
--include src/example.mjs \
--task-envelope /private/tmp/codex-chat-task.txt \
--capsule-id <intended-run-id> \
--transport-kind browser \
--upload-capability unknown \
--output-root /private/tmp/codex-chat-capsules
node .agents/skills/codex-chat/scripts/codex-chat.mjs capsule-validate \
--output-root /private/tmp/codex-chat-capsules \
--capsule-id <intended-run-id> \
--receipt-sha256 <capsule-receipt-sha256> \
--transport-kind browser \
--upload-capability unknown
node .agents/skills/codex-chat/scripts/codex-chat.mjs collaboration-outcome \
--workspace-id <workspace-id> \
--coordinator-id <coordinator-id> \
--work-unit-id <work-unit-id> \
--agent-id <agent-id> \
--attempt-id <attempt-id> \
--run-id <run-id>
node .agents/skills/codex-chat/scripts/codex-chat.mjs manifest \
--root "$PWD" \
--plan /private/tmp/codex-chat-manifest-plan.json \
--output /private/tmp/codex-chat-manifest.json
node .agents/skills/codex-chat/scripts/codex-chat.mjs delivery-receipt \
--state-dir /private/tmp/codex-chat-runs \
--run-id <run-id> \
--manifest /private/tmp/codex-chat-manifest.json \
--plan /private/tmp/codex-chat-delivery-plan.json \
--evidence /private/tmp/codex-chat-provider-evidence.bin
node .agents/skills/codex-chat/scripts/codex-chat.mjs terminal-capture \
--state-dir /private/tmp/codex-chat-runs \
--run-id <run-id> \
--capture /private/tmp/codex-chat-terminal-response.txt \
--result /private/tmp/codex-chat-result.json
node .agents/skills/codex-chat/scripts/codex-chat.mjs recovery-plan \
--state-dir /private/tmp/codex-chat-runs \
--run-id <run-id>
# CODEX_CHAT_CONTROL_TOKEN must already be populated by a secret manager.
node .agents/skills/codex-chat/scripts/codex-chat.mjs control-serve \
--state-dir /var/lib/codex-chat/control \
--host 127.0.0.1 \
--port 9443
node .agents/skills/codex-chat/scripts/codex-chat.mjs control \
--endpoint http://127.0.0.1:9443 \
--request /private/tmp/coordination-request.json--help returns the registry-derived command and option contracts as JSON.
The same registry validates dispatch, so help cannot advertise a command that
has no handler and a command cannot silently accept an undeclared option.
Unknown options fail with USAGE before the selected handler runs.
When collaboration-outcome reports transport_pending_pre_egress, it also
returns disposition=continue_required and repeats the exact transport
decision and nextAction in its canonical statement. That statement is a
durable checkpoint: the coordinator must execute the prescribed read-only
continuation and must not report the pending state as a terminal blocker.
After run creation, every canonical outcome likewise includes a controlled
disposition and the ledger-derived run nextAction.
send_reconciliation_required therefore reports
disposition=reconcile_required and nextAction=reconcile-marker-before-send;
it must not be paraphrased as delivery ambiguity or non-delivery.
Atomic capsule preparation uses a private store outside the source root. Its
content-addressed context, task-envelope, and transport-manifest artifacts are
non-authoritative until the create-once capsule receipt is published last.
Exact replay recovers partial publication; a divergent snapshot under the same
capsule ID fails closed. Read-only capsule validation opens no missing store,
rechecks every object, strictly decodes the three versioned artifacts,
reconstructs the transport manifest, and rejects a crossed selected transport.
The lower-level pack and transport-plan commands
remain create-only compatibility primitives. Delivery receipts use
create-only, content-addressed paths beneath the durable run state directory.
Delivery receipts and terminal captures share one internal
immutable-evidence store for exact-input scanning, private directory identity,
per-slot and run-head serialization, partial-publication recovery, idempotent
replay, and final tamper checks. The CLI never replaces an existing artifact.
| Command | Purpose |
|---|---|
preflight |
Validate source selection, state location, VCS metadata, and scanner availability |
transport-attempt |
Own the durable Browser-to-Ego readiness state machine, write-ahead side effects, exact crash replay, immutable route binding, private capabilities, and resumable status |
collaboration-outcome |
Read the route-bound attempt and optional run, classify exact egress/submission/response authority, and emit canonical report text with mandatory operational fields for pending transport and durable run states |
transport-gate |
Serialize primary-browser health probes, remember a closed host generation, neutrally release an unused claim, and allow one bounded half-open probe after a host restart or cooldown |
pack |
Create and scan a deterministic COLLAB_CONTEXT_V1 artifact |
prepare-capsule |
Atomically prepare, scan, content-address, and commit one context/task/transport capsule with idempotent crash recovery |
capsule-validate |
Read-only revalidation of the authoritative receipt, all capsule objects, codec invariants, and selected transport |
transport-plan |
Create and scan a digest-bound size-aware composer/attachment plan without authorizing browser action |
manifest |
Create and scan a typed COLLAB_CONTEXT_MANIFEST_V2 provenance sidecar |
delivery-receipt |
Create and scan immutable, digest-bound transport evidence without claiming model visibility |
terminal-capture |
Verify, scan, and publish create-once full-response and result evidence |
control-serve |
Run the durable, fenced coordination authority for local or multi-host clients |
control |
Execute one authenticated coordination request against that authority |
record |
Append a typed transition to the hash-chained run ledger |
status |
Derive the current run state and safe next action |
resume |
Recover state without authorizing an unsafe resend |
recovery-plan |
Emit a deterministic read-only transport reconciliation contract |
import |
Bind, quarantine, scan, and optionally apply one result to scratch |
verify |
Execute a digest-pinned verification plan without a shell |
Every command returns one stable JSON envelope suitable for inspection or automation.
codex-chat tracks the controller, collaborator, transport, observed external
model label, agentic allowance, upload capability, and API budget separately.
- The built-in Browser is capability-probed before source selection or capsule
creation. A repeated pre-send
Transport closedopens its durable circuit;js_resetand anothernode_repl-backed surface are not recovery paths. - A shared transport circuit serializes this no-source probe across local
coordinators. After a repeated
Transport closed, later calls fail locally without touching the closed transport for five minutes and return an exact retry time. A host-generation change permits an earlier probe; otherwise one coordinator may claim a same-host half-open zero-egress probe after cooldown. Failure restarts the cooldown, cooldown recovery never claims a restart, and neither path authorizes source work by itself. - Browser claim/resolution and Ego acquire/release effects keep bounded capability-digest receipts. A checkpoint crash can replay only the exact action; replay of an older resolution cannot mutate a newer coordinator's active claim or lease.
- Conclusive pre-egress exhaustion is a durable terminal attempt rather than an exception over stale pending state. Canonical outcome reporting preserves exact reason, retry time, restart observation, and the difference between denied egress authority, unreserved send, ambiguous delivery, confirmed submission, received response, and locally accepted result.
- After a conclusive primary outage, an already-installed Ego Browser is the only fallback. It gets one isolated task space and one read-only readiness attempt. If login or verification is required, control returns to the user; if Ego itself fails, the branch stops without retries or another surface.
- Ego readiness detects account-restored ChatGPT drafts before capsule work. It preserves the inherited draft, tries one source-free distinct tab, and proceeds only when that tab has an authenticated empty composer. The run is then bound to both the task space and exact tab; every later command reselects it, and cleanup preserves the unrelated draft tab. A strict local module rejects unknown readiness fields and draft bytes, decides every readiness state, and plans cleanup before any tab or task-space mutation.
- Ego sends preserve the durable marker outside the browser command, reject
unknown persisted drafts, and canonicalize multiline ProseMirror paragraphs
from exact
textContentinstead of inflatedinnerText. Unexpected composer shapes stop without mutation. Ego types only into an empty composer and uses one verified send-button click. Compose, submit, and observe are separate, so missing command output is reconciled read-only instead of retried. - Ego compose, pre-submit, and post-click branches use a strict local decision core instead of duplicated inline conditions. It receives no raw draft or response text, reasserts the exact task-space/target and attachment identity, and keeps missing output, provisional locators, duplicate markers, and crossed bindings ambiguous without authorizing resend.
- A healthy primary with an unavailable authenticated composer is a provider or user-authentication blocker, not a reason to switch browsers.
- The selected transport is bound to the complete run. Any possible upload or send closes the fallback window; ambiguous delivery is preserved and never resent through the other browser.
- A slow or disconnected response remains observe-only after submission. A preselected observation budget can release the local critical path by recording degraded independence and continuing local work, without cancelling, resending, switching transports, or pretending the provider response is terminal.
- A changed reset time or refreshed page never authorizes another send.
- A conclusively failed provider turn ends the current run.
- If the collaborator is temporarily limited, the run records the observation and waits for a known reset or explicit recovery.
- If both Codex and the collaborator are limited, the run suspends with resume metadata rather than spinning or purchasing capacity.
- Codex may take over locally only when the existing authority permits it. The run then permanently records degraded reviewer independence.
- A changed or unobservable model label is reported as an observation, never treated as proof of backend identity.
- A delivery receipt binds one representation and attachment ordinal to a confirmed routed turn, its exact ledger head, and scanned raw observation evidence. It proves neither upload automation nor model visibility.
- A terminal capture receipt binds the exact task, full response, extracted
result, route, conversation, turn, provider fingerprint, and terminal marker.
A schema-invalid result is durably rejected into correction-only state with
its exact
RESULT_*failure instead of becoming an uncaptured dead end. - Equivalent noncritical resource observations may coalesce within five seconds. General idempotency snapshots retain 128 records, outbound records remain permanent, and a run history segment is capped at 1,024 events before an exact-head-bound continuation; the final 32 slots are reserved for safe completion.
- Distributed coordination separately bounds journal, snapshot, idempotency
results, retained payloads, message tombstones, mailbox count/bytes, claims,
and request rate. Workers poll with read-only
mail.peek, then bindmail.claimto the exact observed message and delivery attempt; 100,000 empty peeks consume zero journal or idempotency records. Near a lifetime segment limit, make all runs terminal and archive the segment; never discard an active segment's fences or idempotency state. - Paid API fallback and automatic credit purchase are disabled by policy.
The runtime has no npm dependencies. Tests use the Node.js built-in test runner. See changelog.md for the Git-derived project history.
npm run test:unit
npm run test:contract
npm run test:chaos
npm run test:e2e
npm testThe aggregate npm test gate runs up to four independent test files in
parallel. Focused suites remain serialized to keep failure diagnosis simple.
Project structure:
.agents/skills/codex-chat/
├── SKILL.md
├── agents/openai.yaml
├── references/
└── scripts/
├── codex-chat.mjs
└── lib/
test/
├── unit/
├── contract/
├── chaos/
└── e2e/
Before sharing or publishing changes:
- inspect the exact file inventory;
- search for machine-specific paths and personal identifiers;
- scan the working tree with
gitleaks; - run the project tests;
- inspect the staged diff;
- scan the committed Git history; and
- verify that the remote contains the intended commit only.
Do not commit generated collaboration capsules, run ledgers, browser state, quarantine artifacts, credentials, or local verification evidence.
Security assumptions and exclusions are documented in
references/security.md.
- The MVP imports at most one existing text-file patch per result.
- The CLI provides evidence and state management; it does not itself automate a browser.
- Durable browser-host generation detection currently targets the macOS ChatGPT desktop app. Other desktop platforms fail closed at this circuit rather than guessing that a restart occurred.
- Ego fallback depends on the separately installed Ego Lite app, skill, CLI, and user-managed login. It does not repair the primary browser transport, provide automatic authentication, or authorize a post-send retry.
- The transport manifest plans one inline or capability-gated attachment path,
but the CLI does not control the browser. Transport adapters remain
responsible for the single observed upload. Delta reconstruction and proof
of backend model visibility are not implemented;
modelVisibleremainsunknown. - The distributed control plane supports clients on several hosts but has one authoritative single-writer process. Replicated consensus, automatic authority-host failover, per-principal authorization, streaming/long-poll delivery, dead-letter queues, broadcasts, and active-segment compaction are not implemented.
- Its bearer token defines a trusted coordination domain. Mutual TLS can authenticate the channel, but certificate identities are not mapped to workspace or operation permissions.
- Hosted, production, deployment, and physical-device verification are outside the local E2E evidence class.
- Original dual-agent workflow article (Chinese) — inspiration for separating the engineering collaborator from the accountable lead; its product and model claims are not treated as implementation requirements.
- OpenAI: Build skills — skill structure, explicit invocation, local discovery, and supporting resources.
- OpenAI: Browser — built-in browser capabilities, separate browser profiles, permissions, and safety boundaries.
- Agent Skills specification — the open skill format
used by
SKILL.md. - Gitleaks — secret scanning for exact context and result artifacts.
codex-chat is an MVP intended for local experimentation and review. It is not
an official OpenAI project, and it is not yet distributed as a plugin or npm
package.