@velum-labs/routekit-eval-setup 1.3.2 → 1.5.0
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.
- package/dist/adapters/authoring-responses-request.d.ts +5 -0
- package/dist/adapters/authoring-responses-request.js +38 -0
- package/dist/adapters/evaluation-evidence-freshness.d.ts +7 -0
- package/dist/adapters/evaluation-evidence-freshness.js +76 -0
- package/dist/adapters/git-task-history.d.ts +67 -0
- package/dist/adapters/git-task-history.js +171 -0
- package/dist/adapters/integrated-repository-history.d.ts +21 -0
- package/dist/adapters/integrated-repository-history.js +175 -0
- package/dist/adapters/repository-command-diagnostic.d.ts +8 -0
- package/dist/adapters/repository-command-diagnostic.js +46 -0
- package/dist/adapters/repository-command-evidence.d.ts +13 -0
- package/dist/adapters/repository-command-evidence.js +102 -0
- package/dist/adapters/repository-command-runner.d.ts +238 -0
- package/dist/adapters/repository-command-runner.js +1483 -0
- package/dist/adapters/repository-import-context.d.ts +47 -0
- package/dist/adapters/repository-import-context.js +469 -0
- package/dist/adapters/repository-node-test-reporter.d.ts +3 -0
- package/dist/adapters/repository-node-test-reporter.js +27 -0
- package/dist/adapters/repository-review-evidence.d.ts +39 -0
- package/dist/adapters/repository-review-evidence.js +632 -0
- package/dist/adapters/repository-seed-selection.d.ts +7 -0
- package/dist/adapters/repository-seed-selection.js +79 -0
- package/dist/adapters/repository-solution-edits.d.ts +49 -0
- package/dist/adapters/repository-solution-edits.js +136 -0
- package/dist/adapters/repository-vitest-phase-adapter.d.ts +8 -0
- package/dist/adapters/repository-vitest-phase-adapter.js +310 -0
- package/dist/adapters/repository-vitest-reporter.d.ts +24 -0
- package/dist/adapters/repository-vitest-reporter.js +314 -0
- package/dist/adapters/strict-authoring-schema.d.ts +5 -0
- package/dist/adapters/strict-authoring-schema.js +158 -0
- package/dist/adapters/test-discovery.d.ts +30 -0
- package/dist/adapters/test-discovery.js +124 -0
- package/dist/adapters/typescript-repository-index.d.ts +51 -0
- package/dist/adapters/typescript-repository-index.js +226 -0
- package/dist/agentic-capabilities-protocol.d.ts +1373 -0
- package/dist/agentic-capabilities-protocol.js +786 -0
- package/dist/case-checkpoint-store.d.ts +29 -0
- package/dist/case-checkpoint-store.js +133 -0
- package/dist/case-pipeline-protocol-v2.d.ts +184 -0
- package/dist/case-pipeline-protocol-v2.js +193 -0
- package/dist/case-pipeline-protocol.d.ts +2626 -0
- package/dist/case-pipeline-protocol.js +371 -0
- package/dist/effect-api.d.ts +74 -10
- package/dist/effect-api.js +56 -6
- package/dist/errors.d.ts +31 -0
- package/dist/errors.js +10 -0
- package/dist/eval-capability-execution-envelope.d.ts +64 -0
- package/dist/eval-capability-execution-envelope.js +98 -0
- package/dist/eval-capability-policy.d.ts +90 -0
- package/dist/eval-capability-policy.js +107 -0
- package/dist/eval-event-log.d.ts +140 -0
- package/dist/eval-event-log.js +220 -0
- package/dist/evaluation-authoring-policy.d.ts +18 -0
- package/dist/evaluation-authoring-policy.js +19 -0
- package/dist/evaluation-authoring-validation.d.ts +22 -0
- package/dist/evaluation-authoring-validation.js +72 -0
- package/dist/evaluation-evidence.d.ts +20 -0
- package/dist/evaluation-evidence.js +319 -0
- package/dist/evaluation-grader-calibration-protocol.d.ts +108 -0
- package/dist/evaluation-grader-calibration-protocol.js +80 -0
- package/dist/evaluation-grader-calibration.d.ts +18 -0
- package/dist/evaluation-grader-calibration.js +334 -0
- package/dist/evaluation-grading-policy.d.ts +24 -0
- package/dist/evaluation-grading-policy.js +54 -0
- package/dist/evaluation-proposal-policy.d.ts +4 -0
- package/dist/evaluation-proposal-policy.js +91 -0
- package/dist/evaluation-source-retrieval.d.ts +68 -0
- package/dist/evaluation-source-retrieval.js +513 -0
- package/dist/evaluation-structure-policy.d.ts +29 -0
- package/dist/evaluation-structure-policy.js +138 -0
- package/dist/index.d.ts +124 -17
- package/dist/index.js +69 -11
- package/dist/inspection.js +2 -3
- package/dist/project-artifacts.d.ts +7 -2
- package/dist/project-artifacts.js +49 -136
- package/dist/project-authoring.d.ts +66 -5
- package/dist/project-authoring.js +783 -109
- package/dist/project-contracts.d.ts +419 -84
- package/dist/project-contracts.js +160 -52
- package/dist/project-store.js +2 -1
- package/dist/project-workflow.d.ts +5 -4
- package/dist/project-workflow.js +154 -35
- package/dist/repository-adversary-protocol.d.ts +64 -0
- package/dist/repository-adversary-protocol.js +105 -0
- package/dist/repository-behavior-protocol.d.ts +188 -0
- package/dist/repository-behavior-protocol.js +202 -0
- package/dist/repository-benchmark-protocol.d.ts +487 -0
- package/dist/repository-benchmark-protocol.js +96 -0
- package/dist/repository-execution-protocol.d.ts +150 -0
- package/dist/repository-execution-protocol.js +38 -0
- package/dist/repository-fixture-instructions.d.ts +3 -0
- package/dist/repository-fixture-instructions.js +91 -0
- package/dist/repository-fixture-protocol.d.ts +79 -0
- package/dist/repository-fixture-protocol.js +79 -0
- package/dist/repository-foundry-plan-protocol.d.ts +118 -0
- package/dist/repository-foundry-plan-protocol.js +296 -0
- package/dist/repository-foundry-progress-protocol.d.ts +52 -0
- package/dist/repository-foundry-progress-protocol.js +52 -0
- package/dist/repository-improvement-protocol.d.ts +100 -0
- package/dist/repository-improvement-protocol.js +106 -0
- package/dist/repository-language-model-protocol.d.ts +43 -0
- package/dist/repository-language-model-protocol.js +146 -0
- package/dist/repository-oracle-coverage-protocol.d.ts +18 -0
- package/dist/repository-oracle-coverage-protocol.js +39 -0
- package/dist/repository-oracle-execution-binding.d.ts +27 -0
- package/dist/repository-oracle-execution-binding.js +59 -0
- package/dist/repository-oracle-protocol.d.ts +230 -0
- package/dist/repository-oracle-protocol.js +156 -0
- package/dist/repository-oracle-scope-policy.d.ts +22 -0
- package/dist/repository-oracle-scope-policy.js +92 -0
- package/dist/repository-quality-policy.d.ts +15 -0
- package/dist/repository-quality-policy.js +357 -0
- package/dist/repository-routing-benchmark-protocol.d.ts +176 -0
- package/dist/repository-routing-benchmark-protocol.js +103 -0
- package/dist/repository-routing-model-protocol.d.ts +36 -0
- package/dist/repository-routing-model-protocol.js +89 -0
- package/dist/repository-routing-plan-protocol.d.ts +112 -0
- package/dist/repository-routing-plan-protocol.js +58 -0
- package/dist/repository-routing-quality-policy.d.ts +9 -0
- package/dist/repository-routing-quality-policy.js +191 -0
- package/dist/repository-seed-qualification-progress-protocol.d.ts +205 -0
- package/dist/repository-seed-qualification-progress-protocol.js +28 -0
- package/dist/repository-semantic-calibration-protocol.d.ts +768 -0
- package/dist/repository-semantic-calibration-protocol.js +276 -0
- package/dist/repository-semantic-calibration.d.ts +163 -0
- package/dist/repository-semantic-calibration.js +581 -0
- package/dist/repository-specification-contract-facts-protocol.d.ts +224 -0
- package/dist/repository-specification-contract-facts-protocol.js +276 -0
- package/dist/repository-specification-critique-protocol.d.ts +189 -0
- package/dist/repository-specification-critique-protocol.js +103 -0
- package/dist/repository-task-family-protocol.d.ts +24 -0
- package/dist/repository-task-family-protocol.js +37 -0
- package/dist/repository-task-seed-protocol.d.ts +384 -0
- package/dist/repository-task-seed-protocol.js +236 -0
- package/dist/repository-trajectory-protocol.d.ts +20 -0
- package/dist/repository-trajectory-protocol.js +42 -0
- package/dist/service.js +1 -1
- package/dist/services/adversary/service.d.ts +64 -0
- package/dist/services/adversary/service.js +330 -0
- package/dist/services/benchmark-compiler/service.d.ts +450 -0
- package/dist/services/benchmark-compiler/service.js +9 -0
- package/dist/services/budgeted-model/service.d.ts +118 -0
- package/dist/services/budgeted-model/service.js +460 -0
- package/dist/services/case-authoring/service.d.ts +163 -0
- package/dist/services/case-authoring/service.js +1456 -0
- package/dist/services/case-finalization/service.d.ts +283 -0
- package/dist/services/case-finalization/service.js +370 -0
- package/dist/services/case-generation/service.d.ts +619 -0
- package/dist/services/case-generation/service.js +2628 -0
- package/dist/services/case-pipeline/service.d.ts +31 -0
- package/dist/services/case-pipeline/service.js +485 -0
- package/dist/services/case-pipeline-v2/service.d.ts +70 -0
- package/dist/services/case-pipeline-v2/service.js +477 -0
- package/dist/services/command-observability/service.d.ts +13 -0
- package/dist/services/command-observability/service.js +3 -0
- package/dist/services/dimension-labeling/service.d.ts +77 -0
- package/dist/services/dimension-labeling/service.js +188 -0
- package/dist/services/eval-candidate/service.d.ts +208 -0
- package/dist/services/eval-candidate/service.js +64 -0
- package/dist/services/eval-capabilities/service.d.ts +183 -0
- package/dist/services/eval-capabilities/service.js +1433 -0
- package/dist/services/eval-environment/service.d.ts +173 -0
- package/dist/services/eval-environment/service.js +127 -0
- package/dist/services/evidence-reconstruction/service.d.ts +36 -0
- package/dist/services/evidence-reconstruction/service.js +145 -0
- package/dist/services/fixture-builder/service.d.ts +62 -0
- package/dist/services/fixture-builder/service.js +36 -0
- package/dist/services/fixture-validation/service.d.ts +75 -0
- package/dist/services/fixture-validation/service.js +295 -0
- package/dist/services/foundry/service.d.ts +831 -0
- package/dist/services/foundry/service.js +442 -0
- package/dist/services/foundry-progress/service.d.ts +62 -0
- package/dist/services/foundry-progress/service.js +149 -0
- package/dist/services/foundry-v2/service.d.ts +54 -0
- package/dist/services/foundry-v2/service.js +28 -0
- package/dist/services/grounded-authoring/service.d.ts +126 -0
- package/dist/services/grounded-authoring/service.js +822 -0
- package/dist/services/historical-case/service.d.ts +722 -0
- package/dist/services/historical-case/service.js +177 -0
- package/dist/services/improvement-loop/service.d.ts +59 -0
- package/dist/services/improvement-loop/service.js +176 -0
- package/dist/services/language-model/service.d.ts +52 -0
- package/dist/services/language-model/service.js +194 -0
- package/dist/services/oracle-builder/service.d.ts +146 -0
- package/dist/services/oracle-builder/service.js +513 -0
- package/dist/services/oracle-coverage/service.d.ts +28 -0
- package/dist/services/oracle-coverage/service.js +50 -0
- package/dist/services/oracle-coverage-witness/service.d.ts +130 -0
- package/dist/services/oracle-coverage-witness/service.js +538 -0
- package/dist/services/pipeline-challenge/service.d.ts +551 -0
- package/dist/services/pipeline-challenge/service.js +427 -0
- package/dist/services/pipeline-controls/service.d.ts +130 -0
- package/dist/services/pipeline-controls/service.js +483 -0
- package/dist/services/pipeline-oracle/service.d.ts +8 -0
- package/dist/services/pipeline-oracle/service.js +256 -0
- package/dist/services/pipeline-seed/service.d.ts +298 -0
- package/dist/services/pipeline-seed/service.js +428 -0
- package/dist/services/pipeline-spec/service.d.ts +103 -0
- package/dist/services/pipeline-spec/service.js +619 -0
- package/dist/services/pipeline-tournament/service.d.ts +258 -0
- package/dist/services/pipeline-tournament/service.js +476 -0
- package/dist/services/quality-gate/service.d.ts +233 -0
- package/dist/services/quality-gate/service.js +136 -0
- package/dist/services/repository-bundle/service.d.ts +33 -0
- package/dist/services/repository-bundle/service.js +114 -0
- package/dist/services/repository-model/service.d.ts +105 -0
- package/dist/services/repository-model/service.js +250 -0
- package/dist/services/repository-public-artifact/service.d.ts +133 -0
- package/dist/services/repository-public-artifact/service.js +330 -0
- package/dist/services/routing-benchmark/service.d.ts +362 -0
- package/dist/services/routing-benchmark/service.js +96 -0
- package/dist/services/specification-critic/service.d.ts +92 -0
- package/dist/services/specification-critic/service.js +172 -0
- package/dist/services/task-family/service.d.ts +40 -0
- package/dist/services/task-family/service.js +55 -0
- package/dist/services/task-seed/service.d.ts +906 -0
- package/dist/services/task-seed/service.js +1406 -0
- package/dist/services/task-specification/service.d.ts +27 -0
- package/dist/services/task-specification/service.js +40 -0
- package/dist/services/trajectory-policy/service.d.ts +110 -0
- package/dist/services/trajectory-policy/service.js +216 -0
- package/dist/test/agentic-capabilities-protocol.test.d.ts +1 -0
- package/dist/test/agentic-capabilities-protocol.test.js +570 -0
- package/dist/test/agentic-capabilities.test.d.ts +1 -0
- package/dist/test/agentic-capabilities.test.js +1461 -0
- package/dist/test/agentic-environment.test.d.ts +1 -0
- package/dist/test/agentic-environment.test.js +213 -0
- package/dist/test/case-pipeline-foundation.test.d.ts +1 -0
- package/dist/test/case-pipeline-foundation.test.js +535 -0
- package/dist/test/case-pipeline-protocol-v2.test.d.ts +1 -0
- package/dist/test/case-pipeline-protocol-v2.test.js +124 -0
- package/dist/test/case-pipeline-v2.test.d.ts +1 -0
- package/dist/test/case-pipeline-v2.test.js +286 -0
- package/dist/test/case-pipeline.test.d.ts +1 -0
- package/dist/test/case-pipeline.test.js +851 -0
- package/dist/test/eval-capability-policy.test.d.ts +1 -0
- package/dist/test/eval-capability-policy.test.js +50 -0
- package/dist/test/eval-event-log.test.d.ts +1 -0
- package/dist/test/eval-event-log.test.js +125 -0
- package/dist/test/evaluation-evidence-freshness.test.d.ts +1 -0
- package/dist/test/evaluation-evidence-freshness.test.js +44 -0
- package/dist/test/evaluation-evidence.test.d.ts +1 -0
- package/dist/test/evaluation-evidence.test.js +230 -0
- package/dist/test/evaluation-grader-calibration.test.d.ts +1 -0
- package/dist/test/evaluation-grader-calibration.test.js +373 -0
- package/dist/test/evaluation-proposal-digest.test.d.ts +1 -0
- package/dist/test/evaluation-proposal-digest.test.js +187 -0
- package/dist/test/evaluation-source-retrieval.test.d.ts +1 -0
- package/dist/test/evaluation-source-retrieval.test.js +237 -0
- package/dist/test/evaluation-structure-policy.test.d.ts +1 -0
- package/dist/test/evaluation-structure-policy.test.js +196 -0
- package/dist/test/fixtures/repository-resource-panel.d.ts +39 -0
- package/dist/test/fixtures/repository-resource-panel.js +111 -0
- package/dist/test/fixtures/vitest-boundary-panel.d.ts +84 -0
- package/dist/test/fixtures/vitest-boundary-panel.js +120 -0
- package/dist/test/fixtures/vitest-phase-panel.d.ts +135 -0
- package/dist/test/fixtures/vitest-phase-panel.js +213 -0
- package/dist/test/fixtures/vitest-reporter-results.d.ts +76 -0
- package/dist/test/fixtures/vitest-reporter-results.js +94 -0
- package/dist/test/grounded-authoring.test.d.ts +1 -0
- package/dist/test/grounded-authoring.test.js +565 -0
- package/dist/test/integrated-repository-history.test.d.ts +1 -0
- package/dist/test/integrated-repository-history.test.js +227 -0
- package/dist/test/project-authoring.test.js +593 -43
- package/dist/test/project-workflow.test.js +419 -40
- package/dist/test/repository-authoring-artifacts.test.d.ts +1 -0
- package/dist/test/repository-authoring-artifacts.test.js +185 -0
- package/dist/test/repository-bundle.test.d.ts +1 -0
- package/dist/test/repository-bundle.test.js +52 -0
- package/dist/test/repository-case-generation.test.d.ts +1 -0
- package/dist/test/repository-case-generation.test.js +3465 -0
- package/dist/test/repository-command-diagnostic.test.d.ts +1 -0
- package/dist/test/repository-command-diagnostic.test.js +55 -0
- package/dist/test/repository-command-signals.test.d.ts +1 -0
- package/dist/test/repository-command-signals.test.js +124 -0
- package/dist/test/repository-fixture-scope-coverage.test.d.ts +1 -0
- package/dist/test/repository-fixture-scope-coverage.test.js +127 -0
- package/dist/test/repository-fixture-validation.test.d.ts +1 -0
- package/dist/test/repository-fixture-validation.test.js +362 -0
- package/dist/test/repository-foundry-progress.test.d.ts +1 -0
- package/dist/test/repository-foundry-progress.test.js +110 -0
- package/dist/test/repository-foundry-quality.test.d.ts +1 -0
- package/dist/test/repository-foundry-quality.test.js +1138 -0
- package/dist/test/repository-import-context.test.d.ts +1 -0
- package/dist/test/repository-import-context.test.js +354 -0
- package/dist/test/repository-model-authoring.test.d.ts +1 -0
- package/dist/test/repository-model-authoring.test.js +544 -0
- package/dist/test/repository-model.test.d.ts +1 -0
- package/dist/test/repository-model.test.js +2195 -0
- package/dist/test/repository-node-test-reporter.test.d.ts +1 -0
- package/dist/test/repository-node-test-reporter.test.js +104 -0
- package/dist/test/repository-oracle-concurrency.test.d.ts +1 -0
- package/dist/test/repository-oracle-concurrency.test.js +542 -0
- package/dist/test/repository-oracle-coverage-witness.test.d.ts +1 -0
- package/dist/test/repository-oracle-coverage-witness.test.js +511 -0
- package/dist/test/repository-oracle-coverage.test.d.ts +1 -0
- package/dist/test/repository-oracle-coverage.test.js +168 -0
- package/dist/test/repository-oracle-evidence.test.d.ts +1 -0
- package/dist/test/repository-oracle-evidence.test.js +185 -0
- package/dist/test/repository-oracle-plan.test.d.ts +1 -0
- package/dist/test/repository-oracle-plan.test.js +176 -0
- package/dist/test/repository-overlay-isolation.test.d.ts +1 -0
- package/dist/test/repository-overlay-isolation.test.js +85 -0
- package/dist/test/repository-preparation-cache.test.d.ts +1 -0
- package/dist/test/repository-preparation-cache.test.js +414 -0
- package/dist/test/repository-public-artifact.test.d.ts +1 -0
- package/dist/test/repository-public-artifact.test.js +273 -0
- package/dist/test/repository-qualification-diagnostics.test.d.ts +1 -0
- package/dist/test/repository-qualification-diagnostics.test.js +524 -0
- package/dist/test/repository-reference-authoring.test.d.ts +1 -0
- package/dist/test/repository-reference-authoring.test.js +1633 -0
- package/dist/test/repository-review-evidence-v2.test.d.ts +1 -0
- package/dist/test/repository-review-evidence-v2.test.js +183 -0
- package/dist/test/repository-review-evidence.test.d.ts +1 -0
- package/dist/test/repository-review-evidence.test.js +124 -0
- package/dist/test/repository-seed-exclusions.test.d.ts +1 -0
- package/dist/test/repository-seed-exclusions.test.js +96 -0
- package/dist/test/repository-seed-selection.test.d.ts +1 -0
- package/dist/test/repository-seed-selection.test.js +504 -0
- package/dist/test/repository-semantic-calibration.test.d.ts +1 -0
- package/dist/test/repository-semantic-calibration.test.js +688 -0
- package/dist/test/repository-solution-edits.test.d.ts +1 -0
- package/dist/test/repository-solution-edits.test.js +377 -0
- package/dist/test/repository-specification-budget.test.d.ts +1 -0
- package/dist/test/repository-specification-budget.test.js +171 -0
- package/dist/test/repository-specification-contract-checkpoint.test.d.ts +1 -0
- package/dist/test/repository-specification-contract-checkpoint.test.js +228 -0
- package/dist/test/repository-specification-contract-facts.test.d.ts +1 -0
- package/dist/test/repository-specification-contract-facts.test.js +177 -0
- package/dist/test/repository-trajectory-authoring.test.d.ts +1 -0
- package/dist/test/repository-trajectory-authoring.test.js +176 -0
- package/dist/test/repository-valid-control-plan.test.d.ts +1 -0
- package/dist/test/repository-valid-control-plan.test.js +45 -0
- package/dist/test/repository-vitest-phase.test.d.ts +1 -0
- package/dist/test/repository-vitest-phase.test.js +848 -0
- package/dist/test/repository-vitest-reporter.test.d.ts +1 -0
- package/dist/test/repository-vitest-reporter.test.js +158 -0
- package/dist/test/repository-workspace-build.test.d.ts +1 -0
- package/dist/test/repository-workspace-build.test.js +160 -0
- package/dist/test/strict-authoring-schema.test.d.ts +1 -0
- package/dist/test/strict-authoring-schema.test.js +169 -0
- package/package.json +48 -6
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { access, mkdir, mkdtemp, realpath, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { test } from "node:test";
|
|
7
|
+
import { promisify } from "node:util";
|
|
8
|
+
import { Effect } from "effect";
|
|
9
|
+
import { repositoryCommandTestEvidenceV1 } from "../adapters/repository-command-evidence.js";
|
|
10
|
+
import { rankRepositorySeedCandidatesV1 } from "../adapters/repository-seed-selection.js";
|
|
11
|
+
import { assertRepositoryFoundryGenerationPlanV1 } from "../repository-foundry-plan-protocol.js";
|
|
12
|
+
import { repositoryFoundryModelPlanV1 } from "../repository-language-model-protocol.js";
|
|
13
|
+
import { planHistoricalRepositoryCaseGenerationV1 } from "../services/foundry/service.js";
|
|
14
|
+
import { RepositoryFoundryProgressLive } from "../services/foundry-progress/service.js";
|
|
15
|
+
import { buildRepositoryBehaviorMapV1 } from "../services/repository-model/service.js";
|
|
16
|
+
const execFilePromise = promisify(execFile);
|
|
17
|
+
const modelPlan = repositoryFoundryModelPlanV1({ primaryModel: "codex/gpt-6-astra" });
|
|
18
|
+
const episode = (commit, subject, paths, occurredAt = "2026-01-01T00:00:00Z") => ({
|
|
19
|
+
id: `git-${commit}`,
|
|
20
|
+
commit,
|
|
21
|
+
parentCommit: "parent",
|
|
22
|
+
occurredAt,
|
|
23
|
+
subject,
|
|
24
|
+
body: "",
|
|
25
|
+
changedPaths: paths.map((path) => ({
|
|
26
|
+
path,
|
|
27
|
+
status: "modified",
|
|
28
|
+
kind: path.includes("test") ? "test" : "implementation"
|
|
29
|
+
})),
|
|
30
|
+
testPaths: paths.filter((path) => path.includes("test")),
|
|
31
|
+
implementationPaths: paths.filter((path) => !path.includes("test")),
|
|
32
|
+
protocolPaths: [],
|
|
33
|
+
behaviorChanging: true,
|
|
34
|
+
seedEligible: true
|
|
35
|
+
});
|
|
36
|
+
test("seed ranking uses dimension evidence and deterministic narrow-change tie breaks", () => {
|
|
37
|
+
const narrow = episode("narrow", "fix wire protocol translation", [
|
|
38
|
+
"src/wire.ts",
|
|
39
|
+
"test/wire.test.ts"
|
|
40
|
+
]);
|
|
41
|
+
const broad = episode("broad", "fix wire protocol translation", [
|
|
42
|
+
"src/wire.ts",
|
|
43
|
+
"src/other.ts",
|
|
44
|
+
"test/wire.test.ts"
|
|
45
|
+
]);
|
|
46
|
+
const unrelated = episode("unrelated", "fix account usage", [
|
|
47
|
+
"src/accounts.ts",
|
|
48
|
+
"test/accounts.test.ts"
|
|
49
|
+
]);
|
|
50
|
+
const docs = episode("docs", "fix wire protocol translation", [
|
|
51
|
+
"examples/wire.ts",
|
|
52
|
+
"examples/wire.test.ts"
|
|
53
|
+
]);
|
|
54
|
+
const map = {
|
|
55
|
+
historyEpisodes: [unrelated, broad, docs, narrow],
|
|
56
|
+
tests: []
|
|
57
|
+
};
|
|
58
|
+
const ranked = rankRepositorySeedCandidatesV1(map, "wire-protocol-compatibility");
|
|
59
|
+
assert.deepEqual(ranked.map((entry) => entry.episode.commit), ["narrow", "broad", "unrelated"]);
|
|
60
|
+
assert.deepEqual(ranked[0]?.matchedTerms, ["wire", "protocol"]);
|
|
61
|
+
assert.equal(ranked[2]?.relevance, 0, "lack of lexical overlap is not a semantic exclusion");
|
|
62
|
+
assert.deepEqual(rankRepositorySeedCandidatesV1({ ...map, historyEpisodes: [...map.historyEpisodes].reverse() }, "wire-protocol-compatibility"), ranked);
|
|
63
|
+
});
|
|
64
|
+
test("bounded retrieval prefers concentrated path evidence over broad changes and subject-only keyword overlap", () => {
|
|
65
|
+
const narrow = episode("narrow", "fix buffered events", ["src/wire.ts", "test/wire.test.ts"]);
|
|
66
|
+
const subjectOnly = episode("subject-only", "fix wire protocol compatibility", [
|
|
67
|
+
"src/project.ts",
|
|
68
|
+
"src/authoring.ts",
|
|
69
|
+
"test/project.test.ts",
|
|
70
|
+
"test/authoring.test.ts"
|
|
71
|
+
]);
|
|
72
|
+
const broad = episode("broad", "fix wire protocol compatibility", [
|
|
73
|
+
"src/wire.ts",
|
|
74
|
+
"test/wire.test.ts",
|
|
75
|
+
...Array.from({ length: 18 }, (_, index) => `src/feature-${index}.ts`)
|
|
76
|
+
]);
|
|
77
|
+
const unrelated = episode("unrelated", "fix account state", [
|
|
78
|
+
"src/account.ts",
|
|
79
|
+
"test/account.test.ts"
|
|
80
|
+
]);
|
|
81
|
+
const map = {
|
|
82
|
+
historyEpisodes: [broad, subjectOnly, unrelated, narrow],
|
|
83
|
+
tests: []
|
|
84
|
+
};
|
|
85
|
+
const ranked = rankRepositorySeedCandidatesV1(map, "wire-protocol-compatibility");
|
|
86
|
+
assert.deepEqual(ranked.map(({ episode }) => episode.commit), ["narrow", "subject-only", "broad", "unrelated"]);
|
|
87
|
+
assert.ok(ranked[2].relevance > ranked[0].relevance, "broader lexical overlap must not consume the first bounded replay slot");
|
|
88
|
+
assert.deepEqual(rankRepositorySeedCandidatesV1({ ...map, historyEpisodes: [...map.historyEpisodes].reverse() }, "wire-protocol-compatibility"), ranked);
|
|
89
|
+
});
|
|
90
|
+
test("seed relevance ignores grammatical filler without turning retrieval into semantic admission", () => {
|
|
91
|
+
const wire = episode("wire", "fix protocol translation", ["src/wire.ts", "test/wire.test.ts"]);
|
|
92
|
+
const unrelated = episode("unrelated", "preserve the behavior and all of the values", [
|
|
93
|
+
"src/selection.ts",
|
|
94
|
+
"test/selection.test.ts"
|
|
95
|
+
]);
|
|
96
|
+
const map = {
|
|
97
|
+
historyEpisodes: [unrelated, wire],
|
|
98
|
+
tests: [
|
|
99
|
+
{
|
|
100
|
+
path: "test/selection.test.ts",
|
|
101
|
+
names: ["preserves the values and all of their state when the context is absent"]
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
};
|
|
105
|
+
const specific = rankRepositorySeedCandidatesV1(map, "wire protocol");
|
|
106
|
+
const grammatical = rankRepositorySeedCandidatesV1(map, "the wire and the protocol for all of their uses when there are any");
|
|
107
|
+
assert.equal(specific[0]?.episode.commit, "wire");
|
|
108
|
+
assert.equal(grammatical[0]?.episode.commit, "wire");
|
|
109
|
+
assert.ok(grammatical.every(({ matchedTerms }) => matchedTerms.every((term) => !["the", "and", "for", "all", "their", "when"].includes(term))));
|
|
110
|
+
const onlyGrammar = rankRepositorySeedCandidatesV1(map, "the and for all their when");
|
|
111
|
+
assert.equal(onlyGrammar.length, 2, "lexical no-match must not discard an eligible seed");
|
|
112
|
+
assert.ok(onlyGrammar.every(({ relevance, matchedTerms }) => relevance === 0 && matchedTerms.length === 0));
|
|
113
|
+
assert.deepEqual(rankRepositorySeedCandidatesV1({ ...map, historyEpisodes: [...map.historyEpisodes].reverse() }, "the and for all their when"), onlyGrammar, "empty content queries keep deterministic ordering without claiming target fit");
|
|
114
|
+
});
|
|
115
|
+
test("filler-only changes to dimension prose cannot manufacture retrieval evidence", () => {
|
|
116
|
+
const wire = episode("wire", "fix wire protocol", ["src/wire.ts", "test/wire.test.ts"]);
|
|
117
|
+
const unrelated = episode("unrelated", "the state and the values", [
|
|
118
|
+
"src/selection.ts",
|
|
119
|
+
"test/selection.test.ts"
|
|
120
|
+
]);
|
|
121
|
+
const map = {
|
|
122
|
+
historyEpisodes: [wire, unrelated],
|
|
123
|
+
tests: []
|
|
124
|
+
};
|
|
125
|
+
assert.deepEqual(rankRepositorySeedCandidatesV1(map, "Wire protocol"), rankRepositorySeedCandidatesV1(map, "The wire and the protocol for all of their uses"), "function words must not contribute to subjects, paths, or test-name scores");
|
|
126
|
+
});
|
|
127
|
+
test("automatic seed retrieval excludes deleted or renamed test overlays without excluding ordinary production changes", () => {
|
|
128
|
+
const ordinary = episode("ordinary", "fix wire handling", ["src/wire.ts", "test/wire.test.ts"]);
|
|
129
|
+
const removedTest = {
|
|
130
|
+
...ordinary,
|
|
131
|
+
commit: "deleted-test",
|
|
132
|
+
changedPaths: ordinary.changedPaths.map((entry) => entry.kind === "test" ? { ...entry, status: "deleted" } : entry)
|
|
133
|
+
};
|
|
134
|
+
const renamedTest = {
|
|
135
|
+
...ordinary,
|
|
136
|
+
commit: "renamed-test",
|
|
137
|
+
changedPaths: ordinary.changedPaths.map((entry) => entry.kind === "test"
|
|
138
|
+
? { ...entry, status: "renamed", previousPath: "test/old-wire.test.ts" }
|
|
139
|
+
: entry)
|
|
140
|
+
};
|
|
141
|
+
const renamedSource = {
|
|
142
|
+
...ordinary,
|
|
143
|
+
commit: "renamed-source",
|
|
144
|
+
changedPaths: ordinary.changedPaths.map((entry) => entry.kind === "implementation"
|
|
145
|
+
? { ...entry, status: "renamed", previousPath: "src/old-wire.ts" }
|
|
146
|
+
: entry)
|
|
147
|
+
};
|
|
148
|
+
const addedTest = {
|
|
149
|
+
...ordinary,
|
|
150
|
+
commit: "added-test",
|
|
151
|
+
changedPaths: ordinary.changedPaths.map((entry) => entry.kind === "test" ? { ...entry, status: "added" } : entry)
|
|
152
|
+
};
|
|
153
|
+
const map = {
|
|
154
|
+
historyEpisodes: [removedTest, renamedTest, ordinary, renamedSource, addedTest],
|
|
155
|
+
tests: []
|
|
156
|
+
};
|
|
157
|
+
assert.deepEqual(rankRepositorySeedCandidatesV1(map, "wire")
|
|
158
|
+
.map(({ episode }) => episode.commit)
|
|
159
|
+
.sort(), ["added-test", "ordinary", "renamed-source"]);
|
|
160
|
+
});
|
|
161
|
+
test("incidental documentation changes remain eligible without admitting example implementation or test targets", () => {
|
|
162
|
+
const production = episode("production", "fix response handling", [
|
|
163
|
+
"src/wire.ts",
|
|
164
|
+
"test/wire.test.ts"
|
|
165
|
+
]);
|
|
166
|
+
const documented = {
|
|
167
|
+
...production,
|
|
168
|
+
commit: "documented",
|
|
169
|
+
changedPaths: [
|
|
170
|
+
...production.changedPaths,
|
|
171
|
+
{
|
|
172
|
+
path: "docs/wire-protocol-compatibility.md",
|
|
173
|
+
status: "modified",
|
|
174
|
+
kind: "documentation"
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
};
|
|
178
|
+
const toy = episode("toy", "fix wire protocol compatibility", [
|
|
179
|
+
"examples/wire.ts",
|
|
180
|
+
"examples/wire.test.ts"
|
|
181
|
+
]);
|
|
182
|
+
const map = {
|
|
183
|
+
historyEpisodes: [production, documented, toy],
|
|
184
|
+
tests: []
|
|
185
|
+
};
|
|
186
|
+
const ranked = rankRepositorySeedCandidatesV1(map, "wire-protocol-compatibility");
|
|
187
|
+
assert.deepEqual(ranked.map(({ episode }) => episode.commit), ["documented", "production"]);
|
|
188
|
+
assert.equal(ranked[0].relevance, ranked[1].relevance, "incidental doc filenames cannot boost relevance");
|
|
189
|
+
});
|
|
190
|
+
test("automatic preparation requires a dimension and an explicit bounded candidate budget", async () => {
|
|
191
|
+
for (const input of [
|
|
192
|
+
{},
|
|
193
|
+
{ requestedDimension: "normalizer", maximumSeedCandidates: 0 },
|
|
194
|
+
{ requestedDimension: "normalizer", maximumSeedCandidates: 11 },
|
|
195
|
+
{ requestedDimension: "normalizer", maximumSeedCandidates: 1.5 }
|
|
196
|
+
]) {
|
|
197
|
+
await assert.rejects(Effect.runPromise(planHistoricalRepositoryCaseGenerationV1({
|
|
198
|
+
repositoryRoot: "/not-inspected",
|
|
199
|
+
caseId: "case",
|
|
200
|
+
modelPlan,
|
|
201
|
+
...input
|
|
202
|
+
})), /request failed validation/u);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
test("automatic preparation rejects an inconclusive candidate then pins a separately indexed historical seed", async () => {
|
|
206
|
+
const root = await mkdtemp(join(tmpdir(), "routekit-seed-selection-"));
|
|
207
|
+
const git = async (...args) => (await execFilePromise("git", ["-C", root, ...args], { encoding: "utf8" })).stdout.trim();
|
|
208
|
+
const commit = async (subject, date) => {
|
|
209
|
+
await git("add", ".");
|
|
210
|
+
await execFilePromise("git", ["-C", root, "commit", "-q", "-m", subject], {
|
|
211
|
+
env: { ...process.env, GIT_AUTHOR_DATE: date, GIT_COMMITTER_DATE: date }
|
|
212
|
+
});
|
|
213
|
+
return git("rev-parse", "HEAD");
|
|
214
|
+
};
|
|
215
|
+
const implementation = join(root, "src/normalizer.js");
|
|
216
|
+
const regression = join(root, "test/normalizer.test.js");
|
|
217
|
+
const testSource = (body) => [
|
|
218
|
+
"import test from 'node:test'; import assert from 'node:assert/strict';",
|
|
219
|
+
"import { normalize } from '../src/normalizer.js';",
|
|
220
|
+
body,
|
|
221
|
+
""
|
|
222
|
+
].join("\n");
|
|
223
|
+
const manifest = {
|
|
224
|
+
name: "fixture-normalizer",
|
|
225
|
+
private: true,
|
|
226
|
+
type: "module",
|
|
227
|
+
scripts: { test: "node --test test/*.test.js" }
|
|
228
|
+
};
|
|
229
|
+
try {
|
|
230
|
+
await git("init", "-q");
|
|
231
|
+
await git("config", "user.name", "Foundry Test");
|
|
232
|
+
await git("config", "user.email", "foundry@example.test");
|
|
233
|
+
await mkdir(join(root, "src"));
|
|
234
|
+
await mkdir(join(root, "test"));
|
|
235
|
+
await writeFile(join(root, "package.json"), JSON.stringify(manifest));
|
|
236
|
+
await writeFile(implementation, "export const normalize = value => value;\n");
|
|
237
|
+
await writeFile(regression, testSource("test('normalizer preserves plain text', () => assert.equal(normalize('value'), 'value'));"));
|
|
238
|
+
const initial = await commit("initial normalizer", "2026-01-01T00:00:00Z");
|
|
239
|
+
await writeFile(implementation, "export const normalize = value => value.trim();\n");
|
|
240
|
+
await writeFile(regression, testSource("test('normalizer trims whitespace', () => assert.equal(normalize(' value '), 'value'));"));
|
|
241
|
+
const good = await commit("fix(normalizer): trim whitespace", "2026-01-02T00:00:00Z");
|
|
242
|
+
await writeFile(implementation, "export const normalize = value => value.trim().toLowerCase();\n");
|
|
243
|
+
await writeFile(regression, testSource("test('normalizer folds case', () => { if (normalize(' VALUE ') !== 'value') throw new TypeError('fixture setup failure'); assert.equal(normalize(' VALUE '), 'value'); });"));
|
|
244
|
+
const bad = await commit("fix(normalizer): fold case", "2026-01-03T00:00:00Z");
|
|
245
|
+
// The current harness no longer runs either historical suite. Each selected
|
|
246
|
+
// episode must be reindexed at its own reference before environment inference.
|
|
247
|
+
await writeFile(join(root, "package.json"), JSON.stringify({ ...manifest, scripts: { test: "node --test unavailable/*.test.js" } }));
|
|
248
|
+
const tip = await commit("chore: move current test runner", "2026-01-04T00:00:00Z");
|
|
249
|
+
const events = [];
|
|
250
|
+
const progress = RepositoryFoundryProgressLive((event) => Effect.sync(() => {
|
|
251
|
+
events.push(event);
|
|
252
|
+
}));
|
|
253
|
+
const base = {
|
|
254
|
+
repositoryRoot: root,
|
|
255
|
+
requestedDimension: "normalizer",
|
|
256
|
+
caseId: "auto-normalizer",
|
|
257
|
+
validControlReviewVersion: 1,
|
|
258
|
+
modelPlan
|
|
259
|
+
};
|
|
260
|
+
await assert.rejects(Effect.runPromise(planHistoricalRepositoryCaseGenerationV1({ ...base, maximumSeedCandidates: 1 })), /no historical seed qualified within 1 candidate attempts/u);
|
|
261
|
+
const plan = await Effect.runPromise(planHistoricalRepositoryCaseGenerationV1(base).pipe(Effect.provide(progress)));
|
|
262
|
+
assertRepositoryFoundryGenerationPlanV1(plan);
|
|
263
|
+
assert.equal(plan.referenceCommit, good);
|
|
264
|
+
assert.equal(plan.initialCommit, initial);
|
|
265
|
+
assert.equal(plan.repository.commit, good);
|
|
266
|
+
assert.equal(plan.requestedDimension, "normalizer");
|
|
267
|
+
assert.equal(plan.validControlReviewVersion, 1);
|
|
268
|
+
assert.ok(events.some((event) => event.detail?.includes(`tip=${tip}; candidates=2`)));
|
|
269
|
+
assert.ok(events.some((event) => event.detail?.includes(`candidate=${bad}; status=rejected`) &&
|
|
270
|
+
event.detail.includes("operational failure prevented grading")));
|
|
271
|
+
assert.ok(events.some((event) => event.detail === `seed-selection candidate=${good}; status=selected`));
|
|
272
|
+
assert.ok(events.every((event) => event.modelCalls === 0));
|
|
273
|
+
await assert.rejects(Effect.runPromise(planHistoricalRepositoryCaseGenerationV1({
|
|
274
|
+
...base,
|
|
275
|
+
referenceCommit: bad,
|
|
276
|
+
maximumSeedCandidates: 10
|
|
277
|
+
})), /operational failure prevented grading/u);
|
|
278
|
+
const map = await Effect.runPromise(buildRepositoryBehaviorMapV1({ repositoryRoot: root, requestedRef: good }));
|
|
279
|
+
assert.equal(plan.repository.tree, map.repository.tree);
|
|
280
|
+
}
|
|
281
|
+
finally {
|
|
282
|
+
await rm(root, { recursive: true, force: true });
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
test("automatic selection retains real listener denial and skips pass/pass lexical distractors within its declared bound", {
|
|
286
|
+
skip: process.platform !== "darwin"
|
|
287
|
+
}, async () => {
|
|
288
|
+
const root = await realpath(await mkdtemp(join(tmpdir(), "routekit-seed-selection-capability-")));
|
|
289
|
+
const canary = "private-composed-seed-qualification";
|
|
290
|
+
const git = async (...args) => (await execFilePromise("git", ["-C", root, ...args], { encoding: "utf8" })).stdout.trim();
|
|
291
|
+
const commit = async (subject, date) => {
|
|
292
|
+
await git("add", ".");
|
|
293
|
+
await execFilePromise("git", [
|
|
294
|
+
"-C",
|
|
295
|
+
root,
|
|
296
|
+
"-c",
|
|
297
|
+
"core.hooksPath=/dev/null",
|
|
298
|
+
"-c",
|
|
299
|
+
"commit.gpgSign=false",
|
|
300
|
+
"-c",
|
|
301
|
+
"user.name=Foundry Test",
|
|
302
|
+
"-c",
|
|
303
|
+
"user.email=foundry@example.test",
|
|
304
|
+
"commit",
|
|
305
|
+
"-qm",
|
|
306
|
+
subject
|
|
307
|
+
], { env: { ...process.env, GIT_AUTHOR_DATE: date, GIT_COMMITTER_DATE: date } });
|
|
308
|
+
return git("rev-parse", "HEAD");
|
|
309
|
+
};
|
|
310
|
+
const testSource = (module, name, body) => [
|
|
311
|
+
"import test from 'node:test';",
|
|
312
|
+
"import assert from 'node:assert/strict';",
|
|
313
|
+
"import net from 'node:net';",
|
|
314
|
+
`import * as subject from '../src/${module}.js';`,
|
|
315
|
+
`test(${JSON.stringify(name)}, { timeout: 5_000 }, async () => {`,
|
|
316
|
+
` console.log(${JSON.stringify(canary)});`,
|
|
317
|
+
" console.log('diagnostic-cwd=' + process.cwd());",
|
|
318
|
+
body,
|
|
319
|
+
"});",
|
|
320
|
+
""
|
|
321
|
+
].join("\n");
|
|
322
|
+
const trimAssertion = " assert.equal(subject.normalize(' value '), 'value');";
|
|
323
|
+
try {
|
|
324
|
+
await git("init", "-q");
|
|
325
|
+
await mkdir(join(root, "src"));
|
|
326
|
+
await mkdir(join(root, "test"));
|
|
327
|
+
await writeFile(join(root, "package.json"), JSON.stringify({
|
|
328
|
+
name: "composed-seed-selection-fixture",
|
|
329
|
+
private: true,
|
|
330
|
+
type: "module",
|
|
331
|
+
scripts: { test: "node --test test/*.test.js" }
|
|
332
|
+
}));
|
|
333
|
+
await writeFile(join(root, "src/normalizer.js"), "export const normalize = value => value;\n");
|
|
334
|
+
await writeFile(join(root, "test/normalizer.test.js"), testSource("normalizer", "normalizer preserves plain text", " assert.equal(subject.normalize('value'), 'value');"));
|
|
335
|
+
for (const side of ["left", "right"]) {
|
|
336
|
+
await writeFile(join(root, `src/${side}.js`), "export const value = 7;\n");
|
|
337
|
+
await writeFile(join(root, `test/${side}.test.js`), testSource(side, `unrelated ${side} counter`, " assert.equal(subject.value, 7);"));
|
|
338
|
+
}
|
|
339
|
+
const initial = await commit("initial fixture", "2026-01-01T00:00:00Z");
|
|
340
|
+
await writeFile(join(root, "src/normalizer.js"), "export const normalize = value => value.trim();\n");
|
|
341
|
+
await writeFile(join(root, "test/normalizer.test.js"), testSource("normalizer", "normalizer trims whitespace", trimAssertion));
|
|
342
|
+
const good = await commit("fix: trim input", "2026-01-02T00:00:00Z");
|
|
343
|
+
const distractors = [];
|
|
344
|
+
for (const [index, side] of ["left", "right"].entries()) {
|
|
345
|
+
// Only the source comment and test name change. The module and assertion
|
|
346
|
+
// are unrelated to trimming, despite target words in the current test name.
|
|
347
|
+
await writeFile(join(root, `src/${side}.js`), `// Clarify the ${side} counter documentation.\nexport const value = 7;\n`);
|
|
348
|
+
await writeFile(join(root, `test/${side}.test.js`), testSource(side, `whitespace compatibility for unrelated ${side} counter`, " assert.equal(subject.value, 7);"));
|
|
349
|
+
distractors.push(await commit(`chore: clarify ${side} counter`, `2026-01-0${String(index + 3)}T00:00:00Z`));
|
|
350
|
+
}
|
|
351
|
+
await writeFile(join(root, "src/normalizer.js"), "export const normalize = value => value.trim().toLowerCase();\n");
|
|
352
|
+
await writeFile(join(root, "test/normalizer.test.js"), testSource("normalizer", "normalizer handles whitespace after opening a listener", [
|
|
353
|
+
" await new Promise((resolve, reject) => {",
|
|
354
|
+
" const server = net.createServer();",
|
|
355
|
+
" server.once('error', (error) => {",
|
|
356
|
+
" console.error('listener-denied-code=' + error.code);",
|
|
357
|
+
// Preserve the original error. assert.fail would manufacture a
|
|
358
|
+
// semantic assertion failure from an unsupported runtime capability.
|
|
359
|
+
" reject(error);",
|
|
360
|
+
" });",
|
|
361
|
+
" server.listen(0, '127.0.0.1', () => {",
|
|
362
|
+
" server.close((error) => error === undefined ? resolve() : reject(error));",
|
|
363
|
+
" });",
|
|
364
|
+
" });",
|
|
365
|
+
" assert.equal(subject.normalize(' VALUE '), 'value');"
|
|
366
|
+
].join("\n")));
|
|
367
|
+
const denied = await commit("fix: fold input case", "2026-01-05T00:00:00Z");
|
|
368
|
+
const expectedOrder = [denied, distractors[1], distractors[0], good];
|
|
369
|
+
const parents = new Map([
|
|
370
|
+
[good, initial],
|
|
371
|
+
[distractors[0], good],
|
|
372
|
+
[distractors[1], distractors[0]],
|
|
373
|
+
[denied, distractors[1]]
|
|
374
|
+
]);
|
|
375
|
+
const discovery = await Effect.runPromise(buildRepositoryBehaviorMapV1({ repositoryRoot: root, requestedRef: "HEAD" }));
|
|
376
|
+
const ranked = rankRepositorySeedCandidatesV1(discovery, "whitespace");
|
|
377
|
+
assert.deepEqual(ranked.map(({ episode }) => episode.commit), expectedOrder);
|
|
378
|
+
assert.ok(ranked.every(({ matchedTerms }) => matchedTerms.includes("whitespace")));
|
|
379
|
+
// Equal-size changes share current test-name overlap; controlled dates
|
|
380
|
+
// establish this shortlist. Neither overlap nor rank certifies semantics.
|
|
381
|
+
const attempt = (maximumSeedCandidates) => {
|
|
382
|
+
const events = [];
|
|
383
|
+
const artifacts = [];
|
|
384
|
+
const progress = RepositoryFoundryProgressLive((event) => Effect.sync(() => {
|
|
385
|
+
events.push(event);
|
|
386
|
+
}), (artifact) => Effect.promise(async () => {
|
|
387
|
+
assert.equal(artifact.schemaName, "routekit_repository_seed_qualification_phase_v1");
|
|
388
|
+
const report = artifact.value;
|
|
389
|
+
// Inspect during recording, not after all selection is complete.
|
|
390
|
+
// Every isolated checkout must already have been released.
|
|
391
|
+
for (const result of report.results) {
|
|
392
|
+
const checkout = /diagnostic-cwd=([^\r\n]+)/u.exec(result.stdout)?.[1];
|
|
393
|
+
assert.ok(checkout, "the real grading command must expose its isolated cwd");
|
|
394
|
+
await assert.rejects(access(checkout), { code: "ENOENT" });
|
|
395
|
+
}
|
|
396
|
+
artifacts.push(artifact);
|
|
397
|
+
}));
|
|
398
|
+
return {
|
|
399
|
+
events,
|
|
400
|
+
artifacts,
|
|
401
|
+
effect: planHistoricalRepositoryCaseGenerationV1({
|
|
402
|
+
repositoryRoot: root,
|
|
403
|
+
requestedDimension: "whitespace",
|
|
404
|
+
caseId: `composed-seed-bound-${String(maximumSeedCandidates)}`,
|
|
405
|
+
maximumSeedCandidates,
|
|
406
|
+
qualificationBatches: 2,
|
|
407
|
+
qualificationRepetitionsPerBatch: 2,
|
|
408
|
+
modelPlan
|
|
409
|
+
}).pipe(Effect.provide(progress))
|
|
410
|
+
};
|
|
411
|
+
};
|
|
412
|
+
const exhausted = attempt(3);
|
|
413
|
+
await assert.rejects(Effect.runPromise(exhausted.effect), /no historical seed qualified within 3 candidate attempts/u);
|
|
414
|
+
const selected = attempt(4);
|
|
415
|
+
const plan = await Effect.runPromise(selected.effect);
|
|
416
|
+
assertRepositoryFoundryGenerationPlanV1(plan);
|
|
417
|
+
assert.equal(plan.initialCommit, initial);
|
|
418
|
+
assert.equal(plan.referenceCommit, good);
|
|
419
|
+
assert.equal(plan.repository.commit, good);
|
|
420
|
+
assert.equal(plan.repository.tree, await git("rev-parse", `${good}^{tree}`));
|
|
421
|
+
assert.equal(plan.requestedDimension, "whitespace");
|
|
422
|
+
for (const [run, references] of [
|
|
423
|
+
[exhausted, expectedOrder.slice(0, 3)],
|
|
424
|
+
[selected, expectedOrder]
|
|
425
|
+
]) {
|
|
426
|
+
const details = run.events.flatMap(({ detail }) => (detail === undefined ? [] : [detail]));
|
|
427
|
+
assert.deepEqual(details.flatMap((detail) => {
|
|
428
|
+
const match = /^seed-selection candidate=([a-f0-9]+); attempt=\d+;/u.exec(detail);
|
|
429
|
+
return match === null ? [] : [match[1]];
|
|
430
|
+
}), references);
|
|
431
|
+
assert.deepEqual(details.flatMap((detail) => {
|
|
432
|
+
const match = /^seed-selection candidate=([a-f0-9]+); status=(rejected|selected)(?:;|$)/u.exec(detail);
|
|
433
|
+
return match === null ? [] : [{ commit: match[1], status: match[2] }];
|
|
434
|
+
}), references.map((reference) => ({
|
|
435
|
+
commit: reference,
|
|
436
|
+
status: reference === good ? "selected" : "rejected"
|
|
437
|
+
})));
|
|
438
|
+
const denialReason = details.find((detail) => detail.startsWith(`seed-selection candidate=${denied}; status=rejected;`));
|
|
439
|
+
assert.ok(denialReason);
|
|
440
|
+
assert.match(denialReason, /operational failure prevented grading/u);
|
|
441
|
+
assert.doesNotMatch(denialReason, /commands are unstable|cross-batch qualification diverged/u);
|
|
442
|
+
for (const distractor of distractors) {
|
|
443
|
+
const reason = details.find((detail) => detail.startsWith(`seed-selection candidate=${distractor}; status=rejected;`));
|
|
444
|
+
assert.ok(reason);
|
|
445
|
+
assert.match(reason, /every reviewed grade command must reproduce the pre-change failure/u);
|
|
446
|
+
}
|
|
447
|
+
assert.ok(run.events.length > 0);
|
|
448
|
+
assert.ok(run.events.every((event) => event.modelCalls === 0 && event.kind !== "model-call"), "even failed authoring starts would violate this local-only qualification baseline");
|
|
449
|
+
assert.doesNotMatch(JSON.stringify(run.events), /private-composed-seed-qualification|diagnostic-cwd|listener-denied-code|stdout|stderr/u);
|
|
450
|
+
assert.equal(run.artifacts.length, references.reduce((count, reference) => count + (reference === denied ? 2 : 6), 0));
|
|
451
|
+
assert.equal(new Set(run.artifacts.map((artifact) => artifact.operationId)).size, run.artifacts.length);
|
|
452
|
+
for (const reference of references) {
|
|
453
|
+
const artifacts = run.artifacts.filter((artifact) => artifact.value.referenceCommit === reference);
|
|
454
|
+
assert.equal(artifacts.length, reference === denied ? 2 : 6);
|
|
455
|
+
for (const batch of [1, 2]) {
|
|
456
|
+
assert.deepEqual(artifacts
|
|
457
|
+
.map((artifact) => artifact.value)
|
|
458
|
+
.filter((report) => report.batch === batch)
|
|
459
|
+
.map((report) => report.phase)
|
|
460
|
+
.sort(), reference === denied
|
|
461
|
+
? batch === 1 ? ["baseline", "pre-change"] : []
|
|
462
|
+
: ["baseline", "post-change", "pre-change"]);
|
|
463
|
+
}
|
|
464
|
+
for (const artifact of artifacts) {
|
|
465
|
+
const report = artifact.value;
|
|
466
|
+
assert.equal(artifact.response.text, JSON.stringify(report));
|
|
467
|
+
assert.equal(artifact.role, "seed-qualifier");
|
|
468
|
+
assert.equal(artifact.model, "local-replay");
|
|
469
|
+
assert.equal(artifact.request.maximumOutputTokens, 0);
|
|
470
|
+
assert.equal(report.diagnosticOnly, true);
|
|
471
|
+
assert.equal(report.admissionEvidence, false);
|
|
472
|
+
if (reference === good)
|
|
473
|
+
assert.equal(report.seedId, plan.seedId);
|
|
474
|
+
assert.deepEqual(report.results.map((result) => result.repetition), [1, 2]);
|
|
475
|
+
for (const result of report.results) {
|
|
476
|
+
const listenerDenied = reference === denied && report.phase !== "baseline";
|
|
477
|
+
const expectedOutcome = listenerDenied
|
|
478
|
+
? "unknown"
|
|
479
|
+
: reference === good && report.phase === "pre-change"
|
|
480
|
+
? "fail"
|
|
481
|
+
: "pass";
|
|
482
|
+
assert.equal(result.commit, report.phase === "post-change" ? reference : parents.get(reference));
|
|
483
|
+
assert.equal(result.stage, "grade");
|
|
484
|
+
assert.equal(result.gradeExecuted, true);
|
|
485
|
+
assert.equal(result.timedOut, false);
|
|
486
|
+
assert.equal(result.outputTruncated, false);
|
|
487
|
+
assert.equal(result.exitCode, expectedOutcome === "pass" ? 0 : 1);
|
|
488
|
+
assert.equal(repositoryCommandTestEvidenceV1(result, result.recipeId).outcome, expectedOutcome);
|
|
489
|
+
assert.ok(result.stdout.includes(canary));
|
|
490
|
+
if (listenerDenied) {
|
|
491
|
+
const output = `${result.stdout}\n${result.stderr}`;
|
|
492
|
+
assert.match(output, /listener-denied-code=(?:EPERM|EACCES)\b/u);
|
|
493
|
+
assert.match(output, /code: ['"](?:EPERM|EACCES)['"]/u);
|
|
494
|
+
assert.doesNotMatch(output, /ERR_ASSERTION|AssertionError/u);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
finally {
|
|
502
|
+
await rm(root, { recursive: true, force: true });
|
|
503
|
+
}
|
|
504
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|