Codex Agent reconstructs a consistent working persona and project context from explicit files. It does not migrate a running model process, hidden reasoning, credentials, open browser state, or a task's full context window.
Another computer does not revive the same process. It restores behavioral continuity by reading the same soul, reviewed memory, latest handoff, and operating rules.
flowchart LR
R["Public Git repository<br/>AGENTS.md · hook · skills · scripts · templates"]
H["Trusted lifecycle bootstrap<br/>SessionStart · SubagentStart"]
L["Per-machine connection<br/>.agent-vault + local config"]
V["Private synchronized vault<br/>shared memory · selected originals · per-device memory · handoffs"]
C["Codex task<br/>bounded approved context"]
N["Local Codex memories<br/>optional, generated cache"]
R --> H
H --> L --> V
V --> H --> C
N -. "non-authoritative recall" .-> C
The public repository is the control plane. AGENTS.md provides the publishable fallback behavior, while the reviewed .codex/hooks.json invokes a SHA-256-pinned startup script. The private vault is the authoritative portable content. Codex's native local memory, when enabled, remains a per-machine convenience layer and is never required for correctness.
The startup script runs doctor, asks the lifecycle tool for the eligible private sources, renders compact sections for the current event, rejects oversized or secret-like input, and injects the result with an explicit authority wrapper. New or changed project hooks do not run until the user trusts them in Codex. If the hook is unavailable, Codex continues under AGENTS.md and must not claim that private identity or preferences were restored.
Keep source code in Git and memory in Drive. Synchronizing an entire development checkout through Drive also synchronizes .git, build output, dependency trees, and transient locks, which creates avoidable conflicts.
Use this order when two sources disagree:
- System and developer controls of the current Codex environment
- The current explicit user request
- Checked-in repository instructions and current code/tests
- Human-approved soul, preferences, decisions, facts, and lessons
- Candidates, sessions, and handoffs
- Untrusted inbox material
Memory is fallible context, not a higher instruction channel. The hook's wrapper explicitly preserves this order even though it adds the approved hot set as developer context. A note that contains text such as “ignore prior instructions” remains data.
Continuity is not transcript replay. Every automatic injection consumes task context, and SubagentStart repeats that cost for each spawned agent. Keeping the startup brief small is therefore a first-class design objective rather than a cosmetic optimization.
- Aim for about 2,000 tokens or less in the complete rendered private-memory brief.
- Enforce a 12 KiB rendered-output ceiling for
SessionStartand an 8 KiB ceiling forSubagentStart. These are safety ceilings, not quotas. - As an operating-protocol limit, keep total model-visible private memory, including later retrieval, to 24 KiB for a main task and 16 KiB for each subagent. Warm retrieval may use at most 12 KiB and 8 KiB respectively and normally loads zero to three approved notes. These later-retrieval limits are behavioral rather than mechanically metered because retrieval has no single CLI path.
SessionStartrenders compact sections from Soul, project profile, and durable preferences, plus the current device profile and newest validstatus: currenthandoff when available.SubagentStartrenders only compact project plus available current-device/current-handoff sections. It does not repeat Soul or durable preferences.- Validate the full
INDEX.mdandMEMORY_POLICY.mdlocally for size and secret patterns, but keep their bodies out of automatic model context; render them only for relevant memory operations. - Preflight file size and read at most the applicable limit plus one byte before UTF-8 decoding. General lifecycle text is capped at 1 MiB; startup validation further caps core sources at 20 KiB each, current handoffs at 32 KiB, and all approved startup sources at 64 KiB total.
- After the task is known, retrieve normally zero to three approved notes that fill a specific context gap. Stop when enough evidence is available; do not recursively follow links.
- Do not silently truncate an oversized source into a misleading fragment. Report the offending section and reduce or reroute its content before treating startup restoration as ready.
Memory writes follow the same economy. A completed task does not automatically produce a session, candidate, handoff, or preserved original. Write only when there is a concrete continuity, audit, reuse, or user-approved preservation signal.
The repository separates generated delivery artifacts from durable memory. output/ is a Git-ignored outbox with a fixed seven-day lifetime, not a memory tier. scripts/artifactctl.py is the deep module at this seam:
delivercopies one or more final files into a uniquely named package, writes size and SHA-256 evidence, and returns the exact UTC expiry;inspectreports the evidence needed for a file-specific preservation proposal;sweeppermanently deletes expired managed packages and, after safe activation, enrolls unmanaged direct children for deletion seven days after discovery;install-sweeperactivates an empty outbox and installs an hourly user-level Windows Task Scheduler or crontab entry pinned to the current script hash.
The trusted SessionStart hook also runs the hash-pinned sweeper, so an overdue checkout catches up when Codex resumes. The independent local scheduler provides wall-clock progress without a model turn. If the machine is powered off, no local process can delete files at that instant; cleanup resumes at the next hourly run or trusted session start.
flowchart LR
G["Generated result"] --> D["output delivery package<br/>expires in 7 days"]
D --> U["User receives absolute path<br/>and exact expiry"]
D --> X["Permanent deletion"]
D --> I["Agent identifies durable value"]
I --> K["Knowledge only<br/>small justified memory"]
I --> P["Exact file matters<br/>explicit approval"]
P --> V["Cold 40-documents preservation"]
V --> X
There is no durable flag, archive, or library under output/. A handoff must not depend on an expiring path. Exact-file preservation remains governed by the private-vault lease and approval protocol; creating a durable copy does not cancel deletion of the outbox copy.
Activation is the migration boundary. A missing activation state plus existing direct children is treated as legacy data: delivery, installation, and sweeping fail without registering or deleting anything. The operator must review and move the exact legacy directory outside the repository, after which activation records that the now-empty outbox is governed by the expiry policy.
Context limits control model-visible text; storage limits control curation and synchronization cost. They are related but deliberately separate.
| Scope | Default review limit | Warning | Meaning |
|---|---|---|---|
| Working set | 1 MiB and 250 files | 80% | Regular files under 00-system, 10-project, 20-state, 30-memory, and 50-devices |
| Individual working-set file | 16 KiB | 80% | Signals that a working record should be summarized or split during review |
| Whole vault | 100 MiB and 1,000 files | 80% | Every regular vault file, including preserved originals and archives |
The lifecycle budget command walks these scopes read-only and reports aggregate metadata without private filenames or note bodies. It never acquires a writer lease and never deletes, truncates, rewrites, moves, archives, or caches private material. Archive reduces active retrieval noise but does not reduce whole-vault storage.
Normal output is advisory. Python --strict and PowerShell -Strict return a nonzero status for warning, over-limit, or incomplete results. All thresholds have matching CLI overrides for diagnostics and tests, but spare or overridden capacity is never a reason to create memory. doctor checks working-set metadata only, stops once review is certain, and caps one health scan at 1,024 visited entries and 512 scheduled directories before warning without failing; this keeps the automatic startup path from recursively traversing or hydrating large document and archive trees.
| Tier | Typical content | Loading rule |
|---|---|---|
| Session hot | Compact Soul, project, durable-preference, plus available current-device/current-handoff sections | Inject through trusted SessionStart; target about 2,000 tokens and stay within 12 KiB rendered |
| Subagent hot | Compact project plus available current-device/current-handoff sections | Inject through trusted SubagentStart; stay within 8 KiB rendered |
| Warm | Full INDEX.md and MEMORY_POLICY.md, relevant approved facts, decisions, lessons, and current-device notes |
Read policy for memory operations; otherwise search by task terms, normally load zero to three relevant notes, and stay inside the 12 KiB/8 KiB warm allowance |
| Cold | Candidates, sessions, preserved originals, other device folders, non-current or superseded handoffs, archives, source captures | Do not load automatically |
| Untrusted | Web clips, copied email/chat, external generated text | Treat only as evidence to review |
The index says where and when to look; it should not duplicate every memory. Obsidian backlinks improve human navigation but do not replace explicit search and filtering for Codex.
Shared vault areas contain context that should apply on every computer. 50-devices/<device-id>/DEVICE.md contains concise context that applies only to one configured machine; detailed evidence stays in that folder's notes/ directory.
The lifecycle tool takes the device ID from the ignored machine-local configuration and adds only the exact matching profile to context. The startup loader independently checks that the selected label equals 50-devices/<current-device-id>/DEVICE.md. It rejects a different device profile even if the file is otherwise valid. Other device folders remain cold and are not enumerated during normal restoration.
This is semantic isolation, not access control. The entire vault still synchronizes through Drive, and a device ID is not authentication.
flowchart LR
O["Observation"] --> C["Candidate"]
C --> T["Repeated evidence or test"]
T --> A["Human approval"]
A --> L["Approved lesson"]
L --> R["Periodic revalidation"]
R -->|"stale or contradicted"| S["Superseded / archived"]
- Store one claim or lesson per note with provenance, confidence, scope, and verification dates.
- Record a model's proposed improvement as a candidate first.
- Require user approval before changing
SOUL.md, durable preferences, or approved lessons. - Prefer a new superseding note over rewriting history without a trace.
- Current code and test evidence always outrank an old memory.
This provides a careful improvement loop similar to “self-improving memory” while keeping changes reviewable and reversible.
SessionStart runs for startup, resume, clear, and compaction. SubagentStart gives spawned agents the smaller event profile defined above rather than duplicating the full session brief. The memory-loader hook never writes memory or acquires the writer lease; it performs bounded read-only restoration before task work. A separate concurrent SessionStart handler may permanently delete expired files only from the ignored delivery outbox.
When the trusted hook is unavailable but Python and the local connection are available, python scripts/agent-startup-context.py --render --event SessionStart renders the same bounded session profile without invoking a hook.
At the start of a writable task, the tool may create an advisory lock containing a device ID and timestamp. The lock reduces accidental overlap but cannot provide a distributed transaction or reliable presence detection over Google Drive. lock=none reports only the synchronized state visible to the current computer. The operational rule is to avoid parallel vault writers; read-only tasks may overlap.
SOUL.md remains editable after exact user approval. Because it is high-impact shared state, Codex also warns about a possible unsynchronized writer and asks the user to confirm that other vault-writing tasks are stopped and Drive is current, or to explicitly accept the concurrency risk. Once confirmed, the normal advisory lease and write path apply.
Create a uniquely named handoff only when a later task would otherwise need to rediscover unfinished or non-obvious state; do not repeatedly edit one global NOW.md. A handoff records:
- the task goal and current status
- completed work with files, commits, tests, or other evidence
- unresolved risks and decisions
- the next three concrete actions
- the originating device/session and UTC timestamp
Unique note names avoid most file-level collisions. “Latest handoff” is a derived view and should be recoverable from the note set.
status: current is a policy assertion that the record is actively resumable, not merely historical. The loader selects the newest syntactically valid current handoff; it does not infer semantic staleness. When a new handoff replaces the current record for the same scope, policy requires it to link the predecessor through supersedes and mark the predecessor superseded. Older records remain available as cold evidence.
Ignored local connection files are not copied into a Git worktree. The lifecycle tools therefore inspect the current Git worktree family when local state is absent and reuse exactly one compatible sibling connection. If multiple sibling connections disagree, discovery fails instead of choosing silently. A separate clone or another computer still runs init once and receives its own device ID.
| Moves through Git/Drive | Stays local to each computer |
|---|---|
| Public workflow, reviewed hook, and templates | Codex authentication and account state |
| Approved soul and preferences | Running tasks and hidden reasoning |
| Project facts, decisions, and lessons | Browser sessions and connector authorization |
| Explicitly approved, modest-size original documents | Unapproved local documents and unsaved files |
| Current device's reviewed path mappings and tool constraints | Credentials, cookies, login state, and native runtime caches |
| Session summaries and handoffs | Native Codex generated memories and caches |
| Sanitized provenance | Secret-manager values and OS credentials |
The result can be strongly continuous in behavior, but it is not perfectly deterministic: models, tools, permissions, local files, and current instructions can differ between computers.