Skip to content

fix(codex): await recovery ACL checks in async parent admission - #7931

Merged
lidge-jun merged 7 commits into
lidge-jun:devfrom
luvs01:codex/7872-async-parent-admission-20261029
Oct 30, 2026
Merged

lidge-jun merged 7 commits into
lidge-jun:devfrom
luvs01:codex/7872-async-parent-admission-20261029

Conversation

@luvs01

@luvs01 luvs01 commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Parent selection admission can block the Windows event loop while recovery ancestry, directory and record ACL subprocesses run. This follows up #7872 item 2 with fresh asynchronous recovery admission and the coordinated caller migration. It does not repeat the merged #7875 cleanup/identity work or close #7872.

Initial implementation: 391f48bd66251ece5167d777eeab80938a311f6c, based on dev@8eb970d9dcd63d119c9a9d20de4c18a27ca542c2. Before publication, current dev was 9c33e4658b7b180ec8dd20f0e6a21daf3699f76e; its added CI-sharding commit has no path overlap with these 30 files. The latest maintainer disposition remains item 2 open; targeted open-PR searches found no duplicate.

Behavior

  • Reserve a unique parent generation before inspection. Contention returns immediately without another ACL inspection; denial, throw and cancellation release only that exact owner.
  • Share the native recovery policy between sync and async drivers. Await the existing ACL/hardening runners while keeping ancestry/directory/leaf pins alive, and recheck their identity, single-link and size constraints after awaits. Preserve the existing DACL policies, per-call timeout, bounded record inspection and pending-child publication protocol.
  • Let existing synchronous writers reuse admission only inside a synchronous commit callback for the same resolved config root and held owner. Promise-like callbacks are excluded; queued work cannot borrow the commit scope.
  • Migrate the async runtime, shim, Desktop restart, Remote Workspace, CLI/machine and management callers. Management holds admission over its config-root hardening barrier and revalidates the mode plan before the existing no-await mutation callback.
  • Revalidate selection input, cache epoch, caller currentness and cancellation after both successful and refused recovery. Classify parent/worker diagnostics by the exact buffer and owner.

No external target, app allowlist, HTTP authentication or ACL policy is broadened.

Verification

Draft / native and formal maintainer-security acceptance pending. Published file blobs were checked against the tested files. Current follow-up head: 52799f3f4724780d8d3649f029dde2b946ae2ccb. New-head automatic checks are tracked separately below.

Current dev-conflict follow-up — 52799f3f4724780d8d3649f029dde2b946ae2ccb

After the successful a2b2892c CI, fresh dev e3ebd82a introduced two textual registration conflicts: adjacent Kiro shard insertion at the layout prefix and LM Studio golden entries at the oracle's first line. No product file or earlier seven-file test fix conflicted. The latest ordinary single-parent fast-forward relocates only this PR's existing codex-cli-update-parent-async.test.ts mapping in the registry and independent golden table. No upstream-only entries were copied into the head, and the independent oracle was not regenerated from the resolver.

Head mapping remains 2,754 entries. The two file-level three-way merges are clean, yielding the expected 2,765-entry union with no missing files. Layout remains 1,999 lines on both the head and synthetic integration result; caps, exemptions, runners and workflows are unchanged. The actual planner's four Linux shard selections, order and batch boundaries are identical before/after in both head and dev-integration contexts. The maintainer's #7943 correction is preserved rather than duplicated.

Focused layout/tooling/ratchet verification: 38 pass / 0 fail, 664 assertions; typecheck: 2,228 files; whitespace check: pass. The earlier seven corrected test/fixture blobs remain byte-identical to a2b2892c. Independent read-only source review of the exact two-file delta, SHA-256 f6b59fbce58ebdc194ac7496fb8cf0fff83384e0c349cb8f2f042e7ab2ba0bdd, found no blocking finding. This review did not execute tests or constitute formal maintainer/native acceptance.

Current-head CI complete, verified 2026-10-29 05:32 UTC: Cross-platform 40819794077, Catalog 40819794129 and Service lifecycle 40819794101 all succeeded on attempt 1 for 52799f3f4724780d8d3649f029dde2b946ae2ccb. Cross-platform finished with 14 successful jobs / 10 policy-skipped jobs, including all four Ubuntu shards and the final aggregate. Completed logs confirm actual checkout d0fdd1cb7ad7a87460e2bb798851570b98b86ff6 = head 52799f3f + dev@b09c9302c4832a12c17da5f57f5d2240fe20f817, containing #7943 and the subsequent #7889/#7745/#7937 changes.

The original 11/11, additional stale-consumer 5/5, and held-Promise ordering 3/3 cases all actually passed in these new-head logs (19/19); these are not results copied from a2b2892c. File-size ratchet, golden membership and layout guards also passed. The Linux desktop job ran Rust fmt/clippy and 247 Rust tests passed / 2 ignored; its bundled-sidecar, packaging and packaged-shell E2E steps were skipped. The eight new Windows native cases were likewise skipped, not passed. Native OS validation and explicit maintainer/security acceptance therefore remain open. GitHub reports mergeable=true, which is separate from merge acceptance. No workflow dispatch, rerun, approval, assertion weakening or CI-policy change was performed.

CI failure follow-up — a2b2892ccc03900c875c2f6c77dd2400bce09b97

Normal fast-forward from 391f48bd; all seven published test/fixture blobs match the tested files. No production source, ACL policy, timeout or workflow was changed in this follow-up.

The initial Cross-platform run 40797643817 failed with 11 cases. Six missing-export errors came from a whole-module mock exposing only the former sync name; the real maybeAutoRestoreCodexShimAsync export exists. One help mock, one capability source oracle and three pinned-sync spies also targeted the old contract. Static inventory reproduced five further stale-consumer failures in CLI head/ready/version-skew tests. All are aligned with the actual async boundary, preserving refusal, ordering, exit-code and call-count assertions.

Exact-base RED: 11 fail / 1 pass for the reported selection, then 5 fail / 4 pass for additional consumers. Final complete affected-file run: 280 pass / 0 fail / 0 skip, 1,439 assertions, seven files, Bun 1.4.4/Linux. Three new held-Promise tests require ready/resolve/ordinary-command preflight to finish before dispatch becomes possible. Typecheck (2,228 files), structure, privacy, whitespace and layout/size (11 pass) gates passed. Full repository/test:changed was not rerun locally for this tests-only correction.

A separate source reader reviewed the immutable seven-file delta, SHA-256 d836ca63edeadd0ac23fb2a96a815a4ea06198b16e57a7474847714bd8352707, with no blocking finding. This read-only review is separate from the initial implementation review below, automatic CI, formal security acceptance and native execution.

Previous head a2b2892c automatic checks: all three workflows succeeded; reconfirmed 2026-10-29 13:38 KST. These results do not claim completion on the new head.

Windows/macOS native jobs were policy-skipped; no Windows/native acceptance is inferred. The 38 earlier native skips, including eight new Windows x64 cases, and explicit maintainer/security disposition remain open. No manual workflow dispatch, approval or rerun was requested. See the diagnosis and publication record.

Earlier implementation verification — 391f48bd

Pinned Bun 1.4.4, Linux:

  • Final core focus: 143 passed / 38 Windows-native skipped / 0 failed, 494 assertions across five files (7.82 s).
  • Layout and size-tool regressions: 11 passed / 0 failed, 88 assertions.
  • Typecheck: 2,228 source files, pass. Structure, privacy and diff whitespace checks: pass.
  • Earlier caller regression work: 269 passed / 2 pre-existing native Windows skips / 0 failed, eight files. This predates the last review corrections and is recorded separately from the final core run.
  • test:changed was attempted, then cancelled with SIGTERM/exit 143 after at least 335 observed seconds because review-driven edits occurred while it was running. It emitted no completion summary. Incomplete, not a pass. Full root/GUI suites were not run; no timeout, assertion, workflow gate or exclusion was relaxed.
OCX_TEST_NO_QUEUE=1 bun test tests/codex-integration/codex-cli-update-parent-async.test.ts tests/codex-integration/catalog-async-lifetime.test.ts tests/codex-integration/codex-cli-update-worker.test.ts tests/codex-integration/codex-cli-update-recovery.test.ts tests/codex-integration/codex-cli-update-windows-pending.test.ts
OCX_TEST_NO_QUEUE=1 bun test tests/test-layout.test.ts tests/ci-workflows/file-size-ratchet.test.ts
bun run typecheck
bun run structure:check
bun run privacy:scan
git diff HEAD --check

Independent source review

A separate reader reviewed the immutable 30-file diff over 8eb970d, SHA-256 4a319c78d59dabffe8bf5596848a9d1e00d61b1526123985dbdbea780a54b679. Two findings were fixed before publication:

  1. Refused/thrown admission could return a stale runtime after inputs/epoch/currentness changed. Six new negative cases failed before the fix; all 12 allow/deny/throw × freshness/cancellation cases then passed and are included in the final focus.
  2. Async parent owners were misclassified as retained workers. Exact buffer/owner diagnostics now avoid the false state and warning without granting or releasing authority.

Final review found no additional blocking code finding. It was read-only source/log review, not an independent test rerun, external security workflow, Windows execution or maintainer acceptance.

Remaining scope and required native evidence

  • Local Windows results on the published head now cover all 38 Windows-gated cases, including the 8 new Windows x64 cases, with individual PASS results. The first invocation completed 31 cases before the caller's 300-second limit terminated it (native exit -1); only the remaining 7 were then run, passing with 33 assertions and exit 0/EOF. This is not a single full-suite completion. Other-SID behavior, ARM64, installed Desktop success and a second real apply remain unverified. The broad native-acceptance checklist remains open.
  • The asynchronous claim covers recovery admission. General atomic secret-file publication, native feature commands and other synchronous leaf operations retain their existing contracts. The native tests separate recovery's sync owner-ACL/icacls counters from the later commit's no-sync-recovery check; they do not claim that whole persistence is free of synchronous ACL work.
  • Synchronous compatibility exports remain, including direct bundled-catalog CLI loading and effort-clamp fallback without an observed catalog. These are explicit residual paths; this candidate does not make every parent path asynchronous or complete [Tracking] #7648 follow-up: Windows updater availability findings and four review corrections #7872.
  • Timeout refusal is preserved, but ACL-runner completion alone is not proof of subprocess reaping. Existing resource ownership/cleanup guarantees are unchanged.
  • Historical initial-head status: Catalog and Service lifecycle succeeded, but Cross-platform 40797643817 subsequently failed with the 11 cases addressed above. Its former queued status is superseded by the exact-head follow-up results.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Structure documentation and test registrations are updated.
  • Security-sensitive changes have final maintainer acceptance; independent scoped source review is recorded above.
  • Exact-head hosted CI and Windows native validation are complete.

Hold an exact generation across fresh Windows recovery inspection and revalidate pinned identity after awaits. Migrate asynchronous parent callers with a root-bound synchronous commit scope and keep stale-result checks on both admission success and denial.

Preserve synchronous compatibility exports and document native validation and remaining synchronous publication boundaries. Follow-up for lidge-jun#7872 item 2; not a completion claim.
@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 8 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between a022a67 and 1481539.

Files selected for processing: 38
  • scripts/test-layout/layout.json
  • src/cli/account-main.ts
  • src/cli/codex-shim-autorestore.ts
  • src/cli/dispatch.ts
  • src/cli/doctor.ts
  • src/cli/index.ts
  • src/cli/init.ts
  • src/cli/restart-scope.ts
  • src/cli/root.ts
  • src/cli/v2.ts
  • src/client/machine-api.ts
  • src/codex/app-server-restart-service.ts
  • src/codex/cli-update-job-store-windows.ts
  • src/codex/cli-update-job-worker.ts
  • src/codex/cli-update-recovery.ts
  • src/codex/cli-update-selection-gate.ts
  • src/codex/desktop-app-restart.ts
  • src/codex/desktop-app/handoff.ts
  • src/codex/runtime.ts
  • src/codex/shim.ts
  • src/remote-control/workspace-codex-runtime.ts
  • src/server/management/agent-settings-routes.ts
  • structure/cli-management.md
  • structure/codex-cli-update.md
  • structure/config.md
  • structure/remote-workspace.md
  • structure/runtime.md
  • tests/cli/cli-capability-operation-workflows.test.ts
  • tests/cli/cli-head.test.ts
  • tests/cli/cli-help-recovery.test.ts
  • tests/cli/cli-ready.test.ts
  • tests/cli/cli-sync-expect-link.test.ts
  • tests/cli/cli-version-skew.test.ts
  • tests/codex-integration/codex-cli-update-parent-async.test.ts
  • tests/codex-integration/codex-cli-update-windows-pending.test.ts
  • tests/codex-integration/multi-agent-keep-native-v1.test.ts
  • tests/fixtures/parent-stop-runner.ts
  • tests/fixtures/test-layout-expected.json
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

Fix stale mocks, spies and source oracles behind the 11 failures in run 40797643817, plus five reproduced failures in related consumers. Preserve refusal, ordering, timeout and handover assertions. Add three held-promise preflight ordering regressions.

Tests: 280 passed across all seven affected test files; typecheck, structure, privacy and layout/size gates passed. No production source changes.

luvs01 commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up for the 11 failures in CI 40797643817 is published as a2b2892, a normal fast-forward from 391f48bd. Latest head/comments were checked before updating; all seven published blobs match the tested files.

Cause and correction

  • 6 stop/update handover failures: the fixture replaces the entire autorestore module with a mock exposing only the former synchronous export. The real maybeAutoRestoreCodexShimAsync implementation exists. The mock now exposes that actual async boundary; real parsing/dispatch/stop guards and handover assertions remain.
  • 1 help + 1 capability + 3 pinned-sync failures: stale mock, synchronous source oracle and spies were still targeting the former contract. They now observe the awaited async calls. No production fallback was added.
  • Static consumer inspection found 5 additional reproducible failures in CLI head/ready/version-skew tests, and negative spies that could pass without observing the real path. These are corrected in the same seven test/fixture files.
  • Three new behavioral cases hold preflight unresolved in ready, resolve and ordinary-command branches, and require the head to remain undispatchable until release. Existing refusals, call counts, ordering and timeouts are preserved.

Evidence and remaining acceptance

Exact-base reproduction: 11 fail / 1 pass for the reported selection; 5 fail / 4 pass for the additional selection. Final full affected-file run on Bun 1.4.4/Linux: 280 pass / 0 fail / 0 skip, 1,439 assertions. Typecheck (2,228 files), structure, privacy and whitespace checks passed; layout/size checks 11 pass. No production source, workflow or security policy changed in this follow-up.

A separate reader reviewed the final immutable diff, SHA-256 d836ca63edeadd0ac23fb2a96a815a4ea06198b16e57a7474847714bd8352707, and found no blocking correction finding. This is independent source review, not an independent execution, formal security approval or native OS acceptance.

New-head automatic Cross-platform CI 40803792663, Catalog 40803792647, and Service lifecycle 40803792666 are in progress at publication. The initial run failed; its prior queued status is superseded. Full repository/test:changed was not rerun locally for this tests-only correction. Exact-head Windows/native checks and maintainer/security acceptance remain separate and pending. No manual CI rerun/dispatch/approval was requested.

luvs01 commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator Author

Exact-head verification update for a2b2892, confirmed 2026-10-29 11:15 KST:

Native Windows/macOS jobs were policy-skipped. The 38 prior native skips (including eight new Windows x64 cases), exact-head native evidence and maintainer/security acceptance remain separate; #7872 item 2 is not declared complete. Keeping Draft. No manual CI dispatch/approval/rerun, merge, force-push, deployment or permission change.

Relocate the existing async parent test mapping in the registry and
independent golden table without changing either mapping or the
four-shard execution plan. Preserve the layout size cap.

luvs01 commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator Author

Published 52799f3 as a normal single-parent fast-forward from a2b, resolving the later dev integration conflict. GitHub now reports mergeable=true; both published JSON blobs match the tested/reviewed files.

The 11-case mock/fixture correction and previous a2b CI success remain valid for that exact earlier head. All seven corrected test/fixture files are unchanged. The new two-file carry only relocates the existing async-parent registration in the layout registry and independent golden. All 2,754 head mappings, four-shard selection/order/batch boundaries, size caps and 1,999 layout lines are preserved. Both file-level three-way merges were clean; no product/ACL policy, timeout or workflow changed.

Local layout/tooling/ratchet: 38 pass / 0 fail, 664 assertions; typecheck: 2,228 files; whitespace: pass. Independent read-only source review of exact delta f6b59fbce58ebdc194ac7496fb8cf0fff83384e0c349cb8f2f042e7ab2ba0bdd found no blocking finding. This source review is distinct from hosted CI, native execution and formal security acceptance.

For the new head, Catalog 40819794129 and Service lifecycle 40819794101 succeeded. Cross-platform 40819794077 is still in progress, with test/runner queues remaining. Actual completed checkout logs confirm d0fdd1cb = 52799f3f + dev@b09c9302, including #7943 and the subsequent upstream registrations. No new-head full CI pass is claimed.

Still Draft. The 38 earlier native skips, including eight new Windows x64 cases, and exact-head maintainer/security acceptance remain open; #7872 item 2 is not closed. No merge, force-push, deployment, permission change or manual CI action was performed.

Final exact-head CI update — 2026-10-29 05:32 UTC

Head remains 52799f3f4724780d8d3649f029dde2b946ae2ccb. Cross-platform 40819794077, Catalog 40819794129 and Service 40819794101 all completed successfully on attempt 1. Cross-platform: 14 successful jobs / 10 policy skips. Actual tested merge is d0fdd1cb with dev b09c9302; new logs show original 11 + additional 5 + held-Promise 3 = 19/19 pass, plus layout/ratchet guards. New Windows-native 8 remain skipped. Linux Rust checks (247 pass / 2 ignored) do not provide Windows ACL, packaged E2E or formal security acceptance. The PR body now records these final results; Draft/native and explicit maintainer-security acceptance remain separate.

luvs01 commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator Author

Windows x64 follow-up on unchanged head 52799f3f4724780d8d3649f029dde2b946ae2ccb: all 38 Windows-gated cases now have individual PASS records, including the eight new cases. These are two bounded local runs, not a completed full two-file suite invocation.

  • The initial two-file run recorded 31 passes and no failing case, then the local launcher’s 300-second overall safety limit stopped it. Individual cases took about 8–13 seconds. This run is recorded as interrupted/exit -1, not suite success.
  • Only the seven cases without a completed result were selected next: three async publication-failure stages (rename/readback/flush), two live child/job fences, and the two native async-parent ACL/timer/denial cases. 7 passed, 0 failed, 33 assertions, 67.04 seconds, native exit 0 and stdout/stderr EOF. The 31 completed cases were not repeated; the other 24 cross-platform cases in these files were not repeated locally.
  • Owned parent/child absence and test-temp cleanup were checked. Source tree, assertions, individual test deadlines, ACL policy and product guards were unchanged.

Environment: Windows 11 x64 10.0.26300, pinned Bun 1.4.4; repository-root preload and test lock enabled, CI/OCX_TEST_NO_QUEUE unset. The shared dependency store has matching runtime lock entries but older Bun declaration packages, so no fresh locked-install or local typecheck claim is made.

Files:

tests/codex-integration/codex-cli-update-windows-pending.test.ts
tests/codex-integration/codex-cli-update-parent-async.test.ts

The second run used:

bun test --isolate ./tests/codex-integration/codex-cli-update-windows-pending.test.ts ./tests/codex-integration/codex-cli-update-parent-async.test.ts --test-name-pattern="async reconciliation publication failure fences: (rename|readback|flush)|fresh native evidence fences (child-alive|job-active) despite terminal receipt|native recovery uses async ACL subprocesses|native async ACL denial preserves recovery bytes"

This supplies the previously missing Windows-gated fixture evidence. It does not establish installed Desktop/updater acceptance or independent security acceptance, and does not complete every remaining synchronous path in #7872. No live app/account/settings change, manual CI dispatch, merge or Ready transition was performed.

Recovery admission can now wait on ACL checks. Read the native feature state and the OpenCodex config inside the admitted callback, recheck the hybrid-pin guard there, and save that fresh config, so a change made meanwhile is neither overruled nor overwritten. Also restores the executable mode of src/cli/index.ts.
The admission is released before the awaiting command resumes, so a save made after the callback could overwrite a competing write with the read copy.
@lidge-jun
lidge-jun marked this pull request as ready for review October 30, 2026 13:08
@lidge-jun

Copy link
Copy Markdown
Owner

Maintainer integration into dev (MAINTAINERS.md exception), exact head 1481539aa78e78d7a6666f218519e311bb633a2a. The PR was marked ready because it now has the maintainer/security acceptance and the native Windows evidence it was waiting for.

Security review. A dedicated fresh gpt-6.1-terra security review of 52799f3f returned PASS. It checked owner-reserved admission and CAS release, pins and identity/single-link/size rechecks across awaits, synchronous commit-scope reuse bound to root and owner, management admission ordering, and the absence of raw ACL output in diagnostics.

Correctness review. Fresh reviews found one real issue: src/cli/v2.ts decided on config and native feature state read before the newly awaited admission, then saved after it. I fixed this on the branch.

  • d81a871b: threads, mode, keep-native-v1 and on re-read inside the admitted callback and recheck the hybrid-pin guard.
  • cb0e0baf: config saves happen inside the callback, so a competing write after the callback is not overwritten.
  • Four deterministic regressions in multi-agent-keep-native-v1.test.ts (held admission plus a post-callback save) failed on the old v2.ts.
  • The executable mode of src/cli/index.ts (100755) is restored.

A doctor --fix-codex-runtime stale-choice concern was rebutted: the merge-base synchronous persistCodexRuntime ran the same recovery admission inside the same resolve-to-write window. The next reviewer accepted the rebuttal and returned PASS on cb0e0baf.

Union. 0ecf0256 and 1481539a merge current dev, because #7876 also edited codex-shim-autorestore.ts and the test-layout registrations. A fresh merge-delta review returned PASS: the internal codex-exec-target skip is kept on both sync and async paths, and each registration appears exactly once. dev has since moved by one commit (#8000) with no file overlap.

Verification. Windows x64, Bun 1.4.4, on 1481539a:

  • The five Windows-native recovery and admission files passed 181 pass / 0 fail.
  • Layout/tooling/ratchet, launcher, CLI head/ready, v2 and parent-async focus passed 171 pass / 0 fail.
  • Typecheck and structure:check passed.

Exact-head CI. Cross-platform run 41058615039 on 1481539a completed success, including all four Ubuntu shards, gates, desktop shell and the ci aggregate. Catalog async contracts and service lifecycle linux-systemd succeeded.

Scope. This lands #7872 item 2 (async recovery admission). The synchronous compatibility exports listed in the description remain.

Not run: ARM64, other-SID behavior, installed Desktop success and a second real apply.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants