Skip to content

fix(node-host): share concurrent skill-bin refreshes - #127113

Merged
steipete merged 2 commits into
mainfrom
codex/fix-node-host-skill-bins-singleflight
Sep 6, 2026
Merged

steipete merged 2 commits into
mainfrom
codex/fix-node-host-skill-bins-singleflight

Conversation

@steipete

@steipete steipete commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Closes #127095

What Problem This Solves

Fixes an issue where node-host users with skill-based command auto-allow enabled would trigger a separate Gateway skill scan for each overlapping command when the shared cache was cold or expired.

Why This Change Was Made

The connection's cache now shares one in-flight refresh. Cleanup checks the promise identity so an older waiter cannot clear a newer retry. The existing 90-second TTL, empty initial-failure result, same-Gateway stale-on-failure behavior, and whole-cache replacement on connection retirement remain intact.

The tests use two overlapping calls and actual resolved binary entries. They cover cold and expired refreshes, warm reuse, shared failure and retry, and an old connection's pending result completing after its replacement starts. Deferred calls are released and the runtime is closed even when a regression assertion fails.

User Impact

Overlapping node commands share the Gateway's workspace discovery work while retaining the same skill-bin values and authorization behavior. A retired connection cannot supply skill trust to its replacement.

Evidence

Trusted main baseline: 554233e269f1a8cb47157c3e17604bc2209a37d9.

  • The existing node-host runtime suite passed all 24 tests.
  • The new bounded regressions produced four expected failures on main: cold and expired callers started duplicate refreshes, on both success and failure paths. The pending-old-connection control passed. All deferred cleanup completed normally.
  • The baseline ran with an isolated empty home/state environment. Candidate execution used secretless same-repository CI.
  • Exact-head CI run 34021605844 passed at 28cff0ec8d3f28ab28ca1ab1811325aa4e141463: all 29 runtime tests, including 5 new cases, and all 9 worker-runtime tests. The latter include real benign command authorization across same-Gateway reconnect, replacement within/after TTL, and replacement-refresh failure.
  • Fresh independent Codex review and the latest exact-head ClawSweeper review found no actionable findings.

Production: +11/-1 lines; tests: +163/-3. Production growth is the single in-flight promise slot, identity-checked cleanup, and its invariant comment.

@clawsweeper

clawsweeper Bot commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

@steipete
steipete marked this pull request as ready for review August 21, 2026 08:31
@openclaw-barnacle openclaw-barnacle Bot added size: S maintainer Maintainer-authored PR labels Aug 21, 2026
@clawsweeper clawsweeper Bot added P2 Normal backlog priority with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Aug 21, 2026
@clawsweeper

clawsweeper Bot commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed September 6, 2026, 4:26 AM ET / 08:26 UTC.

ClawSweeper review

What this changes

The node host shares overlapping skill-binary refresh requests and adds regression coverage for cache expiry, failures, retries, and connection replacement.

Merge readiness

✅ Ready for maintainer review

The fix remains necessary: current main and v2026.9.2 still duplicate overlapping refreshes. The updated patch preserves connection retirement and has no actionable correctness findings.

Priority: P2
Reviewed head: 28cff0ec8d3f28ab28ca1ab1811325aa4e141463

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) A focused owner-level repair with meaningful concurrency regressions and no identified correctness or security defect.
Proof confidence 🌊 off-meta tidepool Not applicable: The supplied repository state identifies a maintainer-authored PR, so the external-contributor proof gate does not apply. Cache regressions and baseline results are supplemental evidence, not an observed after-fix live run; the diff does not materially change authority.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Not applicable Not applicable: The supplied repository state identifies a maintainer-authored PR, so the external-contributor proof gate does not apply. Cache regressions and baseline results are supplemental evidence, not an observed after-fix live run; the diff does not materially change authority.
Evidence reviewed 10 items Current main still needs the fix: Current main directly awaits a separate refresh whenever the timestamp is stale; overlapping callers therefore issue independent requests before either response updates the timestamp.
Latest release also lacks coalescing: The supplied latest release, v2026.9.2, contains the same direct-refresh implementation without an in-flight promise.
Verified introduced production change: The pinned base-to-head production diff adds only promise sharing and identity-checked cleanup. Refresh results, failure handling, TTL, and connection retirement are unchanged.
Findings None None.
Security None None.

How this fits together

The node host asks the Gateway which skill executables may qualify for automatic command approval, then resolves those executables locally. Its connection-owned cache feeds command-policy evaluation.

flowchart TD
  A[Concurrent node commands] --> B[Skill auto-allow policy]
  B --> C{Cache fresh?}
  C -->|Yes| F[Resolved executable entries]
  C -->|No| D[Shared refresh request]
  D --> E[Gateway skill discovery]
  E --> F
  F --> G[Command authorization]
  H[Connection retirement] -->|Replace cache| C
Loading

Before merge

None.

Agent review details

Security

None.

PR surface

Source +10, Tests +160. Total +170 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 11 1 +10
Tests 1 163 3 +160
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 174 4 +170

Review metrics

None.

Root-cause cluster

Relationship: fixed_by_candidate
Canonical: #127095
Summary: This PR is the candidate implementation for the explicitly linked concurrent-refresh bug.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Technical review

Best possible solution:

Keep refresh coalescing inside the connection-owned cache while preserving existing trust retirement, expiry, and failure behavior.

Do we have a high-confidence way to reproduce the issue?

Yes, from source: two commands entering a cold or expired cache before the first response each start a refresh on current main. The supplied baseline results corroborate this; this review did not execute tests.

Is this the best way to solve the issue?

Yes. Sharing the pending promise at the existing cache owner removes duplicate work without adding configuration, changing the protocol, or altering connection retirement.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 66c9bf264b86.

Labels

Label justifications:

  • P2: This addresses deterministic redundant Gateway discovery work in the optional skill auto-allow path without changing authorization results.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🌊 off-meta tidepool and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The supplied repository state identifies a maintainer-authored PR, so the external-contributor proof gate does not apply. Cache regressions and baseline results are supplemental evidence, not an observed after-fix live run; the diff does not materially change authority.

Evidence

What I checked:

  • Current main still needs the fix: Current main directly awaits a separate refresh whenever the timestamp is stale; overlapping callers therefore issue independent requests before either response updates the timestamp. (src/node-host/runtime.ts:201, 66c9bf264b86)
  • Latest release also lacks coalescing: The supplied latest release, v2026.9.2, contains the same direct-refresh implementation without an in-flight promise. (src/node-host/runtime.ts:201, 3928bad9badf)
  • Verified introduced production change: The pinned base-to-head production diff adds only promise sharing and identity-checked cleanup. Refresh results, failure handling, TTL, and connection retirement are unchanged. (src/node-host/runtime.ts:204, 28cff0ec8d3f)
  • Connection and authorization boundaries remain intact: Connection retirement replaces the cache and aborts active invocations. Command dispatch checks cancellation after awaited policy evaluation, before execution. Promise sharing does not introduce a new principal, trust lifetime, or authorization bypass. (src/node-host/runtime.ts:682, 28cff0ec8d3f)
  • Final execution cancellation check: The system.run owner returns when cancellation occurs while skill-bin policy evaluation is awaited. (src/node-host/invoke-system-run.ts:1106, 28cff0ec8d3f)
  • Documented trust contract: The documented opt-in skill allowlist belongs to its supplying Gateway; same-Gateway refresh failures may retain prior trust, while switching Gateways retires it. The patch preserves this contract. Public docs: docs/tools/exec-approvals.md. (docs/tools/exec-approvals.md:581, 28cff0ec8d3f)

Likely related people:

  • steipete: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (8 earlier review cycles)
  • reviewed 2026-08-21T08:38:21.202Z sha 5053cb1 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-22T11:30:45.354Z sha 5053cb1 :: needs maintainer review before merge. :: none
  • reviewed August 22, 2026, 7:49 AM ET / 11:49 UTC sha unknown :: needs maintainer review before merge. :: none
  • reviewed 2026-08-23T14:27:09.830Z sha 5053cb1 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-24T17:49:03.213Z sha 5053cb1 :: needs maintainer review before merge. :: none
  • reviewed 2026-08-24T18:31:36.530Z sha 5053cb1 :: needs maintainer review before merge. :: none
  • reviewed August 27, 2026, 7:47 AM ET / 11:47 UTC sha unknown :: needs maintainer review before merge. :: none
  • reviewed 2026-09-04T05:16:08.002Z sha 5053cb1 :: blocked before merge. :: none

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Aug 27, 2026
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Sep 4, 2026
@steipete steipete self-assigned this Sep 6, 2026
Keep connection-owned cache retirement while coalescing overlapping refreshes.
Replace the empty-result burst with bounded cold, expired, failure, retry,
and retired-connection cases using resolved binary entries and complete cleanup.
@steipete

steipete commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Updated head: 28cff0e. The original fix's ancestry is preserved while integrating main's connection-owned cache retirement.

The replacement tests use two overlapping requests and resolved binary entries. On trusted main 554233e, four cases failed for duplicate refresh requests and the old-connection isolation control passed; cleanup completed normally. Fresh independent source review found no actionable P0–P2 findings. Candidate CI is pending; the PR body records the exact scope and proof limits.

@clawsweeper

clawsweeper Bot commented Sep 6, 2026 •

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event exact_review_queue).
Result: when the review finishes, ClawSweeper will create the durable review comment if needed or update the existing comment in place.

Re-review progress:

@steipete
steipete merged commit accd250 into main Sep 6, 2026
111 checks passed
@steipete
steipete deleted the codex/fix-node-host-skill-bins-singleflight branch September 6, 2026 09:59
@steipete

steipete commented Sep 6, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Sep 7, 2026
Closes openclaw#127095

## What Problem This Solves

Fixes an issue where node-host users with skill-based command auto-allow enabled would trigger a separate Gateway skill scan for each overlapping command when the shared cache was cold or expired.

## Why This Change Was Made

The connection's cache now shares one in-flight refresh. Cleanup checks the promise identity so an older waiter cannot clear a newer retry. The existing 90-second TTL, empty initial-failure result, same-Gateway stale-on-failure behavior, and whole-cache replacement on connection retirement remain intact.

The tests use two overlapping calls and actual resolved binary entries. They cover cold and expired refreshes, warm reuse, shared failure and retry, and an old connection's pending result completing after its replacement starts. Deferred calls are released and the runtime is closed even when a regression assertion fails.

## User Impact

Overlapping node commands share the Gateway's workspace discovery work while retaining the same skill-bin values and authorization behavior. A retired connection cannot supply skill trust to its replacement.

## Evidence

Trusted main baseline: `26e86d29fa3a7e0e49ffb8999fa2afda5df4c9c5`.

- The existing node-host runtime suite passed all 24 tests.
- The new bounded regressions produced four expected failures on main: cold and expired callers started duplicate refreshes, on both success and failure paths. The pending-old-connection control passed. All deferred cleanup completed normally.
- The baseline ran with an isolated empty home/state environment. Candidate execution used secretless same-repository CI.
- [Exact-head CI run 34021605844](https://github.com/openclaw/openclaw/actions/runs/34021605844) passed at `28cff0ec8d3f28ab28ca1ab1811325aa4e141463`: all 29 runtime tests, including 5 new cases, and all 9 worker-runtime tests. The latter include real benign command authorization across same-Gateway reconnect, replacement within/after TTL, and replacement-refresh failure.
- Fresh independent Codex review and the latest exact-head ClawSweeper review found no actionable findings.

Production: +11/-1 lines; tests: +163/-3. Production growth is the single in-flight promise slot, identity-checked cleanup, and its invariant comment.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR P2 Normal backlog priority with limited blast radius. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Node host duplicates concurrent skill-bin refreshes

2 participants