Skip to content

fix(operator): guard Codex background automation continuity - #65

Closed
urbanplanningpros wants to merge 28 commits into
devfrom
fix/operator-codex-background-automation-continuity-35943-35947
Closed

fix(operator): guard Codex background automation continuity#65
urbanplanningpros wants to merge 28 commits into
devfrom
fix/operator-codex-background-automation-continuity-35943-35947

Conversation

@urbanplanningpros

@urbanplanningpros urbanplanningpros commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Issue for this PR

Tracks Codex continuity and operator-safety failures reported in upstream issues, including openai/codex#36141, openai/codex#36157, openai/codex#36160, and stale collaboration-mode state on resume in openai/codex#36161. Repository issues are disabled, so an internal Fixes #... link cannot currently be created; the existing needs:issue policy blocker remains.

Type of change

  • Bug fix
  • Executable operating policy
  • Deterministic fixture coverage

What this PR does

Adds continuity guards for background automations, Worktrees, app-server interruption, remote control, context handoff, sidebar continuation, session-residency anomalies, delegated compaction, parent/child ownership, Linux mount-namespace startup, oversized saved-task payloads, and resumed-thread collaboration-mode drift.

All guards preserve task, operation, idempotency, repository, approval, and external-write receipts; reject automatic replay or unsafe replacement before reconciliation; allow bounded continuation through direct OpenAI control or explicitly approved local/Linux execution; and reject prohibited providers, gateways, automatic selectors, Bedrock, Vertex, and Copilot routing.

Linux unreachable-CWD guard — openai/codex#36160

Added:

  • scripts/operator/codex-linux-unreachable-cwd-continuity-guard.mjs
  • scripts/operator/codex-linux-unreachable-cwd-continuity-guard-selftest.mjs

The guard detects app-server startup under a Linux working directory beginning with (unreachable)/ or an equivalent nested-mount-namespace ENOENT failure. It rejects prefix stripping, inherited/nsenter --wd-only recovery, and relaunch loops. Recovery requires an explicit chdir() inside the effective namespace or a verified approved local/Linux executor, plus canonical cwd verification, readable config paths, startup canaries, checkpoint preservation, and state/write reconciliation.

Oversized saved-task guard — openai/codex#36157

Added:

  • scripts/operator/codex-saved-task-payload-continuity-guard.mjs
  • scripts/operator/codex-saved-task-payload-continuity-guard-selftest.mjs

The guard detects renderer serialization failures and image-heavy saved-task payload pressure. It blocks automatic reopening, task replay, and destructive cleanup; preserves the original task outside automatic resume paths; and permits continuation from verified workspace files, a compact checkpoint with images externalized into hashed artifacts, or a verified approved local/Linux executor.

Plan Mode resume guard — openai/codex#36161

Added:

  • scripts/operator/codex-plan-mode-resume-continuity-guard.mjs
  • scripts/operator/codex-plan-mode-resume-continuity-guard-selftest.mjs

The guard compares requested, client-visible, tool/backend, and injected collaboration modes after a resume. When Default is displayed but Plan constraints remain injected, it blocks mutations in the affected thread, preserves and hashes the source state, reconciles repository and external writes, rejects replay and inherited fork/continue paths, and permits the exact unfinished action only through a fresh Default thread with a compact checkpoint or an explicitly approved local/Linux route.

Run

node scripts/operator/codex-linux-unreachable-cwd-continuity-guard.mjs \
  --input /approved/task/linux-unreachable-cwd-evidence.json \
  --json
node scripts/operator/codex-linux-unreachable-cwd-continuity-guard-selftest.mjs

node scripts/operator/codex-saved-task-payload-continuity-guard.mjs \
  --input /approved/task/saved-task-payload-evidence.json \
  --json
node scripts/operator/codex-saved-task-payload-continuity-guard-selftest.mjs

node scripts/operator/codex-plan-mode-resume-continuity-guard.mjs \
  --input /approved/task/plan-mode-resume-evidence.json \
  --json
node scripts/operator/codex-plan-mode-resume-continuity-guard-selftest.mjs

Verification status

  • node --check passed locally for the new Plan Mode guard and self-test.
  • Its seven deterministic fixtures passed locally before upload.
  • The earlier Linux and saved-task deterministic self-test files remain included.
  • Repository CI and disposable affected-runtime canaries remain required before production promotion.

Checklist

  • Linux nested-mount startup recovery is guarded
  • Oversized image-heavy saved-task recovery is guarded
  • Resumed-thread collaboration-mode drift is guarded
  • Automatic replay, unsafe reopening, inherited stale forks, destructive cleanup, and prohibited routing are rejected
  • New Plan Mode syntax checks and deterministic self-tests executed
  • Repository CI attached and passing
  • Linux namespace, image-heavy saved-task, and cross-version Plan Mode canaries passing
  • needs:issue policy blocker resolved or repository issue-first policy adjusted for disabled issues

Sanitized-Manifest: codex-background-automation-continuity-2026-07-30
Allowed-Paths: scripts/operator/codex-background-automation-continuity-guard.mjs, scripts/operator/codex-background-automation-continuity-guard-selftest.mjs, docs/operator/codex-background-automation-continuity.md, scripts/operator/codex-sidebar-continuation-guard.mjs, scripts/operator/codex-sidebar-continuation-guard-selftest.mjs, docs/operator/codex-sidebar-continuation.md, scripts/operator/codex-windows-voice-session-continuity-guard.mjs, scripts/operator/codex-windows-voice-session-continuity-guard-selftest.mjs, docs/operator/codex-windows-voice-session-continuity.md, scripts/operator/codex-session-residency-continuity-guard.mjs, scripts/operator/codex-session-residency-continuity-guard-selftest.mjs, docs/operator/codex-session-residency-continuity.md, scripts/operator/codex-delegated-compaction-continuity-guard.mjs, scripts/operator/codex-delegated-compaction-continuity-guard-selftest.mjs, scripts/operator/codex-parent-child-turn-continuity-guard.mjs, scripts/operator/codex-parent-child-turn-continuity-guard-selftest.mjs, scripts/operator/codex-linux-unreachable-cwd-continuity-guard.mjs, scripts/operator/codex-linux-unreachable-cwd-continuity-guard-selftest.mjs, scripts/operator/codex-saved-task-payload-continuity-guard.mjs, scripts/operator/codex-saved-task-payload-continuity-guard-selftest.mjs, scripts/operator/codex-plan-mode-resume-continuity-guard.mjs, scripts/operator/codex-plan-mode-resume-continuity-guard-selftest.mjs

@github-actions

Copy link
Copy Markdown

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

Copy link
Copy Markdown
Owner Author

Two new continuity deltas require executable coverage before production promotion:

1. Fork-boundary contamination — openai/codex#36074

Continue in new chat can retain messages after the selected fork point when a later app-server turn contains turn/steer. The residual message can survive compaction and be answered again.

Patch requirements:

  • Bind each persisted ordinary user message to its durable turn_id.
  • For rollback/fork calculations, group consecutive initial and steer messages sharing the same non-empty turn_id as one app-server turn.
  • Before granting the child task authority, verify:
    • intended fork turn ID;
    • actual final retained turn ID;
    • child-history SHA-256;
    • zero messages whose app-server turn occurs after the selected boundary;
    • zero removed messages reintroduced after compaction.
  • If verification fails, preserve the source task, reject the contaminated child, reconcile possible writes, and continue from one compact checkpoint in an explicitly bound fresh task or approved local/Linux executor. Do not retry the native fork path.

Required fixtures:

  1. Ordinary fork without steer passes.
  2. Initial + steer messages with one durable turn_id are removed atomically.
  3. A residual post-boundary message blocks child authority before compaction.
  4. Compaction cannot reintroduce removed content.
  5. Replacement-task replay and prohibited routing are rejected.

2. Duplicate GitHub mention tasks — openai/codex#36072

One @codex review mention created duplicate cloud tasks, associated them with the wrong repository, and Stop did not produce a durable cancelled state.

Patch requirements:

  • Derive a review idempotency key from: GitHub delivery/comment ID + repository node ID + PR number + head SHA + normalized command.
  • Permit exactly one active review task for that key.
  • Verify the task repository identity and PR head SHA before any review or branch authority.
  • Treat Stop/Cancel as pending until canonical cloud-task state confirms a terminal cancellation.
  • When duplicates exist, reconcile each task's comments, checks, branch writes, and review submissions before archiving extras.
  • Continue the required review through one verified task or the authorized local Git/review route; never replay a review whose side effects are unknown.

Required fixtures:

  1. Duplicate deliveries collapse into one task.
  2. Wrong-repository association is blocked before execution.
  3. Cancelled UI state that reverts to running remains non-authoritative.
  4. One task completed and one task unknown triggers reconciliation, not replay.
  5. Correct repository/head verification admits the single task.

Suggested guard expansion: add fork-boundary and GitHub-mention modes to codex-background-automation-continuity-guard.mjs, or create focused guards if the current schema would become ambiguous.

@chatgpt-codex-connector

Copy link
Copy Markdown

Summary

  • Added a fork-boundary continuity guard that:
    • requires durable turn_id bindings for ordinary user messages;
    • groups consecutive messages sharing a turn ID;
    • verifies the intended and actual retained turn, child-history SHA-256, and absence of post-boundary messages;
    • detects partially retained turns and content reintroduced during compaction;
    • rejects native-fork retries, unsafe replacement replay, and prohibited routes. scripts/operator/codex-fork-boundary-continuity-guard.mjsL13-L45
  • Added deterministic fork fixtures covering ordinary forks, atomic initial-plus-steer removal, residual contamination, compaction reintroduction, replacement replay, and prohibited routing. scripts/operator/codex-fork-boundary-continuity-guard-selftest.mjsL10-L31
  • Added a GitHub-mention continuity guard that derives and verifies the review idempotency key, validates repository and head identity, enforces one active review task, requires canonical cancellation, reconciles duplicate side effects, and prevents replay when review effects are unknown. scripts/operator/codex-github-mention-continuity-guard.mjsL12-L26
  • Added deterministic mention fixtures covering duplicate delivery collapse, incorrect repository association, non-authoritative cancellation UI state, completed-plus-unknown task reconciliation, and valid repository/head admission. scripts/operator/codex-github-mention-continuity-guard-selftest.mjsL10-L27
  • Committed the changes as 57f0fac (fix(operator): guard fork and mention continuity) and created the follow-up pull request metadata with the title “fix(operator): cover fork boundaries and duplicate mention tasks.”

Testing

  • node --check scripts/operator/codex-fork-boundary-continuity-guard.mjs
  • node --check scripts/operator/codex-fork-boundary-continuity-guard-selftest.mjs
  • node --check scripts/operator/codex-github-mention-continuity-guard.mjs
  • node --check scripts/operator/codex-github-mention-continuity-guard-selftest.mjs
  • node scripts/operator/codex-fork-boundary-continuity-guard-selftest.mjs
  • node scripts/operator/codex-github-mention-continuity-guard-selftest.mjs
  • git diff --check
  • git status --short --branch — clean working tree after commit.

View task →

Copy link
Copy Markdown
Owner Author

New official continuity delta: fractional rate-limit values can truncate projected thread history

Upstream openai/codex#36083 merged on July 30, 2026. Paginated thread-history materialization could reject otherwise valid rollout records when used_percent was encoded as a floating-point JSON value. Once projection stopped at that record, later final answers could remain in the canonical rollout but never appear in projected history.

Add executable coverage before production promotion:

  1. Treat projected SQLite/UI history as non-authoritative whenever the canonical rollout extends beyond the recorded projection byte offset or ordinal.
  2. Preserve the rollout file exactly; never truncate, rewrite, or replay the affected turn merely because its final answer is absent from projected history.
  3. Record and compare:
    • thread ID;
    • rollout path and SHA-256;
    • projection byte offset and ordinal;
    • first unprojected record offset;
    • canonical final-answer item IDs;
    • projected final-answer item IDs;
    • operation IDs and external-write reconciliation state.
  4. Parse canonical rollout lines through an intermediate generic JSON value before applying the typed schema so integral, fractional, very small, and large floating-point rate-limit percentages are accepted.
  5. Recovery sequence:
    • read the immutable canonical rollout through the approved local/Linux route;
    • classify the turn as completed, active, not dispatched, or unknown;
    • if completed, surface the canonical final answer without replaying tools or writes;
    • if projection alone is stale, rebuild only the projection from the preserved rollout;
    • if external effects are unknown, withhold only that mutation until destination reconciliation is complete.
  6. Keep this correction in canary status until it is present in a pinned stable Codex release.

Required fixtures:

  • 0.0, 1.0, 12.5, 87.25, 1e-12, and a large floating-point percentage all project successfully.
  • A final answer after a fractional rate-limit record remains visible after catch-up materialization.
  • Subsequent history appends continue after the repaired projection.
  • A missing projected answer with a completed canonical turn is recovered without tool replay.
  • Rollout truncation, mutation replay, prohibited routing, and excluded-provider state import are rejected.

Copy link
Copy Markdown
Owner Author

July 30 delegated-task compaction update

Added executable coverage for merged upstream Codex change openai/codex#36128.

New files:

  • scripts/operator/codex-delegated-compaction-continuity-guard.mjs
  • scripts/operator/codex-delegated-compaction-continuity-guard-selftest.mjs

The guard verifies that remote-v2 compaction retains bounded active delegated-agent messages, excludes completion messages, accounts for encrypted delegated content in token estimates, restores initial and delegated context before the latest real message, and strips inherited parent-agent messages when forking a child. It blocks automatic respawn or mutation replay and requires canonical-thread and external-write reconciliation before continuing only the exact unfinished action through the same thread, guarded single-agent execution, or an approved local/Linux route.

Local node --check and deterministic self-tests passed before upload. Remote CI and disposable remote-compaction/fork canaries remain required before production promotion.

Run:

node scripts/operator/codex-delegated-compaction-continuity-guard.mjs \
  --input /approved/task/codex-delegated-compaction-evidence.json \
  --json
node scripts/operator/codex-delegated-compaction-continuity-guard-selftest.mjs

No excluded provider, gateway, automatic selector, Bedrock, Vertex, or Copilot route was introduced.

Copy link
Copy Markdown
Owner Author

July 30 delta: approval integrity and non-interactive session continuity

New upstream findings require three additional boundaries before this PR can receive production authority:

  1. Compaction must not satisfy the current stage with an earlier approval (openai/codex#36131). Persist and verify stage_id, approval_id, exact authorized scope hash, operation ID, and idempotency key before compaction. After compaction, require the same current-stage receipt to be restored; reject any previous-stage approval reuse. Withhold only the affected mutation and continue unrelated work normally.
  2. Cryptographic authorization comparisons must be deterministic (openai/codex#36137). Compare typed planned_sha256 and authorized_sha256 values in the same declared hash domain before invoking semantic review. If Guardian denies while the typed values and explicit scope are identical, preserve the patch and original receipt, do not reword/retry/weaken the control, and continue only after a fresh typed manual approval receipt through pinned direct OpenAI control or an explicitly approved local/Linux executor.
  3. VS Code must not treat missing non-interactive threads as lost state (openai/codex#36135). Inventory mcp/appServer and exec sessions with explicit sourceKinds or codex resume --include-non-interactive; bind session ID, source kind, repository SHA, operation ledger, and external-write reconciliation before resuming.

Required deterministic fixtures:

  • compaction restores the current stage approval and proceeds;
  • compaction reuses a previous stage approval and is blocked;
  • current stage approval is absent after compaction and only that mutation is withheld;
  • exact 64-character SHA-256 values match but semantic review denies; automatic retry is blocked and typed manual reroute is required;
  • reviewer allows while typed scope/hash comparison fails; mutation is blocked;
  • VS Code interactive-only listing omits an existing MCP/exec session; the guard discovers it through explicit source kinds without creating a replacement session;
  • prohibited gateways, automatic selectors, and excluded-provider routes remain rejected.

No source-file change is claimed by this comment; it records the executable patch and fixture requirements for the existing continuity branch.

@github-actions

Copy link
Copy Markdown

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@github-actions

Copy link
Copy Markdown

This pull request has been automatically closed because it was not updated to meet our contributing guidelines within the 2-hour window.

Feel free to open a new pull request that follows our guidelines.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant