NC Codex · Docs

Codex architecture

Last reviewed: 2026-10-10 · Last updated: 2026-10-23 · Change: minor (xtask ci: translation gaps report) · Target: Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS)

How Codex is built today. The design rationale and the planned crates live in plan/architecture.md and plan/adr/ (local-only); this file describes what is on main. Each crate's README.md has the detail.

Shape

One Cargo workspace (Cargo.toml, edition 2024, Rust ≥ 1.95, MIT OR Apache-2.0), 31 library crates in crates/, three binaries in apps/, build tooling in xtask/, and patched third-party crates in vendor/. About 152k lines of Rust and 1,765 tests (2026-10-10). Rust only: no handwritten JS/TS, in the product or the build.

Binary What it is
apps/codex The desktop app (macOS, Windows, Linux, FreeBSD): eframe/egui on wgpu, single instance, Apple events, update check on request
apps/codex-cli inspect, edit, combine, extract, split, run (any automation tool or a JSON script), tools, ui (drive the running app), and the opt-in mcp server
apps/codex-web The same egui shell compiled to WebAssembly

Layers

cargo xtask layers enforces the layering (xtask/src/layers.rs). A crate may depend only on crates in lower layers; nothing below L7 may depend on egui, winit, eframe or rfd; L0–L1 crates are standalone and publishable.

Layer Crates today Role
L0 foundation geom, filters, crypt Geometry; stream filters (Flate, LZW, predictors, ASCII85, ASCIIHex, RunLength); standard security handler R2–R6 (RC4, AES-128/256, SASLprep)
L1 objects cos Lazy, tolerant parser with xref repair; copy-on-write object graph; incremental and full writers with object streams; decryption on load and re-encryption on save
L2 core model content, model, fonts Content-stream operators with source spans and a serializer; typed page tree with inherited attributes and display geometry (/UserUnit, /Rotate); font metrics and encodings for generated appearances
L3 core services render, annot, forms, js, xfa Rendering and inspection (bootstrap: vendored hayro, lopdf); annotation builders and appearance streams; AcroForm model, filling, appearances; sandboxed JavaScript (boa) and FormCalc; XFA template layout and data
L4 features edit, organize, redact, xfdf, sign, ocr, create, export, optimize, preflight, a11y, compare, measure, print One crate per Acrobat tool family
L6 façade engine Session, open documents, edit history, the command registry and tool catalogue. Frontends never reach past it
L7 platform and frontends platform, ui-egui, automation OS services; the egui shell (desktop and web); headless JSON-Schema tools, CLI and MCP

Planned crates that the layer table already reserves (arlington, color, ops, text, ml, security, prepress, search, media, ai, viewport, tools, ui-common) don't exist yet.

Data model and editing

The PDF object graph is the model (crates/engine/README.md §The editing model):

  1. Each open document holds a codex_cos::Document: the parsed objects plus a copy-on-write overlay. Unknown data is preserved because nothing is rebuilt that wasn't understood.
  2. An edit runs on a clone; on success the previous state goes onto the undo stack. Clones share unchanged data, so snapshots are cheap.
  3. After every edit an incremental write produces the working file (original bytes plus one revision); the view is refreshed from those bytes, so what you see is what Save writes.
  4. Saves are incremental and atomic. A full rewrite happens only where it must: redaction, PDF/A conversion, print imposition, a changed password, Save As to another file (garbage-collected, unless the document is signed).
  5. Autosave and crash recovery keep encrypted documents encrypted. Signed documents are protected from rewrites.

Rendering and text

File I/O

Agent control

Every user-facing feature is reachable headlessly (AGENTS.md §3):

Safety

Build and quality gates

cargo xtask ci runs fmt, clippy (-D warnings), a check of codex-cli without default features, the tests (xtask test: cargo-nextest when installed, else cargo test, then the doctests), xtask i18n-report (the strings each interface language has no translation for; it never fails), the layering check, the WASM check (one cargo check over every crate below L8), xtask assets (asset licences and hashes), xtask parity (checklist claims must cite real commands, tools and tests) and xtask deny (dependency licences). Other tasks: xtask fuzz, xtask corpus and xtask check (robustness sweep over the pinned pdf.js corpus), xtask text-oracle (word F1 and reading order against pdftotext), xtask demo-pdf, xtask screenshots, xtask models (OCR models), xtask version. Releases are built by .github/workflows/release.yml (releasing.md).

Revision history

Date Change Summary
2026-10-23 minor xtask ci prints the translation gaps (xtask i18n-report); a missing translation never fails it
2026-10-23 minor xtask ci runs nextest and doctests, checks the CLI without default features, and checks wasm in one call
2026-10-10 major Created from the code on main (crate list, xtask/src/layers.rs, crate READMEs, vendor/README.md)