Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 64 additions & 3 deletions packages/loopover-miner/docs/cross-repo-evaluation.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,53 @@ fleet run-manifest).
- `--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 mode (#7634)

Readiness answers *“can the miner form a plan for this repo?”*. **Full-execution** goes one step further and answers
*“does the miner actually produce working, correct code?”* by running the discover → plan → code → test loop against
each benchmark repo: it drives the configured coding agent to generate a **real diff**, then runs that target repo's
**own test suite** locally against the edited clone.

It is **dry-run only**. The agent really edits the local clone (that is the only way to produce a diff), but the
harness hard-resets the clone back to `HEAD` afterward — it **never opens a PR, never pushes, and never touches the
third-party repo remotely**. It needs nothing beyond a local clone and a configured coding-agent driver; no write
access or forge credentials are required.

### Running it

```bash
node packages/loopover-miner/scripts/cross-repo-evaluation.mjs --full-execution
```

Combinable with the readiness flags: `--repo owner/repo`, `--json`, `--manifest path/to/manifest.json`, and
`--require-majority`.

Prerequisites:

- **Cloned benchmark repos** in `LOOPOVER_MINER_REPO_CLONE_DIR` (same as readiness — see
[Running locally](#running-locally)).
- **A configured coding-agent driver** via `MINER_CODING_AGENT_PROVIDER` plus that provider's credentials — the same
requirement a real attempt has. Without a configured driver, each repo reports an `other` execution failure (no diff
can be generated).

### Execution failure taxonomy

Failures are categorized under `CROSS_REPO_EXECUTION_CATEGORY`, extending the readiness taxonomy for the code + test
loop:

| Category | Meaning |
| --- | --- |
| `plan_not_formed` | Readiness failed — the miner couldn't even form a plan for the repo |
| `code_build_failed` | Plan formed and the agent produced a diff, but the code didn't compile/build |
| `tests_failed` | Code compiled but the target repo's own tests failed |
| `no_op_diff` | Tests passed but the agent's diff was empty (no real change — a trivial pass) |
| `clone_setup` | The repo isn't cloned to the expected path |
| `other` | Unexpected error (e.g. no coding-agent driver configured, no inferred test command, agent crashed) |

The stages run **in order** — plan → code → build → tests → no-op check — so a repo that fails an earlier stage is
reported against that stage (e.g. a repo that never forms a plan reports `plan_not_formed` and the build/test stages
never run).

## Library API

Pure functions live in [`lib/cross-repo-evaluation.js`](../lib/cross-repo-evaluation.js):
Expand All @@ -71,8 +118,22 @@ Pure functions live in [`lib/cross-repo-evaluation.js`](../lib/cross-repo-evalua
- `summarizeCrossRepoEvaluation(results)`
- `formatCrossRepoEvaluationReport(results, summary)`

Full-execution mode (#7634) adds:

- `evaluateRepoFullExecution(entry, options)` — async; inject the `runAgentAttempt`, `buildRepo`, and `runRepoTests`
seams for unit tests
- `runFullCrossRepoExecution(parsed, options)` — async
- `summarizeCrossRepoExecution(results)`
- `formatCrossRepoExecutionReport(results, summary)`

## 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 harness has **two modes**, and **neither** opens a live PR or performs any forge writes:

- **Readiness-only** (default): 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.
- **Dry-run full-execution** (`--full-execution`, #7634): it runs the coding agent and the target repo's own tests
against a local clone, then hard-resets the clone — still no live PR and no forge writes.

A live attempt still needs credentials, governor policy, and queue state as documented in
[`DEPLOYMENT.md`](../DEPLOYMENT.md).
72 changes: 70 additions & 2 deletions packages/loopover-miner/lib/cross-repo-evaluation.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export type CrossRepoEvaluationSummary = {
withoutLoopoverConfig: number;
failuresByCategory: Record<string, number>;
};
type EvaluateRepoReadinessOptions = {
export type EvaluateRepoReadinessOptions = {
repoPath?: string;
resolveRepoPath?: (entry: {
repoFullName: string;
Expand Down Expand Up @@ -100,4 +100,72 @@ export declare function summarizeCrossRepoEvaluation(results: CrossRepoEvaluatio
* Human-readable pass/fail report for one evaluation run (#4788).
*/
export declare function formatCrossRepoEvaluationReport(results: CrossRepoEvaluationResult[], summary?: CrossRepoEvaluationSummary): string;
export {};
/** Execution-stage failure taxonomy (#7634): extends the readiness taxonomy for the code + test loop. Ordered by
* pipeline stage, so a repo that fails an earlier stage is reported against that stage. */
export declare const CROSS_REPO_EXECUTION_CATEGORY: Readonly<{
PLAN_NOT_FORMED: "plan_not_formed";
CODE_BUILD_FAILED: "code_build_failed";
TESTS_FAILED: "tests_failed";
NO_OP_DIFF: "no_op_diff";
CLONE_SETUP: "clone_setup";
OTHER: "other";
}>;
export type CrossRepoExecutionResult = {
repoFullName: string;
passed: boolean;
executionCategory: string | null;
reason: string | null;
readinessPassed: boolean;
diffPresent: boolean | null;
built: boolean | null;
testsPassed: boolean | null;
stack?: RepoStackResult | undefined;
};
export type CrossRepoExecutionSummary = {
total: number;
passed: number;
failed: number;
majorityPassed: boolean;
failuresByCategory: Record<string, number>;
};
/** Injectable local-execution seams (#7634). Real implementations (child_process build/test, the coding-agent
* driver) are wired by the CLI; unit tests inject fakes. Every seam is dry-run: it operates on the local clone
* only, and the harness never pushes or opens a PR. */
export type CrossRepoExecutionSeams = {
runAgentAttempt?: (context: {
repoFullName: string;
repoPath: string;
stack: RepoStackResult;
}) => Promise<{
diff: string;
}>;
buildRepo?: (context: {
repoPath: string;
command: string;
}) => Promise<{
ok: boolean;
detail?: string;
}>;
runRepoTests?: (context: {
repoPath: string;
command: string;
}) => Promise<{
ok: boolean;
detail?: string;
}>;
};
export type EvaluateRepoFullExecutionOptions = EvaluateRepoReadinessOptions & CrossRepoExecutionSeams;
/**
* Run the full discover -> plan -> code -> test loop for one benchmark repo in dry-run (#7634). Reuses
* evaluateRepoReadiness for the plan stage, then delegates the code + build + test steps to injectable seams so the
* orchestration + taxonomy stay unit-testable without a live coding agent. Never pushes or opens a PR.
*/
export declare function evaluateRepoFullExecution(entry: CrossRepoEvaluationManifestRepo, options?: EvaluateRepoFullExecutionOptions): Promise<CrossRepoExecutionResult>;
/** Run full-execution across every repo in a parsed manifest (#7634). Async: each repo runs the real code+test loop. */
export declare function runFullCrossRepoExecution(parsed: ParsedCrossRepoEvaluationManifest, options?: {
repoFilter?: string;
} & EvaluateRepoFullExecutionOptions): Promise<CrossRepoExecutionResult[]>;
/** Reduce full-execution results to pass/fail counts + a strict-majority verdict (#7634). */
export declare function summarizeCrossRepoExecution(results: CrossRepoExecutionResult[]): CrossRepoExecutionSummary;
/** Human-readable full-execution report (#7634), mirroring formatCrossRepoEvaluationReport's shape. */
export declare function formatCrossRepoExecutionReport(results: CrossRepoExecutionResult[], summary?: CrossRepoExecutionSummary): string;
157 changes: 156 additions & 1 deletion packages/loopover-miner/lib/cross-repo-evaluation.js

Large diffs are not rendered by default.

Loading