repair: drive target validation from per-repo toolchain config#240
repair: drive target validation from per-repo toolchain config#240momothemage wants to merge 10 commits into
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed June 2, 2026, 2:38 AM ET / 06:38 UTC. Summary Reproducibility: yes. from source inspection: current main hard-codes pnpm target preparation, and the PR diff still reaches Review metrics: 2 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Copy recommended automerge instructionNext step before merge
Security Review findings
Review detailsBest possible solution: Land the config-driven toolchain path with an explicit pinned Bun provisioning step in the repair execution environment and live ClawHub validation proof before automerge. Do we have a high-confidence way to reproduce the issue? Yes from source inspection: current main hard-codes pnpm target preparation, and the PR diff still reaches Is this the best way to solve the issue? No: the per-repo toolchain config is the right direction, but the implementation is incomplete until Bun is provisioned or an approved runner guarantee is documented and proven. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against a07fc1f94275. Label changesLabel justifications:
Evidence reviewedAcceptance criteria:
What I checked:
Likely related people:
What the crustacean ranks mean
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 re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper automerge |
|
🦞🔧 Source: I will update this PR branch, or open a safe credited replacement, if the repair worker finds a narrow fix. Automerge progress:
|
|
🦞✅ Source: Why human review is needed: What the maintainer can do as a next step: I added |
|
@clawsweeper approve Confirming the choice from the clawhub side:
|
|
🦞👀 Command router queued. I will update this comment with the next step. |
|
@clawseeper approve |
|
@clawsweeper automerge |
|
🦞👀 Command router queued. I will update this comment with the next step. Re-review progress:
|
|
ClawSweeper 🐠 reef update Thanks for the contribution here. ClawSweeper could not safely push to this branch, so it opened a replacement PR from a writable branch and carried the contributor trail along with it. Why replacement: ClawSweeper could not update the source PR branch directly; GitHub did not grant sufficient push rights to the bot for that branch.
fish notes: model gpt-5.5, reasoning high; reviewed against de017c3. |
Drive target validation from per-repo toolchain config
Summary
ClawSweeper's target-validation pipeline was built around a single assumption — the target repo is an OpenClaw pnpm monorepo that exposes a
check:changedscript. Any repo on a different toolchain (in our caseopenclaw/clawhub, which is bun-based) could not get past preflight: every automerge / autofix attempt ended as a no-op witheven when the PR itself was perfectly mergeable.
This PR makes the validation pipeline read three fields per target repo from
config/target-repositories.jsonand removes the hard-coded pnpm +check:changedpair from the runtime path.openclaw/openclawbehavior is preserved exactly.Closes the bug described in
issue.md(area: repair,area: target-validation,multi-repo).Why config alone wasn't enough before
config/target-repositories.jsonalready existed, butprepareTargetToolchain,requiredValidationCommands, andpreflightTargetValidationPlanall ignored it for these decisions. So even with a clawhub entry in place, three things still fired against bun targets:prepareTargetToolchainthrewunsupported target package managerwhenpackage.json#packageManagerdid not start withpnpm@.requiredValidationCommands(in combination with theprompts/repair/autonomous.mddefault) injectedpnpm check:changedfor every OpenClaw-org repo, not justopenclaw/openclaw.preflightTargetValidationPlanthen rejected that command viapackageScriptRequirementbecause clawhub has nocheck:changed, andexecute-fix-artifact.tstreatsvalidation_script_missingas terminal.What changed
New per-repo toolchain config
config/target-repositories.jsonnow declares, for every repo and every generic fallback:package_manager: "pnpm" | "bun" | "npm"validation_commands: string[]— base commands always added before fixArtifact-supplied oneschanged_gate: { command, required_script } | null— the local incremental gate, ornullto disable changed-gate normalizationConcrete entries:
openclaw/openclawpnpm[]pnpm check:changed/check:changedopenclaw/clawhubbun["bun run check"]nullopenclaw/clawsweeperpnpm[]nullopenclaw/fs-safepnpm[]nullpnpm[]nullpnpm[]nullopenclaw/openclaw's gate is pinned through a newcore_target_overridesblock so the runtime never falls back to "no gate" for it. There is also a code-level safety net that returns the same OpenClaw gate if the config file ever drops the entry.New module:
src/repair/target-toolchain-config.tsconfig/target-repositories.json.resolveTargetRepoToolchain(targetRepo)— looks up by repo, falls back to owner-levelgeneric_fallbacks, then to a built-in default.__resetTargetRepoToolchainCache()for tests.Refactor:
src/repair/target-validation.tsTargetValidationOptionsaccepts an optionaltoolchainoverride; tests inject it directly to avoid touching the config file.prepareTargetToolchainis split into three branches:preparePnpmToolchain— unchanged behavior (corepack +pnpm install --frozen-lockfilewith the existingERR_PNPM_OUTDATED_LOCKFILEfallback).prepareBunToolchain—bun --versionsanity check, thenbun install --frozen-lockfile. On lockfile drift, fall back tobun install --no-frozen-lockfileandgit checkout -- bun.lock bun.lockb. Surfaces a clear error when bun is not on PATH.prepareNpmToolchain—npm ciifpackage-lock.jsonexists, elsenpm install.requiredValidationCommandsnow unionscommands ∪ additionalValidationCommands ∪ toolchain.baseValidationCommandsand only appendstoolchain.changedGate.commandwhen the gate'srequiredScriptis actually present in the target'spackage.json#scripts.requiresOpenClawChangedGateis replaced by a genericrequiresChangedGate(cwd, toolchain)plus anisChangedGateCommand(parts, options)helper.validationFallbackCommandsandshouldRetryValidationCommanduse the new helper, so:changed_gate: nulland skip those branches cleanly.pnpm check:changed-specific recovery and retry, exactly as before.resolveAllowedValidationCommandsrewrites stale fixArtifact commands to the configured gate instead of the literalpnpm check:changed. The pnpm-specific normalization (vitest run,test,test:serialpath rewriting, expensive-script downgrade) is now gated ontoolchain.packageManager === "pnpm", so bun targets pass their own commands through unchanged.restoreTargetLockfile(cwd, lockfile)is parameterized — pnpm usespnpm-lock.yaml, bun restores bothbun.lockandbun.lockb.src/repair/validation-command-utils.tspackageScriptRequirementrecognizesbun run <script>and maps it to{ name: "<script>", command: "bun run <script>" }.bunis added to the allowed-executable list soparseAllowedValidationCommand("bun run check")no longer throwsunsupported validation command.Prompts & docs
prompts/repair/autonomous.md(L69) — the LLM is now told the local gate is whichever command the target repo declares inconfig/target-repositories.json#changed_gate, with explicit guidance not to emitpnpm check:changedagainst non-openclaw/openclawrepos.docs/repair/automerge-flow.md(L108) — the same description for human readers.This is the prompt-side fix for the second root cause in the issue (the OpenClaw default leaking into other repos).
How
openclaw/openclawstays compatiblecore_target_overrides["openclaw/openclaw"]pinspackage_manager: pnpmandchanged_gate: pnpm check:changed / check:changed.resolveTargetRepoToolchain("openclaw/openclaw")returns the samepnpm + pnpm check:changedtoolchain.requiredValidationCommands,preflightTargetValidationPlan,resolveAllowedValidationCommands,validationFallbackCommands, andshouldRetryValidationCommandis semantically identical for OpenClaw inputs (verified by the existing tests, see below).Tests
test/repair/target-validation.test.tsis extended with:bunPackageFixture(scripts)— writespackage.jsonwithpackageManager: "bun@1.1.0"and abun.lock.clawhubToolchain()— injects{ packageManager: "bun", baseValidationCommands: ["bun run check"], changedGate: null }.validationOptions(targetRepo, extra)now spreads extras so tests can pass the toolchain override without disk I/O.Three new bun-shaped cases:
requiredValidationCommands([], cwd, opts)returns["bun run check"].preflightTargetValidationPlan({ validation_commands: ["bun run check"] })returns{ status: "passed", resolved_commands: ["bun run check"], available_scripts: ["check"] }.pnpm check:changed, preflight no longer silently rewrites it to the OpenClaw gate; it returnsstatus: "blocked", code: "validation_script_missing", missing_script: "check:changed"so upstream sanitization can drop the command instead of letting the worker no-op.All previously passing OpenClaw tests are untouched by intent and unchanged in fixture content.
Repro / verification
Before:
openclaw/clawhuband opt it into ClawSweeper automerge.validation_script_missing: required pnpm check:changed is unavailable in target checkout. No push, rebase, replacement PR, merge, or re-review.After:
prepareBunToolchain(bun install --frozen-lockfile).passedforbun run check, sinceclawhub/package.json#scripts.checkexists.runAllowedValidationCommandsrunsbun run check. Push / rebase / merge / re-review proceed normally.Local validation:
nvm use 22 corepack enable pnpm install pnpm build node --testThe new bun cases plus the existing pnpm cases are all expected to pass.
Risk & rollback
openclaw/openclawpaths are preserved through both config and code-level fallbacks; tests cover both.Files changed
src/repair/target-toolchain-config.tssrc/repair/target-validation.tssrc/repair/validation-command-utils.tsconfig/target-repositories.jsontest/repair/target-validation.test.tsprompts/repair/autonomous.mddocs/repair/automerge-flow.mdSuggested labels
area: repair,area: target-validation,bug,multi-repoReal behaviour proof