@bradtaylorsf/alpha-loop 1.13.1 → 1.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +99 -1
  2. package/dist/cli.js +40 -2
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/eval.d.ts +22 -0
  5. package/dist/commands/eval.js +105 -1
  6. package/dist/commands/eval.js.map +1 -1
  7. package/dist/commands/evolve-routing.d.ts +24 -0
  8. package/dist/commands/evolve-routing.js +320 -0
  9. package/dist/commands/evolve-routing.js.map +1 -0
  10. package/dist/commands/history.d.ts +2 -0
  11. package/dist/commands/history.js +95 -1
  12. package/dist/commands/history.js.map +1 -1
  13. package/dist/commands/init.d.ts +6 -0
  14. package/dist/commands/init.js +28 -1
  15. package/dist/commands/init.js.map +1 -1
  16. package/dist/commands/report.d.ts +7 -0
  17. package/dist/commands/report.js +27 -0
  18. package/dist/commands/report.js.map +1 -0
  19. package/dist/commands/run.d.ts +16 -0
  20. package/dist/commands/run.js +265 -36
  21. package/dist/commands/run.js.map +1 -1
  22. package/dist/commands/scan.d.ts +1 -1
  23. package/dist/commands/scan.js.map +1 -1
  24. package/dist/engine/agents.d.ts +30 -8
  25. package/dist/engine/agents.js +94 -10
  26. package/dist/engine/agents.js.map +1 -1
  27. package/dist/engine/prerequisites.d.ts +40 -2
  28. package/dist/engine/prerequisites.js +126 -2
  29. package/dist/engine/prerequisites.js.map +1 -1
  30. package/dist/lib/agent.d.ts +39 -2
  31. package/dist/lib/agent.js +106 -4
  32. package/dist/lib/agent.js.map +1 -1
  33. package/dist/lib/config.d.ts +78 -1
  34. package/dist/lib/config.js +217 -1
  35. package/dist/lib/config.js.map +1 -1
  36. package/dist/lib/epics.d.ts +57 -0
  37. package/dist/lib/epics.js +76 -0
  38. package/dist/lib/epics.js.map +1 -0
  39. package/dist/lib/escalation.d.ts +102 -0
  40. package/dist/lib/escalation.js +241 -0
  41. package/dist/lib/escalation.js.map +1 -0
  42. package/dist/lib/eval-matrix.d.ts +125 -0
  43. package/dist/lib/eval-matrix.js +317 -0
  44. package/dist/lib/eval-matrix.js.map +1 -0
  45. package/dist/lib/eval-report.d.ts +12 -0
  46. package/dist/lib/eval-report.js +132 -0
  47. package/dist/lib/eval-report.js.map +1 -0
  48. package/dist/lib/eval-secret-scan.d.ts +41 -0
  49. package/dist/lib/eval-secret-scan.js +163 -0
  50. package/dist/lib/eval-secret-scan.js.map +1 -0
  51. package/dist/lib/eval.js +7 -4
  52. package/dist/lib/eval.js.map +1 -1
  53. package/dist/lib/github.d.ts +25 -0
  54. package/dist/lib/github.js +75 -0
  55. package/dist/lib/github.js.map +1 -1
  56. package/dist/lib/hardware.d.ts +9 -0
  57. package/dist/lib/hardware.js +32 -0
  58. package/dist/lib/hardware.js.map +1 -0
  59. package/dist/lib/pipeline.d.ts +6 -1
  60. package/dist/lib/pipeline.js +223 -19
  61. package/dist/lib/pipeline.js.map +1 -1
  62. package/dist/lib/prerequisites.js +11 -3
  63. package/dist/lib/prerequisites.js.map +1 -1
  64. package/dist/lib/routing-history.d.ts +43 -0
  65. package/dist/lib/routing-history.js +112 -0
  66. package/dist/lib/routing-history.js.map +1 -0
  67. package/dist/lib/routing-promotion.d.ts +95 -0
  68. package/dist/lib/routing-promotion.js +229 -0
  69. package/dist/lib/routing-promotion.js.map +1 -0
  70. package/dist/lib/session.d.ts +10 -1
  71. package/dist/lib/session.js +38 -7
  72. package/dist/lib/session.js.map +1 -1
  73. package/dist/lib/telemetry.d.ts +147 -0
  74. package/dist/lib/telemetry.js +353 -0
  75. package/dist/lib/telemetry.js.map +1 -0
  76. package/dist/lib/verify-epic.d.ts +31 -0
  77. package/dist/lib/verify-epic.js +237 -0
  78. package/dist/lib/verify-epic.js.map +1 -0
  79. package/package.json +1 -1
package/README.md CHANGED
@@ -135,6 +135,15 @@ alpha-loop eval estimate
135
135
 
136
136
  # Compare two config files side-by-side
137
137
  alpha-loop eval compare-configs config-a.yaml config-b.yaml
138
+
139
+ # Apply a single routing profile before running
140
+ alpha-loop eval run --profile hybrid-v1
141
+
142
+ # Matrix run: replay the routing-regression set under every profile and emit a side-by-side report
143
+ # Defaults to a dry-run (validates profiles and case structure). Pass --execute to run pipelines for real.
144
+ alpha-loop eval run --matrix --tags routing-regression
145
+ alpha-loop eval run --matrix --profiles "all-frontier,hybrid-v1" --out eval/reports
146
+ alpha-loop eval run --matrix --tags routing-regression --execute # real runs (see CASE_FORMAT.md)
138
147
  ```
139
148
 
140
149
  Eval cases live in `.alpha-loop/evals/` and scores are appended to `scores.jsonl` (Git-friendly, append-only). The composite score formula is pass-rate primary with lightweight penalties for retries and duration. Real API costs (tokens, USD) are tracked per case from agent output and used for the Pareto frontier.
@@ -170,6 +179,20 @@ alpha-loop evolve --resume # Resume from a previous evolve sessio
170
179
  alpha-loop evolve --dry-run # Preview without changes
171
180
  ```
172
181
 
182
+ #### Routing promotion/demotion (`alpha-loop evolve routing`)
183
+
184
+ Propose per-stage routing changes (frontier → local, or revert to fallback) as draft PRs, based on the metrics aggregated by `alpha-loop report routing` plus the matrix eval.
185
+
186
+ A stage is promoted to its local candidate when (over ≥30 runs): cost-per-issue savings ≥ 40%, pipeline success delta ≥ −3%, and tool-error rate < 2%. Promotions require a matrix eval run within the last 7 days (`alpha-loop eval --matrix --execute`).
187
+
188
+ ```bash
189
+ alpha-loop evolve routing # Propose promotions as a draft PR
190
+ alpha-loop evolve routing --dry-run # Preview without writing config
191
+ alpha-loop evolve routing --demote build # Manually revert a stage to fallback
192
+ ```
193
+
194
+ Every promotion/demotion is appended to `.alpha-loop/learnings/routing-history.md`. PR bodies include a `git revert` rollback snippet plus the previous YAML fragment.
195
+
173
196
  ### Batch Mode
174
197
 
175
198
  By default, Alpha Loop processes issues one at a time — each issue gets its own plan, implement, test, and review agent calls. Batch mode combines multiple issues into single agent calls, dramatically reducing overhead:
@@ -229,13 +252,17 @@ During live verification, the agent takes screenshots at key states and saves th
229
252
  | `alpha-loop init` | Full onboarding: config, templates, vision, scan, sync, commit |
230
253
  | `alpha-loop run` | Fetch matching issues, process them all, then exit |
231
254
  | `alpha-loop run --dry-run` | Preview without making changes |
255
+ | `alpha-loop run --epic <N>` | Process an epic — its sub-issues in checklist order, auto-verify on completion (see [docs/epics.md](docs/epics.md)) |
256
+ | `alpha-loop run --verify-only <N>` | Run just the epic verification pass — evaluates merged PRs against acceptance criteria |
232
257
  | `alpha-loop scan` | Generate/refresh project context and instructions file |
233
258
  | `alpha-loop vision` | **(deprecated)** Use `alpha-loop plan` instead |
234
259
  | `alpha-loop auth` | Save authenticated browser state for verification |
235
260
  | `alpha-loop history` | View session history |
236
261
  | `alpha-loop history <name>` | View a specific session |
237
262
  | `alpha-loop history <name> --qa` | Show QA checklist for session |
263
+ | `alpha-loop history <name> --telemetry` | Show per-stage telemetry table (see [docs/telemetry.md](docs/telemetry.md)) |
238
264
  | `alpha-loop history --clean` | Remove old session data |
265
+ | `alpha-loop report routing` | Aggregate per-stage telemetry + cost-per-issue across sessions |
239
266
  | `alpha-loop sync` | Sync templates to configured harnesses (Claude, Codex, Cursor, etc.) |
240
267
  | `alpha-loop resume` | Resume stranded work — push branches, review, open PRs |
241
268
  | `alpha-loop resume --issue <N>` | Resume a specific issue |
@@ -255,6 +282,8 @@ During live verification, the agent takes screenshots at key states and saves th
255
282
  | `alpha-loop eval import-swebench` | Import eval cases from SWE-bench dataset |
256
283
  | `alpha-loop eval export <case>` | Export an eval case for contributing back (anonymized by default) |
257
284
  | `alpha-loop evolve` | Meta-Harness-style automated optimization loop |
285
+ | `alpha-loop evolve routing` | Propose routing promotions/demotions as draft PRs based on eval metrics |
286
+ | `alpha-loop evolve routing --demote <stage>` | Manually demote a stage to routing.fallback.escalate_to |
258
287
  | `alpha-loop plan` | Generate a full project scope (milestones + issues) from seed inputs using AI |
259
288
  | `alpha-loop plan --seed <file>` | Read seed description from a file instead of prompting |
260
289
  | `alpha-loop plan --dry-run` | Display the plan without creating any GitHub resources |
@@ -283,6 +312,9 @@ Options:
283
312
  --merge-to <branch> Use an existing branch instead of creating a new session branch
284
313
  --batch Batch mode: process multiple issues per agent call (faster, fewer tokens)
285
314
  --batch-size <n> Issues per batch (default: 5)
315
+ --epic <n> Process a specific epic by issue number (skips the picker)
316
+ --skip-epic Skip the epic picker, use flat/milestone flow
317
+ --verify-only <n> Run only the verification pass on an existing epic
286
318
  ```
287
319
 
288
320
  ## Configuration
@@ -293,7 +325,7 @@ Running `alpha-loop init` creates a `.alpha-loop.yaml` file:
293
325
  # Alpha Loop configuration
294
326
  repo: owner/repo-name
295
327
  project: 0 # GitHub Project number (find it in your project URL)
296
- agent: claude # AI agent CLI: claude, codex, opencode
328
+ agent: claude # AI agent CLI: claude, codex, opencode, lmstudio, ollama
297
329
  # model: # omit to use agent's default (e.g., opus, gpt-5.4)
298
330
  label: ready
299
331
  base_branch: main
@@ -461,6 +493,51 @@ pipeline:
461
493
 
462
494
  Use `alpha-loop eval search` to automatically find the best model assignment per step via greedy coordinate descent over your eval suite.
463
495
 
496
+ ### Per-Stage Routing
497
+
498
+ For hybrid cloud/local setups, use `routing:` to target different models and endpoints for each Loop stage. This is how you offload token-heavy middle stages (Build, Test) to local open-weight models while keeping frontier models for Plan and Review:
499
+
500
+ ```yaml
501
+ routing:
502
+ profile: hybrid-v1 # all-frontier | hybrid-v1 | all-local | <custom-name>
503
+ stages:
504
+ plan: { model: claude-opus-4-7, endpoint: anthropic }
505
+ build: { model: qwen3-coder-30b-a3b, endpoint: lmstudio_local }
506
+ test_write: { model: qwen3-coder-30b-a3b, endpoint: lmstudio_local }
507
+ test_exec: { model: qwen3-coder-30b-a3b, endpoint: lmstudio_local }
508
+ review: { model: claude-sonnet-4-6, endpoint: anthropic }
509
+ summary: { model: gemma-4-31b, endpoint: lmstudio_local }
510
+ endpoints:
511
+ anthropic: { type: anthropic, base_url: "https://api.anthropic.com" }
512
+ lmstudio_local: { type: anthropic_compat, base_url: "http://localhost:1234" }
513
+ ollama_local: { type: openai_compat, base_url: "http://localhost:11434/v1" }
514
+ fallback:
515
+ on_tool_error: escalate # escalate | retry | fail
516
+ escalate_to: { model: claude-sonnet-4-6, endpoint: anthropic }
517
+ ```
518
+
519
+ **Stages:** `plan`, `build`, `test_write`, `test_exec`, `review`, `summary` — each takes `{ model, endpoint }` where `endpoint` references a name defined in `routing.endpoints`.
520
+
521
+ **Endpoint types:** `anthropic` (native Anthropic API), `anthropic_compat` (Anthropic-compatible — e.g. LM Studio), or `openai_compat` (OpenAI-compatible — e.g. Ollama, vLLM). See [docs/local-models.md](docs/local-models.md) for LM Studio and Ollama setup, including the `agent: lmstudio` / `agent: ollama` short form for single-agent local mode.
522
+
523
+ **Fallback modes:**
524
+ - `escalate` — when a routed stage errors on a tool call, retry on `escalate_to` (typically a frontier model)
525
+ - `retry` — retry on the same model/endpoint
526
+ - `fail` — surface the error without retry
527
+
528
+ **Profile as a list (A/B):** `profile` may also be an array of names (e.g. `[hybrid-v1, all-local]`). Alpha Loop picks one deterministically per-issue so reruns of the same issue select the same profile — this makes profile comparisons reproducible.
529
+
530
+ **Backwards compatibility:** If you don't set `routing`, alpha-loop uses the top-level `agent:` / `model:` / `pipeline:` exactly as before — no behavior change.
531
+
532
+ ### Local Model Support
533
+
534
+ Alpha Loop can run the token-heavy middle of the Loop (Build, Test) against an open-weight coding model on your own machine — typically a 30B-class model in LM Studio or Ollama — while keeping frontier models for Plan and Review. On a 64GB+ Apple Silicon Mac this typically cuts cost-per-issue by 60–80% without sacrificing Plan/Review quality.
535
+
536
+ - [docs/local-models.md](docs/local-models.md) — hardware prerequisites, install steps for LM Studio 0.4.1+ / Ollama, recommended models (Qwen3-Coder-Next 30B-A3B, Gemma 4 31B, GLM-4.6), Apple Silicon tuning, and troubleshooting.
537
+ - [docs/routing-profiles.md](docs/routing-profiles.md) — copy-pasteable profiles: `all-frontier` (baseline), `hybrid-v1` (recommended default), `all-local` (offline / zero-cost), `budget-hawk` (Haiku cloud + local coder).
538
+
539
+ Quickest path: install LM Studio 0.4.1+, load `qwen3-coder-30b-a3b`, then drop the `hybrid-v1` block from [docs/routing-profiles.md](docs/routing-profiles.md) into your `.alpha-loop.yaml`. `alpha-loop init` detects Apple Silicon + 64GB+ RAM and points you at these docs automatically.
540
+
464
541
  ## GitHub Setup
465
542
 
466
543
  ### Labels
@@ -480,6 +557,27 @@ Use GitHub milestones to group issues into planned releases or sprints. When you
480
557
 
481
558
  Create milestones at `github.com/<owner>/<repo>/milestones/new`. Set due dates to keep yourself on track.
482
559
 
560
+ ### Epics
561
+
562
+ An epic is a GitHub issue with the `epic` label and a task-list body that references sub-issues by number:
563
+
564
+ ```markdown
565
+ ## Sub-issues
566
+ - [ ] #158 Add tenant column to users table
567
+ - [ ] #159 Add tenant middleware
568
+ - [ ] #160 Scope queries by tenant
569
+ ```
570
+
571
+ When you start the loop, open epics appear above milestones in the picker. You can also target one directly:
572
+
573
+ ```bash
574
+ alpha-loop run --epic 165
575
+ ```
576
+
577
+ Sub-issues are processed in checklist order (not issue-number order). Each sub-issue PR gets `Part of #165` appended, and the epic body's checkboxes auto-flip from `- [ ]` to `- [x]` as PRs merge. When every sub-issue has shipped, the loop runs a verification pass against each sub-issue's acceptance criteria — on `pass` the epic is auto-closed, on `partial` or `fail` it stays open with a `needs-human-input` label and a structured comment explaining the gaps.
578
+
579
+ See [docs/epics.md](docs/epics.md) for the full feature reference, including `--verify-only`, the `prefer_epics` config option, skip rules, and safety rails.
580
+
483
581
  ### GitHub Project Board
484
582
 
485
583
  Alpha Loop reads issues from a GitHub Project board (v2). Issues are processed in board order, so you control priority by reordering. When combined with milestones, only "Todo" items in the selected milestone are processed.
package/dist/cli.js CHANGED
@@ -8,7 +8,7 @@ import { syncCommand } from './commands/sync.js';
8
8
  program
9
9
  .name('alpha-loop')
10
10
  .description('Agent-agnostic automated development loop')
11
- .version('1.13.1');
11
+ .version('1.14.1');
12
12
  program
13
13
  .command('init')
14
14
  .description('Full project onboarding: config, templates, vision, scan, sync')
@@ -33,6 +33,9 @@ program
33
33
  .option('--validate', 'Run pre-session validation on all queued issues before processing')
34
34
  .option('--fix', 'Auto-fix validation issues (reorder deps, comment on incomplete issues)')
35
35
  .option('--verbose', 'Stream live agent output to terminal')
36
+ .option('--epic <n>', 'Process a specific epic by issue number (skips the picker)', parseInt)
37
+ .option('--skip-epic', 'Skip the epic picker, use flat/milestone flow')
38
+ .option('--verify-only <n>', 'Run only the verification pass on an existing epic', parseInt)
36
39
  .action(async (options) => {
37
40
  const { runCommand } = await import('./commands/run.js');
38
41
  if (options.once)
@@ -44,7 +47,22 @@ program
44
47
  .description('View session history')
45
48
  .option('--qa', 'Show QA checklist for session')
46
49
  .option('--clean', 'Remove old session data')
50
+ .option('--telemetry', 'Show per-stage telemetry for a session')
47
51
  .action(historyCommand);
52
+ // Report subcommands — routing A/B analysis, cost-per-issue rollups.
53
+ const reportCmd = program
54
+ .command('report')
55
+ .description('Generate cross-session reports (routing, cost, telemetry)');
56
+ reportCmd
57
+ .command('routing')
58
+ .description('Aggregate per-stage telemetry and cost-per-issue across sessions')
59
+ .option('--profile <name>', 'Filter to entries with this routing profile')
60
+ .option('--since <duration>', 'Limit window (e.g. 30d, 12h, 45m)')
61
+ .option('--json', 'Emit machine-readable JSON instead of a table')
62
+ .action(async (options) => {
63
+ const { reportRoutingCommand } = await import('./commands/report.js');
64
+ reportRoutingCommand(options);
65
+ });
48
66
  program
49
67
  .command('scan')
50
68
  .description('Generate/refresh project context')
@@ -143,6 +161,12 @@ evalCmd
143
161
  .option('--type <type>', 'Filter by type: full or step')
144
162
  .option('--step <step>', 'Filter by pipeline step (plan, implement, test, test-fix, review, verify, learn, skill)')
145
163
  .option('--verbose', 'Show detailed output')
164
+ .option('--profile <name>', 'Apply a routing profile (name or path) before running')
165
+ .option('--matrix', 'Run every case under each profile and emit an A/B comparison report (dry-run by default)')
166
+ .option('--profiles <list>', 'Comma-separated profile names/paths for --matrix (default: all-frontier,hybrid-v1,all-local)')
167
+ .option('--baseline <name>', 'Baseline profile for delta computation (default: all-frontier)')
168
+ .option('--out <dir>', 'Output directory for matrix reports (default: eval/reports)')
169
+ .option('--execute', 'Actually run pipelines for --matrix (otherwise validates structure only; see CASE_FORMAT.md for why this is gated)')
146
170
  .action(async (options) => {
147
171
  const { evalRunCommand } = await import('./commands/eval.js');
148
172
  await evalRunCommand(options);
@@ -246,8 +270,13 @@ evalCmd
246
270
  const { evalConvertCommand } = await import('./commands/eval.js');
247
271
  evalConvertCommand(options);
248
272
  });
249
- program
273
+ // Evolve subcommands — `run` (default, Meta-Harness optimization) and
274
+ // `routing` (promotion/demotion automation, issue #163).
275
+ const evolveCmd = program
250
276
  .command('evolve')
277
+ .description('Automated optimization (prompts, skills, config, routing)');
278
+ evolveCmd
279
+ .command('run', { isDefault: true })
251
280
  .description('Meta-Harness-style automated optimization loop')
252
281
  .option('--max-iterations <n>', 'Maximum optimization iterations (default: 5)')
253
282
  .option('--continuous', 'Run until manually stopped (SIGINT)')
@@ -259,5 +288,14 @@ program
259
288
  const { evolveCommand } = await import('./commands/evolve.js');
260
289
  await evolveCommand(options);
261
290
  });
291
+ evolveCmd
292
+ .command('routing')
293
+ .description('Propose routing promotions/demotions as draft PRs based on eval metrics')
294
+ .option('--demote <stage>', 'Manually demote a stage to routing.fallback.escalate_to')
295
+ .option('--dry-run', 'Preview without writing config or opening a PR')
296
+ .action(async (options) => {
297
+ const { evolveRoutingCommand } = await import('./commands/evolve-routing.js');
298
+ await evolveRoutingCommand(options);
299
+ });
262
300
  program.parse();
263
301
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { Config } from '../lib/config.js';
1
2
  export type EvalOptions = {
2
3
  tags?: string;
3
4
  suite?: string;
@@ -5,6 +6,22 @@ export type EvalOptions = {
5
6
  type?: 'full' | 'step';
6
7
  step?: string;
7
8
  verbose?: boolean;
9
+ /** Single-profile run: apply this profile's overrides before the suite. */
10
+ profile?: string;
11
+ /** Multi-profile matrix run. */
12
+ matrix?: boolean;
13
+ /** Comma-separated profile names/paths for --matrix. Defaults to canonical three. */
14
+ profiles?: string;
15
+ /** Output directory for matrix reports. */
16
+ out?: string;
17
+ /** Baseline profile for delta computation (defaults to all-frontier). */
18
+ baseline?: string;
19
+ /**
20
+ * Opt in to actually running pipelines during a matrix run. Without this
21
+ * flag, --matrix validates profiles + case structure only. See
22
+ * evalMatrixCommand for why this is gated.
23
+ */
24
+ execute?: boolean;
8
25
  };
9
26
  export type EvalCaptureOptions = {
10
27
  issue?: string;
@@ -28,6 +45,11 @@ export type EvalSearchOptions = {
28
45
  * Run the eval suite.
29
46
  */
30
47
  export declare function evalRunCommand(options: EvalOptions): Promise<void>;
48
+ /**
49
+ * Run the matrix: every loaded case under every configured profile, then
50
+ * write markdown+CSV reports and print a summary.
51
+ */
52
+ export declare function evalMatrixCommand(options: EvalOptions, baseConfig: Config): Promise<void>;
31
53
  /**
32
54
  * Compare two eval runs.
33
55
  */
@@ -24,6 +24,11 @@ import { exportEvalCase } from '../lib/eval-export.js';
24
24
  import { listTraceSessions, listTraceIssues, readTraceMetadata, readTrace, } from '../lib/traces.js';
25
25
  import { runEvalSuite, estimateRunCost } from '../lib/eval-runner.js';
26
26
  import { resolveStepConfig } from '../lib/config.js';
27
+ import { runMatrix, loadProfileOverrides, applyProfileToConfig, profileDisplayName, } from '../lib/eval-matrix.js';
28
+ import { renderMatrixMarkdown, renderMatrixCsv } from '../lib/eval-report.js';
29
+ import { scanCaseDir, formatFindings } from '../lib/eval-secret-scan.js';
30
+ /** Canonical profiles the matrix run uses when --profiles isn't supplied. */
31
+ const DEFAULT_MATRIX_PROFILES = ['all-frontier', 'hybrid-v1', 'all-local'];
27
32
  /** Helper to ask a question via readline. */
28
33
  function ask(rl, question) {
29
34
  return new Promise((resolve) => {
@@ -34,7 +39,18 @@ function ask(rl, question) {
34
39
  * Run the eval suite.
35
40
  */
36
41
  export async function evalRunCommand(options) {
37
- const config = loadConfig();
42
+ let config = loadConfig();
43
+ // Matrix mode: branch to the matrix runner.
44
+ if (options.matrix) {
45
+ await evalMatrixCommand(options, config);
46
+ return;
47
+ }
48
+ // Single-profile mode: merge the profile's overrides before loading cases.
49
+ if (options.profile) {
50
+ const overrides = loadProfileOverrides(options.profile);
51
+ config = applyProfileToConfig(config, overrides);
52
+ log.info(`Using routing profile: ${profileDisplayName(options.profile)}`);
53
+ }
38
54
  // Map --suite to type filter
39
55
  let type = options.type;
40
56
  if (options.suite === 'step')
@@ -52,6 +68,9 @@ export async function evalRunCommand(options) {
52
68
  log.info(`Eval cases directory: ${evalsDir(undefined, config.evalDir)}`);
53
69
  return;
54
70
  }
71
+ // Secret scan — refuse to run if any case ships credentials.
72
+ if (!assertCasesSecretClean(config.evalDir))
73
+ return;
55
74
  log.step(`Running ${cases.length} eval case(s)...`);
56
75
  console.log('');
57
76
  for (const evalCase of cases) {
@@ -87,6 +106,91 @@ export async function evalRunCommand(options) {
87
106
  console.log(` Delta: ${arrow}${delta.toFixed(2)} (prev: ${previousScore.composite})`);
88
107
  }
89
108
  }
109
+ /**
110
+ * Scan all eval case directories for secrets. Returns true when the suite
111
+ * is clean and safe to run; false and prints findings when dirty.
112
+ */
113
+ function assertCasesSecretClean(evalDir) {
114
+ const casesDir = join(process.cwd(), evalDir, 'cases');
115
+ if (!existsSync(casesDir))
116
+ return true;
117
+ const findings = scanCaseDir(casesDir);
118
+ if (findings.length === 0)
119
+ return true;
120
+ log.error('Secret scan blocked the eval run:');
121
+ console.error(formatFindings(findings));
122
+ console.error('');
123
+ console.error('Redact the offending cases before re-running.');
124
+ return false;
125
+ }
126
+ /**
127
+ * Run the matrix: every loaded case under every configured profile, then
128
+ * write markdown+CSV reports and print a summary.
129
+ */
130
+ export async function evalMatrixCommand(options, baseConfig) {
131
+ const tags = options.tags?.split(',').map((t) => t.trim()).filter(Boolean) ?? ['routing-regression'];
132
+ const cases = loadEvalCases({ tags, caseId: options.case });
133
+ if (cases.length === 0) {
134
+ log.warn(`No eval cases found for tags: ${tags.join(', ')}.`);
135
+ log.info(`Cases directory: ${evalsDir(undefined, baseConfig.evalDir)}/cases/routing-regression/`);
136
+ return;
137
+ }
138
+ if (!assertCasesSecretClean(baseConfig.evalDir))
139
+ return;
140
+ const profiles = options.profiles
141
+ ? options.profiles.split(',').map((p) => p.trim()).filter(Boolean)
142
+ : DEFAULT_MATRIX_PROFILES;
143
+ const baseline = options.baseline ?? 'all-frontier';
144
+ // Gate real execution behind --execute. The eval pipeline currently calls
145
+ // processIssue(), which mutates live GitHub state (project board, labels,
146
+ // branches). Routing-regression case IDs like "001-…" parse back to real
147
+ // issue numbers on the active repo — running the matrix without isolation
148
+ // would update issue #1, #2, … and assign them to the current user.
149
+ // Fixture isolation (clean clone at source_pr's base_sha, no GH mutations)
150
+ // is follow-up work; until then dry-run is the safe default.
151
+ const dryRun = !options.execute;
152
+ log.step(`Matrix run: ${cases.length} case(s) × ${profiles.length} profile(s) [baseline=${baseline}]${dryRun ? ' (dry-run)' : ''}`);
153
+ for (const p of profiles)
154
+ console.log(` profile: ${profileDisplayName(p)}`);
155
+ if (dryRun) {
156
+ log.warn('Dry-run mode: profiles and cases are validated but no pipelines execute.');
157
+ log.warn('Pass --execute to run for real (requires fixture isolation; see CASE_FORMAT.md).');
158
+ }
159
+ console.log('');
160
+ const result = await runMatrix(cases.map((c) => c), { profiles, baseline, outDir: options.out, verbose: options.verbose, dryRun }, baseConfig);
161
+ // Write outputs
162
+ const outDir = options.out ?? join(process.cwd(), 'eval', 'reports');
163
+ const { mkdirSync: mkdir, writeFileSync: write } = await import('node:fs');
164
+ mkdir(outDir, { recursive: true });
165
+ const date = new Date().toISOString().slice(0, 10);
166
+ const mdPath = join(outDir, `routing-${date}.md`);
167
+ const csvPath = join(outDir, `routing-${date}.csv`);
168
+ write(mdPath, renderMatrixMarkdown(result));
169
+ write(csvPath, renderMatrixCsv(result));
170
+ // Print summary. In dry-run we deliberately avoid a "0/N pass" line so
171
+ // automated verifiers and humans don't read it as 17 real failures — the
172
+ // runner was never invoked.
173
+ console.log('');
174
+ log.step('Matrix summary:');
175
+ if (dryRun) {
176
+ for (const t of result.totals) {
177
+ console.log(` ${t.profile}: validated — ${t.caseCount} case(s) loaded, profile applied cleanly (no execution)`);
178
+ }
179
+ }
180
+ else {
181
+ for (const t of result.totals) {
182
+ const delta = result.deltas[t.profile];
183
+ const deltaStr = delta
184
+ ? ` (Δpass=${(delta.pipelineSuccessDelta * 100).toFixed(1)}pp, Δcost=$${delta.costPerIssueDelta.toFixed(3)})`
185
+ : '';
186
+ console.log(` ${t.profile}: ${t.passCount}/${t.caseCount} pass · $${t.totalCostUsd.toFixed(2)} total${deltaStr}`);
187
+ }
188
+ }
189
+ console.log('');
190
+ log.success(`Reports written:`);
191
+ log.info(` ${mdPath}`);
192
+ log.info(` ${csvPath}`);
193
+ }
90
194
  /**
91
195
  * Compare two eval runs.
92
196
  */