feat(miner): add a dry-run full-execution mode to the cross-repo evaluation harness - #7668
Conversation
|
🚨 Contributor flagged. Click here for more info: Superagent Dashboard |
…uation harness The cross-repo harness (JSONbored#4788) is readiness-only: it proves the miner can FORM a plan for a benchmark repo, not that the plan produces working code. Add a --full-execution mode to the existing CLI that runs the real discover -> plan -> code -> test loop, still dry-run: each repo that passes readiness is copied into a discardable scratch workspace, the coding agent (resolved from MINER_CODING_AGENT_PROVIDER, failing closed to a categorized agent_run_failed when unconfigured) works the harness's synthetic issue inside that copy, and the repo's own inferred build and test commands validate the generated diff there. No PR submission, no forge APIs, no writes to the benchmark clone; the scratch tree is removed in every outcome. Build/test commands are tokenized and exec'd directly (never via a shell), so nothing in a benchmark repo's manifest can smuggle shell metacharacters into an interpreted command line. Execution failures extend the existing taxonomy -- agent_run_failed, noop_diff (agent succeeded but changed nothing), build_failed (diff didn't compile), test_failed (repo's own suite failed) -- and flow through the existing summary/report format unchanged, since both are data-driven over category strings. A repo whose stack infers no test command fails with the existing execution_gap: an unvalidatable diff is not a pass. The scratch copy inherits the ACCEPTANCE_CRITERIA.md the readiness pass wrote into the clone, and writeAcceptanceCriteriaFile opens O_EXCL, so the inherited file is cleared from the copy before the spec is re-composed there. Closes JSONbored#7634
7aef5f8 to
5ff2585
Compare
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7668 +/- ##
========================================
Coverage 88.51% 88.52%
========================================
Files 724 724
Lines 76020 76120 +100
Branches 22629 22654 +25
========================================
+ Hits 67291 67384 +93
- Misses 7681 7688 +7
Partials 1048 1048
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-21 07:38:58 UTC
Review summary Nits — 5 non-blocking
Flagged checks (non-blocking)
Decision drivers
Context & advisory signals — never blocks the verdict
Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
|
Moving forward, we should be able to eliminate .js and .d.ts files, as that was a main reason for refactoring to .ts. |
…ge (#7690) * ci(build): catch stale committed miner/mcp compiled output before merge packages/loopover-miner and packages/loopover-mcp compile real TypeScript in place and commit the emitted .js/.d.ts (both ship as installable CLIs, so a runnable .js has to exist without a build step). Nothing enforced that the committed output actually matched a fresh build: root-level tests import the emitted .js by its literal specifier, and the job that builds these packages runs as a separate GitHub Actions job from the one that tests them, so a contributor who edited .ts without rebuilding got tests silently running old behavior with zero CI signal -- the same drift class the Selfhost/Miner env-reference checks were previously added to close. Adds scripts/check-build-drift.mjs (git-status-based, so a compiled file that was never committed at all is caught too, not just a stale one), wires it into ci.yml right after each package's real build step, and into package.json's local test:ci for pre-push parity. Also fixes three comments left stale by the #7290/#7291 TypeScript migrations completing, and adds loopover-mcp's missing migration-complete guard test (mirroring loopover-miner's existing one). * fix(miner): canonicalize the cross-repo-evaluation scratch workspace path defaultPrepareExecutionWorkspace built its scratch directory straight from mkdtempSync, but coding-task-spec.ts's writeAcceptanceCriteriaFile separately realpath's the working directory before writing into it (a deliberate containment-check canonicalization, not something to remove). On macOS, os.tmpdir() resolves under a symlink (/var/folders/... -> /private/var/folders/...), so the two disagreed on which string names the same directory: a plain acceptanceCriteriaPath.startsWith(workingDirectory) check failed even though the file genuinely was inside the working directory. Resolving once at the source, right after mkdtempSync, keeps every downstream path in the same canonical form with no other changes needed, and is a no-op on Linux CI runners where /tmp isn't itself a symlink. Discovered while validating the build-drift check against #7668's own newly-merged full-execution mode.
What
The cross-repo evaluation harness (#4788) is readiness-only: it proves the miner can form a plan for a benchmark repo (
detectRepoStack→resolveMinerGoalSpec→buildCodingTaskSpec), not that the plan produces working code. This adds the--full-executionmode to the existing CLI (scripts/cross-repo-evaluation.mjs) and its underlying lib module — running the real discover → plan → code → test loop, dry-run only.How it works (and stays dry-run)
For each repo that passes the readiness gate:
defaultPrepareExecutionWorkspace); the clone itself is never mutated. The copy is removed in every outcome (finally), including when cleanup itself throws.buildCodingTaskSpecwrites its acceptance-criteria document into its working directory, so the spec is re-built against the scratch tree (the copy's inheritedACCEPTANCE_CRITERIA.mdfrom the readiness pass is cleared first —writeAcceptanceCriteriaFileopensO_EXCL).MINER_CODING_AGENT_PROVIDERviaconstructProductionCodingAgentDriver(lazily imported, so readiness-only consumers never pay for it), failing closed to a categorizedagent_run_failedwhen unconfigured. No live PR submission, no forge APIs.buildCommand(when present) andtestCommandrun inside the scratch copy via a shell-string runner mirroringcreateRealCliSubprocessSpawn(resolve-never-reject, hard timeout, both streams captured).Report taxonomy: extended, not replaced
New execution categories flow through the existing
summarizeCrossRepoEvaluation/formatCrossRepoEvaluationReportunchanged (both are data-driven over category strings):agent_run_failednoop_diffbuild_failedtest_failedA repo whose stack infers no test command fails with the existing
execution_gap— an unvalidatable diff is not a pass.Tests
15 new cases in
test/unit/miner-cross-repo-evaluation.test.ts(59/59 pass), exercising every new branch on both sides with the package's existing fixture + injection conventions: readiness pass-through, workspace-prep failures (Error and non-Error), spec failures inside the workspace (throw / null / unready verdict), the default driver construction path (provider pinned empty viavi.stubEnv, both the injected-env andprocess.envsides), driver throw/malformed-result fallbacks, empty and missingchangedFiles, build fail/timeout/skip, test fail/timeout, missing test command, option plumbing (maxTurns,commandTimeoutMs), the realdefaultPrepareExecutionWorkspace(copy + discard) and the real command runner (exit codes, output capture, timeout kill, spawn error), manifest/filter handling, the CLI flag, and the new categories rendering through the existing report format. The dry-run posture is asserted directly: the agent's task is rooted in a real scratch copy, the acceptance file is written inside it, and the tree is gone afterward while the clone survives.Validation
npx vitest run test/unit/miner-cross-repo-evaluation.test.ts— 59/59.npm run typecheck— exit 0 (fresh@loopover/enginebuild).npm run test:miner-pack,docs:drift-check,engine-parity:drift-check,command-reference:check— all pass;git diff --checkclean.--helpdocuments the flag;--full-executionagainst a fixture manifest reports a clean categorizedagent_run_failed(unconfigured provider) through the existing report format, exit 0.packages/loopover-miner/docs/cross-repo-evaluation.mddocuments the mode, its prerequisites, and the extended taxonomy.Closes #7634