fix(server): new Codex runtime entries no longer disable shadow-home providers#23472
Problem
Codex can create new regular runtime entries in both a shared home and an account-specific shadow home after initial setup. On the next provider refresh, entries such as .tmp or queue_1.sqlite raised CodexShadowHomeEntryConflictError and disabled the shadow provider; this was reproduced with the real dev server and Codex 0.163.0 on Linux.
Change
Keep existing non-core regular shadow entries local, without moving or replacing their contents. Treat each database and its SQLite sidecars as one family when adding links, and skip orphan shared sidecars. Required shared configuration and directories retain their existing conflict checks; private authentication-file handling is unchanged.
Scope and approval
Fixes #5817 GitCafe: https://git.cafe/pingdotgg/t3code/issues/5817 Triaged bug via the automated issue flow. This fixes provider initialization while preserving existing files and link topology. No settings, contracts, or persisted fields are added.
Verification
- Focused server tests:
vp test run src/provider/Drivers/CodexHomeLayout.test.ts --maxWorkers=1fromapps/server: 11 passed on the final head. The baseline produced 2 failures / 8 passes, including the runtime-entry and local-sidecar conflicts. The sidecar fixture now asserts preservation of the existing topology. - After merging main,
vp run check:changedpassed: format, lint, knip, server GraphQL generation, both affected-package typechecks, and all 11 focused tests. Latestorigin/mainis included. - Real app:
vp run dev --no-seed, Linux x64, Node 24.21.0, Codex 0.163.0, isolated disposable homes. All three formerly failing providers initialize and reach the expected unauthenticated status. Queue sentinel rows remain distinct; the existing linked-base/local-sidecar topology remains intact. Controlled regression tests verify byte preservation.
| Fixture | Before | After |
|---|---|---|
| Runtime entries created after setup | .tmp conflict disables provider | Materialization succeeds |
| Regular queue database in each home | queue_1.sqlite conflict disables provider | Both local databases retained; provider initializes |
| Linked database with regular local WAL/SHM | logs_2.sqlite-shm conflict disables provider | Existing files and links retained; provider initializes |
Merged-head changed-file check output · Before runtime transcript · After runtime transcript · Red test report · Green test output · Evidence index · Fixture matrix.
The server-only proof exception applies: no render code changed, so the visual fixture matrix is empty. Runtime evidence uses implementation revision 51cf491; revision c3fd754 only corrects a test comment. Merge revision 282a92e includes current main with both affected files unchanged. Windows/macOS execution and authenticated Codex turns were not checked. Existing split-WAL recovery is outside this fix.
Models: GPT-6.1-Sol through the Codex harness; Claude Opus 5.5 through the Claude harness.
Checks
Added 4 commits
- Merge remote-tracking branch 'origin/main' into fix/issue-5817282a92e
- fix(server): new Codex runtime entries no longer disable shadow-home providers51cf491
- test(server): reproduce issue 5817 Codex shadow-home runtime entry conflictsb913ce5
- test(server): the linked-base WAL fixture names SQLite's Windows journal behaviorc3fd754
Approvability
Verdict: Approved at 282a92e
Macroscope's review found this PR approvable — This is a localized Codex shadow-home bug fix that preserves newly created runtime files and SQLite sidecars without weakening required configuration or private authentication-file checks. The added tests cover the changed reconciliation cases, and no broader product or contract changes are present.
You can add or adjust custom eligibility rules. Learn more.
Thread transfer impact
✅ Thread transfer remains within every enforced ceiling.
| Provider | Metric | Main baseline | This PR | Impact | PR ceiling | |
|---|---|---|---|---|---|---|
| Codex | Total thread wire | 5.0 KiB | 5.0 KiB | −7 B (−0.1%) | 6.8 KiB | ✅ |
| Codex | Thread snapshot wire | 3.8 KiB | 3.8 KiB | 0 B (0.0%) | 4.9 KiB | ✅ |
| Codex | Live turn WebSocket wire | 1.2 KiB | 1.2 KiB | −7 B (−0.6%) | 2.0 KiB | ✅ |
| Codex | Live turn WebSocket decoded | 20.9 KiB | 20.9 KiB | 0 B (0.0%) | 29.3 KiB | ✅ |
| Codex | Live turn messages | 2 | 2 | 0 (0.0%) | 8 | ✅ |
| Claude | Total thread wire | 5.0 KiB | 5.0 KiB | −24 B (−0.5%) | 6.8 KiB | ✅ |
| Claude | Thread snapshot wire | 3.8 KiB | 3.8 KiB | 0 B (0.0%) | 4.9 KiB | ✅ |
| Claude | Live turn WebSocket wire | 1.2 KiB | 1.2 KiB | −24 B (−2.0%) | 2.0 KiB | ✅ |
| Claude | Live turn WebSocket decoded | 21.2 KiB | 21.2 KiB | −41 B (−0.2%) | 29.3 KiB | ✅ |
| Claude | Live turn messages | 2 | 1 | −1 (−50.0%) | 8 | ✅ |
Baseline: 5ffe045 · PR result: 282a92e · Source CI: success
Scenario and decoded snapshot size
10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
- Codex decoded thread snapshot: 108.5 KiB
- Claude decoded thread snapshot: 108.8 KiB
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: fix/issue-5817
- File: .coderabbit.config.ts
- Commit: 282a92e
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Team
- Run ID:
45c5c907-ffe1-4233-b816-950f8b5a0caa
📥 Commits
Reviewing files that changed from the base of the PR and between 5ffe04593166870d3ada2a83eb5fe55f0d192fc7 and 282a92e160ff140945a2e63ef289537e44f77946.
📒 Files selected for processing: 2
apps/server/src/provider/Drivers/CodexHomeLayout.test.tsapps/server/src/provider/Drivers/CodexHomeLayout.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.
📝 Walkthrough
Codex shadow-home materialization now detects regular shadow entries and tracks their SQLite families. It skips incompatible links for local families and sidecars without a shared database. Tests cover repeated materialization and preservation of local and shared files.
Changes: Codex shadow-home reconciliation
Layer / File(s) Summary Detect local SQLite families
apps/server/src/provider/Drivers/CodexHomeLayout.tsMaterialization reads both homes and marks sharable regular shadow entries as local SQLite families. Required shared names and sidecar suffixes define the family mapping. Filter links and validate materialization
apps/server/src/provider/Drivers/CodexHomeLayout.ts,apps/server/src/provider/Drivers/CodexHomeLayout.test.tsMaterialization skips sidecars without a shared base and skips links in local families unless the entries are required shared or replaceable runtime entries. Tests cover new entries between materialization passes, preserved file contents, and local and shared SQLite sidecars. Priority: ➖ Normal
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix · Severity of issue fixed: Medium
Suggested reviewers:
ajraba04
Merge Risk: ⚪ Minimal · up to 282a9
The change preserves local shadow-home entries without an identified merge-blocking issue.
Pre-merge checks: Passed 4
Check name Status Explanation Title check Passed The title is concise, uses conventional commit format, and clearly describes the primary fix: new Codex runtime entries no longer disable shadow-home providers. Linked Issues check Passed Issue #5817requires filename-resilient handling for entries created after materialization, data preservation, SQLite family handling, orphan sidecar handling, and regression tests. `CodexHomeLayout.t…Out of Scope Changes check Passed The changes stay within issue #5817. Production changes are limited to Codex shadow-home materialization and SQLite family reconciliation inCodexHomeLayout.ts. Test helpers and regression cases in …Description check Passed The pull request includes all required sections: Problem, Change, Scope and approval, and Verification. It describes the affected behavior, implementation approach, linked issue, approval context, foc… Full details: Linked Issues check
Explanation
Issue
#5817requires filename-resilient handling for entries created after materialization, data preservation, SQLite family handling, orphan sidecar handling, and regression tests.CodexHomeLayout.tsreads both homes, keeps non-required regular shadow entries local, groups-wal,-shm, and-journalmembers with their base, skips orphan shared sidecars, and preserves required shared-entry conflicts. The focused tests cover repeated materialization, entries created in both homes, local SQLite sidecars, orphan sidecars, and content/topology preservation. Private authentication handling remains separate.
Full details: Out of Scope Changes check
Explanation
The changes stay within issue
#5817. Production changes are limited to Codex shadow-home materialization and SQLite family reconciliation inCodexHomeLayout.ts. Test helpers and regression cases inCodexHomeLayout.test.tsdirectly verify the required behavior. No unrelated settings, contracts, persisted fields, or render changes are present in the supplied change summary.
Full details: Description check
Explanation
The pull request includes all required sections: Problem, Change, Scope and approval, and Verification. It describes the affected behavior, implementation approach, linked issue, approval context, focused test results, runtime validation, limitations, and evidence links.
✨ Finishing Touches
📝 Generate docstrings
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
- Commit to this branch
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
One data-safety note on "Linked database with regular local WAL/SHM → Existing files and links retained". On Windows this keeps the instance up, but the next shadow open makes SQLite recover the stale shadow WAL. A killed Codex leaves that WAL with committed frames. The next checkpoint then writes those pages over rows the main Codex committed while the shadow was down, and integrity_check still reports ok.
I reproduced it with a real Windows file symlink and with a Linux hard link, which gives the same sidecar naming. The standalone repro and output are in https://github.com/pingdotgg/t3code/issues/5817#issuecomment-6352469433. Replacing the files with links instead would drop the shadow's unapplied commits. So this layout probably needs one of two fixes: apply the shadow WAL only when that provably loses nothing, or keep shadow-home Codex from opening shared databases through a link on Windows at all.
Note
🤖 Claude Opus 5.5 responding on behalf of Theo
Heads-up: #26286 merged as c4606e564d. It touches CodexHomeLayout.ts too, so this PR needs a rebase. It does not supersede this PR.
thread-writer-locksis now inKNOWN_SHARED_DIRECTORIESandREPLACEABLE_SHARED_RUNTIME_ENTRIES. With this PR, that makes it a required shared entry, which is what we want: a local copy must not be kept silently, because shadow and main writers would then lock in different directories.- The
NotSymlinkbranch ofensureSymlinknow keeps a localthread-writer-lockswhile it still holds a<thread>.lock, and a later setup links it. auth.lockis inPRIVATE_ENTRY_NAMES.
Verified by focused CodexHomeLayout.test.ts cases that fail on the old source, vp run check:changed, and all 8 required checks green on the merged head.