Skip to content

fix(crabbox): retry cold metadata probes so a slow run --help does not block validation#102159

Merged
steipete merged 1 commit into
mainfrom
claude/crabbox-probe-retry
Jul 8, 2026
Merged

fix(crabbox): retry cold metadata probes so a slow run --help does not block validation#102159
steipete merged 1 commit into
mainfrom
claude/crabbox-probe-retry

Conversation

@steipete

@steipete steipete commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Resolves an issue where scripts/crabbox-wrapper.mjs hard-exits and blocks all remote validation — pnpm check:changed, remote pnpm test lanes, scripts/pr gates — when the crabbox binary is cold (the first call right after a version bump, or one on a loaded machine), even though the binary is perfectly fine.

At startup the wrapper probes crabbox --version and crabbox run --help once each, with a snappy 5s timeout, to enumerate the advertised providers before delegating. Crabbox 0.36 renders run --help as ~52KB on stderr, and a cold binary can exceed 5s rendering it or doing first-run init (and can return nothing on that first call). When the probe is SIGKILLed or comes back empty, one of two guards fires and exits the wrapper with code 2:

  • [crabbox] selected binary failed basic --version/--help sanity checks, or
  • [crabbox] could not parse provider list from --help; refusing to run with --provider without validation

Once Crabbox is warm the same probe returns in ~70ms, so the failure is transient — but while it lasts, every remote gate is dead.

Why This Change Was Made

The probe was a single attempt with an aggressive timeout and no recovery. This adds one generous retry: probeCrabboxMetadata() runs the probe with the default 5s timeout and, only if the result is unusable (killed by timeout, or empty), runs it once more with a 20s timeout. The warm path is unchanged (one ~instant probe); only a slow/empty first probe pays for the retry, after which the existing sanity and provider-list guards judge the recovered result — so a genuinely broken or truly-hung binary still fails, just not a merely-cold one.

This is deliberately minimal and preserves the guards' safety intent (they still reject a binary that never responds or never advertises the selected provider). It does not touch provider selection, sandbox enforcement, or the delegated-sync flow.

User Impact

Maintainers and agents no longer see pnpm check:changed / remote test lanes spuriously die with "refusing to run" or "sanity checks failed" the first time they invoke Crabbox after an upgrade or on a busy machine. The wrapper waits out one cold probe and proceeds. No config or flags change; the warm-path latency is identical.

Evidence

  • Root cause pinned against the real binary: crabbox run --help (0.36.0) exits 0 in ~0.07s warm, writing 52KB to stderr and 0 to stdout; the wrapper's parser handles it fine (71 providers). The failures reproduced only when the first probe was killed/empty — i.e. cold — which the retry now covers.
  • Dogfood — the fixed wrapper end-to-end: ran the validation suite through node scripts/crabbox-wrapper.mjs run itself. It parsed all 71 providers (providers=agent-sandbox,anthropic-sandbox-runtime,…,xcp-ng), warmed a Blacksmith Testbox, delegated-synced, and ran on it — proving the wrapper is usable again (Actions run).
  • On that Testbox: run-oxlint on the script clean, tsgo:core:test clean, check:no-conflict-markers pass, and test/scripts/crabbox-wrapper.test.ts 188 passed.
  • Regression test added: a fake Crabbox whose run --help is slower than the default probe timeout and (like 0.36) writes help to stderr is now recovered by the retry — the wrapper parses providers and exits 0 instead of hard-failing. The existing "times out hung sanity probes" test still asserts a genuinely wedged binary is rejected (its probe stays clamped below both the initial and retry timeouts).

…t block validation

The wrapper probes `crabbox --version` and `crabbox run --help` once each with a
snappy 5s timeout to enumerate providers before delegating. A cold Crabbox — the
first call right after a version bump, or one on a loaded machine — can exceed
that timeout while rendering `run --help` (52KB, emitted on stderr in 0.36) or
doing first-run init, and can emit nothing on that first call. When that happens
both guards fire and hard-exit the wrapper ("selected binary failed basic
--version/--help sanity checks" or "could not parse provider list from --help;
refusing to run"), which blocks ALL remote validation (`pnpm check:changed`,
remote `pnpm test` lanes) even though the binary is fine.

Retry each metadata probe once with a generous 20s timeout when the first attempt
is killed or returns empty. The warm path is unchanged (one ~instant probe); only
a slow/empty first probe pays for the retry, after which the sanity/provider-list
guards judge the recovered result. Add a regression test: a fake Crabbox whose
`run --help` is slower than the default probe timeout (and, like 0.36, writes help
to stderr) is now recovered by the retry instead of hard-failing.
@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts size: S maintainer Maintainer-authored PR labels Jul 8, 2026
@clawsweeper

clawsweeper Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 8, 2026, 7:49 AM ET / 11:49 UTC.

Summary
The PR retries Crabbox wrapper metadata probes once with a longer timeout and adds a regression test for slow run --help provider parsing.

PR surface: Tests +44, Other +18. Total +62 across 2 files.

Reproducibility: yes. at source level: current main probes --version and run --help once with a 5s timeout, then fails on nonzero or empty/unparsed metadata. I did not live-reproduce an actual cold Crabbox 0.36 first-run stall in this checkout.

Review metrics: 1 noteworthy metric.

  • Metadata probe retry budget: 2 probes can grow from 5s each to 5s + 20s each on unusable output. This script gates remote validation, so maintainers should notice the failure-path latency tradeoff before merge.

Stored data model
Persistent data-model change detected: serialized state: test/scripts/crabbox-wrapper.test.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Risk before merge

  • [P1] A genuinely hung or empty-output Crabbox binary can now spend up to about 50 seconds across the two startup metadata probes before the wrapper rejects it, so maintainers should accept that automation latency tradeoff before merge.

Maintainer options:

  1. Accept the retry budget (recommended)
    Merge as-is if maintainers prefer avoiding transient cold-probe failures and accept that a fully unusable binary may take roughly 50 seconds to reject.
  2. Tune the retry before merge
    Reduce the retry timeout or scope the retry only to run --help if the slower failed-binary path is too costly for CI and proof automation.

Next step before merge

  • A maintainer should accept or tune the retry budget before merge; no automated repair is needed unless they choose the tune path.

Maintainer decision needed

  • Question: Should the Crabbox wrapper accept one 20s retry per startup metadata probe, even though a truly unusable binary can now take roughly 50s to reject?
  • Rationale: This is an operational tolerance tradeoff for maintainer validation infrastructure; CI cannot prove the acceptable latency budget on all runners.
  • Likely owner: steipete — This account has prior merged history in the Crabbox wrapper timeout surface and authored the current operational tradeoff.
  • Options:
    • Accept the retry budget (recommended): Merge as-is if avoiding transient cold-probe failures is worth the slower failed-binary path.
    • Tune the retry: Reduce the retry timeout or scope it to run --help if the extra failed-binary wait is too costly.

Security
Cleared: No security or supply-chain regression is apparent from the script-only retry and test fixture changes.

Review details

Best possible solution:

Land the bounded retry if maintainers accept the slower broken-binary failure path, while keeping provider validation and the focused regression coverage intact.

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

Yes at source level: current main probes --version and run --help once with a 5s timeout, then fails on nonzero or empty/unparsed metadata. I did not live-reproduce an actual cold Crabbox 0.36 first-run stall in this checkout.

Is this the best way to solve the issue?

Yes. Retrying only unusable metadata probes preserves the safety guards and is narrower than raising the default timeout for every probe; the main tradeoff is the longer failed-binary path.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 58891c85b68b.

Label changes

Label changes:

  • add P2: The PR targets a remote-validation wrapper failure with limited maintainer/agent workflow blast radius.
  • add merge-risk: 🚨 automation: The diff changes the Crabbox wrapper preflight used by Testbox and proof automation, and a too-generous retry can slow failed automation runs.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes a redacted live-output summary for a wrapper-through-Testbox run plus focused wrapper test results; the linked run supports the Testbox setup context.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes a redacted live-output summary for a wrapper-through-Testbox run plus focused wrapper test results; the linked run supports the Testbox setup context.

Label justifications:

  • P2: The PR targets a remote-validation wrapper failure with limited maintainer/agent workflow blast radius.
  • merge-risk: 🚨 automation: The diff changes the Crabbox wrapper preflight used by Testbox and proof automation, and a too-generous retry can slow failed automation runs.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes a redacted live-output summary for a wrapper-through-Testbox run plus focused wrapper test results; the linked run supports the Testbox setup context.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes a redacted live-output summary for a wrapper-through-Testbox run plus focused wrapper test results; the linked run supports the Testbox setup context.
Evidence reviewed

PR surface:

Tests +44, Other +18. Total +62 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 0 0 0 0
Tests 1 44 0 +44
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 1 22 4 +18
Total 2 66 4 +62

What I checked:

  • Repository policy: Root, scripts-scoped, and test-scoped AGENTS.md files were read and applied to the review depth, wrapper expectations, and validation assessment. (AGENTS.md:1, 58891c85b68b)
  • Current main behavior: Current main's checkedOutput uses one timeout-bound spawnSync call and has no retry path for empty or killed metadata probes. (scripts/crabbox-wrapper.mjs:363, 58891c85b68b)
  • Startup probe path: The wrapper currently calls checkedOutput once for --version and once for run --help before parsing providers and enforcing sanity/provider guards. (scripts/crabbox-wrapper.mjs:3158, 58891c85b68b)
  • PR implementation: The PR adds a probeCrabboxMetadata retry helper and routes the two startup metadata probes through it while preserving the existing guard checks. (scripts/crabbox-wrapper.mjs:383, d8724d727197)
  • Regression coverage: The PR adds a fake Crabbox whose slow run --help writes provider help to stderr, then asserts the wrapper parses providers and exits successfully after retry. (test/scripts/crabbox-wrapper.test.ts:3154, d8724d727197)
  • Provider parser contract: The existing parser accepts provider lists from combined help text, including provider-line and --provider flag formats, which matches the retried help text path. (scripts/crabbox-wrapper-providers.mjs:56, 58891c85b68b)

Likely related people:

  • ejames-dev: Merged PR metadata for the earlier Crabbox wrapper timeout change shows this account authored the commit that added the 5-second sanity-probe timeout this PR now refines. (role: introduced timeout behavior; confidence: high; commits: ac18b4be12c8; files: scripts/crabbox-wrapper.mjs)
  • steipete: Merged PR metadata shows this account added regression coverage and merged the earlier timeout change in the same wrapper/test surface; this PR author also has prior merged history in the area. (role: recent adjacent owner; confidence: high; commits: 2da4024b06a9; files: scripts/crabbox-wrapper.mjs, test/scripts/crabbox-wrapper.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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.

How this review workflow works
  • 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.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. 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. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 automation 🚨 May affect CI, automerge, proof capture, label sync, or maintainer automation. labels Jul 8, 2026
@steipete
steipete merged commit 83ebbcb into main Jul 8, 2026
145 of 155 checks passed
@steipete
steipete deleted the claude/crabbox-probe-retry branch July 8, 2026 11:53
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
…t block validation (openclaw#102159)

The wrapper probes `crabbox --version` and `crabbox run --help` once each with a
snappy 5s timeout to enumerate providers before delegating. A cold Crabbox — the
first call right after a version bump, or one on a loaded machine — can exceed
that timeout while rendering `run --help` (52KB, emitted on stderr in 0.36) or
doing first-run init, and can emit nothing on that first call. When that happens
both guards fire and hard-exit the wrapper ("selected binary failed basic
--version/--help sanity checks" or "could not parse provider list from --help;
refusing to run"), which blocks ALL remote validation (`pnpm check:changed`,
remote `pnpm test` lanes) even though the binary is fine.

Retry each metadata probe once with a generous 20s timeout when the first attempt
is killed or returns empty. The warm path is unchanged (one ~instant probe); only
a slow/empty first probe pays for the retry, after which the sanity/provider-list
guards judge the recovered result. Add a regression test: a fake Crabbox whose
`run --help` is slower than the default probe timeout (and, like 0.36, writes help
to stderr) is now recovered by the retry instead of hard-failing.
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 9, 2026
…t block validation (openclaw#102159)

The wrapper probes `crabbox --version` and `crabbox run --help` once each with a
snappy 5s timeout to enumerate providers before delegating. A cold Crabbox — the
first call right after a version bump, or one on a loaded machine — can exceed
that timeout while rendering `run --help` (52KB, emitted on stderr in 0.36) or
doing first-run init, and can emit nothing on that first call. When that happens
both guards fire and hard-exit the wrapper ("selected binary failed basic
--version/--help sanity checks" or "could not parse provider list from --help;
refusing to run"), which blocks ALL remote validation (`pnpm check:changed`,
remote `pnpm test` lanes) even though the binary is fine.

Retry each metadata probe once with a generous 20s timeout when the first attempt
is killed or returns empty. The warm path is unchanged (one ~instant probe); only
a slow/empty first probe pays for the retry, after which the sanity/provider-list
guards judge the recovered result. Add a regression test: a fake Crabbox whose
`run --help` is slower than the default probe timeout (and, like 0.36, writes help
to stderr) is now recovered by the retry instead of hard-failing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR merge-risk: 🚨 automation 🚨 May affect CI, automerge, proof capture, label sync, or maintainer automation. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. scripts Repository scripts 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.

1 participant