From 4565de30f27d675a63b6aacac5cca1614a4e2f26 Mon Sep 17 00:00:00 2001 From: bitfathers94 <237535319+bitfathers94@users.noreply.github.com> Date: Tue, 21 Jul 2026 05:43:10 +0000 Subject: [PATCH 1/2] feat(miner): add a --full-execution dry-run mode to the cross-repo harness Extend the cross-repo evaluation harness (#4788) from readiness-only to a full-execution mode that drives the live discover -> plan -> code -> test loop against a curated subset of the benchmark repos, generating a real diff and running each target repo's own build + test commands locally. Dry-run only, same read/execute-locally-and-discard posture as the readiness harness: the coding agent edits a throwaway clone, the diff is captured with git, and no PR is opened against any third-party repo. - executeRepoAttempt / runCrossRepoExecution classify the outcome; the agent, build, and test runners are injectable (real spawnSync defaults). - Extend CROSS_REPO_FAILURE_CATEGORY with execution_no_diff, execution_compile_gap, execution_test_failure, and execution_noop_diff; results reuse the existing report + summary format. - --full-execution CLI flag wires a real driver-backed executor; a fullExecution manifest flag marks the subset (--repo overrides it). - Document the new mode and taxonomy in docs/cross-repo-evaluation.md. Closes #7634 --- .../benchmarks/cross-repo/manifest.json | 6 +- .../docs/cross-repo-evaluation.md | 47 ++- .../lib/cross-repo-evaluation.d.ts | 87 ++++- .../lib/cross-repo-evaluation.js | 180 +++++++++- .../lib/cross-repo-evaluation.ts | 316 +++++++++++++++++- .../scripts/cross-repo-evaluation.d.mts | 28 +- .../scripts/cross-repo-evaluation.mjs | 77 ++++- test/unit/miner-cross-repo-evaluation.test.ts | 266 +++++++++++++++ 8 files changed, 966 insertions(+), 41 deletions(-) diff --git a/packages/loopover-miner/benchmarks/cross-repo/manifest.json b/packages/loopover-miner/benchmarks/cross-repo/manifest.json index a6d1bc1b35..164b18e16d 100644 --- a/packages/loopover-miner/benchmarks/cross-repo/manifest.json +++ b/packages/loopover-miner/benchmarks/cross-repo/manifest.json @@ -8,7 +8,8 @@ { "repoFullName": "expressjs/express", "stackHint": "nodejs", - "requireTestCommand": true + "requireTestCommand": true, + "fullExecution": true }, { "repoFullName": "pallets/flask", @@ -28,7 +29,8 @@ { "repoFullName": "lodash/lodash", "stackHint": "nodejs", - "requireTestCommand": true + "requireTestCommand": true, + "fullExecution": true } ] } diff --git a/packages/loopover-miner/docs/cross-repo-evaluation.md b/packages/loopover-miner/docs/cross-repo-evaluation.md index cc36444b74..efe29589f3 100644 --- a/packages/loopover-miner/docs/cross-repo-evaluation.md +++ b/packages/loopover-miner/docs/cross-repo-evaluation.md @@ -33,6 +33,8 @@ bare `"owner/repo"` string or an object: - **`stackHint`** — documentation only (not used by the evaluator) - **`requireTestCommand`** — when `true`, stack detection must infer a test command or the repo fails with `execution_gap` +- **`fullExecution`** — when `true`, this entry is part of the full-execution subset (#7634): a bare + `--full-execution` run drives the live attempt against every entry flagged `true` (see below) Malformed manifest fields degrade to documented defaults with warnings (same tolerant-parser convention as the fleet run-manifest). @@ -60,6 +62,43 @@ fleet run-manifest). - `--repo owner/repo` — evaluate a single manifest entry - `--manifest path/to/manifest.json` — alternate benchmark set (e.g. a fixture manifest in tests) - `--require-majority` — exit `1` unless a strict majority of repos pass (for CI-style gating) + - `--full-execution` — run the live attempt loop instead of the readiness check (see below) + +## Full-execution mode (#7634) + +Readiness answers *"can the miner form a plan for this repo."* **Full-execution mode** answers the real question +behind [#4810](https://github.com/JSONbored/loopover/issues/4810)'s launch-readiness bar — *"does the miner +actually produce working, correct code for this repo"* — by driving the live **discover → plan → code → test** +loop against a subset of the same benchmark repos: + +```bash +# Runs every manifest entry flagged "fullExecution": true; --repo overrides and runs one entry. +MINER_CODING_AGENT_PROVIDER=... node packages/loopover-miner/scripts/cross-repo-evaluation.mjs --full-execution +``` + +It is **dry-run only**, the same read/execute-locally-and-discard posture as the readiness harness, one step +further: the coding agent edits a **throwaway local clone**, the harness captures the resulting diff with `git` +and runs the target repo's **own** build + test commands (from stack detection) locally. There is **no live +GitHub PR submission, no write access to the third-party repos, and no credentials beyond the local clone** — a +PR that adds real PR-submission against a benchmark repo does not satisfy this mode. + +Each subset repo still receives one **pass/fail** line in the same report format. A repo **passes** only when the +agent produced a real (non-empty) diff, it built, and the target test suite passed. The failure taxonomy extends +the readiness categories with execution-specific ones: + +| Category | Meaning | +| --- | --- | +| `execution_no_diff` | The agent ran (or could not be launched) but produced no usable diff | +| `execution_compile_gap` | The generated diff did not build | +| `execution_test_failure` | The diff built but the target repo's own test suite failed | +| `execution_noop_diff` | Tests passed only because the diff was a no-op (no file changes) | + +Readiness-stage failures (`stack_detection_gap`, `clone_setup`, `loopover_assumption`, `execution_gap`) still +apply and short-circuit before the agent runs — a repo the miner cannot even plan for never reaches execution. + +Library entry points: `executeRepoAttempt(entry, options)` and `runCrossRepoExecution(parsed, options)` classify +the outcome; the coding-agent step, build, and test runners are all injectable (the CLI wires the real +driver-backed executor; unit tests inject fakes). ## Library API @@ -73,6 +112,8 @@ Pure functions live in [`lib/cross-repo-evaluation.js`](../lib/cross-repo-evalua ## Wiring -This harness is **readiness-only**: it does not run the coding agent, open PRs, or call forge APIs. A green report -means the miner’s repo-agnostic stack-detection and coding-task-spec path is prepared for the benchmark repo; a live -attempt still needs credentials, governor policy, and queue state as documented in [`DEPLOYMENT.md`](../DEPLOYMENT.md). +The default mode is **readiness-only**: it does not run the coding agent, open PRs, or call forge APIs. A green +report means the miner’s repo-agnostic stack-detection and coding-task-spec path is prepared for the benchmark +repo. `--full-execution` (#7634) goes one step further and runs the agent locally against a throwaway clone, but +still opens no PRs and performs no forge writes. A production attempt against a real target still needs +credentials, governor policy, and queue state as documented in [`DEPLOYMENT.md`](../DEPLOYMENT.md). diff --git a/packages/loopover-miner/lib/cross-repo-evaluation.d.ts b/packages/loopover-miner/lib/cross-repo-evaluation.d.ts index af8e928558..04325345e6 100644 --- a/packages/loopover-miner/lib/cross-repo-evaluation.d.ts +++ b/packages/loopover-miner/lib/cross-repo-evaluation.d.ts @@ -1,10 +1,15 @@ import type { RepoStackResult } from "./stack-detection.js"; -/** Failure taxonomy surfaced in per-repo reports (#4788). */ +/** Failure taxonomy surfaced in per-repo reports. Readiness-mode categories (#4788) plus the full-execution + * categories (#7634) that classify how a live discover → plan → code → test attempt fell short. */ export declare const CROSS_REPO_FAILURE_CATEGORY: Readonly<{ STACK_DETECTION: "stack_detection_gap"; EXECUTION: "execution_gap"; GITTENSOR_ASSUMPTION: "loopover_assumption"; CLONE_SETUP: "clone_setup"; + EXECUTION_NO_DIFF: "execution_no_diff"; + EXECUTION_COMPILE: "execution_compile_gap"; + EXECUTION_TEST: "execution_test_failure"; + EXECUTION_NOOP: "execution_noop_diff"; OTHER: "other"; }>; /** Instruction substrings that indicate a POSITIVE loopover/LoopOver CI assumption leaked into the agent prompt. @@ -21,6 +26,9 @@ export type CrossRepoEvaluationManifestRepo = { stackHint?: string; requireTestCommand?: boolean; fixturePath?: string; + /** Opt this entry into full-execution mode (#7634): `--full-execution` runs the live attempt against every + * entry flagged `true` (a `--repo` filter overrides the flag and runs that one entry regardless). */ + fullExecution?: boolean; }; export type ParsedCrossRepoEvaluationManifest = { present: boolean; @@ -67,6 +75,62 @@ type EvaluateRepoReadinessOptions = { instructions?: string; }; }; +/** Result of running a local shell command (build/test) during a full-execution attempt (#7634). */ +export type LocalCommandResult = { + ok: boolean; + /** True when there was no command to run (e.g. the stack inferred no build command) — treated as a pass. */ + skipped?: boolean; + code?: number | null; + output?: string; +}; +/** Everything a coding-agent executor needs to run one benchmark repo's live attempt (#7634). */ +export type CodingAttemptContext = { + repoFullName: string; + repoPath: string; + stack: RepoStackResult; + instructions: string; + attemptId: string; + maxTurns: number; +}; +/** What a coding-agent executor reports back: the real unified diff it produced (empty string when it made no + * change), plus whether the agent itself considered the run successful (#7634). */ +export type CodingAttemptOutcome = { + ok: boolean; + diff: string; + summary?: string; + error?: string; +}; +export type ExecuteRepoAttemptOptions = EvaluateRepoReadinessOptions & { + /** Discover → plan → code step: run the coding agent against the clone and return its diff. The CLI injects a + * real driver-backed executor; unit tests inject a fake. Left unset, the harness reports `execution_no_diff` + * rather than pretending an agent ran. */ + runCodingAttempt?: (context: CodingAttemptContext) => CodingAttemptOutcome | Promise; + /** Build/compile the clone after the diff is applied. Defaults to running `stack.buildCommand` locally. */ + compileRepo?: (context: { + repoPath: string; + stack: RepoStackResult; + }) => LocalCommandResult | Promise; + /** Run the target repo's own test suite locally. Defaults to running `stack.testCommand`. */ + runRepoTests?: (context: { + repoPath: string; + stack: RepoStackResult; + }) => LocalCommandResult | Promise; + /** Shared spawn used by the default compile/test runners; defaults to a real `spawnSync` in the clone dir. */ + runLocalCommand?: (command: string, context: { + cwd: string; + env?: NodeJS.ProcessEnv; + }) => LocalCommandResult; + /** Turn budget handed to the coding agent (CLI default: 30). */ + maxTurns?: number; +}; +export type CrossRepoExecutionResult = CrossRepoEvaluationResult & { + /** False when the attempt never reached the live agent (readiness gated it out). */ + executed: boolean; + compilePassed?: boolean | null; + testsPassed?: boolean | null; + /** Character length of the produced diff (0 for a no-op); null when no agent ran. */ + diffChars?: number | null; +}; /** Canonical `owner/repo` with exactly one slash and safe segments; anything else → null. */ export declare function normalizeCrossRepoFullName(value: unknown): string | null; /** @@ -92,6 +156,27 @@ export declare function evaluateRepoReadiness(entry: CrossRepoEvaluationManifest export declare function runCrossRepoEvaluation(parsed: ParsedCrossRepoEvaluationManifest, options?: { repoFilter?: string; } & EvaluateRepoReadinessOptions): CrossRepoEvaluationResult[]; +/** + * Run one benchmark repo's full-execution attempt (#7634): gate on readiness, then run the live discover → plan + * → code → test loop against the local clone and classify the outcome. Dry-run only — no forge writes, no PR + * submission; the agent edits a throwaway clone and the diff/results are discarded by the caller. + * + * The pipeline mirrors the failure taxonomy the issue calls for, in order: + * 1. readiness fails → the existing readiness category (attempt never starts; `executed: false`) + * 2. agent errors / no diff → `execution_no_diff` + * 3. diff doesn't build → `execution_compile_gap` + * 4. builds but tests fail → `execution_test_failure` + * 5. tests pass but diff no-op → `execution_noop_diff` + * 6. tests pass, real diff → PASS + */ +export declare function executeRepoAttempt(entry: CrossRepoEvaluationManifestRepo, options?: ExecuteRepoAttemptOptions): Promise; +/** + * Run the full-execution harness across a parsed manifest (#7634). Without a `repoFilter`, only entries flagged + * `fullExecution: true` run (the curated subset); a `repoFilter` overrides the flag and runs that one entry. + */ +export declare function runCrossRepoExecution(parsed: ParsedCrossRepoEvaluationManifest, options?: { + repoFilter?: string; +} & ExecuteRepoAttemptOptions): Promise; /** * Reduce per-repo results to pass/fail counts and whether a strict majority passed (#4788). */ diff --git a/packages/loopover-miner/lib/cross-repo-evaluation.js b/packages/loopover-miner/lib/cross-repo-evaluation.js index 995ae19eba..a726c9de60 100644 --- a/packages/loopover-miner/lib/cross-repo-evaluation.js +++ b/packages/loopover-miner/lib/cross-repo-evaluation.js @@ -3,17 +3,26 @@ // evaluated through the same stack-detection + coding-task-spec path a real attempt uses (detectRepoStack, // resolveMinerGoalSpec, buildCodingTaskSpec) and failures are categorized as stack-detection gaps, execution // readiness gaps, leaked loopover assumptions in agent instructions, clone/setup problems, or other. +import { spawnSync } from "node:child_process"; import { existsSync } from "node:fs"; import { buildCodingTaskSpec } from "./coding-task-spec.js"; import { resolveMinerGoalSpec } from "./miner-goal-spec.js"; import { isValidRepoSegment, resolveRepoCloneDir } from "./repo-clone.js"; import { detectRepoStack } from "./stack-detection.js"; -/** Failure taxonomy surfaced in per-repo reports (#4788). */ +/** Failure taxonomy surfaced in per-repo reports. Readiness-mode categories (#4788) plus the full-execution + * categories (#7634) that classify how a live discover → plan → code → test attempt fell short. */ export const CROSS_REPO_FAILURE_CATEGORY = Object.freeze({ STACK_DETECTION: "stack_detection_gap", EXECUTION: "execution_gap", GITTENSOR_ASSUMPTION: "loopover_assumption", CLONE_SETUP: "clone_setup", + // Full-execution taxonomy (#7634): the plan formed and the coding agent ran, but the attempt failed at a + // later stage — the agent produced no usable diff, the diff didn't build, the target test suite failed, or + // the tests passed only because the diff was a no-op. + EXECUTION_NO_DIFF: "execution_no_diff", + EXECUTION_COMPILE: "execution_compile_gap", + EXECUTION_TEST: "execution_test_failure", + EXECUTION_NOOP: "execution_noop_diff", OTHER: "other", }); /** Instruction substrings that indicate a POSITIVE loopover/LoopOver CI assumption leaked into the agent prompt. @@ -97,6 +106,7 @@ function normalizeRepoList(value, warnings) { let stackHint = null; let requireTestCommand = false; let fixturePath = null; + let fullExecution = false; if (typeof entry === "string") { repoFullName = normalizeCrossRepoFullName(entry); } @@ -106,6 +116,7 @@ function normalizeRepoList(value, warnings) { stackHint = normalizeOptionalString(record.stackHint, "stackHint", warnings); requireTestCommand = normalizeBoolean(record.requireTestCommand, "requireTestCommand", false, warnings); fixturePath = normalizeOptionalString(record.fixturePath, "fixturePath", warnings); + fullExecution = normalizeBoolean(record.fullExecution, "fullExecution", false, warnings); } else { warnings.push(`CrossRepoEvaluationManifest "repos" skipped a non-string, non-mapping entry.`); @@ -125,6 +136,8 @@ function normalizeRepoList(value, warnings) { normalized.stackHint = stackHint; if (fixturePath) normalized.fixturePath = fixturePath; + if (fullExecution) + normalized.fullExecution = true; result.push(normalized); } return result; @@ -216,6 +229,23 @@ function resolveEvaluationRepoPath(entry, options = {}) { function defaultClaimLedger(repoFullName) { return { listClaims: () => [] }; } +/** Compose the synthetic coding-task spec both readiness and full-execution evaluate against, so the two modes + * drive the exact same discover/plan surface a real attempt would (#7634). */ +function buildEvaluationCodingTaskSpec(repoFullName, repoPath, buildSpecImpl, detectImpl) { + return buildSpecImpl({ + repoFullName, + issue: { + number: 1, + title: "Cross-repo evaluation harness smoke issue", + body: "Synthetic issue used only by the cross-repo evaluation harness.", + labels: ["bug"], + }, + context: { issues: [{ number: 1 }], pullRequests: [] }, + claimLedger: defaultClaimLedger(repoFullName), + workingDirectory: repoPath, + detectRepoStack: detectImpl, + }); +} /** * Evaluate one benchmark repo's miner readiness without running a live coding agent (#4788). */ @@ -244,19 +274,7 @@ export function evaluateRepoReadiness(entry, options = {}) { } let specResult; try { - specResult = buildSpecImpl({ - repoFullName, - issue: { - number: 1, - title: "Cross-repo evaluation harness smoke issue", - body: "Synthetic issue used only by the cross-repo evaluation harness.", - labels: ["bug"], - }, - context: { issues: [{ number: 1 }], pullRequests: [] }, - claimLedger: defaultClaimLedger(repoFullName), - workingDirectory: repoPath, - detectRepoStack: detectImpl, - }); + specResult = buildEvaluationCodingTaskSpec(repoFullName, repoPath, buildSpecImpl, detectImpl); } catch (error) { const message = error instanceof Error ? error.message : String(error); @@ -288,6 +306,138 @@ export function runCrossRepoEvaluation(parsed, options = {}) { } return results; } +/** First non-empty line of command output, trimmed and length-capped, for a compact failure reason (#7634). */ +function firstOutputLine(output) { + if (typeof output !== "string") + return ""; + const line = output.split("\n").find((l) => l.trim().length > 0)?.trim() ?? ""; + return line.length > 200 ? `${line.slice(0, 200)}…` : line; +} +/** Real default local-command runner: a synchronous `sh -c` in the clone dir, resolve-not-throw so a non-zero + * exit becomes `ok: false` with its captured output rather than an exception (#7634). */ +function defaultRunLocalCommand(command, context) { + const result = spawnSync("sh", ["-c", command], { + cwd: context.cwd, + env: context.env ?? process.env, + encoding: "utf8", + }); + const output = `${result.stdout ?? ""}${result.stderr ?? ""}`; + if (result.error) { + return { ok: false, code: null, output: result.error.message }; + } + return { ok: result.status === 0, code: result.status, output }; +} +function runStackCommand(command, context, runLocalCommand, options) { + if (!command) + return { ok: true, skipped: true }; + return runLocalCommand(command, { + cwd: context.repoPath, + ...(options.env !== undefined ? { env: options.env } : {}), + }); +} +function executionResult(base, extra) { + return { ...base, executed: true, compilePassed: null, testsPassed: null, diffChars: null, ...extra }; +} +/** + * Run one benchmark repo's full-execution attempt (#7634): gate on readiness, then run the live discover → plan + * → code → test loop against the local clone and classify the outcome. Dry-run only — no forge writes, no PR + * submission; the agent edits a throwaway clone and the diff/results are discarded by the caller. + * + * The pipeline mirrors the failure taxonomy the issue calls for, in order: + * 1. readiness fails → the existing readiness category (attempt never starts; `executed: false`) + * 2. agent errors / no diff → `execution_no_diff` + * 3. diff doesn't build → `execution_compile_gap` + * 4. builds but tests fail → `execution_test_failure` + * 5. tests pass but diff no-op → `execution_noop_diff` + * 6. tests pass, real diff → PASS + */ +export async function executeRepoAttempt(entry, options = {}) { + const readiness = evaluateRepoReadiness(entry, options); + if (!readiness.passed) { + return { ...readiness, executed: false }; + } + const repoFullName = readiness.repoFullName; + const repoPath = resolveEvaluationRepoPath(entry, options); + const stack = readiness.stack; + const detectImpl = options.detectRepoStack ?? detectRepoStack; + const buildSpecImpl = options.buildCodingTaskSpec ?? buildCodingTaskSpec; + const runLocalCommand = options.runLocalCommand ?? defaultRunLocalCommand; + const compileImpl = options.compileRepo ?? ((context) => runStackCommand(context.stack.detected ? context.stack.buildCommand : null, context, runLocalCommand, options)); + const testImpl = options.runRepoTests ?? ((context) => runStackCommand(context.stack.detected ? context.stack.testCommand : null, context, runLocalCommand, options)); + // Re-derive the same coding-task instructions readiness already validated, to hand the live agent (#7634). + let instructions = ""; + try { + instructions = buildEvaluationCodingTaskSpec(repoFullName, repoPath, buildSpecImpl, detectImpl).instructions ?? ""; + } + catch { + instructions = ""; + } + // Stage 2 — discover → plan → code. Without an injected executor the harness will not fabricate a run. + if (typeof options.runCodingAttempt !== "function") { + return executionResult(buildFailure(repoFullName, CROSS_REPO_FAILURE_CATEGORY.EXECUTION_NO_DIFF, "No coding-agent executor configured for full-execution mode (set MINER_CODING_AGENT_PROVIDER and run via the CLI).", { stackDetected: true, usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, stack }), { diffChars: null }); + } + let attempt; + try { + attempt = await options.runCodingAttempt({ + repoFullName, + repoPath, + stack, + instructions, + attemptId: `cross-repo-exec-${repoFullName.replace("/", "__")}`, + maxTurns: Number.isFinite(options.maxTurns) ? options.maxTurns : 30, + }); + } + catch (error) { + const message = error instanceof Error ? error.message : String(error); + return executionResult(buildFailure(repoFullName, CROSS_REPO_FAILURE_CATEGORY.EXECUTION_NO_DIFF, `Coding agent did not run: ${message}`, { + stackDetected: true, + usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, + stack, + }), { diffChars: null }); + } + const diff = typeof attempt?.diff === "string" ? attempt.diff : ""; + if (!attempt || (attempt.ok === false && diff.trim().length === 0)) { + return executionResult(buildFailure(repoFullName, CROSS_REPO_FAILURE_CATEGORY.EXECUTION_NO_DIFF, attempt?.error ?? "Coding agent reported failure and produced no diff.", { stackDetected: true, usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, stack }), { diffChars: diff.length }); + } + // Stage 3 — the produced diff must still build. + const compile = await compileImpl({ repoPath, stack }); + if (!compile.ok) { + return executionResult(buildFailure(repoFullName, CROSS_REPO_FAILURE_CATEGORY.EXECUTION_COMPILE, `Generated diff did not build${firstOutputLine(compile.output) ? `: ${firstOutputLine(compile.output)}` : "."}`, { stackDetected: true, usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, stack }), { compilePassed: false, diffChars: diff.length }); + } + // Stage 4 — the target repo's own test suite must pass. + const test = await testImpl({ repoPath, stack }); + if (!test.ok) { + return executionResult(buildFailure(repoFullName, CROSS_REPO_FAILURE_CATEGORY.EXECUTION_TEST, `Target test suite failed${firstOutputLine(test.output) ? `: ${firstOutputLine(test.output)}` : "."}`, { stackDetected: true, usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, stack }), { compilePassed: true, testsPassed: false, diffChars: diff.length }); + } + // Stage 5 — a passing run with no actual change is a no-op, not a success. + if (diff.trim().length === 0) { + return executionResult(buildFailure(repoFullName, CROSS_REPO_FAILURE_CATEGORY.EXECUTION_NOOP, "Tests passed but the coding agent produced a no-op diff (no file changes).", { stackDetected: true, usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, stack }), { compilePassed: true, testsPassed: true, diffChars: 0 }); + } + return executionResult(buildPass(repoFullName, { usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, stack }), { + compilePassed: true, + testsPassed: true, + diffChars: diff.length, + }); +} +/** + * Run the full-execution harness across a parsed manifest (#7634). Without a `repoFilter`, only entries flagged + * `fullExecution: true` run (the curated subset); a `repoFilter` overrides the flag and runs that one entry. + */ +export async function runCrossRepoExecution(parsed, options = {}) { + const repos = parsed?.manifest?.repos ?? []; + const results = []; + for (const entry of repos) { + if (options.repoFilter) { + if (entry.repoFullName !== options.repoFilter) + continue; + } + else if (entry.fullExecution !== true) { + continue; + } + results.push(await executeRepoAttempt(entry, options)); + } + return results; +} /** * Reduce per-repo results to pass/fail counts and whether a strict majority passed (#4788). */ @@ -343,4 +493,4 @@ export function formatCrossRepoEvaluationReport(results, summary = summarizeCros } return lines.join("\n"); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3Jvc3MtcmVwby1ldmFsdWF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY3Jvc3MtcmVwby1ldmFsdWF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlIQUFpSDtBQUNqSCw4R0FBOEc7QUFDOUcsMkdBQTJHO0FBQzNHLDZHQUE2RztBQUM3RyxxR0FBcUc7QUFFckcsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUVyQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMxRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFHdkQsNkRBQTZEO0FBQzdELE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQU1uQyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ2pCLGVBQWUsRUFBRSxxQkFBcUI7SUFDdEMsU0FBUyxFQUFFLGVBQWU7SUFDMUIsb0JBQW9CLEVBQUUscUJBQXFCO0lBQzNDLFdBQVcsRUFBRSxhQUFhO0lBQzFCLEtBQUssRUFBRSxPQUFPO0NBQ2YsQ0FBQyxDQUFDO0FBRUg7bUdBQ21HO0FBQ25HLE1BQU0sQ0FBQyxNQUFNLG9DQUFvQyxHQUFtRCxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ2hILEVBQUUsRUFBRSxFQUFFLGdCQUFnQixFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRTtJQUNyRCxFQUFFLEVBQUUsRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFO0lBQ25ELEVBQUUsRUFBRSxFQUFFLGlCQUFpQixFQUFFLE9BQU8sRUFBRSxxQ0FBcUMsRUFBRTtJQUN6RSxFQUFFLEVBQUUsRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFO0NBQ25E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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3Jvc3MtcmVwby1ldmFsdWF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY3Jvc3MtcmVwby1ldmFsdWF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlIQUFpSDtBQUNqSCw4R0FBOEc7QUFDOUcsMkdBQTJHO0FBQzNHLDZHQUE2RztBQUM3RyxxR0FBcUc7QUFFckcsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFckMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLG1CQUFtQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDMUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBR3ZEO29HQUNvRztBQUNwRyxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FVbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNqQixlQUFlLEVBQUUscUJBQXFCO0lBQ3RDLFNBQVMsRUFBRSxlQUFlO0lBQzFCLG9CQUFvQixFQUFFLHFCQUFxQjtJQUMzQyxXQUFXLEVBQUUsYUFBYTtJQUMxQix5R0FBeUc7SUFDekcsMkdBQTJHO0lBQzNHLHNEQUFzRDtJQUN0RCxpQkFBaUIsRUFBRSxtQkFBbUI7SUFDdEMsaUJBQWlCLEVBQUUsdUJBQXVCO0lBQzFDLGNBQWMsRUFBRSx3QkFBd0I7SUFDeEMsY0FBYyxFQUFFLHFCQUFxQjtJQUNyQyxLQUFLLEVBQUUsT0FBTztDQUNmLENBQUMsQ0FBQztBQUVIO21HQUNtRztBQUNuRyxNQUFNLENBQUMsTUFBTSxvQ0FBb0MsR0FBbUQsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNoSCxFQUFFLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUs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 \ No newline at end of file diff --git a/packages/loopover-miner/lib/cross-repo-evaluation.ts b/packages/loopover-miner/lib/cross-repo-evaluation.ts index f579b18aef..cfc0726c82 100644 --- a/packages/loopover-miner/lib/cross-repo-evaluation.ts +++ b/packages/loopover-miner/lib/cross-repo-evaluation.ts @@ -4,6 +4,7 @@ // resolveMinerGoalSpec, buildCodingTaskSpec) and failures are categorized as stack-detection gaps, execution // readiness gaps, leaked loopover assumptions in agent instructions, clone/setup problems, or other. +import { spawnSync } from "node:child_process"; import { existsSync } from "node:fs"; import { join } from "node:path"; import { buildCodingTaskSpec } from "./coding-task-spec.js"; @@ -12,18 +13,30 @@ import { isValidRepoSegment, resolveRepoCloneDir } from "./repo-clone.js"; import { detectRepoStack } from "./stack-detection.js"; import type { RepoStackResult } from "./stack-detection.js"; -/** Failure taxonomy surfaced in per-repo reports (#4788). */ +/** Failure taxonomy surfaced in per-repo reports. Readiness-mode categories (#4788) plus the full-execution + * categories (#7634) that classify how a live discover → plan → code → test attempt fell short. */ export const CROSS_REPO_FAILURE_CATEGORY: Readonly<{ STACK_DETECTION: "stack_detection_gap"; EXECUTION: "execution_gap"; GITTENSOR_ASSUMPTION: "loopover_assumption"; CLONE_SETUP: "clone_setup"; + EXECUTION_NO_DIFF: "execution_no_diff"; + EXECUTION_COMPILE: "execution_compile_gap"; + EXECUTION_TEST: "execution_test_failure"; + EXECUTION_NOOP: "execution_noop_diff"; OTHER: "other"; }> = Object.freeze({ STACK_DETECTION: "stack_detection_gap", EXECUTION: "execution_gap", GITTENSOR_ASSUMPTION: "loopover_assumption", CLONE_SETUP: "clone_setup", + // Full-execution taxonomy (#7634): the plan formed and the coding agent ran, but the attempt failed at a + // later stage — the agent produced no usable diff, the diff didn't build, the target test suite failed, or + // the tests passed only because the diff was a no-op. + EXECUTION_NO_DIFF: "execution_no_diff", + EXECUTION_COMPILE: "execution_compile_gap", + EXECUTION_TEST: "execution_test_failure", + EXECUTION_NOOP: "execution_noop_diff", OTHER: "other", }); @@ -45,6 +58,9 @@ export type CrossRepoEvaluationManifestRepo = { stackHint?: string; requireTestCommand?: boolean; fixturePath?: string; + /** Opt this entry into full-execution mode (#7634): `--full-execution` runs the live attempt against every + * entry flagged `true` (a `--repo` filter overrides the flag and runs that one entry regardless). */ + fullExecution?: boolean; }; export type ParsedCrossRepoEvaluationManifest = { @@ -87,6 +103,58 @@ type EvaluateRepoReadinessOptions = { }; }; +/** Result of running a local shell command (build/test) during a full-execution attempt (#7634). */ +export type LocalCommandResult = { + ok: boolean; + /** True when there was no command to run (e.g. the stack inferred no build command) — treated as a pass. */ + skipped?: boolean; + code?: number | null; + output?: string; +}; + +/** Everything a coding-agent executor needs to run one benchmark repo's live attempt (#7634). */ +export type CodingAttemptContext = { + repoFullName: string; + repoPath: string; + stack: RepoStackResult; + instructions: string; + attemptId: string; + maxTurns: number; +}; + +/** What a coding-agent executor reports back: the real unified diff it produced (empty string when it made no + * change), plus whether the agent itself considered the run successful (#7634). */ +export type CodingAttemptOutcome = { + ok: boolean; + diff: string; + summary?: string; + error?: string; +}; + +export type ExecuteRepoAttemptOptions = EvaluateRepoReadinessOptions & { + /** Discover → plan → code step: run the coding agent against the clone and return its diff. The CLI injects a + * real driver-backed executor; unit tests inject a fake. Left unset, the harness reports `execution_no_diff` + * rather than pretending an agent ran. */ + runCodingAttempt?: (context: CodingAttemptContext) => CodingAttemptOutcome | Promise; + /** Build/compile the clone after the diff is applied. Defaults to running `stack.buildCommand` locally. */ + compileRepo?: (context: { repoPath: string; stack: RepoStackResult }) => LocalCommandResult | Promise; + /** Run the target repo's own test suite locally. Defaults to running `stack.testCommand`. */ + runRepoTests?: (context: { repoPath: string; stack: RepoStackResult }) => LocalCommandResult | Promise; + /** Shared spawn used by the default compile/test runners; defaults to a real `spawnSync` in the clone dir. */ + runLocalCommand?: (command: string, context: { cwd: string; env?: NodeJS.ProcessEnv }) => LocalCommandResult; + /** Turn budget handed to the coding agent (CLI default: 30). */ + maxTurns?: number; +}; + +export type CrossRepoExecutionResult = CrossRepoEvaluationResult & { + /** False when the attempt never reached the live agent (readiness gated it out). */ + executed: boolean; + compilePassed?: boolean | null; + testsPassed?: boolean | null; + /** Character length of the produced diff (0 for a no-op); null when no agent ran. */ + diffChars?: number | null; +}; + // True UTF-8 byte count for the size guard (#7223): JS string `.length` is UTF-16 code units, which under-counts // any multi-byte character (up to 4x for astral-plane code points), so `MAX_CROSS_REPO_MANIFEST_BYTES` -- named // and warned about in BYTES -- was actually being compared against a code-unit count. Mirrors the identical helper @@ -153,6 +221,7 @@ function normalizeRepoList(value: unknown, warnings: string[]): CrossRepoEvaluat let stackHint: string | null = null; let requireTestCommand = false; let fixturePath: string | null = null; + let fullExecution = false; if (typeof entry === "string") { repoFullName = normalizeCrossRepoFullName(entry); } else if (entry && typeof entry === "object" && !Array.isArray(entry)) { @@ -161,6 +230,7 @@ function normalizeRepoList(value: unknown, warnings: string[]): CrossRepoEvaluat stackHint = normalizeOptionalString(record.stackHint, "stackHint", warnings); requireTestCommand = normalizeBoolean(record.requireTestCommand, "requireTestCommand", false, warnings); fixturePath = normalizeOptionalString(record.fixturePath, "fixturePath", warnings); + fullExecution = normalizeBoolean(record.fullExecution, "fullExecution", false, warnings); } else { warnings.push(`CrossRepoEvaluationManifest "repos" skipped a non-string, non-mapping entry.`); continue; @@ -177,6 +247,7 @@ function normalizeRepoList(value: unknown, warnings: string[]): CrossRepoEvaluat const normalized: CrossRepoEvaluationManifestRepo = { repoFullName, requireTestCommand }; if (stackHint) normalized.stackHint = stackHint; if (fixturePath) normalized.fixturePath = fixturePath; + if (fullExecution) normalized.fullExecution = true; result.push(normalized); } return result; @@ -276,6 +347,31 @@ function defaultClaimLedger(repoFullName: string): { listClaims: () => never[] } return { listClaims: () => [] }; } +type BuildCodingTaskSpecImpl = NonNullable; + +/** Compose the synthetic coding-task spec both readiness and full-execution evaluate against, so the two modes + * drive the exact same discover/plan surface a real attempt would (#7634). */ +function buildEvaluationCodingTaskSpec( + repoFullName: string, + repoPath: string, + buildSpecImpl: BuildCodingTaskSpecImpl, + detectImpl: (repoPath: string) => RepoStackResult, +): ReturnType { + return buildSpecImpl({ + repoFullName, + issue: { + number: 1, + title: "Cross-repo evaluation harness smoke issue", + body: "Synthetic issue used only by the cross-repo evaluation harness.", + labels: ["bug"], + }, + context: { issues: [{ number: 1 }], pullRequests: [] }, + claimLedger: defaultClaimLedger(repoFullName), + workingDirectory: repoPath, + detectRepoStack: detectImpl, + }); +} + /** * Evaluate one benchmark repo's miner readiness without running a live coding agent (#4788). */ @@ -332,19 +428,7 @@ export function evaluateRepoReadiness( let specResult; try { - specResult = buildSpecImpl({ - repoFullName, - issue: { - number: 1, - title: "Cross-repo evaluation harness smoke issue", - body: "Synthetic issue used only by the cross-repo evaluation harness.", - labels: ["bug"], - }, - context: { issues: [{ number: 1 }], pullRequests: [] }, - claimLedger: defaultClaimLedger(repoFullName), - workingDirectory: repoPath, - detectRepoStack: detectImpl, - }); + specResult = buildEvaluationCodingTaskSpec(repoFullName, repoPath, buildSpecImpl, detectImpl); } catch (error) { const message = error instanceof Error ? error.message : String(error); return buildFailure(repoFullName, CROSS_REPO_FAILURE_CATEGORY.OTHER, message, { @@ -392,6 +476,210 @@ export function runCrossRepoEvaluation( return results; } +/** First non-empty line of command output, trimmed and length-capped, for a compact failure reason (#7634). */ +function firstOutputLine(output: string | undefined): string { + if (typeof output !== "string") return ""; + const line = output.split("\n").find((l) => l.trim().length > 0)?.trim() ?? ""; + return line.length > 200 ? `${line.slice(0, 200)}…` : line; +} + +/** Real default local-command runner: a synchronous `sh -c` in the clone dir, resolve-not-throw so a non-zero + * exit becomes `ok: false` with its captured output rather than an exception (#7634). */ +function defaultRunLocalCommand( + command: string, + context: { cwd: string; env?: NodeJS.ProcessEnv }, +): LocalCommandResult { + const result = spawnSync("sh", ["-c", command], { + cwd: context.cwd, + env: context.env ?? process.env, + encoding: "utf8", + }); + const output = `${result.stdout ?? ""}${result.stderr ?? ""}`; + if (result.error) { + return { ok: false, code: null, output: result.error.message }; + } + return { ok: result.status === 0, code: result.status, output }; +} + +function runStackCommand( + command: string | null, + context: { repoPath: string; stack: RepoStackResult }, + runLocalCommand: NonNullable, + options: ExecuteRepoAttemptOptions, +): LocalCommandResult { + if (!command) return { ok: true, skipped: true }; + return runLocalCommand(command, { + cwd: context.repoPath, + ...(options.env !== undefined ? { env: options.env } : {}), + }); +} + +function executionResult( + base: CrossRepoEvaluationResult, + extra: Partial, +): CrossRepoExecutionResult { + return { ...base, executed: true, compilePassed: null, testsPassed: null, diffChars: null, ...extra }; +} + +/** + * Run one benchmark repo's full-execution attempt (#7634): gate on readiness, then run the live discover → plan + * → code → test loop against the local clone and classify the outcome. Dry-run only — no forge writes, no PR + * submission; the agent edits a throwaway clone and the diff/results are discarded by the caller. + * + * The pipeline mirrors the failure taxonomy the issue calls for, in order: + * 1. readiness fails → the existing readiness category (attempt never starts; `executed: false`) + * 2. agent errors / no diff → `execution_no_diff` + * 3. diff doesn't build → `execution_compile_gap` + * 4. builds but tests fail → `execution_test_failure` + * 5. tests pass but diff no-op → `execution_noop_diff` + * 6. tests pass, real diff → PASS + */ +export async function executeRepoAttempt( + entry: CrossRepoEvaluationManifestRepo, + options: ExecuteRepoAttemptOptions = {}, +): Promise { + const readiness = evaluateRepoReadiness(entry, options); + if (!readiness.passed) { + return { ...readiness, executed: false }; + } + const repoFullName = readiness.repoFullName; + const repoPath = resolveEvaluationRepoPath(entry, options); + const stack = readiness.stack as RepoStackResult; + + const detectImpl = options.detectRepoStack ?? detectRepoStack; + const buildSpecImpl: BuildCodingTaskSpecImpl = + options.buildCodingTaskSpec ?? (buildCodingTaskSpec as unknown as BuildCodingTaskSpecImpl); + const runLocalCommand = options.runLocalCommand ?? defaultRunLocalCommand; + const compileImpl = + options.compileRepo ?? ((context) => runStackCommand(context.stack.detected ? context.stack.buildCommand : null, context, runLocalCommand, options)); + const testImpl = + options.runRepoTests ?? ((context) => runStackCommand(context.stack.detected ? context.stack.testCommand : null, context, runLocalCommand, options)); + + // Re-derive the same coding-task instructions readiness already validated, to hand the live agent (#7634). + let instructions = ""; + try { + instructions = buildEvaluationCodingTaskSpec(repoFullName, repoPath, buildSpecImpl, detectImpl).instructions ?? ""; + } catch { + instructions = ""; + } + + // Stage 2 — discover → plan → code. Without an injected executor the harness will not fabricate a run. + if (typeof options.runCodingAttempt !== "function") { + return executionResult( + buildFailure( + repoFullName, + CROSS_REPO_FAILURE_CATEGORY.EXECUTION_NO_DIFF, + "No coding-agent executor configured for full-execution mode (set MINER_CODING_AGENT_PROVIDER and run via the CLI).", + { stackDetected: true, usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, stack }, + ), + { diffChars: null }, + ); + } + + let attempt: CodingAttemptOutcome; + try { + attempt = await options.runCodingAttempt({ + repoFullName, + repoPath, + stack, + instructions, + attemptId: `cross-repo-exec-${repoFullName.replace("/", "__")}`, + maxTurns: Number.isFinite(options.maxTurns) ? (options.maxTurns as number) : 30, + }); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return executionResult( + buildFailure(repoFullName, CROSS_REPO_FAILURE_CATEGORY.EXECUTION_NO_DIFF, `Coding agent did not run: ${message}`, { + stackDetected: true, + usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, + stack, + }), + { diffChars: null }, + ); + } + + const diff = typeof attempt?.diff === "string" ? attempt.diff : ""; + if (!attempt || (attempt.ok === false && diff.trim().length === 0)) { + return executionResult( + buildFailure( + repoFullName, + CROSS_REPO_FAILURE_CATEGORY.EXECUTION_NO_DIFF, + attempt?.error ?? "Coding agent reported failure and produced no diff.", + { stackDetected: true, usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, stack }, + ), + { diffChars: diff.length }, + ); + } + + // Stage 3 — the produced diff must still build. + const compile = await compileImpl({ repoPath, stack }); + if (!compile.ok) { + return executionResult( + buildFailure( + repoFullName, + CROSS_REPO_FAILURE_CATEGORY.EXECUTION_COMPILE, + `Generated diff did not build${firstOutputLine(compile.output) ? `: ${firstOutputLine(compile.output)}` : "."}`, + { stackDetected: true, usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, stack }, + ), + { compilePassed: false, diffChars: diff.length }, + ); + } + + // Stage 4 — the target repo's own test suite must pass. + const test = await testImpl({ repoPath, stack }); + if (!test.ok) { + return executionResult( + buildFailure( + repoFullName, + CROSS_REPO_FAILURE_CATEGORY.EXECUTION_TEST, + `Target test suite failed${firstOutputLine(test.output) ? `: ${firstOutputLine(test.output)}` : "."}`, + { stackDetected: true, usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, stack }, + ), + { compilePassed: true, testsPassed: false, diffChars: diff.length }, + ); + } + + // Stage 5 — a passing run with no actual change is a no-op, not a success. + if (diff.trim().length === 0) { + return executionResult( + buildFailure( + repoFullName, + CROSS_REPO_FAILURE_CATEGORY.EXECUTION_NOOP, + "Tests passed but the coding agent produced a no-op diff (no file changes).", + { stackDetected: true, usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, stack }, + ), + { compilePassed: true, testsPassed: true, diffChars: 0 }, + ); + } + + return executionResult(buildPass(repoFullName, { usedDefaultGoalSpec: readiness.usedDefaultGoalSpec, stack }), { + compilePassed: true, + testsPassed: true, + diffChars: diff.length, + }); +} + +/** + * Run the full-execution harness across a parsed manifest (#7634). Without a `repoFilter`, only entries flagged + * `fullExecution: true` run (the curated subset); a `repoFilter` overrides the flag and runs that one entry. + */ +export async function runCrossRepoExecution( + parsed: ParsedCrossRepoEvaluationManifest, + options: { repoFilter?: string } & ExecuteRepoAttemptOptions = {}, +): Promise { + const repos = parsed?.manifest?.repos ?? []; + const results: CrossRepoExecutionResult[] = []; + for (const entry of repos) { + if (options.repoFilter) { + if (entry.repoFullName !== options.repoFilter) continue; + } else if (entry.fullExecution !== true) { + continue; + } + results.push(await executeRepoAttempt(entry, options)); + } + return results; +} + /** * Reduce per-repo results to pass/fail counts and whether a strict majority passed (#4788). */ diff --git a/packages/loopover-miner/scripts/cross-repo-evaluation.d.mts b/packages/loopover-miner/scripts/cross-repo-evaluation.d.mts index c263aa2347..74826999d6 100644 --- a/packages/loopover-miner/scripts/cross-repo-evaluation.d.mts +++ b/packages/loopover-miner/scripts/cross-repo-evaluation.d.mts @@ -1,11 +1,23 @@ import type { + CodingAttemptContext, + CodingAttemptOutcome, CrossRepoEvaluationResult, CrossRepoEvaluationSummary, + CrossRepoExecutionResult, + ExecuteRepoAttemptOptions, + LocalCommandResult, ParsedCrossRepoEvaluationManifest, } from "../lib/cross-repo-evaluation.js"; +import type { CodingAgentDriver } from "@loopover/engine"; export type CrossRepoEvaluationCliArgs = - | { manifestPath: string; json: boolean; repoFilter: string | null; requireMajority: boolean } + | { + manifestPath: string; + json: boolean; + repoFilter: string | null; + requireMajority: boolean; + fullExecution: boolean; + } | { error: string } | { help: true }; @@ -15,6 +27,9 @@ export type CrossRepoEvaluationCliOptions = { repoFilter?: string | null; }; +export type CrossRepoExecutionCliOptions = CrossRepoEvaluationCliOptions & + Pick; + export declare function resolveDefaultManifestPath(): string; export declare function parseCrossRepoEvaluationArgs(argv?: readonly string[]): CrossRepoEvaluationCliArgs; @@ -26,3 +41,14 @@ export declare function runCrossRepoEvaluationCli(options?: CrossRepoEvaluationC results: CrossRepoEvaluationResult[]; summary: CrossRepoEvaluationSummary; }; + +export declare function defaultFullExecutionCodingAttempt( + context: CodingAttemptContext, + deps?: { env?: NodeJS.ProcessEnv; driver?: CodingAgentDriver; spawnSync?: typeof import("node:child_process").spawnSync }, +): Promise; + +export declare function runCrossRepoExecutionCli(options?: CrossRepoExecutionCliOptions): Promise<{ + parsed: ParsedCrossRepoEvaluationManifest; + results: CrossRepoExecutionResult[]; + summary: CrossRepoEvaluationSummary; +}>; diff --git a/packages/loopover-miner/scripts/cross-repo-evaluation.mjs b/packages/loopover-miner/scripts/cross-repo-evaluation.mjs index 04de1d9fa4..7f60654365 100644 --- a/packages/loopover-miner/scripts/cross-repo-evaluation.mjs +++ b/packages/loopover-miner/scripts/cross-repo-evaluation.mjs @@ -1,12 +1,16 @@ #!/usr/bin/env node -import { readFileSync } from "node:fs"; +import { spawnSync } from "node:child_process"; +import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; import { dirname, join } from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; +import { constructProductionCodingAgentDriver } from "../lib/coding-agent-construction.js"; import { DEFAULT_CROSS_REPO_MANIFEST_RELATIVE_PATH, formatCrossRepoEvaluationReport, parseCrossRepoEvaluationManifest, runCrossRepoEvaluation, + runCrossRepoExecution, summarizeCrossRepoEvaluation, } from "../lib/cross-repo-evaluation.js"; @@ -22,6 +26,7 @@ export function parseCrossRepoEvaluationArgs(argv) { let json = false; let repoFilter = null; let requireMajority = false; + let fullExecution = false; for (let i = 0; i < args.length; i += 1) { const token = args[i]; if (token === "--json") { @@ -32,6 +37,10 @@ export function parseCrossRepoEvaluationArgs(argv) { requireMajority = true; continue; } + if (token === "--full-execution") { + fullExecution = true; + continue; + } if (token === "--manifest") { const value = args[i + 1]; if (!value) return { error: "Missing value for --manifest." }; @@ -51,7 +60,7 @@ export function parseCrossRepoEvaluationArgs(argv) { } return { error: `Unknown argument: ${token}` }; } - return { manifestPath, json, repoFilter, requireMajority }; + return { manifestPath, json, repoFilter, requireMajority, fullExecution }; } export function loadCrossRepoEvaluationManifest(manifestPath) { @@ -66,6 +75,56 @@ export function runCrossRepoEvaluationCli(options = {}) { return { parsed, results, summary }; } +// Real, dry-run full-execution coding attempt (#7634): resolve the configured coding agent, let it edit the +// local clone, then capture the resulting diff with git -- all against a throwaway clone, no forge writes. +// `git add -A` before the diff so brand-new untracked files count; the acceptance-criteria file is written to +// the OS temp dir (never the clone) so it can't leak into the captured diff. +export async function defaultFullExecutionCodingAttempt(context, deps = {}) { + const env = deps.env ?? process.env; + const driver = deps.driver ?? constructProductionCodingAgentDriver(env); + const scratch = mkdtempSync(join(tmpdir(), "loopover-cross-repo-exec-")); + const acceptanceCriteriaPath = join(scratch, "acceptance-criteria.md"); + writeFileSync(acceptanceCriteriaPath, context.instructions || "Address the synthetic benchmark issue.", "utf8"); + try { + const result = await driver.run({ + attemptId: context.attemptId, + workingDirectory: context.repoPath, + acceptanceCriteriaPath, + instructions: context.instructions, + maxTurns: context.maxTurns, + }); + const spawn = deps.spawnSync ?? spawnSync; + spawn("git", ["add", "-A"], { cwd: context.repoPath }); + const diffResult = spawn("git", ["--no-pager", "diff", "--cached"], { + cwd: context.repoPath, + encoding: "utf8", + maxBuffer: 64 * 1024 * 1024, + }); + const diff = typeof diffResult.stdout === "string" ? diffResult.stdout : ""; + return { ok: result.ok === true, diff, summary: result.summary, error: result.error }; + } finally { + rmSync(scratch, { recursive: true, force: true }); + } +} + +export async function runCrossRepoExecutionCli(options = {}) { + const parsed = options.parsed ?? loadCrossRepoEvaluationManifest(options.manifestPath ?? resolveDefaultManifestPath()); + const env = options.env ?? process.env; + const runCodingAttempt = + options.runCodingAttempt ?? ((context) => defaultFullExecutionCodingAttempt(context, { env })); + const results = await runCrossRepoExecution(parsed, { + repoFilter: options.repoFilter ?? null, + runCodingAttempt, + env, + ...(options.compileRepo ? { compileRepo: options.compileRepo } : {}), + ...(options.runRepoTests ? { runRepoTests: options.runRepoTests } : {}), + ...(options.runLocalCommand ? { runLocalCommand: options.runLocalCommand } : {}), + ...(options.maxTurns !== undefined ? { maxTurns: options.maxTurns } : {}), + }); + const summary = summarizeCrossRepoEvaluation(results); + return { parsed, results, summary }; +} + function printHelp() { console.log( [ @@ -79,6 +138,10 @@ function printHelp() { " --repo Evaluate a single benchmark entry", " --json Emit machine-readable JSON on stdout", " --require-majority Exit 1 unless a strict majority of repos pass", + " --full-execution Dry-run the live discover→plan→code→test loop (#7634) against the", + " fullExecution subset, generating a real diff and running each repo's", + " own test suite locally — no PR submission, no forge writes. Requires a", + " configured coding agent (MINER_CODING_AGENT_PROVIDER).", " -h, --help Show this help", "", "Prerequisite: clone benchmark repos into LOOPOVER_MINER_REPO_CLONE_DIR (see docs/cross-repo-evaluation.md).", @@ -86,7 +149,7 @@ function printHelp() { ); } -function main() { +async function main() { const parsedArgs = parseCrossRepoEvaluationArgs(); if (parsedArgs.help) { printHelp(); @@ -97,7 +160,9 @@ function main() { return 2; } - const { parsed, results, summary } = runCrossRepoEvaluationCli(parsedArgs); + const { parsed, results, summary } = parsedArgs.fullExecution + ? await runCrossRepoExecutionCli(parsedArgs) + : runCrossRepoEvaluationCli(parsedArgs); if (parsedArgs.json) { console.log(JSON.stringify({ warnings: parsed.warnings, results, summary }, null, 2)); } else { @@ -112,5 +177,7 @@ function main() { } if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) { - process.exitCode = main(); + main().then((code) => { + process.exitCode = code; + }); } diff --git a/test/unit/miner-cross-repo-evaluation.test.ts b/test/unit/miner-cross-repo-evaluation.test.ts index 1f1de6a21d..50743ebfd8 100644 --- a/test/unit/miner-cross-repo-evaluation.test.ts +++ b/test/unit/miner-cross-repo-evaluation.test.ts @@ -11,20 +11,25 @@ import { CROSS_REPO_FAILURE_CATEGORY, DEFAULT_CROSS_REPO_MANIFEST_RELATIVE_PATH, MAX_CROSS_REPO_MANIFEST_BYTES, + executeRepoAttempt, formatCrossRepoEvaluationReport, evaluateRepoReadiness, normalizeCrossRepoFullName, parseCrossRepoEvaluationManifest, runCrossRepoEvaluation, + runCrossRepoExecution, scanPositiveLoopoverAssumptions, summarizeCrossRepoEvaluation, } from "../../packages/loopover-miner/lib/cross-repo-evaluation.js"; +import type { CodingAttemptContext } from "../../packages/loopover-miner/lib/cross-repo-evaluation.js"; import type { RepoStackResult } from "../../packages/loopover-miner/lib/stack-detection.js"; import { + defaultFullExecutionCodingAttempt, loadCrossRepoEvaluationManifest, parseCrossRepoEvaluationArgs, resolveDefaultManifestPath, runCrossRepoEvaluationCli, + runCrossRepoExecutionCli, } from "../../packages/loopover-miner/scripts/cross-repo-evaluation.mjs"; const roots: string[] = []; @@ -166,6 +171,26 @@ describe("cross-repo evaluation harness (#4788)", () => { expect(parsed.manifest.repos[0]?.fixturePath).toBeUndefined(); expect(parsed.warnings).toEqual([]); }); + + it("parses the fullExecution flag, attaching it only when true (#7634)", () => { + const parsed = parseCrossRepoEvaluationManifest( + JSON.stringify({ + repos: [ + { repoFullName: "acme/on", fullExecution: true }, + { repoFullName: "acme/off", fullExecution: false }, + { repoFullName: "acme/absent" }, + { repoFullName: "acme/bad", fullExecution: "yes" }, + ], + }), + ); + expect(parsed.manifest.repos).toEqual([ + { repoFullName: "acme/on", requireTestCommand: false, fullExecution: true }, + { repoFullName: "acme/off", requireTestCommand: false }, + { repoFullName: "acme/absent", requireTestCommand: false }, + { repoFullName: "acme/bad", requireTestCommand: false }, + ]); + expect(parsed.warnings.some((w) => w.includes("fullExecution"))).toBe(true); + }); }); describe("scanPositiveLoopoverAssumptions", () => { @@ -495,6 +520,7 @@ describe("cross-repo evaluation harness (#4788)", () => { json: true, repoFilter: "acme/widgets", requireMajority: true, + fullExecution: false, }); expect(parseCrossRepoEvaluationArgs(["--manifest"])).toEqual({ error: "Missing value for --manifest." }); expect(parseCrossRepoEvaluationArgs(["--nope"])).toEqual({ error: "Unknown argument: --nope" }); @@ -528,6 +554,237 @@ describe("cross-repo evaluation harness (#4788)", () => { }); }); + describe("full-execution mode (#7634)", () => { + const nodeRepo = () => tempRepo({ "package.json": pkg({ scripts: { test: "node --test" } }) }); + const okAttempt = (diff: string) => () => Promise.resolve({ ok: true, diff }); + + it("passes readiness failures straight through with executed:false", async () => { + const result = await executeRepoAttempt( + { repoFullName: "acme/missing", requireTestCommand: false }, + { repoPath: "/tmp/definitely-missing", existsSync: () => false, runCodingAttempt: okAttempt("x") }, + ); + expect(result.executed).toBe(false); + expect(result.failureCategory).toBe(CROSS_REPO_FAILURE_CATEGORY.CLONE_SETUP); + }); + + it("reports execution_no_diff when no coding-agent executor is configured", async () => { + const result = await executeRepoAttempt( + { repoFullName: "acme/unwired", requireTestCommand: false }, + { repoPath: nodeRepo(), existsSync: () => true }, + ); + expect(result.executed).toBe(true); + expect(result.failureCategory).toBe(CROSS_REPO_FAILURE_CATEGORY.EXECUTION_NO_DIFF); + expect(result.reason).toContain("No coding-agent executor"); + }); + + it("reports execution_no_diff when the agent throws", async () => { + const result = await executeRepoAttempt( + { repoFullName: "acme/boom", requireTestCommand: false }, + { + repoPath: nodeRepo(), + existsSync: () => true, + runCodingAttempt: () => { + throw new Error("driver exploded"); + }, + }, + ); + expect(result.failureCategory).toBe(CROSS_REPO_FAILURE_CATEGORY.EXECUTION_NO_DIFF); + expect(result.reason).toContain("driver exploded"); + expect(result.diffChars).toBeNull(); + }); + + it("reports execution_no_diff when the agent fails and produces no diff", async () => { + const result = await executeRepoAttempt( + { repoFullName: "acme/empty", requireTestCommand: false }, + { + repoPath: nodeRepo(), + existsSync: () => true, + runCodingAttempt: () => Promise.resolve({ ok: false, diff: " ", error: "agent gave up" }), + }, + ); + expect(result.failureCategory).toBe(CROSS_REPO_FAILURE_CATEGORY.EXECUTION_NO_DIFF); + expect(result.reason).toBe("agent gave up"); + }); + + it("reports execution_compile_gap when the generated diff does not build", async () => { + const result = await executeRepoAttempt( + { repoFullName: "acme/nobuild", requireTestCommand: false }, + { + repoPath: nodeRepo(), + existsSync: () => true, + runCodingAttempt: okAttempt("diff --git a/x b/x\n+broken"), + compileRepo: () => ({ ok: false, code: 1, output: "SyntaxError: bad token\nmore" }), + runRepoTests: () => ({ ok: true }), + }, + ); + expect(result.failureCategory).toBe(CROSS_REPO_FAILURE_CATEGORY.EXECUTION_COMPILE); + expect(result.compilePassed).toBe(false); + expect(result.testsPassed).toBeNull(); + expect(result.reason).toContain("SyntaxError: bad token"); + }); + + it("reports execution_test_failure when the built diff fails the target test suite", async () => { + const result = await executeRepoAttempt( + { repoFullName: "acme/redtests", requireTestCommand: false }, + { + repoPath: nodeRepo(), + existsSync: () => true, + runCodingAttempt: okAttempt("diff --git a/x b/x\n+change"), + compileRepo: () => ({ ok: true }), + runRepoTests: () => ({ ok: false, code: 1, output: "1 failing" }), + }, + ); + expect(result.failureCategory).toBe(CROSS_REPO_FAILURE_CATEGORY.EXECUTION_TEST); + expect(result.compilePassed).toBe(true); + expect(result.testsPassed).toBe(false); + expect(result.reason).toContain("1 failing"); + }); + + it("reports execution_noop_diff when tests pass but the diff is empty", async () => { + const result = await executeRepoAttempt( + { repoFullName: "acme/noop", requireTestCommand: false }, + { + repoPath: nodeRepo(), + existsSync: () => true, + runCodingAttempt: okAttempt(" \n "), + compileRepo: () => ({ ok: true }), + runRepoTests: () => ({ ok: true }), + }, + ); + expect(result.failureCategory).toBe(CROSS_REPO_FAILURE_CATEGORY.EXECUTION_NOOP); + expect(result.testsPassed).toBe(true); + expect(result.diffChars).toBe(0); + }); + + it("passes end-to-end when a real diff builds and the tests pass", async () => { + const result = await executeRepoAttempt( + { repoFullName: "acme/green", requireTestCommand: false }, + { + repoPath: nodeRepo(), + existsSync: () => true, + runCodingAttempt: okAttempt("diff --git a/x b/x\n+real change"), + compileRepo: () => ({ ok: true }), + runRepoTests: () => ({ ok: true }), + }, + ); + expect(result.passed).toBe(true); + expect(result.executed).toBe(true); + expect(result.compilePassed).toBe(true); + expect(result.testsPassed).toBe(true); + expect(result.diffChars).toBeGreaterThan(0); + }); + + it("uses the default compile/test runners via an injected runLocalCommand (skips a null build command)", async () => { + const commands: string[] = []; + const result = await executeRepoAttempt( + { repoFullName: "acme/defaults", requireTestCommand: true }, + { + repoPath: nodeRepo(), + existsSync: () => true, + runCodingAttempt: okAttempt("diff --git a/x b/x\n+change"), + runLocalCommand: (command) => { + commands.push(command); + return { ok: true, code: 0, output: "" }; + }, + }, + ); + expect(result.passed).toBe(true); + // The plain-Node repo has a test script but no build script, so only the inferred test command is spawned. + expect(commands).toEqual(["npm test"]); + }); + + it("threads the derived instructions and attemptId into the coding agent", async () => { + let seen: CodingAttemptContext | null = null; + const result = await executeRepoAttempt( + { repoFullName: "acme/threaded", requireTestCommand: false }, + { + repoPath: nodeRepo(), + existsSync: () => true, + runCodingAttempt: (context) => { + seen = context; + return Promise.resolve({ ok: true, diff: "diff --git a/x b/x\n+c" }); + }, + compileRepo: () => ({ ok: true }), + runRepoTests: () => ({ ok: true }), + }, + ); + expect(result.passed).toBe(true); + expect(seen).not.toBeNull(); + expect(seen!.attemptId).toBe("cross-repo-exec-acme__threaded"); + expect(typeof seen!.instructions).toBe("string"); + }); + + it("runCrossRepoExecution runs only fullExecution entries, and a repoFilter overrides the flag", async () => { + const parsed = parseCrossRepoEvaluationManifest( + JSON.stringify({ + repos: [ + { repoFullName: "acme/a", fullExecution: true }, + { repoFullName: "acme/b" }, + { repoFullName: "acme/c", fullExecution: true }, + ], + }), + ); + const opts = { existsSync: () => false, runCodingAttempt: okAttempt("x") }; + + const subset = await runCrossRepoExecution(parsed, opts); + expect(subset.map((r) => r.repoFullName)).toEqual(["acme/a", "acme/c"]); + + const filtered = await runCrossRepoExecution(parsed, { ...opts, repoFilter: "acme/b" }); + expect(filtered.map((r) => r.repoFullName)).toEqual(["acme/b"]); + }); + + it("defaultFullExecutionCodingAttempt runs the driver then captures the staged diff via git", async () => { + const calls: string[][] = []; + const fakeDriver = { + run: async () => ({ ok: true, changedFiles: ["x"], summary: "done" }), + }; + const fakeSpawn = ((cmd: string, args: string[]) => { + calls.push([cmd, ...args]); + return args.includes("diff") + ? { stdout: "diff --git a/x b/x\n+1", status: 0 } + : { stdout: "", status: 0 }; + }) as never; + + const outcome = await defaultFullExecutionCodingAttempt( + { + repoFullName: "acme/x", + repoPath: nodeRepo(), + stack: { detected: true } as never, + instructions: "do the thing", + attemptId: "a1", + maxTurns: 5, + }, + { driver: fakeDriver, spawnSync: fakeSpawn }, + ); + expect(outcome.ok).toBe(true); + expect(outcome.diff).toContain("diff --git"); + expect(calls[0]).toEqual(["git", "add", "-A"]); + expect(calls[1]).toEqual(["git", "--no-pager", "diff", "--cached"]); + }); + + it("runCrossRepoExecutionCli drives a fixture manifest with injected primitives", async () => { + const repoPath = nodeRepo(); + const manifestDir = tempRepo(); + writeFileSync( + join(manifestDir, "manifest.json"), + JSON.stringify({ + repos: [{ repoFullName: "acme/fixture", fixturePath: repoPath, requireTestCommand: true, fullExecution: true }], + }), + "utf8", + ); + + const { results, summary } = await runCrossRepoExecutionCli({ + manifestPath: join(manifestDir, "manifest.json"), + runCodingAttempt: okAttempt("diff --git a/x b/x\n+shipped"), + compileRepo: () => ({ ok: true }), + runRepoTests: () => ({ ok: true }), + }); + expect(results[0]?.passed).toBe(true); + expect(results[0]?.executed).toBe(true); + expect(summary.passed).toBe(1); + }); + }); + it("documents the harness in packages/loopover-miner/docs/cross-repo-evaluation.md", () => { const doc = readFileSync(join(process.cwd(), "packages/loopover-miner/docs/cross-repo-evaluation.md"), "utf8"); expect(doc).toContain("#4788"); @@ -535,4 +792,13 @@ describe("cross-repo evaluation harness (#4788)", () => { expect(doc).toContain("cross-repo-evaluation.mjs"); expect(doc).toContain("benchmarks/cross-repo/manifest.json"); }); + + it("documents the full-execution mode and its taxonomy (#7634)", () => { + const doc = readFileSync(join(process.cwd(), "packages/loopover-miner/docs/cross-repo-evaluation.md"), "utf8"); + expect(doc).toContain("--full-execution"); + expect(doc).toContain("#7634"); + expect(doc).toContain("execution_compile_gap"); + expect(doc).toContain("execution_test_failure"); + expect(doc).toContain("execution_noop_diff"); + }); }); From 62d411e658ab34f7fad73c35eb47ab2e97403795 Mon Sep 17 00:00:00 2001 From: bitfathers94 <237535319+bitfathers94@users.noreply.github.com> Date: Tue, 21 Jul 2026 06:03:03 +0000 Subject: [PATCH 2/2] fix(miner): run detected stack commands without a shell to close a P1 injection surface defaultRunLocalCommand executed `sh -c ` where the command is derived from untrusted cloned-repo metadata (e.g. a crafted package.json script name), so shell metacharacters could inject extra commands on the evaluating host. Split the command into a plain argv and spawn it directly with `shell: false`; stack commands are already whitespace-separated argv. Adds direct unit tests covering the no-shell argv, inert-metacharacter, spawn-error, and empty-command paths. --- .../lib/cross-repo-evaluation.d.ts | 10 ++++ .../lib/cross-repo-evaluation.js | 17 ++++-- .../lib/cross-repo-evaluation.ts | 15 ++++-- test/unit/miner-cross-repo-evaluation.test.ts | 52 +++++++++++++++++++ 4 files changed, 85 insertions(+), 9 deletions(-) diff --git a/packages/loopover-miner/lib/cross-repo-evaluation.d.ts b/packages/loopover-miner/lib/cross-repo-evaluation.d.ts index 04325345e6..d0cb1639f2 100644 --- a/packages/loopover-miner/lib/cross-repo-evaluation.d.ts +++ b/packages/loopover-miner/lib/cross-repo-evaluation.d.ts @@ -1,3 +1,4 @@ +import { spawnSync } from "node:child_process"; import type { RepoStackResult } from "./stack-detection.js"; /** Failure taxonomy surfaced in per-repo reports. Readiness-mode categories (#4788) plus the full-execution * categories (#7634) that classify how a live discover → plan → code → test attempt fell short. */ @@ -156,6 +157,15 @@ export declare function evaluateRepoReadiness(entry: CrossRepoEvaluationManifest export declare function runCrossRepoEvaluation(parsed: ParsedCrossRepoEvaluationManifest, options?: { repoFilter?: string; } & EvaluateRepoReadinessOptions): CrossRepoEvaluationResult[]; +/** Real default local-command runner: split the detected command into an argv and spawn it directly in the clone + * dir with NO shell (`shell: false`), so shell metacharacters in untrusted repo metadata (e.g. a crafted + * package.json script name) cannot inject extra commands (#7641). Stack commands are plain whitespace-separated + * argv (`npm run build`, `cargo test`, `go build ./...`). Resolve-not-throw: a non-zero exit becomes `ok: false` + * with its captured output rather than an exception (#7634). Exported for direct unit coverage. */ +export declare function defaultRunLocalCommand(command: string, context: { + cwd: string; + env?: NodeJS.ProcessEnv; +}, spawn?: typeof spawnSync): LocalCommandResult; /** * Run one benchmark repo's full-execution attempt (#7634): gate on readiness, then run the live discover → plan * → code → test loop against the local clone and classify the outcome. Dry-run only — no forge writes, no PR diff --git a/packages/loopover-miner/lib/cross-repo-evaluation.js b/packages/loopover-miner/lib/cross-repo-evaluation.js index a726c9de60..c1afb90201 100644 --- a/packages/loopover-miner/lib/cross-repo-evaluation.js +++ b/packages/loopover-miner/lib/cross-repo-evaluation.js @@ -313,13 +313,20 @@ function firstOutputLine(output) { const line = output.split("\n").find((l) => l.trim().length > 0)?.trim() ?? ""; return line.length > 200 ? `${line.slice(0, 200)}…` : line; } -/** Real default local-command runner: a synchronous `sh -c` in the clone dir, resolve-not-throw so a non-zero - * exit becomes `ok: false` with its captured output rather than an exception (#7634). */ -function defaultRunLocalCommand(command, context) { - const result = spawnSync("sh", ["-c", command], { +/** Real default local-command runner: split the detected command into an argv and spawn it directly in the clone + * dir with NO shell (`shell: false`), so shell metacharacters in untrusted repo metadata (e.g. a crafted + * package.json script name) cannot inject extra commands (#7641). Stack commands are plain whitespace-separated + * argv (`npm run build`, `cargo test`, `go build ./...`). Resolve-not-throw: a non-zero exit becomes `ok: false` + * with its captured output rather than an exception (#7634). Exported for direct unit coverage. */ +export function defaultRunLocalCommand(command, context, spawn = spawnSync) { + const [file, ...args] = command.trim().split(/\s+/).filter(Boolean); + if (!file) + return { ok: false, code: null, output: "empty command" }; + const result = spawn(file, args, { cwd: context.cwd, env: context.env ?? process.env, encoding: "utf8", + shell: false, }); const output = `${result.stdout ?? ""}${result.stderr ?? ""}`; if (result.error) { @@ -493,4 +500,4 @@ export function formatCrossRepoEvaluationReport(results, summary = summarizeCros } return lines.join("\n"); } -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3Jvc3MtcmVwby1ldmFsdWF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY3Jvc3MtcmVwby1ldmFsdWF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlIQUFpSDtBQUNqSCw4R0FBOEc7QUFDOUcsMkdBQTJHO0FBQzNHLDZHQUE2RztBQUM3RyxxR0FBcUc7QUFFckcsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFckMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLG1CQUFtQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDMUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBR3ZEO29HQUNvRztBQUNwRyxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FVbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNqQixlQUFlLEVBQUUscUJBQXFCO0lBQ3RDLFNBQVMsRUFBRSxlQUFlO0lBQzFCLG9CQUFvQixFQUFFLHFCQUFxQjtJQUMzQyxXQUFXLEVBQUUsYUFBYTtJQUMxQix5R0FBeUc7SUFDekcsMkdBQTJHO0lBQzNHLHNEQUFzRDtJQUN0RCxpQkFBaUIsRUFBRSxtQkFBbUI7SUFDdEMsaUJBQWlCLEVBQUUsdUJBQXVCO0lBQzFDLGNBQWMsRUFBRSx3QkFBd0I7SUFDeEMsY0FBYyxFQUFFLHFCQUFxQjtJQUNyQyxLQUFLLEVBQUUsT0FBTztDQUNmLENBQUMsQ0FBQztBQUVIO21HQUNtRztBQUNuRyxNQUFNLENBQUMsTUFBTSxvQ0FBb0MsR0FBbUQsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNoSCxFQUFFLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUs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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3Jvc3MtcmVwby1ldmFsdWF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY3Jvc3MtcmVwby1ldmFsdWF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlIQUFpSDtBQUNqSCw4R0FBOEc7QUFDOUcsMkdBQTJHO0FBQzNHLDZHQUE2RztBQUM3RyxxR0FBcUc7QUFFckcsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFckMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLG1CQUFtQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDMUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBR3ZEO29HQUNvRztBQUNwRyxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FVbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNqQixlQUFlLEVBQUUscUJBQXFCO0lBQ3RDLFNBQVMsRUFBRSxlQUFlO0lBQzFCLG9CQUFvQixFQUFFLHFCQUFxQjtJQUMzQyxXQUFXLEVBQUUsYUFBYTtJQUMxQix5R0FBeUc7SUFDekcsMkdBQTJHO0lBQzNHLHNEQUFzRDtJQUN0RCxpQkFBaUIsRUFBRSxtQkFBbUI7SUFDdEMsaUJBQWlCLEVBQUUsdUJBQXVCO0lBQzFDLGNBQWMsRUFBRSx3QkFBd0I7SUFDeEMsY0FBYyxFQUFFLHFCQUFxQjtJQUNyQyxLQUFLLEVBQUUsT0FBTztDQUNmLENBQUMsQ0FBQztBQUVIO21HQUNtRztBQUNuRyxNQUFNLENBQUMsTUFBTSxvQ0FBb0MsR0FBbUQsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUNoSCxFQUFFLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUs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 \ No newline at end of file diff --git a/packages/loopover-miner/lib/cross-repo-evaluation.ts b/packages/loopover-miner/lib/cross-repo-evaluation.ts index cfc0726c82..cfca89a74c 100644 --- a/packages/loopover-miner/lib/cross-repo-evaluation.ts +++ b/packages/loopover-miner/lib/cross-repo-evaluation.ts @@ -483,16 +483,23 @@ function firstOutputLine(output: string | undefined): string { return line.length > 200 ? `${line.slice(0, 200)}…` : line; } -/** Real default local-command runner: a synchronous `sh -c` in the clone dir, resolve-not-throw so a non-zero - * exit becomes `ok: false` with its captured output rather than an exception (#7634). */ -function defaultRunLocalCommand( +/** Real default local-command runner: split the detected command into an argv and spawn it directly in the clone + * dir with NO shell (`shell: false`), so shell metacharacters in untrusted repo metadata (e.g. a crafted + * package.json script name) cannot inject extra commands (#7641). Stack commands are plain whitespace-separated + * argv (`npm run build`, `cargo test`, `go build ./...`). Resolve-not-throw: a non-zero exit becomes `ok: false` + * with its captured output rather than an exception (#7634). Exported for direct unit coverage. */ +export function defaultRunLocalCommand( command: string, context: { cwd: string; env?: NodeJS.ProcessEnv }, + spawn: typeof spawnSync = spawnSync, ): LocalCommandResult { - const result = spawnSync("sh", ["-c", command], { + const [file, ...args] = command.trim().split(/\s+/).filter(Boolean); + if (!file) return { ok: false, code: null, output: "empty command" }; + const result = spawn(file, args, { cwd: context.cwd, env: context.env ?? process.env, encoding: "utf8", + shell: false, }); const output = `${result.stdout ?? ""}${result.stderr ?? ""}`; if (result.error) { diff --git a/test/unit/miner-cross-repo-evaluation.test.ts b/test/unit/miner-cross-repo-evaluation.test.ts index 50743ebfd8..1a738296c2 100644 --- a/test/unit/miner-cross-repo-evaluation.test.ts +++ b/test/unit/miner-cross-repo-evaluation.test.ts @@ -11,6 +11,7 @@ import { CROSS_REPO_FAILURE_CATEGORY, DEFAULT_CROSS_REPO_MANIFEST_RELATIVE_PATH, MAX_CROSS_REPO_MANIFEST_BYTES, + defaultRunLocalCommand, executeRepoAttempt, formatCrossRepoEvaluationReport, evaluateRepoReadiness, @@ -762,6 +763,57 @@ describe("cross-repo evaluation harness (#4788)", () => { expect(calls[1]).toEqual(["git", "--no-pager", "diff", "--cached"]); }); + it("defaultRunLocalCommand spawns the argv directly with no shell (no `sh -c` injection surface)", () => { + let seen: { file: string; args: string[]; opts: Record } | null = null; + const fakeSpawn = ((file: string, args: string[], opts: Record) => { + seen = { file, args, opts }; + return { stdout: "out", stderr: "err", status: 0 }; + }) as never; + + const result = defaultRunLocalCommand("npm run build", { cwd: "/clone", env: { FOO: "1" } }, fakeSpawn); + + expect(result).toEqual({ ok: true, code: 0, output: "outerr" }); + // The command must be split into a real argv and run WITHOUT a shell — never `sh -c ""`. + expect(seen!.file).toBe("npm"); + expect(seen!.args).toEqual(["run", "build"]); + expect(seen!.opts.shell).toBe(false); + expect(seen!.opts.cwd).toBe("/clone"); + expect(seen!.opts.env).toEqual({ FOO: "1" }); + }); + + it("defaultRunLocalCommand keeps a crafted script name as an inert argv token (no metacharacter injection)", () => { + let seen: { file: string; args: string[] } | null = null; + const fakeSpawn = ((file: string, args: string[]) => { + seen = { file, args }; + return { status: 1 }; + }) as never; + + // A malicious repo whose build script is named `build; rm -rf ~` would inject via `sh -c`; here it stays one token. + const result = defaultRunLocalCommand("npm run build;rm", { cwd: "/clone" }, fakeSpawn); + + // Missing stdout/stderr default to empty; a non-zero exit resolves to ok:false rather than throwing. + expect(result).toEqual({ ok: false, code: 1, output: "" }); + expect(seen!.file).toBe("npm"); + expect(seen!.args).toEqual(["run", "build;rm"]); + }); + + it("defaultRunLocalCommand surfaces a spawn error as ok:false with the error message", () => { + const fakeSpawn = (() => ({ error: new Error("spawn ENOENT") })) as never; + const result = defaultRunLocalCommand("cargo build", { cwd: "/clone" }, fakeSpawn); + expect(result).toEqual({ ok: false, code: null, output: "spawn ENOENT" }); + }); + + it("defaultRunLocalCommand rejects an empty command without spawning anything", () => { + let spawned = false; + const fakeSpawn = (() => { + spawned = true; + return { status: 0 }; + }) as never; + const result = defaultRunLocalCommand(" ", { cwd: "/clone" }, fakeSpawn); + expect(result).toEqual({ ok: false, code: null, output: "empty command" }); + expect(spawned).toBe(false); + }); + it("runCrossRepoExecutionCli drives a fixture manifest with injected primitives", async () => { const repoPath = nodeRepo(); const manifestDir = tempRepo();