## Thinking Path
> - Paperclip runs Codex locally and in remote sandboxes.
> - The runner must preserve startup configuration and session identity.
> - Missing project trust can disable repository configuration.
> - Full-history requests use deprecated provider fields.
> - Resume usage describes old work and must not become new run usage.
> - This change corrects startup trust, state reads, and usage
classification.
## Linked Issues or Issue Description
**What happened?**
Normal Codex runs could show repository-trust and history-deprecation
warnings.
Resume could report the preceding turn's token snapshot as a late-turn
warning.
The historical last-usage value could also be attributed to the new run.
**Expected behavior**
Trust the server-selected startup root in isolated configuration. Read
lightweight
provider state and paginated evidence. Use historical cumulative usage
as a
baseline without a new charge or user-facing warning.
**Steps to reproduce**
1. Start a native Codex task in a selected repository.
2. Finish the turn and resume the provider thread.
3. Inspect provider notices, history requests, and per-run usage.
4. Repeat startup and cold resume inside a Daytona sandbox.
**Paperclip version or commit**
Codex CLI 0.153.4 is the pinned runtime and reproduced baseline.
Replayed onto master at 6abeb6733. Related authority work: Refs #13092.
This PR retains its startup cleanup and protocol-integrity checks.
**Deployment mode**
Local source checkout and disposable Daytona sandbox.
## What Changed
- Classify the exact historical resume usage event before the generic
stale-turn warning.
- Persist cumulative usage baselines across recovery of the same run.
- Use excludeTurns on resume and lightweight thread reads.
- Page turn metadata and selected turn items with cursor and identity
validation.
- Reject unsupported or incomplete history instead of guessing that
execution is idle.
- Trust the startup execution root on its host, including Git worktree
trust keys.
- Start Codex in that root and retain the selected sandbox profile on
later turns.
- Keep unrelated isolated configuration and Codex's separate hook trust
policy.
- Add Rust, TypeScript, accounting, native integration, and local
run-log documentation.
## Verification
- Codex and native-transport TypeScript: 333 passed before PR replay.
- Adjacent OpenCode/ACPX driver and accounting tests: 49 passed.
- Rust library, serialized: 226 passed. Native Codex integration: 72
passed, 1 ignored, plus two pagination regressions.
- Repository typecheck and build passed. All repository test groups have
passing coverage after fixture and resource retests; the initial
monolithic command was not clean.
- Fresh real Codex native browser tasks returned correct answers without
the three targeted notices. Answers persisted after refresh and restart.
- Real same-thread TypeScript driver tests passed locally and in
Daytona, including cold resume, configuration, skills, and an approved
harmless hook.
- Local usage summed to 64,607 tokens. Daytona usage summed to 42,737
tokens. Each sum matched its final session total exactly.
- See doc/plans/2026-09-09-codex-integration-acceptance.md for the scope
and limits of the live tests.
- After replay onto current master and review fixes: 334 Codex, backend,
and live-session tests passed, including checkpoint serialization and
real-runner process restart. TypeScript checks passed.
- The native Codex integration run passed 83 tests; the large lineage
test passed separately with the release runner (its debug build exceeded
the test deadline).
- All GitHub checks passed on the final PR head. Greptile is 5/5 with no
unresolved review threads. CI regenerates the lockfile for the added
TOML dependency, per repository policy.
- The first server shard hit a timing-dependent duplicate-key failure in
the unchanged artifact-document concurrency test. Its focused 11-test
suite passed locally. One CI retry on the same head passed all 103 files
and 1,405 tests (2 skipped): [retry
result](https://github.com/paperclipai/paperclip/actions/runs/34398832930/job/102631274667).
## Risks
- Trust applies only to the server-selected startup root and isolated
configuration. Sandbox and tool permissions remain authoritative.
- Codex still requires approval of individual hook hashes. This change
does not bypass that policy.
- Providers without the required history APIs fail explicitly.
- Daytona acceptance used the production TypeScript driver. Remote
Paperclip UI and remote Rust execution were not tested.
- No new public API, database state, recovery policy, or UI control is
included.
## Model Used
OpenAI Codex, GPT-6 (`gpt-6-astra`). Used for reasoning, code edits,
tool use,
and test execution. The exact context-window limit is not exposed in
this
session. Real-provider acceptance used Codex CLI 0.153.4 with
`gpt-5.6-sol`.
## Checklist
- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` OR (b) described the issue in-PR following the relevant issue
template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
---------
Co-authored-by: Paperclip <noreply@paperclip.ing>
4.5 KiB
Correct Codex startup trust, history reads, and resume notices
Date: 2026-09-09. Approved scope: three Codex integration fixes. This supersedes this document's earlier exploratory recommendations. Feed display and full-answer streaming are separate preceding changes.
Product rules
- Trust the execution root that Paperclip selects at startup. Resolve it on the execution host, including a Git worktree's main repository trust key. Write only the isolated Codex configuration. Keep sandbox, tool, and secret controls authoritative. Later directory changes do not grant new trust.
- Codex retains model conversation context. Paperclip reads provider state to establish execution authority or recover specific evidence. Normal resume must not download historical message contents.
- A resume usage snapshot describes completed work. It can establish a cumulative baseline, but must not charge that work to a new run or produce a warning. Other stale notifications and invalid authoritative events keep their existing validation.
Implementation
Resume usage
Handle the exact root-thread thread/tokenUsage/updated snapshot before the
settled-turn warning branch. Keep its reported historical turn identity and a
bounded local codex_resume_usage_snapshot diagnostic. The Rust normalizer
must not emit a billable usage event for the snapshot. The TypeScript driver
persists its cumulative baseline with the existing checkpoint and reports a
monotonic run delta. Attachment begins a new delta at the last observed total;
recovery of the same run preserves its baseline. Repeated snapshots are not
additional receipts. Missing thread or turn identity does not gain authority.
Supported state and history reads
Use excludeTurns: true for resume and includeTurns: false for thread state.
Request turn metadata with thread/turns/list and itemsView: notLoaded.
Only request thread/items/list content for a specific turn when reconciliation
needs its final answer, tool result, or completion evidence. Follow cursors,
keep stable order, deduplicate IDs, reject repeated cursors and incomplete
responses. A missing API reports a compatibility/read error; there is no
Codex full-history fallback.
Rust uses lightweight idle/active state, then paginated metadata when it needs an active turn identity. The controller's runner transport serves targeted recovery evidence from committed runner events; it rejects content reads outside the retained turn window. Existing non-Codex proxy behavior stays separate from Codex's protocol requirements.
Startup trust
Before spawning Codex, canonicalize the selected root and add its trusted project entry to the isolated config. Preserve unrelated settings and use a private atomic replacement. Start the provider process in that same root, so startup cannot load the Paperclip server checkout by accident. Persist the startup directory in the existing optional session checkpoint for cold resume. Remote roots are resolved on the execution host.
Retain the server-selected permission profile on subsequent TypeScript turns, including Daytona's existing external sandbox profile. Do not change approval policy or bypass the external sandbox boundary.
Repository trust loads hook definitions, but Codex 0.153.4 separately reviews individual hook hashes. Preserve that policy. Acceptance explicitly approves only the harmless fixture hook through Codex's supported config API; product code does not bypass hook trust or invoke provider hooks itself.
Verification and exclusions
Use Codex CLI 0.153.4, the pinned supported baseline. Test snapshot replay and cold recovery accounting, cross-thread isolation, full-history avoidance, metadata/item pagination, incomplete evidence, worktree/non-Git/canonical trust, malformed config, and unchanged sandbox profiles. Run focused Rust, TypeScript, server lifecycle/accounting tests, then repository typecheck, tests, and build.
Use fresh local test-drive data and a disposable Daytona sandbox with real Codex. Verify an initial repository read, two follow-ups, cold resume, config and skill markers, one hook execution per startup/resume, exact cumulative usage arithmetic, and absence of the three original warnings. Inspect the browser answer after refresh. Record local/native and remote/TypeScript proof separately, including any environment warnings or unverified behavior.
No new UI, task state, public API, database migration, retry policy, or session replacement workflow. Preserve the Gmail handoff patch and existing test data.
See acceptance evidence.