Skip to content

Reconcile uncertain local tool calls before resuming - #5502

Merged
markstuart-oai merged 29 commits into
feat/codex-harnessfrom
feat/worker-reconciliation
Nov 5, 2026
Merged

markstuart-oai merged 29 commits into
feat/codex-harnessfrom
feat/worker-reconciliation

Conversation

@markstuart-oai

@markstuart-oai markstuart-oai commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Review stack: #5504 (CI) > #5499 (turn controls) > #5500 (receipts) > #5501 (executor) > #5502 (recovery) > #5503 (example) > #5495 (docs). Combined reference: #5494.

Requirements · REQ733.

Summary

Recovery preserves the exact text received by a custom tool. It decodes JSON for ordinary function calls.

Once the application records an applied or not_applied outcome, it can reopen the session without submitting that receipt again. This also covers histories that retain a native tool start but lack its native completion.

The SDK reconciles uncertain calls from the root session. If an uncertain effect belongs to a child, recovery stops before exposing a receipt that the root cannot reconcile.

A process can exit after a tool takes effect but before its result is recorded. Reopening that history must stop before another model request or automatic replay. Add LocalRecoveryRequired with the uncertain calls and retained history, plus ReconciledCall input for outcomes the application verified independently. UncertainCall.reconcile(outcome=..., result=...) constructs that confirmation from the reported call's IDs, without requiring the caller to copy them.

Bind each supplied result to the original native thread, turn and call under the local storage writer. Flush and read back the result before admitting new work. Retained reconciliation tags prevent replay of those recorded invocation IDs. The application owns effect reconciliation and duplicate prevention across new call IDs; this does not provide general exactly-once execution or undo effects. Recovery requires a supported idle local session; cold descendant recovery remains unsupported.

Layer 4 of 5; base feat/worker-executor. It uses the executor and retained-record contracts from the earlier layers. Model auth remains API-key-only; managed login/billing are excluded under REQ731.

Acceptance dependencies enabled here: REQ781 needs crash reconciliation, and REQ780 needs uncertain-effect reconciliation before another publication decision. This layer supplies recovery controls; it does not establish application acceptance.

Test plan

The old projection asked for another receipt on a second ordinary reopen for both outcomes. The fix passed 27 recovery and history tests, including both receipt-free reopens, retrying an identical receipt, and fencing reuse of the original call ID.

All 27 native storage and descendant recovery cases passed. Five focused cases covered JSON-looking custom text, empty input and mixed raw/native history records. Ruff and the focused type checks passed.

Issue number

None linked. Owning requirements database IDs are listed above.

Checks

  • I've added new tests, if relevant
  • I've run the applicable checks in AGENTS.md, including .agents/skills/code-change-verification/scripts/run.sh when required
  • I've confirmed all required checks pass
  • I've completed the review required by AGENTS.md

@markstuart-oai
markstuart-oai requested review from a team, rm-openai and seratch as code owners November 4, 2026 04:17
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-05T02:23:21.541221Z 1488586 New commits
🔒 Security Review ✅ Completed 2026-11-05T02:24:52.963455Z 1488586 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at b15f244. Reviewed the reconciliation layer against its immediate base: application receipts must cover every unresolved invocation, match native thread/turn/call identities, and agree with retained results. Durable import precedes replay fencing; descendants and executor-policy mismatches remain guarded. No actionable findings.

Static review only; no candidate code or tests run. Hosted lint/docs checks passed; Linux/macOS native CI remains running and Windows checks are skipped. Leave unmerged as requested.

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at d2f6580.

Reviewed the recovery API update with an independent reviewer. UncertainCall.reconcile preserves the original identity and delegates validation to ReconciledCall without side effects. Regression changes cover invalid confirmations, journal equivalence, repeated reopen and replay fencing. No actionable findings in this layer; underlying executor blockers remain tracked on5501.

Static review only; no candidate code or tests run. Fresh hosted CI remains pending. Leave unmerged as requested.

@markstuart-oai
markstuart-oai force-pushed the feat/worker-reconciliation branch from d2f6580 to 94defa9 Compare November 4, 2026 05:54

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 94defa9c8b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/agents/recovery.py Resolved

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed the existing recovery finding: #5502 (comment). Custom-tool input such as 42, null, or {} is projected as function arguments, then JSON-decoded in _uncertain_call, changing the original input before an application verifies the external effect. Preserve the call kind and decode only function-call arguments; retain custom-tool input verbatim. This supersedes my earlier approval. No duplicate inline comment added.

Static review only; no candidate code or tests executed. Hosted CI: pending: native-linux / Native package (ubuntu-24.04), native-linux / Native package (ubuntu-24.04), native-macos / Native package (macos-latest), native-macos / Native package (macos-latest); no failed checks observed.

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom-tool recovery input finding is fixed. The history projection preserves raw custom input separately through native item replacement, including empty and JSON-shaped strings, while function arguments retain normal JSON decoding. No remaining actionable finding in this layer.

Static review only; no candidate code or tests executed. Hosted CI: pending: native-linux / Native package (ubuntu-24.04), native-linux / Native package (ubuntu-24.04), native-macos / Native package (macos-latest), native-macos / Native package (macos-latest); no failed checks observed.

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the exact tree changes and inherited executor updates. No additional issue in this layer. One existing P2 remains: #5501 (comment). For an implicit WSS Environment without network policy, a pending manual turn explicitly limited to tools=[manual_tool] still captures an executor-policy digest solely because active is non-null. Its saved operation_tools already excludes executor capabilities, yet restore without the unused Environment fails with Checkpoint and Environment must agree. Gate the active-turn digest requirement on the operation actually selecting executor tools; retain strict-write and network-policy checks. No duplicate inline finding.

The sandbox-denial output report is not a blocker: result-policy capture marks the call before execution, the global completed-item filter withholds output before observers/history, and the error path returns the withheld failure.

Static review only; no candidate code or tests executed. Hosted checks pending: native-linux / Native package (ubuntu-24.04), native-linux / Native package (ubuntu-24.04), native-macos / Native package (macos-latest), native-macos / Native package (macos-latest). Failed checks: none observed.

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shared physical write-root and storage protections are sound: filesystem identities cover alternate paths, checklist aliases and hard links are checked, and private runtime symlinks fail closed. Disjoint storage and write grants remain supported. The executor startup fixture also removes the parent-selected port race. Reconciliation behavior is unchanged in the actual old/new blob diff.

Coordinator and independent static reviews of actual old/new file contents found no actionable issue. Hosted CI on this new head remains pending; prior-head results do not qualify it. No candidate code or local tests executed.

Base automatically changed from feat/worker-executor to feat/codex-harness November 5, 2026 01:22

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approved f7dae0bc4f1a64fd858473b2da319cf8812a9836. Only the shared deep-path hard-link scanner patch and its manifest changed; both exactly match the current base and the previously reviewed fix. Recovery implementation is unchanged. No new actionable findings from coordinator and independent static review.

Fresh hosted native CI remains pending. No candidate code, builds or local tests executed. Existing merge holds remain in effect.

@markstuart-oai
markstuart-oai merged commit 7df7872 into feat/codex-harness Nov 5, 2026
44 checks passed
@markstuart-oai
markstuart-oai deleted the feat/worker-reconciliation branch November 5, 2026 03:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants