Repository navigation
fix(runtime): retain decisions delivered before confirmation waits - #4589
Conversation
Queue the response raced against prompt emission, and discard decisions queued before each new tool, nested action or interactive iteration prompt. Keep non-interactive and already-cancelled limit paths from consuming another session's answer. Signed-off-by: Arnaud Héritier <aheritier@users.noreply.github.com>
There was a problem hiding this comment.
🟢 Approval recommended
The buffered handshake and stale-decision draining are consistently wired and comprehensively regression-tested.
0 open findings
What changed in this PR
Fixes lost confirmation decisions by buffering one resume response and clearing stale decisions before new prompts.
Changes:
- Buffers immediate resume decisions.
- Arms tool, nested, and iteration-limit prompts against stale responses.
- Adds regression coverage for timing and overlap scenarios.
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
aheritier
left a comment
There was a problem hiding this comment.
Reviewed all nine changed files and the confirmation, nested-action, iteration-limit, and ACP call paths. The bounded buffer and prompt-time draining address the observed lost-response window without broadening approval policy. The regression tests cover immediate responses, stale decisions, nested confirmations, and iteration-limit paths that do not wait. I found no actionable correctness, security, performance, or simplification findings warranting inline comments.
One validation improvement: please provide race-detector results for head 1859c94, ideally covering the affected packages and repeated handshake regressions. Required CI passed, but test-race was skipped because it only runs on main; the local race/stress results reported in the PR description were not independently verified.
Addressing review 5515463573: new race-detector executions on October 14, including a separate stateless verifier executing its own commands, all against exact head Environment: Ubuntu 26.04 LTS, linux/amd64, Linux 6.12.103, Go 1.27.2, GCC 15.2.0, Task 3.53.1, 16 available CPUs. All commands explicitly set New resultsThe handshake regex selects 20 runtime + 1 dispatcher top-level tests, plus subtests: 4,200 selected top-level executions in the author run and 2,100 in the verifier run. Counts force new execution; no Independent verifier's raw test outputAffected packages, count 1: Selected regressions, count 100: Raw evidence and qualifications
|

Fixes #4557
Cause
Recovered both complete CI job logs, not just timeout cleanup:
TestACPRuntimeConfig_DeclaredBudgetsRemainOmittedAcrossTurnsstuck 9m42s.askUseris waiting for a resume decision while ACP has already handled the permission response and returned to its event loop. The runtime's nonblocking send on an unbuffered resume channel loses responses that arrive after prompt emission but before the receiver parks. The race-test steps ran 12m41s / 11m39s, not the 45-minute workflow budget.Change
No ACP source/assertion changes, timeout increases, retries, workflow or dependency changes. Requests remain unkeyed: simultaneous interactive sessions and arbitrarily late responses arriving after a new prompt is visible are a pre-existing protocol limitation, not a session-keyed approval redesign in this patch.
Validation
Local Go 1.27.2 / Ubuntu 26.04 / GCC 15.2; Task 3.53.1 and golangci-lint 2.14.0 match repository pins. CI Ubuntu 24.04.5 differs.
task --force build,task test,task --force lint: pass, zero lint issues.CGO_ENABLED=1 task test-race: full repository pass on final tree.CGO_ENABLED=1 go test -race -shuffle=on -count=20 ./pkg/runtime/... ./pkg/acp: pass (before final noninteractive-limit guard).GOMAXPROCS=2,-test.count=150 -test.timeout=90s: planner's baseline 2/8 processes hang with CI-identical stacks; fixed 0/8, all 1,200 iterations complete. This is stress evidence, not a CI failure-rate estimate.An unchanged filesystem-sensitive
TestFileCache_dedupSkipsRedundantWritefailed once in normal tests and once in the final full-race attempt; subsequent complete reruns passed. Separate unchanged-cache control reproduces 82/100 failures locally. No cache assertions were modified. Initial module-cache permission/tooling setup failures and test assertion lint corrections are retained in the evidence report.Independent review found the overlapping-background iteration-limit drain; corrected and regression-tested before fresh final review. PR opened as draft for CI; no skipped race CI is counted as passed.
Fresh final independent reviewer: approve, no unresolved findings; reviewed head
1859c940367648f6323e3f09a8d567488ae96276.