@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,619 @@
|
|
|
1
|
+
import { Clock, Effect, Option, Schema } from "effect";
|
|
2
|
+
import { captureGitTreeSnapshotV1, readGitTreeFileV1 } from "../../adapters/git-task-history.js";
|
|
3
|
+
import { checkpointDigestV1, PipelineStageError, pipelineStageToProgressStageV1 } from "../../case-pipeline-protocol.js";
|
|
4
|
+
import { RepositoryFoundryError } from "../../errors.js";
|
|
5
|
+
import { repositoryFoundryRoleOutputCeilingV1 } from "../../repository-foundry-plan-protocol.js";
|
|
6
|
+
import { repositoryFoundryModelAssignmentV1 } from "../../repository-language-model-protocol.js";
|
|
7
|
+
import { RepositorySpecificationBehaviorCoverageV1, RepositorySpecificationCritiqueAxisV1, RepositorySpecificationDimensionFitV1, RepositorySpecificationReferenceCompatibilityV1 } from "../../repository-specification-critique-protocol.js";
|
|
8
|
+
import { generateWithFeedbackV1 } from "../budgeted-model/service.js";
|
|
9
|
+
import { reportFoundryStageV1 } from "../foundry-progress/service.js";
|
|
10
|
+
import { groundedStructuredGenerationV1 } from "../grounded-authoring/service.js";
|
|
11
|
+
import { RepositoryFoundryLanguageModel } from "../language-model/service.js";
|
|
12
|
+
/**
|
|
13
|
+
* Reference-grounded specification stage for the additive case pipeline.
|
|
14
|
+
* The analyst and private critic inspect only pinned Git trees. The writer is
|
|
15
|
+
* deliberately blind to the reference tree and receives only public behavior
|
|
16
|
+
* prose plus complete pre-change sources. Reviews are advisory specification
|
|
17
|
+
* evidence; they never constitute benchmark admission evidence.
|
|
18
|
+
*/
|
|
19
|
+
const STAGE = "spec";
|
|
20
|
+
const MAX_CONTEXT_FILES = 12;
|
|
21
|
+
const MAX_CONTEXT_FILE_BYTES = 96_000;
|
|
22
|
+
const MAX_CONTEXT_TOTAL_BYTES = 256_000;
|
|
23
|
+
const DIMENSION_MISMATCH_CONFIRMATIONS = 2;
|
|
24
|
+
const AnalystCitationV1 = Schema.Struct({
|
|
25
|
+
commit: Schema.Literals(["initial", "reference"]),
|
|
26
|
+
path: Schema.String,
|
|
27
|
+
startLine: Schema.Finite,
|
|
28
|
+
endLine: Schema.Finite
|
|
29
|
+
});
|
|
30
|
+
const AnalystScopeEntryV1 = Schema.Struct({
|
|
31
|
+
id: Schema.String,
|
|
32
|
+
kind: Schema.Literals(["changed", "preserved"]),
|
|
33
|
+
behaviorIds: Schema.Array(Schema.String),
|
|
34
|
+
description: Schema.String,
|
|
35
|
+
evidence: Schema.Array(AnalystCitationV1)
|
|
36
|
+
});
|
|
37
|
+
const PipelineSpecificationAnalysisV1 = Schema.Struct({
|
|
38
|
+
summary: Schema.String,
|
|
39
|
+
userObservableBehaviors: Schema.Array(Schema.String),
|
|
40
|
+
constraints: Schema.Array(Schema.String),
|
|
41
|
+
risks: Schema.Array(Schema.String),
|
|
42
|
+
relevantPaths: Schema.Array(Schema.String),
|
|
43
|
+
scope: Schema.Array(AnalystScopeEntryV1)
|
|
44
|
+
});
|
|
45
|
+
const PipelineVisibleTaskProposalV1 = Schema.Struct({
|
|
46
|
+
requestText: Schema.String,
|
|
47
|
+
constraints: Schema.Array(Schema.String)
|
|
48
|
+
});
|
|
49
|
+
const PipelineSpecificationReviewOutputV1 = Schema.Struct({
|
|
50
|
+
verdict: Schema.Literals(["sufficient", "insufficient"]),
|
|
51
|
+
detail: Schema.String,
|
|
52
|
+
criticalBehaviorCoverage: Schema.Array(RepositorySpecificationBehaviorCoverageV1),
|
|
53
|
+
dimensionFit: RepositorySpecificationDimensionFitV1,
|
|
54
|
+
referenceCompatibility: RepositorySpecificationReferenceCompatibilityV1,
|
|
55
|
+
findings: Schema.Array(Schema.Struct({
|
|
56
|
+
axis: RepositorySpecificationCritiqueAxisV1,
|
|
57
|
+
severity: Schema.Literals(["blocker", "warning"]),
|
|
58
|
+
detail: Schema.String
|
|
59
|
+
}))
|
|
60
|
+
});
|
|
61
|
+
const ANALYST_INSTRUCTIONS = `You are the private repository analyst for one coding benchmark case.
|
|
62
|
+
Inspect both pinned Git trees with the grounded tools before submitting. The complete dimension contract is
|
|
63
|
+
supplied as {id, description, includes, excludes}; apply every field and do not broaden the historical change
|
|
64
|
+
to force a fit. Establish the actual user-observable change and the behavior the reference preserves.
|
|
65
|
+
Return at least one changed and one preserved scope clause. Every clause must cite non-empty one-based inclusive
|
|
66
|
+
line ranges in both the initial and reference trees using {commit, path, startLine, endLine}. Cover every supplied
|
|
67
|
+
target behavior id with grounded scope. Select only complete pre-change files that a blind coding agent needs;
|
|
68
|
+
relevantPaths becomes the writer's entire repository context, so keep it focused. Public analysis and scope
|
|
69
|
+
prose must not include commits, private source identifiers, test contents, or implementation instructions.
|
|
70
|
+
Do not write the visible task, fixtures, or a solution. Return one submit action only after grounding the result.`;
|
|
71
|
+
const WRITER_INSTRUCTIONS = `You are the blind specification-writer for a repository coding benchmark.
|
|
72
|
+
You receive public issue scope, the complete dimension contract, and complete files from the pinned pre-change
|
|
73
|
+
checkout. You do not receive the reference tree, historical patch, private citations, tests added by the change,
|
|
74
|
+
or hidden fixtures. Write a realistic issue-style request that states all changed behavior and necessary
|
|
75
|
+
preservation boundaries while allowing any behaviorally correct implementation. Do not invent requirements to
|
|
76
|
+
match the dimension. Do not mention benchmark machinery or prescribe implementation details. On a revision,
|
|
77
|
+
resolve every supplied review finding while preserving the authentic scope. Return only requestText and constraints.`;
|
|
78
|
+
const CRITIC_INSTRUCTIONS = `You are the single private reference critic for a benchmark specification.
|
|
79
|
+
Inspect both pinned Git trees with the grounded tools. Review the visible task against the complete dimension
|
|
80
|
+
contract and every grounded changed and preserved scope clause. Model criticism is advisory: do not claim that
|
|
81
|
+
your review admits or rejects a benchmark. Return exactly one coverage record for every critical behavior id.
|
|
82
|
+
Return dimensionFit for the exact dimension id, supported by paths in the initial tree. Return
|
|
83
|
+
referenceCompatibility with exactly one scopeCoverage record per scope id; every support record must cite
|
|
84
|
+
non-empty one-based inclusive reference-tree lines using the supplied sourceId catalog. Mark the review
|
|
85
|
+
sufficient only when the task covers all critical behavior, fits the complete dimension contract, and is fully
|
|
86
|
+
compatible with the pinned reference. Findings and detail sent to the blind writer must remain public behavior
|
|
87
|
+
prose: do not quote private code, commits, source ids, tests, or prescribe a patch. If the authentic change is
|
|
88
|
+
off-dimension, say mismatch rather than widening it. Return one submit action after grounding the review.`;
|
|
89
|
+
const failure = (detail, cause) => new RepositoryFoundryError({
|
|
90
|
+
operation: "run-pipeline-stage",
|
|
91
|
+
detail,
|
|
92
|
+
...(cause === undefined ? {} : { cause })
|
|
93
|
+
});
|
|
94
|
+
const assignmentOf = (input) => Effect.try({
|
|
95
|
+
try: () => repositoryFoundryModelAssignmentV1(input.plan, input.role),
|
|
96
|
+
catch: (cause) => failure(`could not resolve ${input.role} model assignment`, cause)
|
|
97
|
+
});
|
|
98
|
+
const nonEmpty = (value) => value.trim().length > 0;
|
|
99
|
+
const uniqueNonEmpty = (values) => values.length > 0 && new Set(values).size === values.length && values.every(nonEmpty);
|
|
100
|
+
const citationKey = (citation) => `${citation.commit}:${citation.path}:${String(citation.startLine)}:${String(citation.endLine)}`;
|
|
101
|
+
const readCitationContent = Effect.fnUntraced(function* (input) {
|
|
102
|
+
const snapshot = input.snapshots[input.citation.commit];
|
|
103
|
+
const key = `${input.citation.commit}:${input.citation.path}`;
|
|
104
|
+
const cached = input.cache.get(key);
|
|
105
|
+
if (cached !== undefined)
|
|
106
|
+
return cached;
|
|
107
|
+
if (!snapshot.files.includes(input.citation.path))
|
|
108
|
+
return undefined;
|
|
109
|
+
const content = yield* readGitTreeFileV1({ snapshot, path: input.citation.path });
|
|
110
|
+
input.cache.set(key, content);
|
|
111
|
+
return content;
|
|
112
|
+
});
|
|
113
|
+
const citationIsValid = Effect.fnUntraced(function* (input) {
|
|
114
|
+
if (!nonEmpty(input.citation.path) ||
|
|
115
|
+
!Number.isSafeInteger(input.citation.startLine) ||
|
|
116
|
+
!Number.isSafeInteger(input.citation.endLine) ||
|
|
117
|
+
input.citation.startLine < 1 ||
|
|
118
|
+
input.citation.endLine < input.citation.startLine) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
const content = yield* readCitationContent(input);
|
|
122
|
+
if (content === undefined)
|
|
123
|
+
return false;
|
|
124
|
+
const lines = content.split("\n");
|
|
125
|
+
return (input.citation.endLine <= lines.length &&
|
|
126
|
+
lines
|
|
127
|
+
.slice(input.citation.startLine - 1, input.citation.endLine)
|
|
128
|
+
.join("\n")
|
|
129
|
+
.trim().length > 0);
|
|
130
|
+
});
|
|
131
|
+
const validateAnalysis = Effect.fnUntraced(function* (input) {
|
|
132
|
+
const findings = [];
|
|
133
|
+
if (!nonEmpty(input.analysis.summary) ||
|
|
134
|
+
!uniqueNonEmpty(input.analysis.userObservableBehaviors) ||
|
|
135
|
+
input.analysis.constraints.some((entry) => !nonEmpty(entry)) ||
|
|
136
|
+
input.analysis.risks.some((entry) => !nonEmpty(entry))) {
|
|
137
|
+
findings.push({
|
|
138
|
+
kind: "contract",
|
|
139
|
+
message: "Analysis requires a summary, user-observable behaviors, and non-empty constraint and risk entries."
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
if (!uniqueNonEmpty(input.analysis.relevantPaths) ||
|
|
143
|
+
input.analysis.relevantPaths.length > MAX_CONTEXT_FILES ||
|
|
144
|
+
input.analysis.relevantPaths.some((path) => !input.snapshots.initial.files.includes(path))) {
|
|
145
|
+
findings.push({
|
|
146
|
+
kind: "contract",
|
|
147
|
+
message: `Select between one and ${String(MAX_CONTEXT_FILES)} unique files that exist in the pinned initial tree.`
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
const scopeIds = input.analysis.scope.map((entry) => entry.id);
|
|
151
|
+
if (input.analysis.scope.length < 2 ||
|
|
152
|
+
new Set(scopeIds).size !== scopeIds.length ||
|
|
153
|
+
input.analysis.scope.some((entry) => !nonEmpty(entry.id) ||
|
|
154
|
+
!nonEmpty(entry.description) ||
|
|
155
|
+
!uniqueNonEmpty(entry.behaviorIds) ||
|
|
156
|
+
entry.behaviorIds.some((id) => !input.behaviorIds.has(id)) ||
|
|
157
|
+
entry.evidence.length < 2 ||
|
|
158
|
+
new Set(entry.evidence.map(citationKey)).size !== entry.evidence.length ||
|
|
159
|
+
!entry.evidence.some((citation) => citation.commit === "initial") ||
|
|
160
|
+
!entry.evidence.some((citation) => citation.commit === "reference")) ||
|
|
161
|
+
!input.analysis.scope.some((entry) => entry.kind === "changed") ||
|
|
162
|
+
!input.analysis.scope.some((entry) => entry.kind === "preserved") ||
|
|
163
|
+
[...input.behaviorIds].some((behaviorId) => !input.analysis.scope.some((entry) => entry.behaviorIds.includes(behaviorId)))) {
|
|
164
|
+
findings.push({
|
|
165
|
+
kind: "contract",
|
|
166
|
+
message: "Scope needs unique changed and preserved clauses, must cover every target behavior id, and each clause needs initial and reference line citations."
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
const citations = input.analysis.scope.flatMap((entry) => entry.evidence);
|
|
170
|
+
const citationChecks = yield* Effect.forEach(citations, (citation) => citationIsValid({ citation, snapshots: input.snapshots, cache: input.cache }));
|
|
171
|
+
if (citationChecks.some((valid) => !valid)) {
|
|
172
|
+
findings.push({
|
|
173
|
+
kind: "contract",
|
|
174
|
+
message: "One or more scope citations do not identify non-empty, one-based inclusive lines in the named pinned tree."
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
const contextContents = yield* Effect.forEach(input.analysis.relevantPaths, (path) => readCitationContent({
|
|
178
|
+
citation: { commit: "initial", path, startLine: 1, endLine: 1 },
|
|
179
|
+
snapshots: input.snapshots,
|
|
180
|
+
cache: input.cache
|
|
181
|
+
}));
|
|
182
|
+
const contextBytes = contextContents.map((content) => content === undefined ? 0 : Buffer.byteLength(content));
|
|
183
|
+
if (contextBytes.some((bytes) => bytes > MAX_CONTEXT_FILE_BYTES) ||
|
|
184
|
+
contextBytes.reduce((total, bytes) => total + bytes, 0) > MAX_CONTEXT_TOTAL_BYTES) {
|
|
185
|
+
findings.push({
|
|
186
|
+
kind: "contract",
|
|
187
|
+
message: `Select complete context files within ${String(MAX_CONTEXT_FILE_BYTES)} bytes per file and ${String(MAX_CONTEXT_TOTAL_BYTES)} bytes total. Oversized files are not truncated.`
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
return findings;
|
|
191
|
+
});
|
|
192
|
+
const loadContextSources = Effect.fnUntraced(function* (input) {
|
|
193
|
+
const sources = [];
|
|
194
|
+
let totalBytes = 0;
|
|
195
|
+
for (const path of input.paths) {
|
|
196
|
+
if (!input.initial.files.includes(path)) {
|
|
197
|
+
return yield* failure(`analyst selected an unavailable initial-tree context path: ${path}`);
|
|
198
|
+
}
|
|
199
|
+
const content = yield* readGitTreeFileV1({ snapshot: input.initial, path });
|
|
200
|
+
const bytes = Buffer.byteLength(content);
|
|
201
|
+
if (bytes > MAX_CONTEXT_FILE_BYTES) {
|
|
202
|
+
return yield* failure(`analyst selected ${path}, whose complete ${String(bytes)} bytes exceed the ${String(MAX_CONTEXT_FILE_BYTES)}-byte context-file bound; no truncated file was presented as complete`);
|
|
203
|
+
}
|
|
204
|
+
totalBytes += bytes;
|
|
205
|
+
if (totalBytes > MAX_CONTEXT_TOTAL_BYTES) {
|
|
206
|
+
return yield* failure(`complete writer context exceeds ${String(MAX_CONTEXT_TOTAL_BYTES)} bytes; no context file was truncated`);
|
|
207
|
+
}
|
|
208
|
+
sources.push({ path, content });
|
|
209
|
+
}
|
|
210
|
+
return sources;
|
|
211
|
+
});
|
|
212
|
+
const makeSourceCatalog = Effect.fnUntraced(function* (input) {
|
|
213
|
+
const paths = [...new Set(input.paths)].sort();
|
|
214
|
+
const sources = [];
|
|
215
|
+
for (const path of paths) {
|
|
216
|
+
for (const phase of ["initial", "reference"]) {
|
|
217
|
+
const content = yield* readCitationContent({
|
|
218
|
+
citation: { commit: phase, path, startLine: 1, endLine: 1 },
|
|
219
|
+
snapshots: input.snapshots,
|
|
220
|
+
cache: input.cache
|
|
221
|
+
});
|
|
222
|
+
if (content === undefined)
|
|
223
|
+
continue;
|
|
224
|
+
sources.push({
|
|
225
|
+
sourceId: `spec-source-${checkpointDigestV1({ phase, path }).slice(0, 16)}`,
|
|
226
|
+
phase,
|
|
227
|
+
path,
|
|
228
|
+
content
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return sources;
|
|
233
|
+
});
|
|
234
|
+
const reviewCitationValid = (evidence, sources) => {
|
|
235
|
+
const source = sources.find((candidate) => candidate.sourceId === evidence.sourceId && candidate.phase === "reference");
|
|
236
|
+
if (source === undefined ||
|
|
237
|
+
!Number.isSafeInteger(evidence.startLine) ||
|
|
238
|
+
!Number.isSafeInteger(evidence.endLine) ||
|
|
239
|
+
evidence.startLine < 1 ||
|
|
240
|
+
evidence.endLine < evidence.startLine) {
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
const lines = source.content.split("\n");
|
|
244
|
+
return (evidence.endLine <= lines.length &&
|
|
245
|
+
lines
|
|
246
|
+
.slice(evidence.startLine - 1, evidence.endLine)
|
|
247
|
+
.join("\n")
|
|
248
|
+
.trim().length > 0);
|
|
249
|
+
};
|
|
250
|
+
const validateReview = (input) => {
|
|
251
|
+
const findings = [];
|
|
252
|
+
const coverageIds = input.review.criticalBehaviorCoverage.map((entry) => entry.behaviorId);
|
|
253
|
+
if (coverageIds.length !== input.criticalBehaviorIds.size ||
|
|
254
|
+
new Set(coverageIds).size !== coverageIds.length ||
|
|
255
|
+
coverageIds.some((id) => !input.criticalBehaviorIds.has(id)) ||
|
|
256
|
+
input.review.criticalBehaviorCoverage.some((entry) => !nonEmpty(entry.detail))) {
|
|
257
|
+
findings.push({
|
|
258
|
+
kind: "contract",
|
|
259
|
+
message: "Return exactly one non-empty criticalBehaviorCoverage record for every critical behavior id."
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
const dimensionFit = input.review.dimensionFit;
|
|
263
|
+
if (dimensionFit.requestedDimension !== input.dimensionId ||
|
|
264
|
+
!nonEmpty(dimensionFit.detail) ||
|
|
265
|
+
!uniqueNonEmpty(dimensionFit.evidencePaths) ||
|
|
266
|
+
dimensionFit.evidencePaths.some((path) => !input.initial.files.includes(path))) {
|
|
267
|
+
findings.push({
|
|
268
|
+
kind: "contract",
|
|
269
|
+
message: "dimensionFit must address the exact supplied dimension id with a substantive explanation and existing initial-tree evidence paths."
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
const compatibility = input.review.referenceCompatibility;
|
|
273
|
+
const compatibilityIds = compatibility.scopeCoverage.map((entry) => entry.scopeId);
|
|
274
|
+
if (!nonEmpty(compatibility.detail) ||
|
|
275
|
+
compatibilityIds.length !== input.scopeIds.size ||
|
|
276
|
+
new Set(compatibilityIds).size !== compatibilityIds.length ||
|
|
277
|
+
compatibilityIds.some((id) => !input.scopeIds.has(id)) ||
|
|
278
|
+
compatibility.scopeCoverage.some((entry) => !nonEmpty(entry.detail) ||
|
|
279
|
+
entry.evidence.length === 0 ||
|
|
280
|
+
entry.evidence.some((evidence) => !reviewCitationValid(evidence, input.sources)))) {
|
|
281
|
+
findings.push({
|
|
282
|
+
kind: "contract",
|
|
283
|
+
message: "referenceCompatibility needs one substantive, valid reference-line-cited scopeCoverage record for every scope id."
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
if (!nonEmpty(input.review.detail) ||
|
|
287
|
+
input.review.findings.some((finding) => !nonEmpty(finding.detail))) {
|
|
288
|
+
findings.push({
|
|
289
|
+
kind: "contract",
|
|
290
|
+
message: "Review detail and finding detail must be non-empty."
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
if (input.review.verdict === "sufficient" &&
|
|
294
|
+
(dimensionFit.outcome !== "fit" ||
|
|
295
|
+
compatibility.outcome !== "compatible" ||
|
|
296
|
+
input.review.criticalBehaviorCoverage.some((entry) => entry.outcome !== "covered") ||
|
|
297
|
+
input.review.findings.some((finding) => finding.severity === "blocker"))) {
|
|
298
|
+
findings.push({
|
|
299
|
+
kind: "contract",
|
|
300
|
+
message: "A sufficient verdict requires fit, compatible reference evidence, complete critical coverage, and no blocker findings."
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
return findings;
|
|
304
|
+
};
|
|
305
|
+
const acceptedReview = (review) => review.verdict === "sufficient" &&
|
|
306
|
+
review.dimensionFit.outcome === "fit" &&
|
|
307
|
+
review.referenceCompatibility.outcome === "compatible" &&
|
|
308
|
+
review.criticalBehaviorCoverage.every((entry) => entry.outcome === "covered") &&
|
|
309
|
+
review.findings.every((finding) => finding.severity !== "blocker");
|
|
310
|
+
const publicReviewFeedback = (review) => [
|
|
311
|
+
review.detail,
|
|
312
|
+
review.dimensionFit.detail,
|
|
313
|
+
...review.criticalBehaviorCoverage
|
|
314
|
+
.filter((entry) => entry.outcome !== "covered")
|
|
315
|
+
.map((entry) => entry.detail),
|
|
316
|
+
...review.referenceCompatibility.scopeCoverage
|
|
317
|
+
.filter((entry) => entry.outcome !== "supported")
|
|
318
|
+
.map((entry) => entry.detail),
|
|
319
|
+
...(review.referenceCompatibility.questionResolutions ?? [])
|
|
320
|
+
.filter((entry) => entry.outcome === "unresolved")
|
|
321
|
+
.map((entry) => entry.detail),
|
|
322
|
+
...review.findings.map((finding) => finding.detail)
|
|
323
|
+
].filter(nonEmpty);
|
|
324
|
+
const leakFindingsOf = (reviews) => reviews.flatMap((review) => review.findings
|
|
325
|
+
.filter((finding) => finding.axis === "hidden-answer-leakage")
|
|
326
|
+
.map((finding) => finding.detail));
|
|
327
|
+
const reviewOutputOf = (review) => Schema.decodeUnknownOption(PipelineSpecificationReviewOutputV1)({
|
|
328
|
+
verdict: review.verdict,
|
|
329
|
+
detail: review.detail,
|
|
330
|
+
criticalBehaviorCoverage: review.criticalBehaviorCoverage,
|
|
331
|
+
dimensionFit: review.dimensionFit,
|
|
332
|
+
referenceCompatibility: review.referenceCompatibility,
|
|
333
|
+
findings: review.findings
|
|
334
|
+
});
|
|
335
|
+
const checkpointLastReview = (checkpoint, parentDigest) => {
|
|
336
|
+
if (checkpoint === undefined ||
|
|
337
|
+
checkpoint.parentDigest !== parentDigest ||
|
|
338
|
+
checkpoint.reviews.length === 0) {
|
|
339
|
+
return undefined;
|
|
340
|
+
}
|
|
341
|
+
const decoded = reviewOutputOf(checkpoint.reviews.at(-1));
|
|
342
|
+
return Option.isSome(decoded) && !acceptedReview(decoded.value)
|
|
343
|
+
? { checkpoint, review: decoded.value }
|
|
344
|
+
: undefined;
|
|
345
|
+
};
|
|
346
|
+
const publicBehaviorOf = (seed, scope) => seed.targetBehavior.map((behavior) => ({
|
|
347
|
+
id: behavior.id,
|
|
348
|
+
critical: behavior.critical,
|
|
349
|
+
description: scope
|
|
350
|
+
.filter((entry) => entry.behaviorIds.includes(behavior.id))
|
|
351
|
+
.map((entry) => entry.description)
|
|
352
|
+
.join(" ")
|
|
353
|
+
}));
|
|
354
|
+
/** Source-only authoring also accepts an unqualified draft seed. It never executes repository recipes. */
|
|
355
|
+
export const draftPipelineSpecificationV1 = Effect.fn("PipelineSpec.draft")(function* (input) {
|
|
356
|
+
const seed = input.seed;
|
|
357
|
+
const referenceCommit = seed.referenceCommit;
|
|
358
|
+
if (referenceCommit === undefined || referenceCommit === seed.initialState.commit) {
|
|
359
|
+
return yield* failure("spec stage requires distinct pinned initial and reference commits");
|
|
360
|
+
}
|
|
361
|
+
yield* reportFoundryStageV1(pipelineStageToProgressStageV1(STAGE), "grounding changed and preserved scope against pinned Git trees");
|
|
362
|
+
const languageModel = yield* RepositoryFoundryLanguageModel;
|
|
363
|
+
const [analystAssignment, writerAssignment, criticAssignment] = yield* Effect.all([
|
|
364
|
+
assignmentOf({ plan: input.context.modelPlan, role: "repository-analyst" }),
|
|
365
|
+
assignmentOf({ plan: input.context.modelPlan, role: "specification-writer" }),
|
|
366
|
+
assignmentOf({ plan: input.context.modelPlan, role: "specification-critic-b" })
|
|
367
|
+
]);
|
|
368
|
+
const snapshots = {
|
|
369
|
+
initial: yield* captureGitTreeSnapshotV1({
|
|
370
|
+
repositoryRoot: input.context.repositoryRoot,
|
|
371
|
+
requestedRef: seed.initialState.commit
|
|
372
|
+
}),
|
|
373
|
+
reference: yield* captureGitTreeSnapshotV1({
|
|
374
|
+
repositoryRoot: input.context.repositoryRoot,
|
|
375
|
+
requestedRef: referenceCommit
|
|
376
|
+
})
|
|
377
|
+
};
|
|
378
|
+
const contentCache = new Map();
|
|
379
|
+
const behaviorIds = new Set(seed.targetBehavior.map((behavior) => behavior.id));
|
|
380
|
+
const criticalBehaviorIds = new Set(seed.targetBehavior.filter((behavior) => behavior.critical).map((behavior) => behavior.id));
|
|
381
|
+
const parentDigest = input.parentDigest;
|
|
382
|
+
const resumable = checkpointLastReview(input.checkpoints.spec, parentDigest);
|
|
383
|
+
let analysis;
|
|
384
|
+
let scope;
|
|
385
|
+
let contextSources;
|
|
386
|
+
let sourceCatalog;
|
|
387
|
+
const episode = input.map.historyEpisodes.find((candidate) => "changeEpisodeId" in seed.source && candidate.id === seed.source.changeEpisodeId);
|
|
388
|
+
const groundedSourcePaths = [
|
|
389
|
+
...seed.capabilityEvidence.flatMap((evidence) => evidence.path === undefined ? [] : [evidence.path]),
|
|
390
|
+
...seed.targetBehavior.flatMap((behavior) => behavior.evidence.flatMap((evidence) => (evidence.path === undefined ? [] : [evidence.path]))),
|
|
391
|
+
...(episode?.changedPaths.flatMap((changed) => changed.previousPath === undefined ? [changed.path] : [changed.previousPath, changed.path]) ?? [])
|
|
392
|
+
];
|
|
393
|
+
if (resumable === undefined) {
|
|
394
|
+
const analyst = yield* groundedStructuredGenerationV1({
|
|
395
|
+
checkpointStore: input.workCheckpointStore,
|
|
396
|
+
languageModel,
|
|
397
|
+
assignment: analystAssignment,
|
|
398
|
+
operationId: `${input.context.caseId}:spec:analyst`,
|
|
399
|
+
instructions: ANALYST_INSTRUCTIONS,
|
|
400
|
+
task: {
|
|
401
|
+
dimension: input.context.dimension,
|
|
402
|
+
seed: {
|
|
403
|
+
id: seed.id,
|
|
404
|
+
summary: seed.summary,
|
|
405
|
+
source: seed.source,
|
|
406
|
+
targetBehavior: seed.targetBehavior,
|
|
407
|
+
capabilityEvidence: seed.capabilityEvidence
|
|
408
|
+
},
|
|
409
|
+
repository: {
|
|
410
|
+
initialCommit: snapshots.initial.commit,
|
|
411
|
+
referenceCommit: snapshots.reference.commit
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
outputSchema: PipelineSpecificationAnalysisV1,
|
|
415
|
+
schemaName: "routekit_pipeline_spec_analysis_v1",
|
|
416
|
+
tools: {
|
|
417
|
+
repositoryRoot: input.context.repositoryRoot,
|
|
418
|
+
commits: { initial: snapshots.initial.commit, reference: snapshots.reference.commit }
|
|
419
|
+
},
|
|
420
|
+
validateSubmission: (candidate) => validateAnalysis({ analysis: candidate, behaviorIds, snapshots, cache: contentCache }),
|
|
421
|
+
maxTurns: Math.max(1, Math.trunc(input.context.budget.maxModelCalls) + 1),
|
|
422
|
+
maxToolTurnsBeforeSubmit: 3,
|
|
423
|
+
maximumOutputTokens: repositoryFoundryRoleOutputCeilingV1("repository-analyst")
|
|
424
|
+
});
|
|
425
|
+
contextSources = yield* loadContextSources({
|
|
426
|
+
initial: snapshots.initial,
|
|
427
|
+
paths: analyst.value.relevantPaths
|
|
428
|
+
});
|
|
429
|
+
sourceCatalog = yield* makeSourceCatalog({
|
|
430
|
+
paths: [...groundedSourcePaths, ...contextSources.map((source) => source.path)],
|
|
431
|
+
snapshots,
|
|
432
|
+
cache: contentCache
|
|
433
|
+
});
|
|
434
|
+
scope = analyst.value.scope.map(({ evidence: _evidence, ...entry }) => entry);
|
|
435
|
+
analysis = {
|
|
436
|
+
summary: analyst.value.summary,
|
|
437
|
+
userObservableBehaviors: analyst.value.userObservableBehaviors,
|
|
438
|
+
constraints: analyst.value.constraints,
|
|
439
|
+
risks: analyst.value.risks
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
analysis = resumable.checkpoint.analysis;
|
|
444
|
+
scope = resumable.checkpoint.scope;
|
|
445
|
+
contextSources = resumable.checkpoint.contextSources;
|
|
446
|
+
sourceCatalog = yield* makeSourceCatalog({
|
|
447
|
+
paths: [...groundedSourcePaths, ...contextSources.map((source) => source.path)],
|
|
448
|
+
snapshots,
|
|
449
|
+
cache: contentCache
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
const scopeIds = new Set(scope.map((entry) => entry.id));
|
|
453
|
+
const publicTargetBehavior = publicBehaviorOf(seed, scope);
|
|
454
|
+
let previousVisible = resumable?.checkpoint.visible;
|
|
455
|
+
let priorReviewFeedback = resumable === undefined ? [] : publicReviewFeedback(resumable.review);
|
|
456
|
+
const reviews = [
|
|
457
|
+
...(resumable?.checkpoint.reviews ?? [])
|
|
458
|
+
];
|
|
459
|
+
let consecutiveDimensionMismatches = 0;
|
|
460
|
+
for (const prior of [...reviews].reverse()) {
|
|
461
|
+
const decoded = reviewOutputOf(prior);
|
|
462
|
+
if (Option.isNone(decoded) || decoded.value.dimensionFit.outcome !== "mismatch")
|
|
463
|
+
break;
|
|
464
|
+
consecutiveDimensionMismatches += 1;
|
|
465
|
+
}
|
|
466
|
+
let revisions = resumable === undefined ? 0 : resumable.checkpoint.revisions + 1;
|
|
467
|
+
const startingSequence = reviews.length;
|
|
468
|
+
for (let sequence = startingSequence;; sequence += 1) {
|
|
469
|
+
yield* reportFoundryStageV1(pipelineStageToProgressStageV1(STAGE), sequence === 0
|
|
470
|
+
? "writing blind visible task"
|
|
471
|
+
: `revising visible task, round ${String(sequence)}`);
|
|
472
|
+
const writer = yield* generateWithFeedbackV1({
|
|
473
|
+
...(input.workCheckpointStore === undefined ? {} : {
|
|
474
|
+
checkpoint: {
|
|
475
|
+
store: input.workCheckpointStore,
|
|
476
|
+
binding: { parentDigest, initialCommit: snapshots.initial.commit }
|
|
477
|
+
}
|
|
478
|
+
}),
|
|
479
|
+
languageModel,
|
|
480
|
+
assignment: writerAssignment,
|
|
481
|
+
operationId: `${input.context.caseId}:spec:writer:round-${String(sequence)}`,
|
|
482
|
+
instructions: WRITER_INSTRUCTIONS,
|
|
483
|
+
input: {
|
|
484
|
+
dimension: input.context.dimension,
|
|
485
|
+
targetBehavior: publicTargetBehavior,
|
|
486
|
+
analysis,
|
|
487
|
+
scope,
|
|
488
|
+
initialRepositoryContext: contextSources,
|
|
489
|
+
...(previousVisible === undefined
|
|
490
|
+
? {}
|
|
491
|
+
: { previousVisible, behavioralReviewFeedback: priorReviewFeedback })
|
|
492
|
+
},
|
|
493
|
+
schemaName: "routekit_pipeline_visible_task_v1",
|
|
494
|
+
outputSchema: PipelineVisibleTaskProposalV1,
|
|
495
|
+
maximumOutputTokens: repositoryFoundryRoleOutputCeilingV1("specification-writer"),
|
|
496
|
+
maxAttempts: Math.max(1, Math.trunc(input.context.budget.maxModelCalls) + 1),
|
|
497
|
+
validate: (proposal) => Effect.succeed(!nonEmpty(proposal.requestText) || proposal.constraints.some((entry) => !nonEmpty(entry))
|
|
498
|
+
? [
|
|
499
|
+
{
|
|
500
|
+
kind: "contract",
|
|
501
|
+
message: "Visible request text and every supplied constraint must be non-empty."
|
|
502
|
+
}
|
|
503
|
+
]
|
|
504
|
+
: [])
|
|
505
|
+
});
|
|
506
|
+
const visible = {
|
|
507
|
+
lane: "repository-agent",
|
|
508
|
+
id: input.context.caseId,
|
|
509
|
+
requestText: writer.value.requestText,
|
|
510
|
+
checkoutCommit: snapshots.initial.commit,
|
|
511
|
+
allowedTools: ["read", "search", "edit", "shell", "test"],
|
|
512
|
+
constraints: [
|
|
513
|
+
...new Set([
|
|
514
|
+
...writer.value.constraints,
|
|
515
|
+
"Do not weaken or delete tests to make the task pass.",
|
|
516
|
+
"Preserve unrelated public behavior."
|
|
517
|
+
])
|
|
518
|
+
]
|
|
519
|
+
};
|
|
520
|
+
yield* reportFoundryStageV1(pipelineStageToProgressStageV1(STAGE), `checking visible task against private reference, round ${String(sequence)}`);
|
|
521
|
+
const critic = yield* groundedStructuredGenerationV1({
|
|
522
|
+
checkpointStore: input.workCheckpointStore,
|
|
523
|
+
languageModel,
|
|
524
|
+
assignment: criticAssignment,
|
|
525
|
+
operationId: `${input.context.caseId}:spec:critic:round-${String(sequence)}`,
|
|
526
|
+
instructions: CRITIC_INSTRUCTIONS,
|
|
527
|
+
task: {
|
|
528
|
+
dimension: input.context.dimension,
|
|
529
|
+
targetBehavior: seed.targetBehavior,
|
|
530
|
+
analysis,
|
|
531
|
+
scope,
|
|
532
|
+
visible,
|
|
533
|
+
sourceCatalog: sourceCatalog.map(({ content: _content, ...source }) => source)
|
|
534
|
+
},
|
|
535
|
+
outputSchema: PipelineSpecificationReviewOutputV1,
|
|
536
|
+
schemaName: "routekit_pipeline_specification_review_v1",
|
|
537
|
+
tools: {
|
|
538
|
+
repositoryRoot: input.context.repositoryRoot,
|
|
539
|
+
commits: { initial: snapshots.initial.commit, reference: snapshots.reference.commit }
|
|
540
|
+
},
|
|
541
|
+
validateSubmission: (review) => Effect.succeed(validateReview({
|
|
542
|
+
review,
|
|
543
|
+
criticalBehaviorIds,
|
|
544
|
+
scopeIds,
|
|
545
|
+
initial: snapshots.initial,
|
|
546
|
+
dimensionId: input.context.dimension.id,
|
|
547
|
+
sources: sourceCatalog
|
|
548
|
+
})),
|
|
549
|
+
maxTurns: Math.max(1, Math.trunc(input.context.budget.maxModelCalls) + 1),
|
|
550
|
+
maxToolTurnsBeforeSubmit: 3,
|
|
551
|
+
maximumOutputTokens: repositoryFoundryRoleOutputCeilingV1("specification-critic-b")
|
|
552
|
+
});
|
|
553
|
+
const review = {
|
|
554
|
+
reviewerId: `${input.context.caseId}:spec:critic:round-${String(sequence)}`,
|
|
555
|
+
reviewerKind: "model-critic",
|
|
556
|
+
independentlyProduced: true,
|
|
557
|
+
...critic.value
|
|
558
|
+
};
|
|
559
|
+
reviews.push(review);
|
|
560
|
+
const createdAt = new Date(yield* Clock.currentTimeMillis).toISOString();
|
|
561
|
+
const checkpoint = {
|
|
562
|
+
version: 1,
|
|
563
|
+
stage: STAGE,
|
|
564
|
+
parentDigest,
|
|
565
|
+
createdAt,
|
|
566
|
+
visible,
|
|
567
|
+
analysis,
|
|
568
|
+
scope,
|
|
569
|
+
contextSources,
|
|
570
|
+
reviews,
|
|
571
|
+
revisions,
|
|
572
|
+
leakFindings: leakFindingsOf(reviews)
|
|
573
|
+
};
|
|
574
|
+
yield* input.checkpoint(checkpoint);
|
|
575
|
+
if (acceptedReview(critic.value))
|
|
576
|
+
return checkpoint;
|
|
577
|
+
if (critic.value.dimensionFit.outcome === "mismatch") {
|
|
578
|
+
consecutiveDimensionMismatches += 1;
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
consecutiveDimensionMismatches = 0;
|
|
582
|
+
}
|
|
583
|
+
if (consecutiveDimensionMismatches >= DIMENSION_MISMATCH_CONFIRMATIONS) {
|
|
584
|
+
return yield* new RepositoryFoundryError({
|
|
585
|
+
operation: "run-pipeline-stage",
|
|
586
|
+
detail: "specification cannot assess the requested dimension: repeated private grounded reviews established a dimension mismatch",
|
|
587
|
+
cause: new PipelineStageError({
|
|
588
|
+
stage: STAGE,
|
|
589
|
+
detail: "repeated private grounded reviews established that the authentic change does not fit the requested dimension",
|
|
590
|
+
terminal: true
|
|
591
|
+
}),
|
|
592
|
+
generationRejection: {
|
|
593
|
+
code: "specification-dimension-mismatch",
|
|
594
|
+
completedRevisions: revisions
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
// A bounded capability returns its real review/checkpoint to the orchestrator,
|
|
599
|
+
// not a fabricated acceptance or an unbounded hidden revision waterfall.
|
|
600
|
+
if (input.maximumReviewRounds !== undefined &&
|
|
601
|
+
sequence - startingSequence + 1 >= input.maximumReviewRounds) {
|
|
602
|
+
return checkpoint;
|
|
603
|
+
}
|
|
604
|
+
previousVisible = visible;
|
|
605
|
+
priorReviewFeedback = publicReviewFeedback(critic.value);
|
|
606
|
+
revisions += 1;
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
/** Legacy callers still require and preserve their qualified seed checkpoint. */
|
|
610
|
+
export const runPipelineSpecStageV1 = (input) => {
|
|
611
|
+
const seedCheckpoint = input.checkpoints.seed;
|
|
612
|
+
return seedCheckpoint === undefined
|
|
613
|
+
? Effect.fail(failure("spec stage requires an accepted seed checkpoint"))
|
|
614
|
+
: draftPipelineSpecificationV1({
|
|
615
|
+
...input,
|
|
616
|
+
seed: seedCheckpoint.seed,
|
|
617
|
+
parentDigest: checkpointDigestV1(seedCheckpoint)
|
|
618
|
+
});
|
|
619
|
+
};
|