Skip to content

fix(runner): answered approvals close before a carried sibling re-parks the turn - #5910

Merged
mmabrouk merged 4 commits into
release/v0.112.0from
fix/resume-approval-ordering
Aug 10, 2026
Merged

fix(runner): answered approvals close before a carried sibling re-parks the turn#5910
mmabrouk merged 4 commits into
release/v0.112.0from
fix/resume-approval-ordering

Conversation

@mmabrouk

Copy link
Copy Markdown
Member

Context

When one turn raises two approval gates and the resume answers only one, the answered call executed but its result was replaced with the synthetic APPROVED_EXECUTION_RESULT_UNKNOWN: the carried (unanswered) sibling triggered the pause synchronously, before the race that should observe the answered call's real completion. Full characterization with runner-log and DB evidence: #5907. Live evidence includes a production-path shape (an auto-allowed rename racing a client-tool park).

Changes

  • The resume block re-parks the carried sibling only AFTER each answered/allowed execution gets its waitForToolCallClosure window, on the same per-call bound the paused-settle path uses. Pi is exempt by design: its batch semantics make a pending sibling during closure impossible, so the park-and-carry branch keeps owning those spans. Carried-gate re-park semantics are unchanged.
  • The existing carry test (which reproduced the exact topology but asserted nothing about the answered gate) now asserts the closure window is open when the answer lands and the real completion reaches the tracer; a new sibling test delivers the completion only while the re-park has not fired.
  • Benchmark corrections: name-06 mounts the rename ops with permission: allow, mirroring the shipped overlay (the product never gates these; the approval-race regression lives at the runner unit layer). The QA harness now collects and answers EVERY raised gate in a turn instead of only the last (back-compatible for single-gate flows; all consumers audited).

Tests

Red/green proven by stashing the fix: before, 2 failed with APPROVED_EXECUTION_RESULT_UNKNOWN written into the settle; after, 48/48 in the file, 2145/2145 across the runner suite, tsc clean. Scenario JSON validated, persona drift locks green, CI-pinned ruff clean.

Known follow-up (not this PR)

A carried gate is re-parked server-side but every later frame for it is suppressed, so the client is never re-told it owes an answer and the gate expires at the 10-minute TTL. Needs its own issue: re-emit carried gates on resume or re-render from the durable interaction rows.

…arried sibling re-parks

In the resume block, the carried-sibling re-park fired synchronously
after the answer batch — before the Promise.race — so a freshly-approved
execution's real completion was never observed and the paused-settle
replaced it with APPROVED_EXECUTION_RESULT_UNKNOWN (issue #5907). The
re-park now waits for each answered/allowed execution's closure first,
on the same per-call bound the paused-settle uses. Pi stays exempt on
purpose: it prepares the whole batch before executing any call, so while
a carried sibling gate is pending closure is impossible and the
park-and-carry branch keeps owning those spans. The carried gate's
re-park semantics are unchanged.
…ed re-park

The carry test reproduced the exact two-gates-one-answered topology of
issue #5907 but never asserted the answered gate's result — the failure
mode had zero assertion coverage. It now delivers frames in the fixed
order (answer, real completion, then the re-park), asserts the closure
window is open when the answer lands, that the real completion reaches
the tracer, and that no sentinel replaces it. A sibling test pins the
window end to end: the completion is delivered only while the pause has
not re-armed, so it goes red on the pre-fix ordering (the settle
replaced the result with the UNKNOWN sentinel) and green after.
…; the harness answers every raised gate

name-06 now mounts both rename ops with permission: allow, matching the
product build-kit overlay — these calls never gate in the product, so
the scenario measures naming behavior, not approval mechanics; the
approval-race regression (issue #5907) is guarded at the runner unit
layer instead, noted in the scenario's about block.

qa_matrix_lib's Turn.approval was a single dict overwritten by each
tool-approval-request frame, so a multi-gate turn only ever answered the
LAST gate and left the rest pending until their TTL. Turn.approvals now
collects every raised gate in raise order (a re-raise refreshes its id
in place), approval_reply answers each, assistant_message marks each
gated part, and Turn.approval stays as a back-compat property returning
the last gate — every existing caller reads truthiness plus ids and none
assigns, so single-gate flows are byte-identical. Unit tests pin the
single-gate message, the answer-all behavior, and the re-raise refresh.
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Aug 10, 2026
@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Error Error Aug 10, 2026 4:38pm

Request Review

@dosubot dosubot Bot added bug report Something isn't working tests labels Aug 10, 2026
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5a6b5cb7-e117-4fb4-a25e-4e5cc61726d8

📥 Commits

Reviewing files that changed from the base of the PR and between 849e920 and a593825.

📒 Files selected for processing (2)
  • .agents/skills/agent-release-gate/resources/qa_matrix_lib.py
  • .agents/skills/agent-release-gate/resources/test_qa_matrix_lib_approvals.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • .agents/skills/agent-release-gate/resources/qa_matrix_lib.py

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of multiple approval requests in a single turn.
    • Ensured every approval is answered and repeated requests are refreshed correctly.
    • Fixed approval resumption so completed tool calls close before remaining approvals are reactivated.
    • Preserved accurate completion results in tracing during approval workflows.
  • Tests

    • Added coverage for multi-approval responses, repeated approval requests, and delayed completion handling.
  • Documentation

    • Clarified rename permissions in the self-naming scenario.

Walkthrough

The PR adds ordered multi-gate approval tracking, answers all gated tool calls, refreshes repeated gates, and delays approval re-parking until approved tools close. It also updates approval tests and self-naming scenario permissions.

Changes

Approval flow

Layer / File(s) Summary
Multi-gate approval model and validation
.agents/skills/agent-release-gate/resources/qa_matrix_lib.py, .agents/skills/agent-release-gate/resources/test_qa_matrix_lib_approvals.py
Turn stores ordered approvals and keeps approval as the latest-gate view. Replies cover every gated tool call. Tests cover compatibility, multiple gates, and gate refreshes.
Approval resume closure window
services/runner/src/engines/sandbox_agent/run-turn.ts, services/runner/tests/unit/session-keepalive-approval.test.ts
Non-Pi resumes wait for approved tool completion before re-parking carried sibling gates. Tests verify completion tracing and delayed closure behavior.

Self-naming scenario permissions

Layer / File(s) Summary
Rename permission configuration
benchmarks/agent-config-editing/scenarios/09-self-naming.json
The scenario grants allow permission to rename_session and rename_agent and documents the approval scope.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • Agenta-AI/agenta#5089 — Describes parallel approval-gate handling in the same approval flow.
  • Agenta-AI/agenta#5382 — Modifies multi-gate tracking and resume settlement behavior in the same runner path.
  • Agenta-AI/agenta#5550 — Modifies concurrent permission-gate handling and completion ordering in run-turn.ts.

Sequence Diagram(s)

sequenceDiagram
  participant ApprovalReply
  participant runTurn
  participant ApprovedTool
  participant SiblingGate
  ApprovalReply->>runTurn: resume approved tool call
  runTurn->>ApprovedTool: wait for closure
  ApprovedTool->>runTurn: deliver real completion
  runTurn->>SiblingGate: re-arm carried approval pause
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main runner approval-ordering fix.
Description check ✅ Passed The description clearly explains the approval race, implementation changes, tests, and known follow-up.
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.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/resume-approval-ordering

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.

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: f0eab286-c566-4bb9-a803-33ca448d502f

📥 Commits

Reviewing files that changed from the base of the PR and between f4f8ff9 and 849e920.

📒 Files selected for processing (5)
  • .agents/skills/agent-release-gate/resources/qa_matrix_lib.py
  • .agents/skills/agent-release-gate/resources/test_qa_matrix_lib_approvals.py
  • benchmarks/agent-config-editing/scenarios/09-self-naming.json
  • services/runner/src/engines/sandbox_agent/run-turn.ts
  • services/runner/tests/unit/session-keepalive-approval.test.ts

Comment thread .agents/skills/agent-release-gate/resources/qa_matrix_lib.py Outdated
@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Status Destroyed (PR closed)

Updated at 2026-08-10T16:51:32.796Z

@mmabrouk
mmabrouk merged commit a79f324 into release/v0.112.0 Aug 10, 2026
40 of 42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug report Something isn't working size:M This PR changes 30-99 lines, ignoring generated files. tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant