Skip to content

fix(agents): avoid duplicate recovery tool-map charge - #1555

Merged
Wibias merged 3 commits into
lidge-jun:devfrom
soulbah:codex/fix-recovery-tool-map-budget
Aug 12, 2026
Merged

fix(agents): avoid duplicate recovery tool-map charge#1555
Wibias merged 3 commits into
lidge-jun:devfrom
soulbah:codex/fix-recovery-tool-map-budget

Conversation

@soulbah

@soulbah soulbah commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Keep the original tool bridge maps after encrypted task recovery reparses the request. Recovery changes the assignment content, not the tool definitions, so rebuilding the maps charged the translator budget twice and could reject requests near the limit.
  • Add a regression test that exercises the authenticated recovery path with a namespaced tool and asserts one retained-map charge.
  • Clarify the opt-in startup warning: recovered plaintext assignment data stays in the bounded process-local cache.

This follows up on the review left on #1540 and keeps the non-persistable response-state guard added before that PR merged. Refs #92.

The branch is rebased onto dev at cfc61c1cd, including #1556. The overlap in core.ts was resolved by preserving #1556's recovered-task fallback reroute and removing only the redundant buildToolBridgeMaps call.

Verification

  • Regression test before the fix: failed with Expected: 1, Received: 2.
  • bun scripts/test.ts tests/agent-task-recovery.test.ts tests/agent-task-recovery-fallback.test.ts tests/responses-state.test.ts tests/agent-task-recovery-security.test.ts tests/agent-task-recovery-cache.test.ts tests/config.test.ts — 274 pass, 0 fail.
  • bun run typecheck
  • bun run privacy:scan
  • git diff --check origin/dev...HEAD
  • bun run prepush — exited 0 with 11,454 pass, 8 skip, 0 fail on head b7f468ed4c4ce5bc8aed36505a2d236942a069d0 (tree f114cee4214664ed171c6bc4b5b745b1102b454a). React Doctor also reported three compiler diagnostics in unchanged tests/codex-account-pool-behaviour.test.tsx; this PR changes no GUI files.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • Bug Fixes

    • Improved experimental task recovery and tool dispatch reliability.
    • Prevented duplicate translator-budget charges during recovery.
    • Updated startup messaging to clarify that recovered assignment data is retained as plaintext in a bounded process-local cache.
  • Tests

    • Added coverage for namespaced tool mappings, recovery dispatch, translator budgeting, startup warning disclosures, and reliable API-key deletion flows.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 42fe855b-0288-4f26-8d46-280b5cea93c0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5e1895d1-9d74-4196-9169-597ca7e998db

📥 Commits

Reviewing files that changed from the base of the PR and between b7f468e and 2311264.

📒 Files selected for processing (1)
  • gui/tests/apikeys-refresh-preserve.test.tsx

📝 Walkthrough

Walkthrough

The change updates the task-recovery warning, preserves existing toolBridgeMaps during recovery reparsing, adds translator-budget coverage for namespaced tool mappings, and separates React test actions for API key deletion timing.

Changes

Agent-task recovery

Layer / File(s) Summary
Recovery warning contract
src/server/index.ts, tests/agent-task-recovery.test.ts
The warning and test assertions identify recovered plaintext assignment data and the process-local cache.
Tool bridge recovery coverage
src/server/responses/core.ts, tests/helpers/agent-task-recovery.ts, tests/agent-task-recovery.test.ts
Recovery reparsing no longer rebuilds existing toolBridgeMaps. The test helper forwards tools and translatorBudget. The regression test verifies one charge for a namespaced mapping and disposes the budget.
GUI delete-flow test timing
gui/tests/apikeys-refresh-preserve.test.tsx
The delete-button click and confirmation-timer advancement run in separate React act blocks.

Estimated code review effort: 2 (Simple) | ~10 minutes

Mergeability Score: ⚪ Minimal · up to 23112

The change is narrowly scoped to prevent duplicate recovery tool-map charging, with regression coverage and the listed checks passing; no actionable merge-blocking risk remains.

Possibly related PRs

Suggested reviewers: ingwannu, lidge-jun

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: preventing duplicate tool-map translator-budget charges during agent-task recovery.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 added the bug Something isn't working label Aug 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

UI screenshot waived by the gui-screenshot-waived label.
This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently. If no CodeRabbit review appears, comment @coderabbitai review to request one.
Maintainers: @lidge-jun @Ingwannu @Wibias

@soulbah

soulbah commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/agent-task-recovery.test.ts`:
- Around line 183-188: Update the fetch mock and assertions in the recovery test
around the globalThis.fetch stub: record each request’s URL and headers, then
assert exactly one recovery request contains the expected authorization and
chatgpt-account-id headers. Also assert that the routed provider request
occurred, and perform these request assertions before validating mappingCharges.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f9317099-ef32-4076-8e4b-d7c60b3519e2

📥 Commits

Reviewing files that changed from the base of the PR and between 6c5f94a and fc7ec6c.

📒 Files selected for processing (4)
  • src/server/index.ts
  • src/server/responses/core.ts
  • tests/agent-task-recovery.test.ts
  • tests/helpers/agent-task-recovery.ts
💤 Files with no reviewable changes (1)
  • src/server/responses/core.ts

Comment thread tests/agent-task-recovery.test.ts Outdated
@soulbah
soulbah force-pushed the codex/fix-recovery-tool-map-budget branch from 4dcbf00 to 27a3123 Compare August 12, 2026 19:10
@github-actions
github-actions Bot marked this pull request as ready for review August 12, 2026 19:11
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@github-actions[bot] The readiness checklist is complete. PR #1555 is marked ready for review.


🧠 Learnings used
Learnt from: Wibias
Repo: lidge-jun/opencodex PR: 986
File: .github/workflows/enforce-pr-target.yml:631-636
Timestamp: 2026-08-04T06:41:30.089Z
Learning: For the PR readiness gate in `.github/workflows/enforce-pr-target.yml`, the required scope is to bind contributor checklist completion and maintainer notification to the exact PR head SHA, then reset them after a new head commit. Maintainer approval staleness is separate from this gate and should be enforced by GitHub branch protection, such as `dismiss-stale-reviews` or `require_last_push_approval`, when configured for `dev`.

You are interacting with an AI system.

1 similar comment
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@github-actions[bot] The readiness checklist is complete. PR #1555 is marked ready for review.


🧠 Learnings used
Learnt from: Wibias
Repo: lidge-jun/opencodex PR: 986
File: .github/workflows/enforce-pr-target.yml:631-636
Timestamp: 2026-08-04T06:41:30.089Z
Learning: For the PR readiness gate in `.github/workflows/enforce-pr-target.yml`, the required scope is to bind contributor checklist completion and maintainer notification to the exact PR head SHA, then reset them after a new head commit. Maintainer approval staleness is separate from this gate and should be enforced by GitHub branch protection, such as `dismiss-stale-reviews` or `require_last_push_approval`, when configured for `dev`.

You are interacting with an AI system.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@github-actions[bot] Acknowledged. PR #1555 is marked ready for review. The readiness checklist is complete for head SHA 27a3123abca0d19e6fbfc0141c7f8d3ee0c685a9.


🧠 Learnings used
Learnt from: Wibias
Repo: lidge-jun/opencodex PR: 986
File: .github/workflows/enforce-pr-target.yml:631-636
Timestamp: 2026-08-04T06:41:30.089Z
Learning: For the PR readiness gate in `.github/workflows/enforce-pr-target.yml`, the required scope is to bind contributor checklist completion and maintainer notification to the exact PR head SHA, then reset them after a new head commit. Maintainer approval staleness is separate from this gate and should be enforced by GitHub branch protection, such as `dismiss-stale-reviews` or `require_last_push_approval`, when configured for `dev`.

You are interacting with an AI system.

@Wibias Wibias left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The fix itself looks correct, including the security-sensitive parts. recoverEncryptedAgentTask only replaces the encrypted assignment/input item; it does not alter the declared tools, trailing additional_tools, or tool_choice, so keeping the original caller-authorized toolBridgeMaps is the right way to avoid charging the translator retained budget twice. The non-persistable guard remains in place, and the updated warning is more accurate about recovered plaintext.

I am blocking on branch freshness/integration validation before approval. This head is based on 5f9b783b, while current dev is 0a8147b3; dev is 17 commits ahead of the merge base, which is beyond the repository's normal freshness window. Current dev also changed src/server/responses/core.ts (the #1500 web-search streaming argument at the later runWithWebSearch call). That hunk is separate from this recovery change, so I do not see a semantic conflict, but this is a security-boundary server path and the full suite reported here was run against the older base.

Please rebase/update onto current dev and rerun the focused recovery/state tests, typecheck/privacy scan, and full prepush/CI. I found no additional code or security blocker in the present diff.

@github-actions
github-actions Bot marked this pull request as draft August 12, 2026 20:13
Recovery reparsing changes task content, not tool definitions. Keep the original bridge maps to avoid charging the translator budget twice, and make the plaintext retention warning explicit.

Refs lidge-jun#92
@soulbah
soulbah force-pushed the codex/fix-recovery-tool-map-budget branch from 27a3123 to b7f468e Compare August 12, 2026 20:37
@soulbah

soulbah commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — I rebased this onto current dev at cfc61c1cd, including #1556.

The conflict was limited to the same recovery block. I kept #1556's fallback reroute intact and removed only the redundant buildToolBridgeMaps call.

Validation on the rebased head:

  • focused recovery/fallback/state/security/cache/config tests: 274 pass, 0 fail
  • typecheck, privacy scan, and diff check: pass
  • full bun run prepush: exited 0 with 11,454 pass, 8 skip, 0 fail

One transparent note: the React Doctor step printed three compiler diagnostics in unchanged tests/codex-account-pool-behaviour.test.tsx, although it returned 0. This PR has no GUI changes.

@github-actions
github-actions Bot marked this pull request as ready for review August 12, 2026 20:40
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

@github-actions[bot] The readiness checklist is complete for head SHA b7f468ed4c4ce5bc8aed36505a2d236942a069d0. I will review the current PR changes.


🧠 Learnings used
Learnt from: Wibias
Repo: lidge-jun/opencodex PR: 986
File: .github/workflows/enforce-pr-target.yml:631-636
Timestamp: 2026-08-04T06:41:30.089Z
Learning: For the PR readiness gate in `.github/workflows/enforce-pr-target.yml`, the required scope is to bind contributor checklist completion and maintainer notification to the exact PR head SHA, then reset them after a new head commit. Maintainer approval staleness is separate from this gate and should be enforced by GitHub branch protection, such as `dismiss-stale-reviews` or `require_last_push_approval`, when configured for `dev`.
⚠️ Action not completed

Already reviewed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@github-actions[bot] Acknowledged. PR #1555 is ready for review. The readiness checklist is complete for head SHA b7f468ed4c4ce5bc8aed36505a2d236942a069d0.


🧠 Learnings used
Learnt from: Wibias
Repo: lidge-jun/opencodex PR: 986
File: .github/workflows/enforce-pr-target.yml:631-636
Timestamp: 2026-08-04T06:41:30.089Z
Learning: For the PR readiness gate in `.github/workflows/enforce-pr-target.yml`, the required scope is to bind contributor checklist completion and maintainer notification to the exact PR head SHA, then reset them after a new head commit. Maintainer approval staleness is separate from this gate and should be enforced by GitHub branch protection, such as `dismiss-stale-reviews` or `require_last_push_approval`, when configured for `dev`.

You are interacting with an AI system.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@github-actions[bot] Acknowledged. PR #1555 is ready for review, and the readiness checklist is complete for head SHA b7f468ed4c4ce5bc8aed36505a2d236942a069d0.


🧠 Learnings used
Learnt from: Wibias
Repo: lidge-jun/opencodex PR: 986
File: .github/workflows/enforce-pr-target.yml:631-636
Timestamp: 2026-08-04T06:41:30.089Z
Learning: For the PR readiness gate in `.github/workflows/enforce-pr-target.yml`, the required scope is to bind contributor checklist completion and maintainer notification to the exact PR head SHA, then reset them after a new head commit. Maintainer approval staleness is separate from this gate and should be enforced by GitHub branch protection, such as `dismiss-stale-reviews` or `require_last_push_approval`, when configured for `dev`.

You are interacting with an AI system.

@Wibias Wibias left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Re-review on exact head b7f468ed4c4ce5bc8aed36505a2d236942a069d0: approved.

My previous blocker was branch freshness/integration validation. That is resolved: this head is rebased directly onto current dev cfc61c1cdb5e117d109a03996079aeeedfde770b, including #1556.

I rechecked the overlapping recovery block. #1556's post-recovery fallback re-selection and route update remain intact, as does the non-persistable plaintext guard. The production delta here is limited to removing the redundant second buildToolBridgeMaps call.

That removal is correct: recoverEncryptedAgentTask only replaces the encrypted assignment/input part and does not change the caller-declared tools or tool choice. The original maps therefore remain the caller-authorized mapping authority, while rebuilding them only charged the retained translator budget twice. The strengthened regression also proves one authenticated recovery request, one routed provider request, and one namespaced mapping charge.

The updated warning accurately discloses plaintext retention in the bounded process-local cache. I found no remaining correctness, privacy, or security blocker in the current diff.

Repository Actions have not run yet on this fork head (action_required with no jobs), so merge should still wait for exact-head Cross-platform CI / React Doctor approval and successful completion.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@github-actions[bot] Acknowledged. PR #1555 is ready for review at head SHA b7f468ed4c4ce5bc8aed36505a2d236942a069d0. The readiness checklist and deterministic hygiene checks passed.


🧠 Learnings used
Learnt from: Wibias
Repo: lidge-jun/opencodex PR: 986
File: .github/workflows/enforce-pr-target.yml:631-636
Timestamp: 2026-08-04T06:41:30.089Z
Learning: For the PR readiness gate in `.github/workflows/enforce-pr-target.yml`, the required scope is to bind contributor checklist completion and maintainer notification to the exact PR head SHA, then reset them after a new head commit. Maintainer approval staleness is separate from this gate and should be enforced by GitHub branch protection, such as `dismiss-stale-reviews` or `require_last_push_approval`, when configured for `dev`.

You are interacting with an AI system.

@github-actions
github-actions Bot marked this pull request as draft August 12, 2026 21:41
@Wibias
Wibias marked this pull request as ready for review August 12, 2026 21:41
@github-actions
github-actions Bot marked this pull request as draft August 12, 2026 21:41
@Wibias
Wibias marked this pull request as ready for review August 12, 2026 21:42
@github-actions
github-actions Bot marked this pull request as draft August 12, 2026 21:43
@Wibias Wibias added the gui-screenshot-waived Maintainer waiver for false-positive GUI screenshot requirements label Aug 12, 2026
@github-actions
github-actions Bot marked this pull request as ready for review August 12, 2026 21:43
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

@github-actions[bot] The readiness checklist is complete for head SHA 23112646cf682179a5454176062fc4eb8e029a8b. I will review the current PR changes.


🧠 Learnings used
Learnt from: Wibias
Repo: lidge-jun/opencodex PR: 986
File: .github/workflows/enforce-pr-target.yml:631-636
Timestamp: 2026-08-04T06:41:30.089Z
Learning: For the PR readiness gate in `.github/workflows/enforce-pr-target.yml`, the required scope is to bind contributor checklist completion and maintainer notification to the exact PR head SHA, then reset them after a new head commit. Maintainer approval staleness is separate from this gate and should be enforced by GitHub branch protection, such as `dismiss-stale-reviews` or `require_last_push_approval`, when configured for `dev`.
⚠️ Action not completed

Already reviewed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@github-actions[bot] Acknowledged. PR #1555 is ready for review at head SHA 23112646cf682179a5454176062fc4eb8e029a8b. The review readiness checklist is complete.


🧠 Learnings used
Learnt from: Wibias
Repo: lidge-jun/opencodex PR: 986
File: .github/workflows/enforce-pr-target.yml:631-636
Timestamp: 2026-08-04T06:41:30.089Z
Learning: For the PR readiness gate in `.github/workflows/enforce-pr-target.yml`, the required scope is to bind contributor checklist completion and maintainer notification to the exact PR head SHA, then reset them after a new head commit. Maintainer approval staleness is separate from this gate and should be enforced by GitHub branch protection, such as `dismiss-stale-reviews` or `require_last_push_approval`, when configured for `dev`.

You are interacting with an AI system.

@Wibias
Wibias merged commit 75cacdf into lidge-jun:dev Aug 12, 2026
42 of 59 checks passed

Wibias commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Thanks @soulbah — merged. This is useful because recovery only changes the recovered assignment content, so rebuilding the tool bridge maps after the reparse was both unnecessary and costly: it charged the translator retained budget twice and could make otherwise-valid recovered tasks fail near the limit. Keeping the original maps also preserves the caller-authorized tool mapping across recovery. The focused regression coverage and clearer plaintext-cache warning are appreciated too.

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

Labels

bug Something isn't working gui-screenshot-waived Maintainer waiver for false-positive GUI screenshot requirements review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants