Skip to content

fix: correlation runId ambiguity + approval-recording handling (review findings)#10

Merged
olivrg merged 2 commits into
mainfrom
fix/correlation-runid-and-approval-failclose
Jun 17, 2026
Merged

fix: correlation runId ambiguity + approval-recording handling (review findings)#10
olivrg merged 2 commits into
mainfrom
fix/correlation-runid-and-approval-failclose

Conversation

@olivrg

@olivrg olivrg commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Addresses review findings against the before_tool_call path (PR #9).

Fixes

  • Correlation — fail closed on runId-lane ambiguity (blocker). runId is per-turn (shared by every tool call in one agent turn), so two calls in a turn without a toolCallId collided on run:<runId> and the 2nd silently overwrote the binding → mis-correlated /audit. The registry now distinguishes lanes (toolCall/run/none): only toolCallId is per-call-unique (full concurrency); the runId lane is now fail-closed on ambiguity like the no-ID lane. Tests added (same-runId collision, distinct runIds, sequential reuse).
  • Approval-recording failure surfaced + documented (blocker → upstream). onResolution now throws on a { ok:false } from resolveApproval instead of swallowing it. Verified against the installed OpenClaw runtime that onResolution is invoked fire-and-forget (notifyPluginApprovalResolution: Promise.resolve(onResolution(...)).catch(log.warn)), so the throw is logged but does not gate execution. This enforcement gap is not adapter-fixable — documented as a known cooperative-grade limitation / upstream blocker in README.md + AGENTS.md. It does not affect the /evaluate fail-closed guarantee (the host enforces block).
  • Minor: raw NUL key separator → JSON.stringify([session, toolName]) (ASCII, unambiguous); ambiguity block reason reworded to "Helio cannot correlate ambiguous concurrent tool calls" (now covers runId + no-ID).

Verification

pnpm verify green — 98 tests, typecheck, lint, format, build.

Not in scope

The approval-recording enforcement gap is tracked as an upstream OpenClaw item (needs an awaited/deny-capable approval callback); nothing further is fixable adapter-side.

olivrg added 2 commits June 17, 2026 19:14
…rator

Review finding (blocker): runId is per-turn (shared across a turn's tool calls), so two calls in one turn without a toolCallId collided on run:<runId> and the 2nd silently overwrote the binding. The registry now distinguishes lanes (toolCall/run/none) — only toolCallId is per-call-unique (full concurrency); the runId lane is fail-closed on ambiguity like the no-ID lane. Also (minor) replace the raw NUL key separator with JSON.stringify([session,toolName]).
…enforcement gap

Review findings: (1) onResolution ignored a { ok:false } from resolveApproval — it now throws so the failure is surfaced. The installed OpenClaw runtime calls onResolution fire-and-forget (notifyPluginApprovalResolution), so the throw is logged but does NOT gate execution; this enforcement gap is not adapter-fixable and is documented as a known cooperative-grade limitation / upstream blocker in AGENTS.md + README. (2) Reworded the ambiguity block reason to 'Helio cannot correlate ambiguous concurrent tool calls' (covers runId + no-ID collisions).
@olivrg olivrg merged commit 6bae110 into main Jun 17, 2026
1 check passed
@olivrg olivrg deleted the fix/correlation-runid-and-approval-failclose branch June 17, 2026 18:20
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.

1 participant