fix(server): new Codex runtime entries no longer disable shadow-home providers#23472

open4
main
fix/issue-5817
opened6d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 20h ago

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=1 from apps/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:changed passed: format, lint, knip, server GraphQL generation, both affected-package typechecks, and all 11 focused tests. Latest origin/main is 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.
FixtureBeforeAfter
Runtime entries created after setup.tmp conflict disables providerMaterialization succeeds
Regular queue database in each homequeue_1.sqlite conflict disables providerBoth local databases retained; provider initializes
Linked database with regular local WAL/SHMlogs_2.sqlite-shm conflict disables providerExisting 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.

Proof audit: sufficient.

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

21 successful · 13 skipped
All checks passed
282a92e

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
Synced from GitHub

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.

Synced from GitHub

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire5.0 KiB5.0 KiB−7 B (−0.1%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.2 KiB1.2 KiB−7 B (−0.6%)2.0 KiB✅
CodexLive turn WebSocket decoded20.9 KiB20.9 KiB0 B (0.0%)29.3 KiB✅
CodexLive turn messages220 (0.0%)8✅
ClaudeTotal thread wire5.0 KiB5.0 KiB−24 B (−0.5%)6.8 KiB✅
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
ClaudeLive turn WebSocket wire1.2 KiB1.2 KiB−24 B (−2.0%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.2 KiB21.2 KiB−41 B (−0.2%)29.3 KiB✅
ClaudeLive turn messages21−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.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
📥 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.ts
  • apps/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.ts
Materialization 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.ts
Materialization 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 nameStatusExplanation
Title checkPassedThe 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 checkPassedIssue #5817 requires 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 checkPassedThe changes stay within issue #5817. Production changes are limited to Codex shadow-home materialization and SQLite family reconciliation in CodexHomeLayout.ts. Test helpers and regression cases in …
Description checkPassedThe 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 #5817 requires filename-resilient handling for entries created after materialization, data preservation, SQLite family handling, orphan sidecar handling, and regression tests. CodexHomeLayout.ts reads both homes, keeps non-required regular shadow entries local, groups -wal, -shm, and -journal members 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 in CodexHomeLayout.ts. Test helpers and regression cases in CodexHomeLayout.test.ts directly 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.

Synced from GitHub

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-locks is now in KNOWN_SHARED_DIRECTORIES and REPLACEABLE_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 NotSymlink branch of ensureSymlink now keeps a local thread-writer-locks while it still holds a <thread>.lock, and a later setup links it.
  • auth.lock is in PRIVATE_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.