@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,146 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { RepositoryFoundryError } from "../../errors.js";
|
|
3
|
+
import { type RepositoryHiddenOracleV1 } from "../../repository-oracle-protocol.js";
|
|
4
|
+
import type { RepositoryHistoricalOracleInputV1 } from "../../repository-execution-protocol.js";
|
|
5
|
+
export type { RepositoryExecutableSolutionV1, RepositoryStructuralOracleClauseV1 } from "../../repository-execution-protocol.js";
|
|
6
|
+
export type OracleBuilderShape = {
|
|
7
|
+
readonly buildHistorical: (input: RepositoryHistoricalOracleInputV1) => Effect.Effect<RepositoryHiddenOracleV1, import("../../errors.js").RepositoryFoundryError>;
|
|
8
|
+
};
|
|
9
|
+
declare const OracleBuilder_base: Context.ServiceClass<OracleBuilder, "@velum-labs/routekit-eval-setup/OracleBuilder", OracleBuilderShape>;
|
|
10
|
+
export declare class OracleBuilder extends OracleBuilder_base {
|
|
11
|
+
}
|
|
12
|
+
export type RepositoryHistoricalOracleExecutionInputV1 = RepositoryHistoricalOracleInputV1 & {
|
|
13
|
+
/**
|
|
14
|
+
* Host-owned execution evidence from a previously interrupted invocation.
|
|
15
|
+
* Only complete, strictly validated replay units are reused.
|
|
16
|
+
*/
|
|
17
|
+
readonly resumeOracle?: RepositoryHiddenOracleV1;
|
|
18
|
+
/** Persist complete baseline repetitions, fixture repetitions, and structural inspections. */
|
|
19
|
+
readonly onReplayCompleted?: (oracle: RepositoryHiddenOracleV1) => Effect.Effect<void>;
|
|
20
|
+
/** Persist a complete per-solution boundary before another solution starts. */
|
|
21
|
+
readonly onSolutionCompleted?: (oracle: RepositoryHiddenOracleV1) => Effect.Effect<void>;
|
|
22
|
+
};
|
|
23
|
+
export declare const buildHistoricalHiddenOracleV1: (input: RepositoryHistoricalOracleExecutionInputV1) => Effect.Effect<{
|
|
24
|
+
readonly version: 1;
|
|
25
|
+
readonly fixtures: readonly ({
|
|
26
|
+
readonly kind: "historical-regression";
|
|
27
|
+
readonly expectationMode: "changes";
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly description: string;
|
|
30
|
+
readonly expectedBehavior: string;
|
|
31
|
+
readonly source: "historical" | "generated" | "reviewed";
|
|
32
|
+
readonly testPath: string;
|
|
33
|
+
} | {
|
|
34
|
+
readonly kind: "boundary";
|
|
35
|
+
readonly expectationMode: "changes" | "preserved";
|
|
36
|
+
readonly id: string;
|
|
37
|
+
readonly description: string;
|
|
38
|
+
readonly expectedBehavior: string;
|
|
39
|
+
readonly source: "historical" | "generated" | "reviewed";
|
|
40
|
+
readonly testPath: string;
|
|
41
|
+
} | {
|
|
42
|
+
readonly kind: "counterfactual";
|
|
43
|
+
readonly expectationMode: "changes";
|
|
44
|
+
readonly id: string;
|
|
45
|
+
readonly description: string;
|
|
46
|
+
readonly expectedBehavior: string;
|
|
47
|
+
readonly source: "historical" | "generated" | "reviewed";
|
|
48
|
+
readonly testPath: string;
|
|
49
|
+
} | {
|
|
50
|
+
readonly kind: "metamorphic";
|
|
51
|
+
readonly expectationMode: "preserved";
|
|
52
|
+
readonly id: string;
|
|
53
|
+
readonly description: string;
|
|
54
|
+
readonly expectedBehavior: string;
|
|
55
|
+
readonly source: "historical" | "generated" | "reviewed";
|
|
56
|
+
readonly testPath: string;
|
|
57
|
+
})[];
|
|
58
|
+
readonly caseId: string;
|
|
59
|
+
readonly hardFailurePolicy: "any-critical-hard-clause-fails";
|
|
60
|
+
readonly clauses: readonly ({
|
|
61
|
+
readonly kind: "candidate-policy";
|
|
62
|
+
readonly policyId: string;
|
|
63
|
+
readonly forbiddenPaths: readonly string[];
|
|
64
|
+
readonly id: string;
|
|
65
|
+
readonly critical: boolean;
|
|
66
|
+
readonly description: string;
|
|
67
|
+
} | {
|
|
68
|
+
readonly kind: "test-command";
|
|
69
|
+
readonly recipeId: string;
|
|
70
|
+
readonly expectedExitCode: number;
|
|
71
|
+
readonly fixtureIds: readonly string[];
|
|
72
|
+
readonly id: string;
|
|
73
|
+
readonly critical: boolean;
|
|
74
|
+
readonly description: string;
|
|
75
|
+
} | {
|
|
76
|
+
readonly kind: "json-field";
|
|
77
|
+
readonly id: string;
|
|
78
|
+
readonly description: string;
|
|
79
|
+
readonly critical: boolean;
|
|
80
|
+
readonly operator: "equals" | "present" | "absent";
|
|
81
|
+
readonly pointer: string;
|
|
82
|
+
readonly expectedJson?: string | undefined;
|
|
83
|
+
} | {
|
|
84
|
+
readonly kind: "ordered-events";
|
|
85
|
+
readonly id: string;
|
|
86
|
+
readonly description: string;
|
|
87
|
+
readonly critical: boolean;
|
|
88
|
+
readonly eventTypes: readonly string[];
|
|
89
|
+
readonly terminalEvent?: string | undefined;
|
|
90
|
+
} | {
|
|
91
|
+
readonly kind: "property";
|
|
92
|
+
readonly propertyId: string;
|
|
93
|
+
readonly fixtureIds: readonly string[];
|
|
94
|
+
readonly id: string;
|
|
95
|
+
readonly critical: boolean;
|
|
96
|
+
readonly description: string;
|
|
97
|
+
} | {
|
|
98
|
+
readonly kind: "differential";
|
|
99
|
+
readonly implementationIds: readonly string[];
|
|
100
|
+
readonly fixtureIds: readonly string[];
|
|
101
|
+
readonly id: string;
|
|
102
|
+
readonly critical: boolean;
|
|
103
|
+
readonly description: string;
|
|
104
|
+
} | {
|
|
105
|
+
readonly kind: "architecture";
|
|
106
|
+
readonly ruleId: string;
|
|
107
|
+
readonly expectedPaths: readonly string[];
|
|
108
|
+
readonly id: string;
|
|
109
|
+
readonly critical: boolean;
|
|
110
|
+
readonly description: string;
|
|
111
|
+
} | {
|
|
112
|
+
readonly kind: "transformation-completeness";
|
|
113
|
+
readonly ruleId: string;
|
|
114
|
+
readonly forbiddenLegacyPaths: readonly string[];
|
|
115
|
+
readonly requiredNewPaths: readonly string[];
|
|
116
|
+
readonly id: string;
|
|
117
|
+
readonly critical: boolean;
|
|
118
|
+
readonly description: string;
|
|
119
|
+
} | {
|
|
120
|
+
readonly kind: "semantic-residual";
|
|
121
|
+
readonly criterion: string;
|
|
122
|
+
readonly id: string;
|
|
123
|
+
readonly critical: boolean;
|
|
124
|
+
readonly description: string;
|
|
125
|
+
})[];
|
|
126
|
+
readonly solutions: readonly {
|
|
127
|
+
readonly kind: "historical-reference" | "independent-valid" | "simplified-valid" | "behavior-preserving-valid" | "historical-defect" | "mutation" | "model-near-miss" | "reward-hacking";
|
|
128
|
+
readonly id: string;
|
|
129
|
+
readonly expectedClass: "valid" | "wrong";
|
|
130
|
+
readonly family: string;
|
|
131
|
+
readonly commit?: string | undefined;
|
|
132
|
+
}[];
|
|
133
|
+
readonly observations: readonly {
|
|
134
|
+
readonly outcome: "pass" | "fail" | "unknown";
|
|
135
|
+
readonly solutionId: string;
|
|
136
|
+
readonly clauseId: string;
|
|
137
|
+
readonly repetition: number;
|
|
138
|
+
readonly detail: string;
|
|
139
|
+
readonly inconclusiveReason?: "unattributed-test-failure" | undefined;
|
|
140
|
+
}[];
|
|
141
|
+
readonly knownLimitations: readonly string[];
|
|
142
|
+
readonly executionBindingDigest?: string | undefined;
|
|
143
|
+
readonly executionRepetitions?: number | undefined;
|
|
144
|
+
}, RepositoryFoundryError, never>;
|
|
145
|
+
export declare const makeOracleBuilder: Effect.Effect<OracleBuilderShape, never, never>;
|
|
146
|
+
export declare const OracleBuilderLive: Layer.Layer<OracleBuilder, never, never>;
|
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { Context, Effect, Layer, Option, Semaphore } from "effect";
|
|
3
|
+
import { checkpointDigestV1 } from "../../case-pipeline-protocol.js";
|
|
4
|
+
import { repositoryCommandTestEvidenceV1 } from "../../adapters/repository-command-evidence.js";
|
|
5
|
+
import { inspectRepositorySolutionPathsV1, makeRepositoryPreparationCacheV1, replayRepositoryCommandsV1 } from "../../adapters/repository-command-runner.js";
|
|
6
|
+
import { RepositoryFoundryError } from "../../errors.js";
|
|
7
|
+
import { assertRepositoryHiddenFixtureSuiteV1 } from "../../repository-fixture-protocol.js";
|
|
8
|
+
import { assertRepositoryHiddenOracleV1 } from "../../repository-oracle-protocol.js";
|
|
9
|
+
import { evaluateRepositoryOracleAdequacyV1 } from "../../repository-quality-policy.js";
|
|
10
|
+
import { repositoryOracleExecutionBindingV1 } from "../../repository-oracle-execution-binding.js";
|
|
11
|
+
import { RepositoryFoundryEvidenceReconstruction } from "../evidence-reconstruction/service.js";
|
|
12
|
+
import { reportFoundryAuthoringArtifactV1, reportFoundryHeartbeatV1 } from "../foundry-progress/service.js";
|
|
13
|
+
export class OracleBuilder extends Context.Service()("@velum-labs/routekit-eval-setup/OracleBuilder") {
|
|
14
|
+
}
|
|
15
|
+
export const buildHistoricalHiddenOracleV1 = Effect.fn("OracleBuilder.buildHistorical")(function* (input) {
|
|
16
|
+
const reconstruction = yield* Effect.serviceOption(RepositoryFoundryEvidenceReconstruction);
|
|
17
|
+
if (Option.isSome(reconstruction))
|
|
18
|
+
return yield* reconstruction.value.oracle(input);
|
|
19
|
+
const oracleConcurrency = input.oracleConcurrency === undefined ? 2 : input.oracleConcurrency;
|
|
20
|
+
if (!Number.isInteger(oracleConcurrency) || oracleConcurrency < 1 || oracleConcurrency > 4) {
|
|
21
|
+
return yield* new RepositoryFoundryError({
|
|
22
|
+
operation: "run-command",
|
|
23
|
+
detail: "oracleConcurrency must be an integer from 1 to 4"
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (input.seed.status !== "qualified" || input.seed.referenceCommit === undefined) {
|
|
27
|
+
throw new Error("historical hidden oracle requires a qualified seed with a reference commit");
|
|
28
|
+
}
|
|
29
|
+
if (input.hiddenFixtureSuite !== undefined) {
|
|
30
|
+
assertRepositoryHiddenFixtureSuiteV1(input.hiddenFixtureSuite);
|
|
31
|
+
if (input.hiddenFixtureSuite.caseId !== input.caseId) {
|
|
32
|
+
throw new Error("hidden fixture suite case id does not match the oracle case");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const { executionBindingDigest, solutions, solutionMetadata, hiddenTestOverlays, protectedControlOverlays, structuralClauses, repetitions } = repositoryOracleExecutionBindingV1(input);
|
|
36
|
+
const ids = new Set(solutions.map((solution) => solution.id));
|
|
37
|
+
if (ids.size !== solutions.length) {
|
|
38
|
+
throw new Error("repository executable solution ids must be unique");
|
|
39
|
+
}
|
|
40
|
+
const executionId = randomUUID();
|
|
41
|
+
const evidenceKind = input.hiddenFixtureSuite === undefined ? "historical" : "generated";
|
|
42
|
+
const recordExecution = (suffix, value) => reportFoundryAuthoringArtifactV1({
|
|
43
|
+
version: 1,
|
|
44
|
+
operationId: `${input.caseId}:oracle:${executionId}:${suffix}`,
|
|
45
|
+
role: "oracle-executor",
|
|
46
|
+
model: "host",
|
|
47
|
+
reasoningEffort: "none",
|
|
48
|
+
schemaName: "routekit_repository_oracle_execution_v1",
|
|
49
|
+
validation: "validated",
|
|
50
|
+
request: {
|
|
51
|
+
instructions: "Host-recorded isolated execution evidence. This is not a model request or benchmark admission.",
|
|
52
|
+
input: {
|
|
53
|
+
executionId,
|
|
54
|
+
kind: evidenceKind,
|
|
55
|
+
caseId: input.caseId,
|
|
56
|
+
initialCommit: input.seed.initialState.commit,
|
|
57
|
+
referenceCommit: input.seed.referenceCommit
|
|
58
|
+
},
|
|
59
|
+
jsonSchema: { type: "object" },
|
|
60
|
+
maximumOutputTokens: 0
|
|
61
|
+
},
|
|
62
|
+
response: { text: JSON.stringify(value) },
|
|
63
|
+
value
|
|
64
|
+
});
|
|
65
|
+
const preparationCache = yield* makeRepositoryPreparationCacheV1({
|
|
66
|
+
repositoryRoot: input.repositoryRoot,
|
|
67
|
+
commits: [input.seed.initialState.commit, input.seed.referenceCommit],
|
|
68
|
+
trustedPreparationRecipes: input.seed.environment.trustedPreparationRecipes
|
|
69
|
+
});
|
|
70
|
+
const testClauses = input.seed.environment.gradeRecipes.map((recipe) => ({
|
|
71
|
+
id: `test-${recipe.id}`,
|
|
72
|
+
kind: "test-command",
|
|
73
|
+
critical: true,
|
|
74
|
+
description: `The repository's reviewed regression command ${recipe.id} passes.`,
|
|
75
|
+
recipeId: recipe.id,
|
|
76
|
+
expectedExitCode: 0,
|
|
77
|
+
fixtureIds: []
|
|
78
|
+
}));
|
|
79
|
+
const fixtureExecutions = input.hiddenFixtureSuite?.fixtures.map((fixture) => {
|
|
80
|
+
const recipe = [...input.seed.environment.gradeRecipes]
|
|
81
|
+
.filter((candidate) => candidate.cwd === "." ||
|
|
82
|
+
fixture.testPath === candidate.cwd ||
|
|
83
|
+
fixture.testPath.startsWith(`${candidate.cwd}/`))
|
|
84
|
+
.sort((left, right) => right.cwd.length - left.cwd.length)[0];
|
|
85
|
+
const overlay = input.hiddenFixtureSuite.overlays.find((candidate) => candidate.fixtureIds.length === 1 && candidate.fixtureIds[0] === fixture.id);
|
|
86
|
+
if (recipe === undefined || overlay === undefined) {
|
|
87
|
+
throw new Error(`hidden fixture ${JSON.stringify(fixture.id)} has no independently executable reviewed recipe and overlay`);
|
|
88
|
+
}
|
|
89
|
+
return { fixture, recipe, overlay };
|
|
90
|
+
}) ?? [];
|
|
91
|
+
const fixtureClauses = fixtureExecutions.map(({ fixture, recipe }) => ({
|
|
92
|
+
id: `fixture-${fixture.id}`,
|
|
93
|
+
kind: "test-command",
|
|
94
|
+
critical: true,
|
|
95
|
+
description: `The independently executed hidden fixture ${fixture.id} satisfies its expected behavior.`,
|
|
96
|
+
recipeId: recipe.id,
|
|
97
|
+
expectedExitCode: 0,
|
|
98
|
+
fixtureIds: [fixture.id]
|
|
99
|
+
}));
|
|
100
|
+
const validationClauses = input.seed.environment.candidateValidationRecipes.map((recipe) => ({
|
|
101
|
+
id: `validation-${recipe.id}`,
|
|
102
|
+
kind: "test-command",
|
|
103
|
+
critical: true,
|
|
104
|
+
description: "The candidate builds or passes its reviewed static validation before behavioral grading.",
|
|
105
|
+
recipeId: recipe.id,
|
|
106
|
+
expectedExitCode: 0,
|
|
107
|
+
fixtureIds: []
|
|
108
|
+
}));
|
|
109
|
+
const candidatePolicyClause = {
|
|
110
|
+
id: "candidate-policy-protected-paths",
|
|
111
|
+
kind: "candidate-policy",
|
|
112
|
+
critical: true,
|
|
113
|
+
description: "The candidate does not modify protected harness controls. Visible tests are independently restored or overlaid for hidden grading.",
|
|
114
|
+
policyId: "protected-harness-controls",
|
|
115
|
+
forbiddenPaths: [...new Set(input.seed.environment.protectedControlPaths)].sort()
|
|
116
|
+
};
|
|
117
|
+
const structuralPaths = [
|
|
118
|
+
...new Set(structuralClauses.flatMap((clause) => clause.kind === "architecture"
|
|
119
|
+
? [...clause.expectedPaths]
|
|
120
|
+
: [...clause.requiredNewPaths, ...clause.forbiddenLegacyPaths]))
|
|
121
|
+
];
|
|
122
|
+
const replaySolution = Effect.fnUntraced(function* (solution, solutionIndex) {
|
|
123
|
+
const observations = [...solutionRows[solutionIndex]];
|
|
124
|
+
const observed = (clauseId, repetition) => observations.some((row) => row.clauseId === clauseId && row.repetition === repetition);
|
|
125
|
+
const overridePaths = solution.fileOverrides?.map((override) => override.path) ?? [];
|
|
126
|
+
const duplicateOverridePaths = [
|
|
127
|
+
...new Set(overridePaths.filter((path, index) => overridePaths.indexOf(path) !== index))
|
|
128
|
+
];
|
|
129
|
+
const forbiddenOverridePaths = overridePaths.filter((path) => candidatePolicyClause.forbiddenPaths.includes(path));
|
|
130
|
+
const policyViolations = [
|
|
131
|
+
...forbiddenOverridePaths.map((path) => `protected path override: ${path}`),
|
|
132
|
+
...duplicateOverridePaths.map((path) => `duplicate path override: ${path}`)
|
|
133
|
+
];
|
|
134
|
+
observations.push(...Array.from({ length: repetitions }, (_, index) => ({
|
|
135
|
+
solutionId: solution.id,
|
|
136
|
+
clauseId: candidatePolicyClause.id,
|
|
137
|
+
repetition: index + 1,
|
|
138
|
+
outcome: policyViolations.length === 0 ? "pass" : "fail",
|
|
139
|
+
detail: policyViolations.length === 0
|
|
140
|
+
? "candidate material passed protected-path preflight"
|
|
141
|
+
: policyViolations.join("; ")
|
|
142
|
+
})).filter((row) => !observed(row.clauseId, row.repetition)));
|
|
143
|
+
if (policyViolations.length > 0) {
|
|
144
|
+
yield* publishReplayProgress(solutionIndex, observations);
|
|
145
|
+
return observations;
|
|
146
|
+
}
|
|
147
|
+
for (let repetition = 1; repetition <= repetitions; repetition += 1) {
|
|
148
|
+
if ([...validationClauses, ...testClauses].every((clause) => observed(clause.id, repetition)))
|
|
149
|
+
continue;
|
|
150
|
+
const results = yield* replayRepositoryCommandsV1({
|
|
151
|
+
preparationCache,
|
|
152
|
+
repositoryRoot: input.repositoryRoot,
|
|
153
|
+
commit: solution.commit,
|
|
154
|
+
recipes: input.seed.environment.gradeRecipes,
|
|
155
|
+
trustedPreparationRecipes: input.seed.environment.trustedPreparationRecipes,
|
|
156
|
+
candidateValidationRecipes: input.seed.environment.candidateValidationRecipes,
|
|
157
|
+
overlays: [...protectedControlOverlays, ...hiddenTestOverlays],
|
|
158
|
+
...(solution.fileOverrides === undefined ? {} : { fileOverrides: solution.fileOverrides }),
|
|
159
|
+
repetitions: 1,
|
|
160
|
+
repetitionStart: repetition
|
|
161
|
+
});
|
|
162
|
+
yield* recordExecution(`solution-${solutionIndex}:baseline:${repetition}`, {
|
|
163
|
+
diagnosticOnly: true,
|
|
164
|
+
admissionEvidence: false,
|
|
165
|
+
complete: false,
|
|
166
|
+
solutionId: solution.id,
|
|
167
|
+
results
|
|
168
|
+
});
|
|
169
|
+
yield* reportFoundryHeartbeatV1({
|
|
170
|
+
detail: `oracle baseline replay complete; solutionIndex=${solutionIndex + 1}; commandResults=${results.length}`
|
|
171
|
+
});
|
|
172
|
+
const preparationFailure = results.find((result) => !result.gradeExecuted && result.stage === "trusted-preparation");
|
|
173
|
+
if (preparationFailure !== undefined) {
|
|
174
|
+
return yield* new RepositoryFoundryError({
|
|
175
|
+
operation: "run-command",
|
|
176
|
+
detail: [
|
|
177
|
+
`trusted environment preparation failed for ${solution.id}`,
|
|
178
|
+
`recipe=${preparationFailure.recipeId}`,
|
|
179
|
+
`exit=${String(preparationFailure.exitCode)}`,
|
|
180
|
+
`timeout=${String(preparationFailure.timedOut)}`
|
|
181
|
+
].join("; ")
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
const validationResults = [
|
|
185
|
+
...new Map(results.map((result) => [result.repetition, result])).values()
|
|
186
|
+
];
|
|
187
|
+
for (const result of validationResults) {
|
|
188
|
+
for (const recipe of input.seed.environment.candidateValidationRecipes) {
|
|
189
|
+
const validation = result.candidateValidationResults.find((candidate) => candidate.recipeId === recipe.id);
|
|
190
|
+
observations.push({
|
|
191
|
+
solutionId: solution.id,
|
|
192
|
+
clauseId: `validation-${recipe.id}`,
|
|
193
|
+
repetition: result.repetition,
|
|
194
|
+
outcome: validation !== undefined && validation.exitCode === 0 && !validation.timedOut
|
|
195
|
+
? "pass"
|
|
196
|
+
: "unknown",
|
|
197
|
+
detail: validation === undefined
|
|
198
|
+
? `validation not executed because an earlier candidate validation failed; terminalStage=${result.stage}; terminalRecipe=${result.recipeId}`
|
|
199
|
+
: [
|
|
200
|
+
`exit=${String(validation.exitCode)}`,
|
|
201
|
+
`timeout=${String(validation.timedOut)}`,
|
|
202
|
+
`durationMs=${String(validation.durationMs)}`,
|
|
203
|
+
...(validation.outputTruncated ? ["output=truncated"] : [])
|
|
204
|
+
].join("; ")
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
for (const clause of testClauses) {
|
|
209
|
+
const result = results.find((candidate) => candidate.repetition === repetition && candidate.recipeId === clause.recipeId) ?? results.find((candidate) => candidate.repetition === repetition);
|
|
210
|
+
const evidence = repositoryCommandTestEvidenceV1(result, clause.recipeId);
|
|
211
|
+
observations.push({
|
|
212
|
+
solutionId: solution.id,
|
|
213
|
+
clauseId: clause.id,
|
|
214
|
+
repetition,
|
|
215
|
+
outcome: evidence.outcome,
|
|
216
|
+
...(evidence.inconclusiveReason === undefined
|
|
217
|
+
? {}
|
|
218
|
+
: { inconclusiveReason: evidence.inconclusiveReason }),
|
|
219
|
+
detail: result === undefined
|
|
220
|
+
? `recipe=${clause.recipeId}; result=unobserved`
|
|
221
|
+
: [
|
|
222
|
+
`recipe=${clause.recipeId}`,
|
|
223
|
+
`observedRecipe=${result.recipeId}`,
|
|
224
|
+
`exit=${String(result.exitCode)}`,
|
|
225
|
+
`stage=${result.stage}`,
|
|
226
|
+
`gradeExecuted=${String(result.gradeExecuted)}`,
|
|
227
|
+
`timeout=${String(result.timedOut)}`,
|
|
228
|
+
`durationMs=${String(result.durationMs)}`,
|
|
229
|
+
...(result.preparation === undefined
|
|
230
|
+
? []
|
|
231
|
+
: [
|
|
232
|
+
`preparationTemplate=${result.preparation.templateKey}`,
|
|
233
|
+
`cloneDurationMs=${result.preparation.cloneDurationMs}`
|
|
234
|
+
]),
|
|
235
|
+
`evidence=${evidence.detail}`,
|
|
236
|
+
...(result.outputTruncated ? ["output=truncated"] : [])
|
|
237
|
+
].join("; ")
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
yield* publishReplayProgress(solutionIndex, observations);
|
|
241
|
+
}
|
|
242
|
+
for (const [fixtureIndex, { fixture, recipe, overlay }] of fixtureExecutions.entries()) {
|
|
243
|
+
for (let repetition = 1; repetition <= repetitions; repetition += 1) {
|
|
244
|
+
if (observed(`fixture-${fixture.id}`, repetition))
|
|
245
|
+
continue;
|
|
246
|
+
const fixtureResults = yield* replayRepositoryCommandsV1({
|
|
247
|
+
preparationCache,
|
|
248
|
+
repositoryRoot: input.repositoryRoot,
|
|
249
|
+
commit: solution.commit,
|
|
250
|
+
recipes: [recipe],
|
|
251
|
+
trustedPreparationRecipes: input.seed.environment.trustedPreparationRecipes,
|
|
252
|
+
candidateValidationRecipes: input.seed.environment.candidateValidationRecipes,
|
|
253
|
+
overlays: [...protectedControlOverlays, ...hiddenTestOverlays],
|
|
254
|
+
contentOverlays: [
|
|
255
|
+
{
|
|
256
|
+
path: overlay.path,
|
|
257
|
+
content: overlay.content
|
|
258
|
+
}
|
|
259
|
+
],
|
|
260
|
+
...(solution.fileOverrides === undefined
|
|
261
|
+
? {}
|
|
262
|
+
: { fileOverrides: solution.fileOverrides }),
|
|
263
|
+
repetitions: 1,
|
|
264
|
+
repetitionStart: repetition
|
|
265
|
+
});
|
|
266
|
+
yield* recordExecution(`solution-${solutionIndex}:fixture-${fixtureIndex}:${repetition}`, {
|
|
267
|
+
diagnosticOnly: true,
|
|
268
|
+
admissionEvidence: false,
|
|
269
|
+
complete: false,
|
|
270
|
+
solutionId: solution.id,
|
|
271
|
+
fixtureId: fixture.id,
|
|
272
|
+
results: fixtureResults
|
|
273
|
+
});
|
|
274
|
+
yield* reportFoundryHeartbeatV1({
|
|
275
|
+
detail: `oracle fixture replay complete; solutionIndex=${solutionIndex + 1}; fixtureIndex=${fixtureIndex + 1}; commandResults=${fixtureResults.length}`
|
|
276
|
+
});
|
|
277
|
+
const result = fixtureResults.find((candidate) => candidate.repetition === repetition && candidate.recipeId === recipe.id) ?? fixtureResults.find((candidate) => candidate.repetition === repetition);
|
|
278
|
+
const evidence = repositoryCommandTestEvidenceV1(result, recipe.id);
|
|
279
|
+
observations.push({
|
|
280
|
+
solutionId: solution.id,
|
|
281
|
+
clauseId: `fixture-${fixture.id}`,
|
|
282
|
+
repetition,
|
|
283
|
+
outcome: evidence.outcome,
|
|
284
|
+
...(evidence.inconclusiveReason === undefined
|
|
285
|
+
? {}
|
|
286
|
+
: { inconclusiveReason: evidence.inconclusiveReason }),
|
|
287
|
+
detail: result === undefined
|
|
288
|
+
? `fixture=${fixture.id}; recipe=${recipe.id}; result=unobserved`
|
|
289
|
+
: [
|
|
290
|
+
`fixture=${fixture.id}`,
|
|
291
|
+
`recipe=${recipe.id}`,
|
|
292
|
+
`observedRecipe=${result.recipeId}`,
|
|
293
|
+
`exit=${String(result.exitCode)}`,
|
|
294
|
+
`stage=${result.stage}`,
|
|
295
|
+
`gradeExecuted=${String(result.gradeExecuted)}`,
|
|
296
|
+
`timeout=${String(result.timedOut)}`,
|
|
297
|
+
`durationMs=${String(result.durationMs)}`,
|
|
298
|
+
...(result.preparation === undefined
|
|
299
|
+
? []
|
|
300
|
+
: [
|
|
301
|
+
`preparationTemplate=${result.preparation.templateKey}`,
|
|
302
|
+
`cloneDurationMs=${result.preparation.cloneDurationMs}`
|
|
303
|
+
]),
|
|
304
|
+
`evidence=${evidence.detail}`,
|
|
305
|
+
...(result.outputTruncated ? ["output=truncated"] : [])
|
|
306
|
+
].join("; ")
|
|
307
|
+
});
|
|
308
|
+
yield* publishReplayProgress(solutionIndex, observations);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (structuralPaths.length > 0 &&
|
|
312
|
+
!structuralClauses.every((clause) => Array.from({ length: repetitions }, (_, index) => index + 1).every((repetition) => observed(clause.id, repetition)))) {
|
|
313
|
+
const pathInspections = yield* inspectRepositorySolutionPathsV1({
|
|
314
|
+
repositoryRoot: input.repositoryRoot,
|
|
315
|
+
commit: solution.commit,
|
|
316
|
+
paths: structuralPaths,
|
|
317
|
+
repetitions,
|
|
318
|
+
...(solution.fileOverrides === undefined ? {} : { fileOverrides: solution.fileOverrides })
|
|
319
|
+
});
|
|
320
|
+
for (const clause of structuralClauses) {
|
|
321
|
+
for (let repetition = 1; repetition <= repetitions; repetition += 1) {
|
|
322
|
+
const inspected = pathInspections.filter((entry) => entry.repetition === repetition);
|
|
323
|
+
const outcome = clause.kind === "architecture"
|
|
324
|
+
? clause.expectedPaths.every((path) => inspectionKind(inspected, path) === "file")
|
|
325
|
+
: clause.requiredNewPaths.every((path) => inspectionKind(inspected, path) === "file") &&
|
|
326
|
+
clause.forbiddenLegacyPaths.every((path) => inspectionKind(inspected, path) === "missing");
|
|
327
|
+
observations.push({
|
|
328
|
+
solutionId: solution.id,
|
|
329
|
+
clauseId: clause.id,
|
|
330
|
+
repetition,
|
|
331
|
+
outcome: outcome ? "pass" : "fail",
|
|
332
|
+
detail: structuralObservationDetail(clause, inspected)
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
yield* publishReplayProgress(solutionIndex, observations);
|
|
337
|
+
}
|
|
338
|
+
return observations;
|
|
339
|
+
});
|
|
340
|
+
const clauses = [
|
|
341
|
+
candidatePolicyClause,
|
|
342
|
+
...validationClauses,
|
|
343
|
+
...testClauses,
|
|
344
|
+
...fixtureClauses,
|
|
345
|
+
...structuralClauses
|
|
346
|
+
];
|
|
347
|
+
const makeOracle = (observations) => {
|
|
348
|
+
const oracle = {
|
|
349
|
+
version: 1,
|
|
350
|
+
caseId: input.caseId,
|
|
351
|
+
hardFailurePolicy: "any-critical-hard-clause-fails",
|
|
352
|
+
executionBindingDigest,
|
|
353
|
+
executionRepetitions: repetitions,
|
|
354
|
+
fixtures: input.hiddenFixtureSuite?.fixtures ?? [],
|
|
355
|
+
clauses,
|
|
356
|
+
// Executable overrides belong to the execution input, not the oracle's
|
|
357
|
+
// public solution metadata. The digest above preserves their identity
|
|
358
|
+
// across the schema round trip that deliberately omits patch bodies.
|
|
359
|
+
solutions: solutionMetadata,
|
|
360
|
+
observations: [...observations].sort((left, right) => solutions.findIndex(({ id }) => id === left.solutionId) -
|
|
361
|
+
solutions.findIndex(({ id }) => id === right.solutionId) ||
|
|
362
|
+
clauses.findIndex(({ id }) => id === left.clauseId) -
|
|
363
|
+
clauses.findIndex(({ id }) => id === right.clauseId) ||
|
|
364
|
+
left.repetition - right.repetition),
|
|
365
|
+
knownLimitations: [
|
|
366
|
+
...(input.hiddenFixtureSuite === undefined
|
|
367
|
+
? ["No generated counterfactual or metamorphic fixtures were supplied."]
|
|
368
|
+
: []),
|
|
369
|
+
...(structuralClauses.length === 0
|
|
370
|
+
? [
|
|
371
|
+
"No reviewed structural or transformation-completeness clauses were supplied for this case."
|
|
372
|
+
]
|
|
373
|
+
: [])
|
|
374
|
+
]
|
|
375
|
+
};
|
|
376
|
+
assertRepositoryHiddenOracleV1(oracle);
|
|
377
|
+
return oracle;
|
|
378
|
+
};
|
|
379
|
+
const expectedOracle = makeOracle([]);
|
|
380
|
+
const solutionRows = Array.from({ length: solutions.length }, () => []);
|
|
381
|
+
const observationKey = (clauseId, repetition) => `${clauseId}:${repetition}`;
|
|
382
|
+
const replayUnits = [
|
|
383
|
+
Array.from({ length: repetitions }, (_, index) => observationKey(candidatePolicyClause.id, index + 1)),
|
|
384
|
+
...Array.from({ length: repetitions }, (_, index) => [...validationClauses, ...testClauses].map((clause) => observationKey(clause.id, index + 1))),
|
|
385
|
+
...fixtureClauses.flatMap((clause) => Array.from({ length: repetitions }, (_, index) => [observationKey(clause.id, index + 1)])),
|
|
386
|
+
structuralClauses.flatMap((clause) => Array.from({ length: repetitions }, (_, index) => observationKey(clause.id, index + 1)))
|
|
387
|
+
].filter((unit) => unit.length > 0);
|
|
388
|
+
const completeSolution = (rows) => {
|
|
389
|
+
const policyFailed = rows.some((row) => row.clauseId === candidatePolicyClause.id && row.outcome === "fail");
|
|
390
|
+
return (rows.length === (policyFailed ? repetitions : expectedOracle.clauses.length * repetitions));
|
|
391
|
+
};
|
|
392
|
+
// Legacy checkpoints did not bind patch content or the preparation plan.
|
|
393
|
+
// Preserve their surrounding tournament state, but replay execution instead
|
|
394
|
+
// of either trusting incomplete identity or permanently rejecting resume.
|
|
395
|
+
if (input.resumeOracle?.executionBindingDigest !== undefined) {
|
|
396
|
+
const resumed = input.resumeOracle;
|
|
397
|
+
if (resumed.executionBindingDigest !== executionBindingDigest ||
|
|
398
|
+
(resumed.executionRepetitions !== undefined && resumed.executionRepetitions !== repetitions) ||
|
|
399
|
+
resumed.caseId !== expectedOracle.caseId ||
|
|
400
|
+
resumed.hardFailurePolicy !== expectedOracle.hardFailurePolicy ||
|
|
401
|
+
checkpointDigestV1(resumed.fixtures) !== checkpointDigestV1(expectedOracle.fixtures) ||
|
|
402
|
+
checkpointDigestV1(resumed.clauses) !== checkpointDigestV1(expectedOracle.clauses) ||
|
|
403
|
+
checkpointDigestV1(resumed.solutions) !== checkpointDigestV1(expectedOracle.solutions)) {
|
|
404
|
+
return yield* new RepositoryFoundryError({
|
|
405
|
+
operation: "run-command",
|
|
406
|
+
detail: "resumable oracle evidence does not bind the current executable inputs, environment, case, suite, clauses, and solutions"
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
if (resumed.observations.some((row) => !ids.has(row.solutionId))) {
|
|
410
|
+
return yield* new RepositoryFoundryError({
|
|
411
|
+
operation: "run-command",
|
|
412
|
+
detail: "resumable oracle evidence refers to an unknown solution"
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
const clauseIds = new Set(expectedOracle.clauses.map(({ id }) => id));
|
|
416
|
+
for (const [solutionIndex, solution] of solutions.entries()) {
|
|
417
|
+
const rows = resumed.observations.filter((observation) => observation.solutionId === solution.id);
|
|
418
|
+
if (rows.length === 0)
|
|
419
|
+
continue;
|
|
420
|
+
const keys = new Set();
|
|
421
|
+
for (const row of rows) {
|
|
422
|
+
const key = `${row.clauseId}:${String(row.repetition)}`;
|
|
423
|
+
if (!clauseIds.has(row.clauseId) ||
|
|
424
|
+
row.repetition < 1 ||
|
|
425
|
+
row.repetition > repetitions ||
|
|
426
|
+
keys.has(key)) {
|
|
427
|
+
return yield* new RepositoryFoundryError({
|
|
428
|
+
operation: "run-command",
|
|
429
|
+
detail: `resumable oracle evidence is invalid for solution ${JSON.stringify(solution.id)}`
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
keys.add(key);
|
|
433
|
+
}
|
|
434
|
+
const policyFailed = rows.some((row) => row.clauseId === candidatePolicyClause.id && row.outcome === "fail");
|
|
435
|
+
const expectedKeys = policyFailed
|
|
436
|
+
? Array.from({ length: repetitions }, (_, index) => `${candidatePolicyClause.id}:${String(index + 1)}`)
|
|
437
|
+
: expectedOracle.clauses.flatMap((clause) => Array.from({ length: repetitions }, (_, index) => `${clause.id}:${String(index + 1)}`));
|
|
438
|
+
if (rows.some((row) => !expectedKeys.includes(observationKey(row.clauseId, row.repetition))) ||
|
|
439
|
+
!replayUnits[0].every((key) => keys.has(key)) ||
|
|
440
|
+
replayUnits.some((unit) => unit.some((key) => keys.has(key)) && !unit.every((key) => keys.has(key)))) {
|
|
441
|
+
return yield* new RepositoryFoundryError({
|
|
442
|
+
operation: "run-command",
|
|
443
|
+
detail: `resumable oracle evidence contains an incomplete replay unit for solution ${JSON.stringify(solution.id)}`
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
solutionRows[solutionIndex] = rows;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
let completedSolutions = solutionRows.filter(completeSolution).length;
|
|
450
|
+
const progressSemaphore = yield* Semaphore.make(1);
|
|
451
|
+
const publishReplayProgress = (solutionIndex, observations) => progressSemaphore.withPermit(Effect.gen(function* () {
|
|
452
|
+
// Snapshot before publishing: another concurrent solution may finish while
|
|
453
|
+
// the durable callback runs, but it cannot overwrite this accepted prefix.
|
|
454
|
+
solutionRows[solutionIndex] = [...observations];
|
|
455
|
+
if (input.onReplayCompleted !== undefined) {
|
|
456
|
+
yield* input.onReplayCompleted(makeOracle(solutionRows.flat()));
|
|
457
|
+
}
|
|
458
|
+
yield* reportFoundryHeartbeatV1({
|
|
459
|
+
detail: `oracle replay checkpoint; solutionIndex=${solutionIndex + 1}; observations=${observations.length}`
|
|
460
|
+
});
|
|
461
|
+
}));
|
|
462
|
+
// Each replay owns fresh scoped checkouts, HOME/TMPDIR, and child process groups.
|
|
463
|
+
// Keep all repetitions and fixtures sequential within one solution; flatten in input order.
|
|
464
|
+
yield* Effect.forEach(solutions
|
|
465
|
+
.map((solution, index) => ({ solution, index }))
|
|
466
|
+
.filter(({ index }) => !completeSolution(solutionRows[index])), ({ solution, index }) => replaySolution(solution, index).pipe(Effect.flatMap((rows) => progressSemaphore.withPermit(Effect.gen(function* () {
|
|
467
|
+
solutionRows[index] = rows;
|
|
468
|
+
completedSolutions += 1;
|
|
469
|
+
yield* recordExecution(`solution-${index}:complete`, {
|
|
470
|
+
diagnosticOnly: true,
|
|
471
|
+
admissionEvidence: false,
|
|
472
|
+
complete: false,
|
|
473
|
+
solutionId: solution.id,
|
|
474
|
+
observations: rows
|
|
475
|
+
});
|
|
476
|
+
if (input.onSolutionCompleted !== undefined) {
|
|
477
|
+
yield* input.onSolutionCompleted(makeOracle(solutionRows.flat()));
|
|
478
|
+
}
|
|
479
|
+
yield* reportFoundryHeartbeatV1({
|
|
480
|
+
detail: `oracle solution completed=${completedSolutions}/${solutions.length}; solutionIndex=${index + 1}; observations=${rows.length}`
|
|
481
|
+
});
|
|
482
|
+
})))), { concurrency: oracleConcurrency });
|
|
483
|
+
const oracle = makeOracle(solutionRows.flat());
|
|
484
|
+
const adequacy = evaluateRepositoryOracleAdequacyV1(oracle);
|
|
485
|
+
yield* recordExecution("complete", {
|
|
486
|
+
diagnosticOnly: true,
|
|
487
|
+
admissionEvidence: false,
|
|
488
|
+
complete: true,
|
|
489
|
+
oracle,
|
|
490
|
+
adequacy
|
|
491
|
+
});
|
|
492
|
+
const unresolved = new Set([
|
|
493
|
+
...adequacy.falseAcceptedSolutionIds,
|
|
494
|
+
...adequacy.falseRejectedSolutionIds,
|
|
495
|
+
...adequacy.unstableSolutionIds
|
|
496
|
+
]).size;
|
|
497
|
+
yield* reportFoundryHeartbeatV1({
|
|
498
|
+
role: "oracle-executor",
|
|
499
|
+
detail: `oracle measurement; executionId=${executionId}; kind=${evidenceKind}; solutions=${solutions.length}; ` +
|
|
500
|
+
`falseAccepts=${adequacy.falseAcceptedSolutionIds.length}; falseRejects=${adequacy.falseRejectedSolutionIds.length}; ` +
|
|
501
|
+
`unstable=${adequacy.unstableSolutionIds.length}; unresolved=${unresolved}; adequate=${String(adequacy.admitted)}`
|
|
502
|
+
});
|
|
503
|
+
return oracle;
|
|
504
|
+
}, Effect.scoped);
|
|
505
|
+
const inspectionKind = (inspections, path) => inspections.find((entry) => entry.path === path)?.kind ?? "unobserved";
|
|
506
|
+
const structuralObservationDetail = (clause, inspections) => {
|
|
507
|
+
const paths = clause.kind === "architecture"
|
|
508
|
+
? clause.expectedPaths
|
|
509
|
+
: [...clause.requiredNewPaths, ...clause.forbiddenLegacyPaths];
|
|
510
|
+
return paths.map((path) => `${path}=${inspectionKind(inspections, path)}`).join("; ");
|
|
511
|
+
};
|
|
512
|
+
export const makeOracleBuilder = Effect.succeed(OracleBuilder.of({ buildHistorical: buildHistoricalHiddenOracleV1 }));
|
|
513
|
+
export const OracleBuilderLive = Layer.effect(OracleBuilder, makeOracleBuilder);
|