Files
orca/src/main/codex
Brennan Benson 677718c4a5 fix(codex): stop rebuilding shared Codex state from a read that failed (STA-4823) (#15417)
* fix(codex): stop rebuilding shared Codex state from a read that failed (STA-4823)

Six shared files were rebuilt, erased or reported healthy after a read that had
only failed. Batch A of the STA-4606 split: every one of these is reachable and
testable on the host lane, so none of them wait on the WSL work.

- `config-toml-trust.ts` upsertHookTrustEntries: `existsSync` reported a locked
  config.toml as absent, so the base content became '' and the upsert rewrote
  the file from the trust entries alone — a trust-only stub, with the user's
  model, provider, MCP servers, approvals and comments gone. It refuses now;
  every hook-service caller already turns that into "trust entries could not be
  written. Run /hooks in Codex to approve."
- `codex-trust-grant-ledger.ts`: an unreadable ledger degraded to empty and the
  next write persisted a file holding only the home being written, dropping
  every other home's grants. The write paths refuse; the read path still
  degrades, and a corrupt ledger is still rebuilt.
- `codex-pane-account-registry.ts`: an unreadable registry erased every pane's
  attribution AND cached that erasure, so it survived the file recovering. The
  failure is no longer cached, and both write sites refuse rather than persist a
  registry derived from an empty stand-in.
- `hooks-json-read.ts`: the read arm already separated "no hooks" from "could
  not read", but the `existsSync` arm in front of it returned a valid empty
  config for a file that could not be opened. One read now classifies both.
- `config-settings-baseline.ts`: absent, unparseable and unreadable all collapsed
  into `null`, so the snapshot rebuilt a baseline it could not read — recording
  an in-Codex edit as Orca's own write, after which promotion skips it forever.
- `config-sync-stall.ts`: an unreadable runtime config read as absent and the
  status reported `synced` while the mirror was refusing. It reports
  `managed-home-unavailable`, the existing reason for exactly this, rather than
  borrowing a source-side one and blaming the wrong path.

Absent and malformed still rebuild throughout — resetting corrupt state is the
intent, and conflating it with unreadable would wedge a user on a broken file.

* fix(codex): close shared state read-denial gaps

* fix(codex): recover oversized settings baselines

* fix(codex): name the stalled managed config

* fix(codex): preserve hooks after failed source reads

* test(codex): correct what the denyExistence rig actually models

MEASURED on both platforms: a file-permission denial leaves existsSync TRUE
and fails only the content read — chmod 000 gives EACCES on macOS, icacls
/deny (R) gives EPERM errno -4048 on Windows, with stat/lstat succeeding in
both. The rig's docblock claimed this mode modelled that denial. It does not.

What it models is the UNC / \\wsl$ transport, where an unreachable distro
reports errno UNKNOWN at every level and existsSync folds it to false.

The distinction decides what the D29 guard is worth: under a permission denial
the pre-fix code already failed safe, because existsSync was true so it took
the read branch and threw. Only a transport that lies about existence reaches
the rebuild-from-empty path. No behaviour change; the comment was wrong, not
the code.

* test(codex): exercise live baseline read denial

* fix(codex): retry pane attribution writes

* fix(codex): retry reconciliation registry writes

* fix(codex): report unreadable sync baselines
2026-08-23 13:52:18 -07:00
..