@tea-agent/loop-agent 0.1.0-fe-test.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/AGENTS.md +114 -0
- package/CHANGELOG.md +2283 -0
- package/README.md +177 -0
- package/bin/agent-worker.js +22 -0
- package/bin/loop-agent.js +57 -0
- package/dist/adapters/aimax.js +91 -0
- package/dist/adapters/context.js +32 -0
- package/dist/adapters/index.js +29 -0
- package/dist/adapters/loop-agent.js +192 -0
- package/dist/adapters/types.js +1 -0
- package/dist/application/context-usage/skill-resolution-stats.js +263 -0
- package/dist/application/dag/args.js +486 -0
- package/dist/application/dag/generate-task-dag.js +408 -0
- package/dist/application/dag/report-dag.js +14 -0
- package/dist/application/dag/run-dag.js +109 -0
- package/dist/application/dag/validate-dag.js +166 -0
- package/dist/application/evaluation/alias.js +184 -0
- package/dist/application/evaluation/budget.js +192 -0
- package/dist/application/evaluation/campaign-hash.js +47 -0
- package/dist/application/evaluation/campaign-matrix.js +372 -0
- package/dist/application/evaluation/campaign-scorecard.js +135 -0
- package/dist/application/evaluation/campaign.js +370 -0
- package/dist/application/evaluation/candidate-hash.js +75 -0
- package/dist/application/evaluation/candidate.js +69 -0
- package/dist/application/evaluation/corpus-hash.js +38 -0
- package/dist/application/evaluation/corpus.js +56 -0
- package/dist/application/evaluation/experiment.js +294 -0
- package/dist/application/evaluation/ignition.js +198 -0
- package/dist/application/evaluation/integrity-audit.js +162 -0
- package/dist/application/evaluation/outer-loop.js +132 -0
- package/dist/application/evaluation/pi-cell-executor.js +39 -0
- package/dist/application/evaluation/private-verifier.js +46 -0
- package/dist/application/evaluation/promotion-policy.js +151 -0
- package/dist/application/evaluation/proposer.js +98 -0
- package/dist/application/evaluation/replay.js +289 -0
- package/dist/application/evaluation/types.js +652 -0
- package/dist/application/loop/run-action.js +19 -0
- package/dist/application/task-lifecycle/advance.js +1204 -0
- package/dist/application/task-lifecycle/gates.js +130 -0
- package/dist/application/task-lifecycle/index.js +7 -0
- package/dist/application/task-lifecycle/observe.js +424 -0
- package/dist/application/task-lifecycle/plan-transitions.js +251 -0
- package/dist/application/task-lifecycle/recommendations.js +180 -0
- package/dist/application/task-lifecycle/record.js +73 -0
- package/dist/application/task-lifecycle/types.js +1 -0
- package/dist/build-stamp.json +6 -0
- package/dist/cli/catalog.js +24 -0
- package/dist/cli/command-definitions.js +659 -0
- package/dist/cli/help.js +56 -0
- package/dist/cli/index.js +5 -0
- package/dist/cli/program.js +647 -0
- package/dist/cli/router.js +13 -0
- package/dist/cli/update/init-surface-notifier.js +167 -0
- package/dist/cli/update/notifier.js +117 -0
- package/dist/cli/update/npm-client.js +151 -0
- package/dist/cli/update/policy.js +92 -0
- package/dist/cli/update/runtime-activity.js +29 -0
- package/dist/cli/update/state.js +68 -0
- package/dist/cli-governance/active-residue-check.js +38 -0
- package/dist/cli.js +57 -0
- package/dist/commands/client-recovery.js +1373 -0
- package/dist/commands/closeout.js +13 -0
- package/dist/commands/coverage-audit.js +14 -0
- package/dist/commands/coverage-report.js +50 -0
- package/dist/commands/cursor-prompt.js +182 -0
- package/dist/commands/dag-approve.js +142 -0
- package/dist/commands/dag-final-verification.js +76 -0
- package/dist/commands/dag-init-hybrid.js +57 -0
- package/dist/commands/dag-reconcile-run.js +5 -0
- package/dist/commands/dag-reconcile-tasks.js +51 -0
- package/dist/commands/dag-reject.js +91 -0
- package/dist/commands/dag-report.js +76 -0
- package/dist/commands/dag-request-interrupt.js +20 -0
- package/dist/commands/dag-rerun-task.js +19 -0
- package/dist/commands/dag-rerun.js +111 -0
- package/dist/commands/dag-resume.js +35 -0
- package/dist/commands/dag-run-task.js +12 -0
- package/dist/commands/dag-validate.js +20 -0
- package/dist/commands/dag-workflow-compile.js +91 -0
- package/dist/commands/dag-workflow-plan.js +130 -0
- package/dist/commands/dag-workflow-validate.js +66 -0
- package/dist/commands/delegate.js +130 -0
- package/dist/commands/docs-archive.js +5 -0
- package/dist/commands/docs-audit.js +6 -0
- package/dist/commands/doctor.js +283 -0
- package/dist/commands/eval.js +1398 -0
- package/dist/commands/examples.js +90 -0
- package/dist/commands/goal.js +92 -0
- package/dist/commands/handoff-check.js +5 -0
- package/dist/commands/harvest.js +44 -0
- package/dist/commands/import-prd.js +81 -0
- package/dist/commands/init-upgrade.js +3085 -0
- package/dist/commands/init.js +3630 -0
- package/dist/commands/inspect.js +11 -0
- package/dist/commands/instructions.js +223 -0
- package/dist/commands/knowledge.js +162 -0
- package/dist/commands/loop-benchmark.js +72 -0
- package/dist/commands/loop.js +251 -0
- package/dist/commands/new-task.js +5 -0
- package/dist/commands/operator.js +44 -0
- package/dist/commands/pi-prompt.js +174 -0
- package/dist/commands/pi-reuse-benchmark.js +153 -0
- package/dist/commands/plan-list.js +5 -0
- package/dist/commands/plan.js +50 -0
- package/dist/commands/promote-run.js +29 -0
- package/dist/commands/reference-index.js +16 -0
- package/dist/commands/run-dag-progress.js +123 -0
- package/dist/commands/run-dag.js +22 -0
- package/dist/commands/spine.js +38 -0
- package/dist/commands/stats.js +113 -0
- package/dist/commands/status.js +57 -0
- package/dist/commands/study-init.js +192 -0
- package/dist/commands/task-advance.js +366 -0
- package/dist/commands/task-contract.js +269 -0
- package/dist/commands/task-source-prepare.js +479 -0
- package/dist/commands/task-status.js +133 -0
- package/dist/commands/workflow.js +259 -0
- package/dist/commands/worktree-create.js +31 -0
- package/dist/commands/worktree-list.js +5 -0
- package/dist/commands/worktree-remove.js +26 -0
- package/dist/executors/config-core.js +5 -0
- package/dist/executors/config.js +2 -0
- package/dist/executors/dag-pi-executor.js +1277 -0
- package/dist/executors/dag-static-executor.js +42 -0
- package/dist/executors/dag.js +3 -0
- package/dist/executors/index.js +6 -0
- package/dist/executors/model-routing.js +71 -0
- package/dist/executors/pi-defaults.js +9 -0
- package/dist/executors/pi-event-serializer.js +65 -0
- package/dist/executors/pi-executor.js +981 -0
- package/dist/executors/pi-playwright-cli-tool.js +1006 -0
- package/dist/executors/pi-prompt-transport.js +198 -0
- package/dist/executors/pi-reuse-benchmark.js +316 -0
- package/dist/executors/pi-runtime-reuse.js +29 -0
- package/dist/executors/pi-sdk-executor.js +722 -0
- package/dist/executors/pi-sdk.js +1 -0
- package/dist/executors/pi-writer-tool-policy.js +266 -0
- package/dist/executors/pi.js +3 -0
- package/dist/executors/playwright-cli-launcher.js +63 -0
- package/dist/executors/process-tree.js +33 -0
- package/dist/executors/shell-executor.js +3055 -0
- package/dist/executors/shell-presets.js +99 -0
- package/dist/executors/shell-verification.js +262 -0
- package/dist/executors/shell-write-guard.js +543 -0
- package/dist/executors/shell.js +3 -0
- package/dist/executors/static.js +1 -0
- package/dist/governance/checks.js +437 -0
- package/dist/governance/document-index-closure.js +164 -0
- package/dist/governance/exec-plans.js +549 -0
- package/dist/governance/harness.js +9 -0
- package/dist/governance/index.js +3 -0
- package/dist/governance/manifest-types.js +254 -0
- package/dist/governance/manifest.js +2 -0
- package/dist/governance/path-guard.js +69 -0
- package/dist/governance/path-guards.js +2 -0
- package/dist/governance/profiles.js +3 -0
- package/dist/governance/requirement-coverage.js +425 -0
- package/dist/governance/skill-safety.js +135 -0
- package/dist/governance/spine-audit.js +155 -0
- package/dist/infrastructure/evaluation/alias-store.js +199 -0
- package/dist/infrastructure/evaluation/campaign-store.js +154 -0
- package/dist/infrastructure/evaluation/candidate-store.js +439 -0
- package/dist/infrastructure/evaluation/corpus-store.js +181 -0
- package/dist/infrastructure/evaluation/experiment-store.js +124 -0
- package/dist/infrastructure/evaluation/ignition-store.js +82 -0
- package/dist/infrastructure/evaluation/private-verifier-store.js +145 -0
- package/dist/infrastructure/evaluation/proposer-store.js +78 -0
- package/dist/infrastructure/evaluation/store.js +40 -0
- package/dist/infrastructure/harness/active-residue-policy.js +73 -0
- package/dist/infrastructure/harness/artifact-store.js +72 -0
- package/dist/infrastructure/harness/atomic-write.js +50 -0
- package/dist/infrastructure/harness/completed-facts-guard.js +40 -0
- package/dist/infrastructure/harness/loop-action-store.js +20 -0
- package/dist/infrastructure/harness/loop-store.js +41 -0
- package/dist/infrastructure/harness/one-shot-run-store.js +94 -0
- package/dist/infrastructure/harness/task-store.js +108 -0
- package/dist/records/closeout.js +2 -0
- package/dist/records/harvest.js +215 -0
- package/dist/records/index.js +3 -0
- package/dist/records/one-shot-runs.js +386 -0
- package/dist/records/promotion.js +200 -0
- package/dist/shared/artifacts-core.js +107 -0
- package/dist/shared/artifacts.js +2 -0
- package/dist/shared/context-files.js +32 -0
- package/dist/shared/context.js +2 -0
- package/dist/shared/copy-dir.js +17 -0
- package/dist/shared/git-progress.js +172 -0
- package/dist/shared/index.js +5 -0
- package/dist/shared/logger.js +17 -0
- package/dist/shared/one-shot-prompt-args.js +98 -0
- package/dist/shared/openspec-spec.js +125 -0
- package/dist/shared/operator/capabilities.js +2659 -0
- package/dist/shared/operator/command-lifecycle.js +94 -0
- package/dist/shared/operator/envelope.js +59 -0
- package/dist/shared/operator/index.js +5 -0
- package/dist/shared/operator/registry.js +38 -0
- package/dist/shared/operator/types.js +5 -0
- package/dist/shared/output-truncation.js +37 -0
- package/dist/shared/package-metadata.js +530 -0
- package/dist/shared/path-refs.js +31 -0
- package/dist/shared/pi-retry-settings.js +23 -0
- package/dist/shared/playwright-cli-command-policy.js +41 -0
- package/dist/shared/preview.js +39 -0
- package/dist/shared/prompts.js +26 -0
- package/dist/shared/reference-context.js +264 -0
- package/dist/shared/resilient-git.js +133 -0
- package/dist/shared/runtime-activity.js +6 -0
- package/dist/shared/timeout-policy.js +24 -0
- package/dist/shared/timeout.js +1 -0
- package/dist/shared/types.js +5 -0
- package/dist/sidecars/cursor-prompt/executor.js +428 -0
- package/dist/sidecars/cursor-prompt/index.js +3 -0
- package/dist/sidecars/cursor-prompt/stream.js +121 -0
- package/dist/task/config-types.js +235 -0
- package/dist/task/config.js +2 -0
- package/dist/task/contract/adopt.js +166 -0
- package/dist/task/contract/apply.js +326 -0
- package/dist/task/contract/canonicalize.js +60 -0
- package/dist/task/contract/constants.js +30 -0
- package/dist/task/contract/diff.js +177 -0
- package/dist/task/contract/hash.js +42 -0
- package/dist/task/contract/import-revision.js +96 -0
- package/dist/task/contract/index.js +17 -0
- package/dist/task/contract/journal.js +155 -0
- package/dist/task/contract/lock.js +153 -0
- package/dist/task/contract/observe.js +296 -0
- package/dist/task/contract/paths.js +19 -0
- package/dist/task/contract/project.js +185 -0
- package/dist/task/contract/recover.js +312 -0
- package/dist/task/contract/request-ledger.js +37 -0
- package/dist/task/contract/schema.js +153 -0
- package/dist/task/contract/transaction.js +160 -0
- package/dist/task/contract/types.js +1 -0
- package/dist/task/contract/validate-draft.js +106 -0
- package/dist/task/dag-source-paths.js +50 -0
- package/dist/task/delegate.js +208 -0
- package/dist/task/frontend-preflight.js +131 -0
- package/dist/task/frontend-project-capability.js +570 -0
- package/dist/task/goal-audit.js +51 -0
- package/dist/task/goal-policy.js +8 -0
- package/dist/task/goal.js +3 -0
- package/dist/task/ids.js +1 -0
- package/dist/task/index.js +12 -0
- package/dist/task/lifecycle.js +1 -0
- package/dist/task/operator/capabilities.js +6 -0
- package/dist/task/operator/envelope.js +2 -0
- package/dist/task/operator/index.js +5 -0
- package/dist/task/operator/registry.js +2 -0
- package/dist/task/operator/types.js +1 -0
- package/dist/task/paths.js +1 -0
- package/dist/task/read-model.js +140 -0
- package/dist/task/runtime.js +708 -0
- package/dist/task/source-prepare/artifact-meta.js +137 -0
- package/dist/task/source-prepare/build-draft.js +232 -0
- package/dist/task/source-prepare/completeness.js +248 -0
- package/dist/task/source-prepare/index.js +10 -0
- package/dist/task/source-prepare/parse-intent.js +496 -0
- package/dist/task/source-prepare/path-policy.js +197 -0
- package/dist/task/source-prepare/placeholder-paths.js +77 -0
- package/dist/task/source-prepare/prepare.js +920 -0
- package/dist/task/source-prepare/reference-integrity.js +290 -0
- package/dist/task/source-prepare/semantic-intake.js +717 -0
- package/dist/task/source-prepare/types.js +7 -0
- package/dist/task/source-references.js +228 -0
- package/dist/task/source-state.js +1 -0
- package/dist/task/state.js +41 -0
- package/dist/task/subagent-guidance.js +1 -0
- package/dist/task/task-demand-routing.js +443 -0
- package/dist/task/workflow-state-types.js +92 -0
- package/dist/task/worktree-cleanup.js +140 -0
- package/dist/task/worktree.js +388 -0
- package/dist/verification/maven/cache.js +142 -0
- package/dist/verification/maven/index.js +120 -0
- package/dist/verification/maven/plan-commands.js +421 -0
- package/dist/verification/maven/pom-static.js +136 -0
- package/dist/verification/maven/scope-resolve.js +153 -0
- package/dist/verification/maven/stale.js +130 -0
- package/dist/verification/maven/types.js +23 -0
- package/dist/verification/maven/workspace-graph.js +322 -0
- package/dist/worker/cli.js +957 -0
- package/dist/worker/closeout/apply.js +73 -0
- package/dist/worker/closeout/preview.js +30 -0
- package/dist/worker/console/app-data.js +316 -0
- package/dist/worker/console/chat/artifact-card.js +30 -0
- package/dist/worker/console/chat/assistant-content.js +121 -0
- package/dist/worker/console/chat/chat-event-store.js +981 -0
- package/dist/worker/console/chat/chat-ui-policy.js +25 -0
- package/dist/worker/console/chat/compaction-errors.js +64 -0
- package/dist/worker/console/chat/composer-draft-store.js +45 -0
- package/dist/worker/console/chat/context-panel.js +54 -0
- package/dist/worker/console/chat/contract-apply-receipt-store.js +174 -0
- package/dist/worker/console/chat/explore-tools.js +299 -0
- package/dist/worker/console/chat/human-gate-card.js +45 -0
- package/dist/worker/console/chat/interview-adapter.js +149 -0
- package/dist/worker/console/chat/mcp-inventory.js +221 -0
- package/dist/worker/console/chat/model-resolver.js +215 -0
- package/dist/worker/console/chat/operation-card.js +92 -0
- package/dist/worker/console/chat/pi-console-config.js +376 -0
- package/dist/worker/console/chat/pi-runtime.js +2446 -0
- package/dist/worker/console/chat/repo-browser.js +140 -0
- package/dist/worker/console/chat/repo-walk.js +125 -0
- package/dist/worker/console/chat/resource-loader.js +59 -0
- package/dist/worker/console/chat/resource-preferences-store.js +152 -0
- package/dist/worker/console/chat/routes.js +3137 -0
- package/dist/worker/console/chat/runtime-context.js +102 -0
- package/dist/worker/console/chat/runtime-selection.js +96 -0
- package/dist/worker/console/chat/semantic-activity.js +489 -0
- package/dist/worker/console/chat/session-store.js +484 -0
- package/dist/worker/console/chat/shortcuts.js +217 -0
- package/dist/worker/console/chat/tool-adapter.js +131 -0
- package/dist/worker/console/chat/tool-preview.js +247 -0
- package/dist/worker/console/chat/tools.js +212 -0
- package/dist/worker/console/chat/turn-execution-registry.js +82 -0
- package/dist/worker/console/chat/turn-process.js +346 -0
- package/dist/worker/console/chat/usage.js +165 -0
- package/dist/worker/console/chat/workspace-landing.js +103 -0
- package/dist/worker/console/dag-confirmation.js +347 -0
- package/dist/worker/console/dag-execution-receipt.js +393 -0
- package/dist/worker/console/doctor.js +230 -0
- package/dist/worker/console/draft-store.js +158 -0
- package/dist/worker/console/harness-pi-model-matrix.js +137 -0
- package/dist/worker/console/human-gate-token.js +130 -0
- package/dist/worker/console/index.js +17 -0
- package/dist/worker/console/inspect-split.js +82 -0
- package/dist/worker/console/interview/assessment.js +67 -0
- package/dist/worker/console/interview/grill-me.js +277 -0
- package/dist/worker/console/interview/session.js +100 -0
- package/dist/worker/console/interview/tools.js +109 -0
- package/dist/worker/console/loopback.js +16 -0
- package/dist/worker/console/mutation-gate-receipt-store.js +184 -0
- package/dist/worker/console/night-aux-ticker.js +146 -0
- package/dist/worker/console/observe-health-match.js +179 -0
- package/dist/worker/console/observe-link.js +42 -0
- package/dist/worker/console/open-browser.js +134 -0
- package/dist/worker/console/operation-run-facts.js +190 -0
- package/dist/worker/console/operation-runner.js +353 -0
- package/dist/worker/console/operation-sse.js +184 -0
- package/dist/worker/console/operation-store.js +169 -0
- package/dist/worker/console/operation-wait.js +355 -0
- package/dist/worker/console/operator-actions.js +3768 -0
- package/dist/worker/console/operator-selection.js +105 -0
- package/dist/worker/console/operator-surface-health.js +24 -0
- package/dist/worker/console/operator-user-error.js +45 -0
- package/dist/worker/console/pi-readiness.js +288 -0
- package/dist/worker/console/prd-identity.js +102 -0
- package/dist/worker/console/prd-intake-bridge.js +441 -0
- package/dist/worker/console/prd-reference-discovery.js +124 -0
- package/dist/worker/console/recovery-cta.js +320 -0
- package/dist/worker/console/recovery-error-copy.js +198 -0
- package/dist/worker/console/recovery-selection.js +107 -0
- package/dist/worker/console/repo-fingerprint.js +35 -0
- package/dist/worker/console/resolve-dag-run-for-task.js +115 -0
- package/dist/worker/console/resource-loader.js +95 -0
- package/dist/worker/console/routes.js +475 -0
- package/dist/worker/console/security.js +170 -0
- package/dist/worker/console/server.js +357 -0
- package/dist/worker/console/sibling-controller.js +33 -0
- package/dist/worker/console/static/assets/abnfDiagram-N423BO3Z-BmOEx0gA.js +1 -0
- package/dist/worker/console/static/assets/arc-BGiVVe8b.js +1 -0
- package/dist/worker/console/static/assets/architectureDiagram-T3A2C74G-nDdu4rgJ.js +36 -0
- package/dist/worker/console/static/assets/blockDiagram-VBNYF7ZC-Bb5u0BWf.js +132 -0
- package/dist/worker/console/static/assets/c4Diagram-5PPSVZJV-BlhC0j94.js +10 -0
- package/dist/worker/console/static/assets/channel-Tl-FkUqr.js +1 -0
- package/dist/worker/console/static/assets/chunk-2GRJ4B5K-Ai8_qQXI.js +1 -0
- package/dist/worker/console/static/assets/chunk-2Q5K7J3B-B9gyCjqX.js +1 -0
- package/dist/worker/console/static/assets/chunk-5RXB4S5H-Bzbj3zGH.js +231 -0
- package/dist/worker/console/static/assets/chunk-5VM5RSS4-BT415PvT.js +15 -0
- package/dist/worker/console/static/assets/chunk-6Q2QTUOP-D_A5_5QL.js +88 -0
- package/dist/worker/console/static/assets/chunk-GF5L2VYU-srJkaP3f.js +206 -0
- package/dist/worker/console/static/assets/chunk-JWPE2WC7-UYGvEP4l.js +1 -0
- package/dist/worker/console/static/assets/chunk-KBJHAD2P-B8luBrrz.js +1 -0
- package/dist/worker/console/static/assets/chunk-RYQCIY6F-DN7wXZSq.js +1 -0
- package/dist/worker/console/static/assets/chunk-XXDRQBXY-DXKyMuKS.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BaehtRk4.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BaehtRk4.js +1 -0
- package/dist/worker/console/static/assets/cose-bilkent-JH36ORCC-dqvoynXj.js +1 -0
- package/dist/worker/console/static/assets/cynefin-VYW2F7L2--PcyL34A.js +166 -0
- package/dist/worker/console/static/assets/cynefinDiagram-MW4NZA55-DvWs_hTY.js +62 -0
- package/dist/worker/console/static/assets/cytoscape.esm-yzknjiTM.js +321 -0
- package/dist/worker/console/static/assets/dagre-VZM6K2ZE-DxeIxbyO.js +4 -0
- package/dist/worker/console/static/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/worker/console/static/assets/diagram-7IWD3JNH-DPCG61Of.js +30 -0
- package/dist/worker/console/static/assets/diagram-B4RE2ZJO-CmuU50-U.js +3 -0
- package/dist/worker/console/static/assets/diagram-LBJQPF4R-B61XLD_v.js +24 -0
- package/dist/worker/console/static/assets/diagram-Q27KOJAE-BB7HTRRY.js +24 -0
- package/dist/worker/console/static/assets/diagram-UB23O5K3-DvkboAIp.js +41 -0
- package/dist/worker/console/static/assets/ebnfDiagram-BXEA7PRR-BdJ_y1fL.js +1 -0
- package/dist/worker/console/static/assets/erDiagram-JOGREHBK-9bUBZTRi.js +85 -0
- package/dist/worker/console/static/assets/flowDiagram-UKHOOZJN-Dw4L4RBa.js +156 -0
- package/dist/worker/console/static/assets/ganttDiagram-PKOTCBZU-Jr82N_QP.js +292 -0
- package/dist/worker/console/static/assets/gitGraphDiagram-DS77QQ5N-DAz9wFLr.js +106 -0
- package/dist/worker/console/static/assets/graph-DOmOIIwC.js +1 -0
- package/dist/worker/console/static/assets/index-B7Y-0g3J.css +1 -0
- package/dist/worker/console/static/assets/index-DkCrqaYg.js +325 -0
- package/dist/worker/console/static/assets/infoDiagram-6WML65LV-CBB5Np7y.js +2 -0
- package/dist/worker/console/static/assets/init-Gi6I4Gst.js +1 -0
- package/dist/worker/console/static/assets/ishikawaDiagram-WSZJBQD7-D8IOp94y.js +70 -0
- package/dist/worker/console/static/assets/journeyDiagram-NVQOT4AX-Dgd3AHGG.js +139 -0
- package/dist/worker/console/static/assets/kanban-definition-27J2QSJJ-BmYOxLE9.js +89 -0
- package/dist/worker/console/static/assets/layout-D-LzfAck.js +1 -0
- package/dist/worker/console/static/assets/linear-DfYTEF6J.js +1 -0
- package/dist/worker/console/static/assets/map-DxJ2ADlA.js +1 -0
- package/dist/worker/console/static/assets/mermaid.core-BjuFPRqa.js +308 -0
- package/dist/worker/console/static/assets/mindmap-definition-FAOFIHXS-CLyUViGd.js +96 -0
- package/dist/worker/console/static/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/worker/console/static/assets/pegDiagram-VL7TDLO6-BvX2Di4-.js +1 -0
- package/dist/worker/console/static/assets/pieDiagram-7S7Q4E2Y-BFj0_OLv.js +39 -0
- package/dist/worker/console/static/assets/quadrantDiagram-CIZ2JOQS-BIUrD_hx.js +7 -0
- package/dist/worker/console/static/assets/railroadDiagram-AXF67PYL-CHBB48fj.js +1 -0
- package/dist/worker/console/static/assets/requirementDiagram-LRYGKXZP-sJrYw2Sf.js +84 -0
- package/dist/worker/console/static/assets/sankeyDiagram-W5VNT64P-BzHH6fPR.js +40 -0
- package/dist/worker/console/static/assets/sequenceDiagram-SI44F4Z6-7QCnelCt.js +162 -0
- package/dist/worker/console/static/assets/sizeCapture-X5ZJPWSS-sDYSxn72.js +1 -0
- package/dist/worker/console/static/assets/stateDiagram-OKZ733FA-XpiUdwzm.js +1 -0
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-eEhq2A8Y.js +1 -0
- package/dist/worker/console/static/assets/swimlanes-SLNWSIFB-DvqgNPzD.js +2 -0
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-la8AC7fo.js +8 -0
- package/dist/worker/console/static/assets/timeline-definition-Z64GVDOM-2TyOYNx0.js +120 -0
- package/dist/worker/console/static/assets/vennDiagram-T6HMQDX7-B-nM6wM2.js +34 -0
- package/dist/worker/console/static/assets/wardleyDiagram-T6FBY63Y-B86wPdbr.js +78 -0
- package/dist/worker/console/static/assets/xychartDiagram-ELKLHX3M-Dr1C4AQz.js +7 -0
- package/dist/worker/console/static/favicon.svg +37 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_AMS-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Main-Bold.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Main-Italic.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Main-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Math-Italic.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Script-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Size1-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Size2-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Size3-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Size4-Regular.woff2 +0 -0
- package/dist/worker/console/static/fonts/katex/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/dist/worker/console/static/index.html +15 -0
- package/dist/worker/console/static-src/app/console-types.js +184 -0
- package/dist/worker/console/static-src/app/useConsoleShell.js +101 -0
- package/dist/worker/console/static-src/app/useOperatorActions.js +324 -0
- package/dist/worker/console/static-src/app/usePrdImport.js +172 -0
- package/dist/worker/console/static-src/app/useRecoveryActions.js +289 -0
- package/dist/worker/console/static-src/app/useRecoveryConsole.js +425 -0
- package/dist/worker/console/static-src/app/useTaskWizard.js +296 -0
- package/dist/worker/console/static-src/chat-markdown-security.js +38 -0
- package/dist/worker/console/static-src/chat-view-types.js +2 -0
- package/dist/worker/console/static-src/night/night-types.js +24 -0
- package/dist/worker/console/static-src/night/useNightBoard.js +94 -0
- package/dist/worker/console/static-src/night/useNightWizard.js +171 -0
- package/dist/worker/console/static-src/night-prepare-result.js +118 -0
- package/dist/worker/console/static-src/operator-chat/activity-journey.js +125 -0
- package/dist/worker/console/static-src/operator-chat/activity-rail-presentation.js +73 -0
- package/dist/worker/console/static-src/operator-chat/activity-references.js +20 -0
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +420 -0
- package/dist/worker/console/static-src/operator-chat/format.js +71 -0
- package/dist/worker/console/static-src/operator-chat/landing-density.js +23 -0
- package/dist/worker/console/static-src/operator-chat/mutation-gate.js +45 -0
- package/dist/worker/console/static-src/operator-chat/refs.js +86 -0
- package/dist/worker/console/static-src/operator-chat/resource-auto-invocation.js +91 -0
- package/dist/worker/console/static-src/operator-chat/resource-diagnostics.js +204 -0
- package/dist/worker/console/static-src/operator-chat/runtime-snapshot-store.js +257 -0
- package/dist/worker/console/static-src/operator-chat/session-title-watcher.js +128 -0
- package/dist/worker/console/static-src/operator-chat/sidebar-split.js +90 -0
- package/dist/worker/console/static-src/operator-chat/slash-palette-layout.js +24 -0
- package/dist/worker/console/static-src/operator-chat/slash-palette-nav.js +141 -0
- package/dist/worker/console/static-src/operator-chat/spatial-overlay.js +38 -0
- package/dist/worker/console/static-src/operator-chat/tools-catalog.js +77 -0
- package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +690 -0
- package/dist/worker/console/static-src/operator-chat/turn-submission.js +158 -0
- package/dist/worker/console/static-src/operator-chat/types.js +1 -0
- package/dist/worker/console/static-src/operator-chat/useActivityRailTransition.js +59 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +495 -0
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +780 -0
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +280 -0
- package/dist/worker/console/static-src/operator-chat/useComposer.js +257 -0
- package/dist/worker/console/static-src/operator-chat/useInterview.js +108 -0
- package/dist/worker/console/static-src/operator-chat/useOverlayFocus.js +84 -0
- package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +148 -0
- package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +358 -0
- package/dist/worker/console/static-src/operator-chat/useRuntimeSnapshot.js +196 -0
- package/dist/worker/console/static-src/operator-chat/useWorkspaceLayout.js +58 -0
- package/dist/worker/console/static-src/operator-chat/workspace-layout-mode.js +35 -0
- package/dist/worker/console/static-src/prd-file-import.js +218 -0
- package/dist/worker/console/vite.config.js +27 -0
- package/dist/worker/console/workflow-kinds.js +46 -0
- package/dist/worker/delivery/final-verification.js +302 -0
- package/dist/worker/delivery/git-transaction.js +497 -0
- package/dist/worker/delivery/package.js +537 -0
- package/dist/worker/delivery/verification-bundle.js +544 -0
- package/dist/worker/feature/acceptance-policy.js +227 -0
- package/dist/worker/feature/advance.js +301 -0
- package/dist/worker/feature/decision-loader.js +99 -0
- package/dist/worker/feature/discover.js +14 -0
- package/dist/worker/feature/doctor.js +223 -0
- package/dist/worker/feature/fullstack-validate.js +337 -0
- package/dist/worker/feature/next-action.js +140 -0
- package/dist/worker/feature/profile-schema.js +47 -0
- package/dist/worker/feature/ready-plan-projection.js +82 -0
- package/dist/worker/feature/reducer.js +137 -0
- package/dist/worker/feature/review.js +678 -0
- package/dist/worker/feature/run.js +390 -0
- package/dist/worker/feature/scaffold.js +812 -0
- package/dist/worker/feature/types.js +1 -0
- package/dist/worker/follow-up/approve.js +273 -0
- package/dist/worker/follow-up/factory.js +234 -0
- package/dist/worker/follow-up/paths.js +25 -0
- package/dist/worker/follow-up/policy.js +26 -0
- package/dist/worker/follow-up/schema.js +93 -0
- package/dist/worker/follow-up/store.js +96 -0
- package/dist/worker/loop-agent/command-result.js +1 -0
- package/dist/worker/loop-agent/controller-protocol.js +143 -0
- package/dist/worker/loop-agent/loop-agent-client.js +489 -0
- package/dist/worker/loop-agent/parse-json.js +14 -0
- package/dist/worker/materialize/harness-task-lifecycle-probe.js +126 -0
- package/dist/worker/materialize/harness-task-lineage.js +220 -0
- package/dist/worker/materialize/harness-task-materializer.js +648 -0
- package/dist/worker/metrics/projector.js +139 -0
- package/dist/worker/observability/dag-execution-trajectory.js +591 -0
- package/dist/worker/observability/event-history.js +216 -0
- package/dist/worker/observability/event-store.js +83 -0
- package/dist/worker/observability/events.js +79 -0
- package/dist/worker/observability/interrupt-eligibility.js +264 -0
- package/dist/worker/observability/progress-composite.js +34 -0
- package/dist/worker/observability/read-model.js +2499 -0
- package/dist/worker/observability/snapshot-store.js +43 -0
- package/dist/worker/observability/types.js +1 -0
- package/dist/worker/observe/dag-node-execution-output.js +180 -0
- package/dist/worker/observe/dag-run-artifacts.js +90 -0
- package/dist/worker/observe/health.js +58 -0
- package/dist/worker/observe/night-jobs.js +104 -0
- package/dist/worker/observe/node-input.js +441 -0
- package/dist/worker/observe/paths.js +174 -0
- package/dist/worker/observe/routes.js +1077 -0
- package/dist/worker/observe/server.js +117 -0
- package/dist/worker/observe/spec-evidence.js +398 -0
- package/dist/worker/observe/static/api.js +117 -0
- package/dist/worker/observe/static/app.js +169 -0
- package/dist/worker/observe/static/constants.js +182 -0
- package/dist/worker/observe/static/copy.js +67 -0
- package/dist/worker/observe/static/custom-select.js +567 -0
- package/dist/worker/observe/static/dag-edge-routing.js +368 -0
- package/dist/worker/observe/static/dag-helpers.js +161 -0
- package/dist/worker/observe/static/dag-history-labels.js +95 -0
- package/dist/worker/observe/static/dag-layout.d.ts +36 -0
- package/dist/worker/observe/static/dag-layout.js +163 -0
- package/dist/worker/observe/static/dag-model.js +145 -0
- package/dist/worker/observe/static/dom.js +220 -0
- package/dist/worker/observe/static/favicon.svg +37 -0
- package/dist/worker/observe/static/format-pool.d.ts +71 -0
- package/dist/worker/observe/static/format-pool.js +153 -0
- package/dist/worker/observe/static/format.js +347 -0
- package/dist/worker/observe/static/index.html +409 -0
- package/dist/worker/observe/static/kpi.js +78 -0
- package/dist/worker/observe/static/markdown-render.js +124 -0
- package/dist/worker/observe/static/operator-chrome.css +517 -0
- package/dist/worker/observe/static/operator-chrome.d.ts +83 -0
- package/dist/worker/observe/static/operator-chrome.js +623 -0
- package/dist/worker/observe/static/relations.js +133 -0
- package/dist/worker/observe/static/router.js +156 -0
- package/dist/worker/observe/static/run-processing.js +148 -0
- package/dist/worker/observe/static/shell-chrome.js +65 -0
- package/dist/worker/observe/static/state.js +496 -0
- package/dist/worker/observe/static/styles.css +3567 -0
- package/dist/worker/observe/static/views/batch.js +227 -0
- package/dist/worker/observe/static/views/dag-graph.js +508 -0
- package/dist/worker/observe/static/views/dag-inspector.js +1722 -0
- package/dist/worker/observe/static/views/dag-trajectory.js +313 -0
- package/dist/worker/observe/static/views/dag.js +483 -0
- package/dist/worker/observe/static/views/dags.js +877 -0
- package/dist/worker/observe/static/views/dashboard.js +747 -0
- package/dist/worker/observe/static/views/failures.js +143 -0
- package/dist/worker/observe/static/views/feature.js +492 -0
- package/dist/worker/observe/static/views/night.js +201 -0
- package/dist/worker/observe/static/views/pool.js +708 -0
- package/dist/worker/observe/static/views/run.js +453 -0
- package/dist/worker/observe/static/views/session-timeline.js +771 -0
- package/dist/worker/observe/static/views/shell.js +7 -0
- package/dist/worker/observe/static/views/task.js +315 -0
- package/dist/worker/observe/static/views/timeline.js +163 -0
- package/dist/worker/outcomes/adapters.js +153 -0
- package/dist/worker/outcomes/declared-artifacts.js +103 -0
- package/dist/worker/outcomes/evidence-tokens.js +29 -0
- package/dist/worker/outcomes/gate.js +40 -0
- package/dist/worker/outcomes/projector.js +227 -0
- package/dist/worker/outcomes/registry.js +1 -0
- package/dist/worker/outcomes/store.js +131 -0
- package/dist/worker/outcomes/types.js +79 -0
- package/dist/worker/pool/attempt-identity.js +41 -0
- package/dist/worker/pool/attempt-lease.js +184 -0
- package/dist/worker/pool/attempt-transition.js +210 -0
- package/dist/worker/pool/begin-attempt-with-lease.js +26 -0
- package/dist/worker/pool/begin-attempt.js +35 -0
- package/dist/worker/pool/doctor.js +165 -0
- package/dist/worker/pool/failure-routing.js +182 -0
- package/dist/worker/pool/migrate-state.js +303 -0
- package/dist/worker/pool/reconcile.js +285 -0
- package/dist/worker/pool/recovery-decision.js +163 -0
- package/dist/worker/pool/run-owner-store.js +126 -0
- package/dist/worker/pool/run-store.js +360 -0
- package/dist/worker/pool/runtime-reconcile-inventory.js +127 -0
- package/dist/worker/pool/state-projection.js +57 -0
- package/dist/worker/pool/types.js +17 -0
- package/dist/worker/pool/validation.js +144 -0
- package/dist/worker/preflight.js +157 -0
- package/dist/worker/profile-mapping.js +76 -0
- package/dist/worker/progress-reporter.js +63 -0
- package/dist/worker/report/morning-report.js +155 -0
- package/dist/worker/repos/repo-resolver.js +23 -0
- package/dist/worker/run-task/execute-prepared-task.js +178 -0
- package/dist/worker/run-task/run-task.js +912 -0
- package/dist/worker/runner/run-ready.js +561 -0
- package/dist/worker/runner/single-task-attempt.js +176 -0
- package/dist/worker/scheduler/admission.js +547 -0
- package/dist/worker/scheduler/auto-followup.js +99 -0
- package/dist/worker/scheduler/cli.js +644 -0
- package/dist/worker/scheduler/clock-install/darwin-launchd.js +238 -0
- package/dist/worker/scheduler/clock-install/linux-systemd-user.js +224 -0
- package/dist/worker/scheduler/clock-install/types.js +1 -0
- package/dist/worker/scheduler/clock-install/win32-schtasks.js +227 -0
- package/dist/worker/scheduler/clock-install.js +284 -0
- package/dist/worker/scheduler/clock.js +420 -0
- package/dist/worker/scheduler/dispatcher.js +503 -0
- package/dist/worker/scheduler/doctor.js +431 -0
- package/dist/worker/scheduler/evidence.js +170 -0
- package/dist/worker/scheduler/git-base.js +90 -0
- package/dist/worker/scheduler/index.js +25 -0
- package/dist/worker/scheduler/lease.js +114 -0
- package/dist/worker/scheduler/lifecycle.js +348 -0
- package/dist/worker/scheduler/lock.js +80 -0
- package/dist/worker/scheduler/morning-window.js +191 -0
- package/dist/worker/scheduler/night-git-finalizer.js +114 -0
- package/dist/worker/scheduler/night-harvest.js +412 -0
- package/dist/worker/scheduler/paths.js +92 -0
- package/dist/worker/scheduler/prepared-attempt-recovery.js +471 -0
- package/dist/worker/scheduler/recovery.js +277 -0
- package/dist/worker/scheduler/reservation.js +146 -0
- package/dist/worker/scheduler/retry.js +199 -0
- package/dist/worker/scheduler/scheduler-loop.js +272 -0
- package/dist/worker/scheduler/store.js +275 -0
- package/dist/worker/scheduler/traceability.js +54 -0
- package/dist/worker/scheduler/trigger.js +258 -0
- package/dist/worker/scheduler/types.js +369 -0
- package/dist/worker/scheduler/workspace-adapter.js +128 -0
- package/dist/worker/task-graph/acceptance-schema.js +40 -0
- package/dist/worker/task-graph/ready-planner.js +267 -0
- package/dist/worker/task-graph/ready-queue.js +23 -0
- package/dist/worker/task-graph/task-graph-schema.js +59 -0
- package/dist/worker/task-graph/types.js +1 -0
- package/dist/worker/task-graph/validate.js +293 -0
- package/dist/worker/task-spec/complexity-mapping.js +8 -0
- package/dist/worker/task-spec/schema.js +125 -0
- package/dist/worker/task-spec/types.js +1 -0
- package/dist/worker/task-spec/validate.js +391 -0
- package/dist/worker/task-spec/workflow-routing.js +149 -0
- package/dist/workflows/dag/authoring.js +8 -0
- package/dist/workflows/dag/authority-surface.js +138 -0
- package/dist/workflows/dag/backend-test-analysis-contract.js +507 -0
- package/dist/workflows/dag/backend-test-case-coverage-analysis.js +1985 -0
- package/dist/workflows/dag/backend-test-case-manifest.js +638 -0
- package/dist/workflows/dag/backend-test-classification-contract.js +38 -0
- package/dist/workflows/dag/backend-test-contract-envelope.js +205 -0
- package/dist/workflows/dag/backend-test-coverage-contract.js +202 -0
- package/dist/workflows/dag/backend-test-execution-contract.js +715 -0
- package/dist/workflows/dag/backend-test-gap-fill.js +205 -0
- package/dist/workflows/dag/backend-test-intake-context.js +178 -0
- package/dist/workflows/dag/backend-test-layout.js +133 -0
- package/dist/workflows/dag/backend-test-markdown-workflow.js +1984 -0
- package/dist/workflows/dag/backend-test-module-stem.js +26 -0
- package/dist/workflows/dag/backend-test-pytest-collection.js +859 -0
- package/dist/workflows/dag/backend-test-result-contract.js +1030 -0
- package/dist/workflows/dag/backend-test-scenario-param.js +1670 -0
- package/dist/workflows/dag/backend-test-scenario-partitions.js +249 -0
- package/dist/workflows/dag/backend-test-semantic-review-contract.js +36 -0
- package/dist/workflows/dag/backend-test-stability-contract.js +57 -0
- package/dist/workflows/dag/backend-test-writer-completeness.js +1058 -0
- package/dist/workflows/dag/budget-enforcement.js +67 -0
- package/dist/workflows/dag/canvas-observer.js +474 -0
- package/dist/workflows/dag/context-policy.js +137 -0
- package/dist/workflows/dag/contract-output-registry.js +14 -0
- package/dist/workflows/dag/contract-validator-registrations.js +10 -0
- package/dist/workflows/dag/controller-identity.js +104 -0
- package/dist/workflows/dag/convergence/controller.js +596 -0
- package/dist/workflows/dag/decision-envelope.js +557 -0
- package/dist/workflows/dag/decision-evidence.js +153 -0
- package/dist/workflows/dag/decision-gates.js +1 -0
- package/dist/workflows/dag/dynamic-runtime/condition.js +48 -0
- package/dist/workflows/dag/dynamic-runtime/loop-until.js +161 -0
- package/dist/workflows/dag/dynamic-runtime/map.js +435 -0
- package/dist/workflows/dag/dynamic-runtime/reduction.js +72 -0
- package/dist/workflows/dag/dynamic-runtime/shared.js +203 -0
- package/dist/workflows/dag/event-observer.js +132 -0
- package/dist/workflows/dag/executor-registry.js +23 -0
- package/dist/workflows/dag/facts.js +4 -0
- package/dist/workflows/dag/failure-category.js +118 -0
- package/dist/workflows/dag/failure-routing.js +105 -0
- package/dist/workflows/dag/final-verification.js +180 -0
- package/dist/workflows/dag/frontend-implementation-contract.js +1911 -0
- package/dist/workflows/dag/frontend-lint-baseline.js +474 -0
- package/dist/workflows/dag/frontend-plan-render.js +90 -0
- package/dist/workflows/dag/frontend-prewrite-gate.js +1011 -0
- package/dist/workflows/dag/frontend-project-capability.js +1 -0
- package/dist/workflows/dag/frontend-recovery-plan.js +73 -0
- package/dist/workflows/dag/frontend-recovery-root-manifest.js +123 -0
- package/dist/workflows/dag/frontend-recovery-run.js +539 -0
- package/dist/workflows/dag/frontend-repair.js +541 -0
- package/dist/workflows/dag/frontend-review-context.js +116 -0
- package/dist/workflows/dag/frontend-risk.js +161 -0
- package/dist/workflows/dag/frontend-test-case-checklist.js +343 -0
- package/dist/workflows/dag/frontend-test-case-manifest.js +104 -0
- package/dist/workflows/dag/frontend-test-case-quality.js +105 -0
- package/dist/workflows/dag/frontend-test-html-report.js +174 -0
- package/dist/workflows/dag/frontend-test-l5-report.js +177 -0
- package/dist/workflows/dag/frontend-test-result-contract.js +487 -0
- package/dist/workflows/dag/frontend-verification-trace.js +275 -0
- package/dist/workflows/dag/frontend-worktree-diff.js +201 -0
- package/dist/workflows/dag/frontend-writer-recovery.js +106 -0
- package/dist/workflows/dag/frontend-writer-rollback.js +821 -0
- package/dist/workflows/dag/governance-constants.js +5 -0
- package/dist/workflows/dag/governance-profile.js +413 -0
- package/dist/workflows/dag/index.js +6 -0
- package/dist/workflows/dag/init-hybrid.js +7345 -0
- package/dist/workflows/dag/interrupt-request.js +559 -0
- package/dist/workflows/dag/knowledge-curator.js +165 -0
- package/dist/workflows/dag/l5-report-metrics.js +33 -0
- package/dist/workflows/dag/lifecycle.js +855 -0
- package/dist/workflows/dag/liveness-policy.js +251 -0
- package/dist/workflows/dag/node-execution.js +1081 -0
- package/dist/workflows/dag/observer-compose.js +52 -0
- package/dist/workflows/dag/output-protocol.js +356 -0
- package/dist/workflows/dag/project-governance-context.js +514 -0
- package/dist/workflows/dag/prompt-source.js +88 -0
- package/dist/workflows/dag/prompt.js +348 -0
- package/dist/workflows/dag/reconcile-run.js +145 -0
- package/dist/workflows/dag/reconcile-tasks.js +404 -0
- package/dist/workflows/dag/recovery-recommendation.js +329 -0
- package/dist/workflows/dag/repair-artifact.js +363 -0
- package/dist/workflows/dag/report.js +1229 -0
- package/dist/workflows/dag/rerun-plan.js +614 -0
- package/dist/workflows/dag/rerun-run.js +556 -0
- package/dist/workflows/dag/rerun-task.js +370 -0
- package/dist/workflows/dag/retry-policy.js +263 -0
- package/dist/workflows/dag/run-store.js +41 -0
- package/dist/workflows/dag/runner.js +1069 -0
- package/dist/workflows/dag/runtime-contract.js +87 -0
- package/dist/workflows/dag/runtime.js +5 -0
- package/dist/workflows/dag/scheduler.js +497 -0
- package/dist/workflows/dag/sdd-embedded.js +128 -0
- package/dist/workflows/dag/skill-instructions.js +478 -0
- package/dist/workflows/dag/skill-snapshot.js +553 -0
- package/dist/workflows/dag/skills.js +41 -0
- package/dist/workflows/dag/spec.js +3 -0
- package/dist/workflows/dag/task-contract-binding.js +138 -0
- package/dist/workflows/dag/task-demand-routing.js +1 -0
- package/dist/workflows/dag/topo.js +30 -0
- package/dist/workflows/dag/types.js +1145 -0
- package/dist/workflows/dag/upstream-artifacts.js +98 -0
- package/dist/workflows/dag/validate.js +998 -0
- package/dist/workflows/dag/workspace-checkpoint.js +186 -0
- package/dist/workflows/dynamic/artifacts.js +65 -0
- package/dist/workflows/dynamic/compile.js +371 -0
- package/dist/workflows/dynamic/compileTypes.js +1 -0
- package/dist/workflows/dynamic/errors.js +5 -0
- package/dist/workflows/dynamic/index.js +7 -0
- package/dist/workflows/dynamic/profiles.js +156 -0
- package/dist/workflows/dynamic/spec.js +115 -0
- package/dist/workflows/dynamic/validate.js +275 -0
- package/dist/workflows/loop/actions/dag-action.js +129 -0
- package/dist/workflows/loop/actions/pi-review.js +267 -0
- package/dist/workflows/loop/actions/shared.js +157 -0
- package/dist/workflows/loop/actions/shell-verify.js +82 -0
- package/dist/workflows/loop/actions/types.js +1 -0
- package/dist/workflows/loop/actions/workflow-action.js +255 -0
- package/dist/workflows/loop/actions.js +160 -0
- package/dist/workflows/loop/benchmark.js +510 -0
- package/dist/workflows/loop/closeout.js +135 -0
- package/dist/workflows/loop/context.js +47 -0
- package/dist/workflows/loop/events.js +26 -0
- package/dist/workflows/loop/hash.js +32 -0
- package/dist/workflows/loop/index.js +8 -0
- package/dist/workflows/loop/paths.js +17 -0
- package/dist/workflows/loop/policy/auto-policy.js +112 -0
- package/dist/workflows/loop/policy/path-patterns.js +13 -0
- package/dist/workflows/loop/rounds.js +81 -0
- package/dist/workflows/loop/signals.js +52 -0
- package/dist/workflows/loop/state.js +116 -0
- package/dist/workflows/loop/templates.js +54 -0
- package/dist/workflows/loop/types.js +28 -0
- package/docs/README.md +82 -0
- package/docs/architecture/README.md +35 -0
- package/docs/architecture/dag-execution.md +165 -0
- package/docs/architecture/evolution.md +108 -0
- package/docs/architecture/facts-and-state.md +74 -0
- package/docs/architecture/runtime-boundaries.md +226 -0
- package/docs/architecture/system-overview.md +100 -0
- package/docs/architecture/worker-and-feature.md +122 -0
- package/docs/governance/README.md +18 -0
- package/docs/governance/harness-methodology-debugging.md +177 -0
- package/docs/governance/harness-methodology-tdd.md +130 -0
- package/docs/governance/harness-methodology-verification.md +27 -0
- package/docs/init-surface.manifest.json +358 -0
- package/docs/operations/README.md +15 -0
- package/docs/operations/local-development-environment.md +77 -0
- package/docs/skills/README.md +7 -0
- package/docs/skills/vetted-skill-registry.md +49 -0
- package/docs/templates/README.md +67 -0
- package/docs/templates/adr.md +60 -0
- package/docs/templates/agent-dag-authority-surface-audit.prompt.md +94 -0
- package/docs/templates/agent-dag-decision-envelope.schema.json +213 -0
- package/docs/templates/agent-dag-decision-gate-dogfood-report.md +117 -0
- package/docs/templates/agent-dag-decision-gate.prompt.md +246 -0
- package/docs/templates/agent-dag-process-supervisor.prompt.md +98 -0
- package/docs/templates/agent-dag-report.schema.json +473 -0
- package/docs/templates/agent-dag-review-verdict.prompt.md +68 -0
- package/docs/templates/agent-dag.base.json +190 -0
- package/docs/templates/agent-dag.final-verification.json +185 -0
- package/docs/templates/agent-dag.schema.json +590 -0
- package/docs/templates/agent-dag.supervised-implementation.json +640 -0
- package/docs/templates/agent-worker-production-readiness-checklist.md +47 -0
- package/docs/templates/backend-test-analysis.schema.json +37 -0
- package/docs/templates/backend-test-case-manifest.schema.json +223 -0
- package/docs/templates/backend-test-dag.classify.prompt.md +75 -0
- package/docs/templates/backend-test-dag.generate-pytest.prompt.md +41 -0
- package/docs/templates/backend-test-dag.json +671 -0
- package/docs/templates/backend-test-dag.retrospect.prompt.md +165 -0
- package/docs/templates/backend-test-dag.review-cases.prompt.md +36 -0
- package/docs/templates/backend-test-execution.schema.json +138 -0
- package/docs/templates/backend-test-result.schema.json +99 -0
- package/docs/templates/branch-merge-report.md +115 -0
- package/docs/templates/evaluation/agents-map-slim-v1.candidate.json +9 -0
- package/docs/templates/evaluation/agents-map-slim-v1.md +87 -0
- package/docs/templates/evaluation/agents-map-verbose-v0.candidate.json +9 -0
- package/docs/templates/evaluation/agents-map-verbose-v0.md +153 -0
- package/docs/templates/evaluation/campaign-budget-v1.json +12 -0
- package/docs/templates/evaluation/campaign-dogfood-v0.json +24 -0
- package/docs/templates/evaluation/campaign-evidence-v1.json +44 -0
- package/docs/templates/evaluation/context-policy-baseline-v1.json +17 -0
- package/docs/templates/evaluation/context-policy-role-specialized-v1.json +28 -0
- package/docs/templates/evaluation/corpus-dogfood-v0.manifest.json +118 -0
- package/docs/templates/evaluation/matrix-dag-dry-run-v1.json +21 -0
- package/docs/templates/evaluation/matrix-fixture-v1.json +10 -0
- package/docs/templates/evaluation/private-verifier-dogfood-v0.json +16 -0
- package/docs/templates/exec-plan.md +66 -0
- package/docs/templates/feature-spec.md +53 -0
- package/docs/templates/frontend-design-contract.md +68 -0
- package/docs/templates/frontend-eval/fixtures/failures/01-type-build-error.md +17 -0
- package/docs/templates/frontend-eval/fixtures/failures/02-unit-component-test-fail.md +16 -0
- package/docs/templates/frontend-eval/fixtures/failures/03-fixture-schema-drift.md +16 -0
- package/docs/templates/frontend-eval/fixtures/failures/04-missing-loading-empty-error-state.md +16 -0
- package/docs/templates/frontend-eval/fixtures/failures/05-forbidden-write-writeset-expansion.md +16 -0
- package/docs/templates/frontend-eval/fixtures/failures/06-unapproved-dependency-add.md +16 -0
- package/docs/templates/frontend-eval/fixtures/failures/07-mock-production-on.md +21 -0
- package/docs/templates/frontend-eval/fixtures/functional/01-simple-component-style.md +29 -0
- package/docs/templates/frontend-eval/fixtures/functional/02-form-validation.md +28 -0
- package/docs/templates/frontend-eval/fixtures/functional/03-list-detail-page.md +28 -0
- package/docs/templates/frontend-eval/fixtures/functional/04-api-mock.md +29 -0
- package/docs/templates/frontend-eval/fixtures/functional/05-permission-auth-gated-ui.md +27 -0
- package/docs/templates/frontend-eval/fixtures/functional/06-ssr-server-client-boundary.md +28 -0
- package/docs/templates/frontend-eval/fixtures/functional/07-shared-public-component-api.md +28 -0
- package/docs/templates/frontend-eval/fixtures/functional/08-pure-local-no-remote.md +27 -0
- package/docs/templates/frontend-eval/metrics.md +138 -0
- package/docs/templates/frontend-eval/smoke-targets.md +53 -0
- package/docs/templates/frontend-implementation-contract.schema.json +35 -0
- package/docs/templates/frontend-task-constraints.md +62 -0
- package/docs/templates/frontend-task-requirement.md +104 -0
- package/docs/templates/frontend-test-case-checklist.md +44 -0
- package/docs/templates/frontend-test-case.example.md +143 -0
- package/docs/templates/frontend-test-dag.generate-cases.prompt.md +63 -0
- package/docs/templates/frontend-test-dag.json +409 -0
- package/docs/templates/frontend-test-dag.retrieve-context.prompt.md +21 -0
- package/docs/templates/frontend-test-dag.retrospect.prompt.md +5 -0
- package/docs/templates/frontend-test-dag.review-cases.prompt.md +5 -0
- package/docs/templates/frontend-test-dag.review-execution.prompt.md +3 -0
- package/docs/templates/frontend-test-standard-scenarios.v1.json +159 -0
- package/docs/templates/harness.schema.json +351 -0
- package/docs/templates/hybrid-dag.json +188 -0
- package/docs/templates/init-evolution-review.md +35 -0
- package/docs/templates/init-managed-agents.md +157 -0
- package/docs/templates/interactive-ui-round2-experiment.md +66 -0
- package/docs/templates/knowledge-graph-bootstrap-dag.json +118 -0
- package/docs/templates/knowledge-sync-dag.json +178 -0
- package/docs/templates/knowledge-sync-draft.schema.json +71 -0
- package/docs/templates/product-line/AGENTS.md +9 -0
- package/docs/templates/product-line/README.md +42 -0
- package/docs/templates/product-line/acceptance.yaml +23 -0
- package/docs/templates/product-line/closeout.yaml +9 -0
- package/docs/templates/product-line/design.md +13 -0
- package/docs/templates/product-line/feature-scaffold-batch.example.yaml +31 -0
- package/docs/templates/product-line/feature.yaml +11 -0
- package/docs/templates/product-line/links.md +10 -0
- package/docs/templates/product-line/requirement.md +17 -0
- package/docs/templates/product-line/scaffold-samples/README.md +36 -0
- package/docs/templates/product-line/scaffold-samples/backend-only/acceptance.yaml +16 -0
- package/docs/templates/product-line/scaffold-samples/backend-only/design.md +14 -0
- package/docs/templates/product-line/scaffold-samples/backend-only/feature.yaml +14 -0
- package/docs/templates/product-line/scaffold-samples/backend-only/requirement.md +6 -0
- package/docs/templates/product-line/scaffold-samples/backend-only/tasks/BE-IMPL-001.yaml +83 -0
- package/docs/templates/product-line/scaffold-samples/backend-only/tasks/task-graph.yaml +14 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/acceptance.yaml +18 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/design.md +18 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/feature.yaml +14 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/requirement.md +6 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/BE-IMPL-001.yaml +84 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/CONTRACT-001.yaml +84 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/FE-IMPL-001.yaml +86 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/task-graph.yaml +40 -0
- package/docs/templates/product-line/scaffold-samples/frontend-only/acceptance.yaml +16 -0
- package/docs/templates/product-line/scaffold-samples/frontend-only/design.md +14 -0
- package/docs/templates/product-line/scaffold-samples/frontend-only/feature.yaml +14 -0
- package/docs/templates/product-line/scaffold-samples/frontend-only/requirement.md +6 -0
- package/docs/templates/product-line/scaffold-samples/frontend-only/tasks/FE-IMPL-001.yaml +85 -0
- package/docs/templates/product-line/scaffold-samples/frontend-only/tasks/task-graph.yaml +14 -0
- package/docs/templates/product-line/task-graph.yaml +23 -0
- package/docs/templates/product-line/task.yaml +68 -0
- package/docs/templates/product-line/test-plan.md +7 -0
- package/docs/templates/production-readiness-checklist.md +57 -0
- package/docs/templates/progress-log.md +27 -0
- package/docs/templates/project-start-checklist.md +9 -0
- package/docs/templates/qa-report.md +48 -0
- package/docs/templates/sprint-contract.md +29 -0
- package/docs/templates/worker-dogfood-evidence.md +80 -0
- package/docs/templates/worker-dogfood-setup.md +68 -0
- package/examples/decision-gate-agent-dag.json +177 -0
- package/examples/example-dag.json +46 -0
- package/examples/hybrid-loop-agent-dag.json +189 -0
- package/examples/l5-report-coms-process-definition.html +322 -0
- package/examples/l5-report-demo.html +79 -0
- package/harness.json +90 -0
- package/package.json +98 -0
- package/scripts/kb-bootstrap-init-skeleton.sh +241 -0
- package/scripts/kb-graph-incremental-prepare.mjs +386 -0
- package/scripts/kb-graph-materialize.mjs +105 -0
- package/scripts/kb-graph-promote.mjs +164 -0
- package/scripts/kb-query.mjs +554 -0
- package/skills/agent-worker/SKILL.md +48 -0
- package/skills/agent-worker/references/agent-worker-operator.md +159 -0
- package/skills/ai-engineering-context/SKILL.md +48 -0
- package/skills/analyze-product-dependencies/SKILL.md +108 -0
- package/skills/analyze-product-dependencies/references/api-documentation-schema.md +35 -0
- package/skills/analyze-product-dependencies/references/dependency-analysis-schema.md +38 -0
- package/skills/analyze-product-dependencies/references/example.md +76 -0
- package/skills/analyze-product-dependencies/references/forward-test-cases.md +110 -0
- package/skills/analyze-product-dependencies/references/input-contract.md +34 -0
- package/skills/analyze-product-dependencies/references/kb-integration.md +64 -0
- package/skills/analyze-product-dependencies/references/scouting-rules.md +76 -0
- package/skills/analyze-product-dependencies/scripts/test-validators.mjs +460 -0
- package/skills/analyze-product-dependencies/scripts/validate-api-documentation.mjs +194 -0
- package/skills/analyze-product-dependencies/scripts/validate-dependency-analysis.mjs +200 -0
- package/skills/analyze-product-dependencies/scripts/validate-product-requirement-input.mjs +90 -0
- package/skills/analyze-product-dependencies/scripts/validation-helpers.mjs +138 -0
- package/skills/analyze-product-requirements/SKILL.md +145 -0
- package/skills/analyze-product-requirements/references/acceptance-criteria.md +87 -0
- package/skills/analyze-product-requirements/references/clarification-and-knowledge.md +70 -0
- package/skills/analyze-product-requirements/references/example.md +104 -0
- package/skills/analyze-product-requirements/references/forward-test-cases.md +144 -0
- package/skills/analyze-product-requirements/references/kb-integration.md +56 -0
- package/skills/analyze-product-requirements/references/product-analysis-schema.md +41 -0
- package/skills/analyze-product-requirements/references/product-requirement-schema.md +42 -0
- package/skills/analyze-product-requirements/references/requirement-clarification-schema.md +66 -0
- package/skills/analyze-product-requirements/scripts/compute-source-identity.mjs +35 -0
- package/skills/analyze-product-requirements/scripts/test-validators.mjs +501 -0
- package/skills/analyze-product-requirements/scripts/validate-product-analysis.mjs +100 -0
- package/skills/analyze-product-requirements/scripts/validate-product-requirement.mjs +109 -0
- package/skills/analyze-product-requirements/scripts/validate-requirement-clarification.mjs +109 -0
- package/skills/analyze-product-requirements/scripts/validation-helpers.mjs +175 -0
- package/skills/browser-tools/SKILL.md +196 -0
- package/skills/browser-tools/browser-content.js +103 -0
- package/skills/browser-tools/browser-cookies.js +35 -0
- package/skills/browser-tools/browser-eval.js +53 -0
- package/skills/browser-tools/browser-hn-scraper.js +108 -0
- package/skills/browser-tools/browser-nav.js +44 -0
- package/skills/browser-tools/browser-pick.js +162 -0
- package/skills/browser-tools/browser-screenshot.js +34 -0
- package/skills/browser-tools/browser-start.js +86 -0
- package/skills/browser-tools/package-lock.json +2556 -0
- package/skills/browser-tools/package.json +19 -0
- package/skills/code-review-core/SKILL.md +20 -0
- package/skills/codebase-scout/SKILL.md +19 -0
- package/skills/frontend-bounded-implement/SKILL.md +53 -0
- package/skills/frontend-design-review/SKILL.md +79 -0
- package/skills/frontend-design-review/references/review-checklist.md +43 -0
- package/skills/frontend-implementation/SKILL.md +52 -0
- package/skills/frontend-implementation/references/code-standards.md +33 -0
- package/skills/frontend-implementation/references/design-spec.md +56 -0
- package/skills/frontend-implementation/references/node-contracts.md +31 -0
- package/skills/frontend-review/SKILL.md +55 -0
- package/skills/frontend-review/references/review-findings.md +50 -0
- package/skills/frontend-verification/SKILL.md +61 -0
- package/skills/frontend-verification/references/verification-checklist.md +48 -0
- package/skills/grill-me/SKILL.md +10 -0
- package/skills/grill-with-docs/SKILL.md +80 -0
- package/skills/grill-with-docs/adr-format.md +58 -0
- package/skills/grill-with-docs/context-format.md +52 -0
- package/skills/init-capability-evolution/SKILL.md +70 -0
- package/skills/local-jacoco-coverage/SKILL.md +281 -0
- package/skills/local-jacoco-coverage/references/requirement-to-source-mapping.md +85 -0
- package/skills/local-jacoco-coverage/references/runtime-alignment.md +106 -0
- package/skills/local-jacoco-coverage/scripts/run-coverage-analysis.sh +148 -0
- package/skills/local-jacoco-coverage/scripts/start-jacoco-agent.sh +110 -0
- package/skills/loop-agent/SKILL.md +68 -0
- package/skills/loop-agent/references/README.md +67 -0
- package/skills/loop-agent/references/command-reference.md +645 -0
- package/skills/loop-agent/references/docs-converge.md +126 -0
- package/skills/loop-agent/references/harness-policy.md +289 -0
- package/skills/loop-agent/references/hybrid-dag.md +245 -0
- package/skills/loop-agent/references/learned/README.md +21 -0
- package/skills/loop-agent/references/long-running-loop.md +57 -0
- package/skills/loop-agent/references/model-routing.md +45 -0
- package/skills/loop-agent/references/multi-worktree.md +54 -0
- package/skills/loop-agent/references/one-shot-runs.md +84 -0
- package/skills/loop-agent/references/orchestrator-and-interventions.md +175 -0
- package/skills/loop-agent/references/pi-prompt.md +23 -0
- package/skills/loop-agent/references/pi-subagent-assisted-mode.md +84 -0
- package/skills/loop-agent/references/post-implementation-and-patterns.md +54 -0
- package/skills/loop-agent/references/source-and-plan-practice.md +169 -0
- package/skills/loop-agent/references/task-workflow.md +104 -0
- package/skills/loop-agent/references/verification-and-failure-handling.md +148 -0
- package/skills/playwright-cli/SKILL.md +93 -0
- package/skills/playwright-cli/references/element-attributes.md +23 -0
- package/skills/playwright-cli/references/playwright-tests.md +39 -0
- package/skills/playwright-cli/references/request-mocking.md +87 -0
- package/skills/playwright-cli/references/running-code.md +241 -0
- package/skills/playwright-cli/references/session-management.md +225 -0
- package/skills/playwright-cli/references/storage-state.md +275 -0
- package/skills/playwright-cli/references/test-generation.md +433 -0
- package/skills/playwright-cli/references/tracing.md +5 -0
- package/skills/playwright-cli/references/video-recording.md +5 -0
- package/skills/playwright-cli-case-generator/SKILL.md +108 -0
- package/skills/requesting-code-review/SKILL.md +101 -0
- package/skills/requesting-code-review/code-reviewer.md +168 -0
- package/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/skills/systematic-debugging/SKILL.md +312 -0
- package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/skills/systematic-debugging/find-polluter.sh +63 -0
- package/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/skills/systematic-debugging/test-academic.md +14 -0
- package/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/skills/test-driven-development/SKILL.md +27 -0
- package/skills/using-git-worktrees/SKILL.md +215 -0
- package/skills/verification-before-completion/SKILL.md +154 -0
- package/skills/webapp-testing/SKILL.md +19 -0
|
@@ -0,0 +1,1011 @@
|
|
|
1
|
+
import { readFile, stat } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { isOpenspecSpecFilePath } from "../../shared/openspec-spec.js";
|
|
5
|
+
import { writeTextArtifactFile } from "../../infrastructure/harness/artifact-store.js";
|
|
6
|
+
import { countExcludedGovernanceSpecFiles, resolveOpenspecGovernanceRoot, } from "../../task/frontend-project-capability.js";
|
|
7
|
+
import { analyzeFrontendImplementationContract, writeFrontendImplementationContractArtifact, writeDeterministicJsonArtifact, assertFrontendSourceBindingFresh, deterministicSha256, sha256Hex, serializeDeterministicJson, applyFrontendImplementationContractPatch, extractFrontendImplementationJson, FrontendContractFailure, frontendNormalizationActionSchema, } from "./frontend-implementation-contract.js";
|
|
8
|
+
import { renderFrontendPlanMarkdown } from "./frontend-plan-render.js";
|
|
9
|
+
import { captureFrontendWorktreeBaseline } from "./frontend-worktree-diff.js";
|
|
10
|
+
import { pathMatchesPattern } from "../../shared/git-progress.js";
|
|
11
|
+
import { normalizeVerdictCandidateLine } from "./dynamic-runtime/shared.js";
|
|
12
|
+
export const FRONTEND_PREWRITE_RESULT_SCHEMA_ID = "frontend-prewrite-result-v1";
|
|
13
|
+
export const FRONTEND_PREWRITE_RESULT_ARTIFACT_NAME = "frontend-prewrite-result.json";
|
|
14
|
+
/** Canonical contract serialization must stay at or below this byte size. */
|
|
15
|
+
export const FRONTEND_CONTRACT_MAX_BYTES = 65536;
|
|
16
|
+
/**
|
|
17
|
+
* Machine-readable failure classification for blocked/retryable-invalid
|
|
18
|
+
* prewrite outcomes. Kept alongside the human-readable failureReason so
|
|
19
|
+
* downstream routing (repair prompting, dashboards, retry policies) can act on
|
|
20
|
+
* a stable code instead of parsing prose.
|
|
21
|
+
*/
|
|
22
|
+
export const frontendPrewriteFailureCodeSchema = z.enum([
|
|
23
|
+
"plan-text-unreadable",
|
|
24
|
+
"review-text-unreadable",
|
|
25
|
+
"verdict-not-pass",
|
|
26
|
+
"missing-requirement-ids",
|
|
27
|
+
"source-binding-not-fresh",
|
|
28
|
+
"contract-invalid",
|
|
29
|
+
"contract-blocked",
|
|
30
|
+
"mock-strategy-outside-allowed",
|
|
31
|
+
"mock-strategy-no-verification-commands",
|
|
32
|
+
"target-outside-write-set",
|
|
33
|
+
"verification-target-outside-write-set",
|
|
34
|
+
"openspec-not-read",
|
|
35
|
+
"candidate-missing-drift",
|
|
36
|
+
"openspec-citation-block-unparseable",
|
|
37
|
+
"openspec-not-cited",
|
|
38
|
+
"openspec-citation-not-read",
|
|
39
|
+
"component-spec-reference-invalid",
|
|
40
|
+
"component-spec-not-cited",
|
|
41
|
+
"component-choices-missing",
|
|
42
|
+
"contract-too-large",
|
|
43
|
+
"revision-patch-unmergeable",
|
|
44
|
+
]);
|
|
45
|
+
export const frontendPrewriteResultV1Schema = z
|
|
46
|
+
.object({
|
|
47
|
+
schemaVersion: z.literal(1),
|
|
48
|
+
schemaId: z.literal(FRONTEND_PREWRITE_RESULT_SCHEMA_ID),
|
|
49
|
+
classification: z.enum([
|
|
50
|
+
"accepted",
|
|
51
|
+
"accepted-normalized",
|
|
52
|
+
"retryable-invalid",
|
|
53
|
+
"blocked",
|
|
54
|
+
]),
|
|
55
|
+
failureCode: frontendPrewriteFailureCodeSchema.nullable(),
|
|
56
|
+
normalizationActions: z.array(frontendNormalizationActionSchema),
|
|
57
|
+
candidateRawSha256: z.string().regex(/^[a-f0-9]{64}$/),
|
|
58
|
+
candidateJsonSha256: z.string().regex(/^[a-f0-9]{64}$/).nullable(),
|
|
59
|
+
canonicalSha256: z.string().regex(/^[a-f0-9]{64}$/).nullable(),
|
|
60
|
+
selectedPlanNodeId: z.string().regex(/^[a-z][a-z0-9-]*$/),
|
|
61
|
+
sourceBindingSha256: z.string().regex(/^[a-f0-9]{64}$/).nullable(),
|
|
62
|
+
writeSetDigest: z.string().regex(/^[a-f0-9]{64}$/).nullable(),
|
|
63
|
+
retryCount: z.number().int().min(0).max(1),
|
|
64
|
+
maxRetryCount: z.literal(1),
|
|
65
|
+
failureReason: z.string().nullable(),
|
|
66
|
+
digestAlgorithm: z.literal("sha256"),
|
|
67
|
+
})
|
|
68
|
+
.strict()
|
|
69
|
+
.superRefine((value, ctx) => {
|
|
70
|
+
const acceptedLike = value.classification === "accepted" ||
|
|
71
|
+
value.classification === "accepted-normalized";
|
|
72
|
+
const failed = value.classification === "retryable-invalid" ||
|
|
73
|
+
value.classification === "blocked";
|
|
74
|
+
if (acceptedLike) {
|
|
75
|
+
if (value.failureReason !== null)
|
|
76
|
+
ctx.addIssue({
|
|
77
|
+
code: "custom",
|
|
78
|
+
message: "failureReason must be null for accepted/accepted-normalized",
|
|
79
|
+
path: ["failureReason"],
|
|
80
|
+
});
|
|
81
|
+
if (value.failureCode !== null)
|
|
82
|
+
ctx.addIssue({
|
|
83
|
+
code: "custom",
|
|
84
|
+
message: "failureCode must be null for accepted/accepted-normalized",
|
|
85
|
+
path: ["failureCode"],
|
|
86
|
+
});
|
|
87
|
+
if (!value.candidateJsonSha256 || !value.canonicalSha256)
|
|
88
|
+
ctx.addIssue({
|
|
89
|
+
code: "custom",
|
|
90
|
+
message: "candidateJsonSha256 and canonicalSha256 are required for accepted/accepted-normalized",
|
|
91
|
+
path: ["candidateJsonSha256"],
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (value.classification === "accepted" && value.normalizationActions.length !== 0)
|
|
95
|
+
ctx.addIssue({
|
|
96
|
+
code: "custom",
|
|
97
|
+
message: "accepted must have empty normalizationActions",
|
|
98
|
+
path: ["normalizationActions"],
|
|
99
|
+
});
|
|
100
|
+
if (value.classification === "accepted-normalized" &&
|
|
101
|
+
value.normalizationActions.length === 0)
|
|
102
|
+
ctx.addIssue({
|
|
103
|
+
code: "custom",
|
|
104
|
+
message: "accepted-normalized must have non-empty normalizationActions",
|
|
105
|
+
path: ["normalizationActions"],
|
|
106
|
+
});
|
|
107
|
+
if (failed) {
|
|
108
|
+
if (value.normalizationActions.length !== 0)
|
|
109
|
+
ctx.addIssue({
|
|
110
|
+
code: "custom",
|
|
111
|
+
message: "retryable-invalid/blocked must have empty normalizationActions",
|
|
112
|
+
path: ["normalizationActions"],
|
|
113
|
+
});
|
|
114
|
+
if (!value.failureReason)
|
|
115
|
+
ctx.addIssue({
|
|
116
|
+
code: "custom",
|
|
117
|
+
message: "failureReason must be non-empty for retryable-invalid/blocked",
|
|
118
|
+
path: ["failureReason"],
|
|
119
|
+
});
|
|
120
|
+
if (value.failureCode === null)
|
|
121
|
+
ctx.addIssue({
|
|
122
|
+
code: "custom",
|
|
123
|
+
message: "failureCode must be non-null for retryable-invalid/blocked",
|
|
124
|
+
path: ["failureCode"],
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
export const frontendWriterAdmissionSchema = z
|
|
129
|
+
.object({
|
|
130
|
+
schemaVersion: z.literal(1),
|
|
131
|
+
writerNodeId: z.enum(["frontend-implement-pi", "frontend-repair-pi"]),
|
|
132
|
+
decision: z.enum(["authorized", "denied"]),
|
|
133
|
+
sourceArtifact: z.string().min(1),
|
|
134
|
+
artifactHash: z.string().regex(/^[a-f0-9]{64}$/),
|
|
135
|
+
checkedAt: z.string().min(1),
|
|
136
|
+
reason: z.string().nullable(),
|
|
137
|
+
})
|
|
138
|
+
.strict();
|
|
139
|
+
async function selectNode(runDir, primary, fallbacks) {
|
|
140
|
+
const candidates = [primary, ...fallbacks.filter((id) => id !== primary)];
|
|
141
|
+
const rejections = [];
|
|
142
|
+
for (const nodeId of candidates) {
|
|
143
|
+
try {
|
|
144
|
+
const raw = await readFile(path.join(runDir, `${nodeId}.json`), "utf8");
|
|
145
|
+
const record = JSON.parse(raw);
|
|
146
|
+
if (record.status === "FINISHED")
|
|
147
|
+
return nodeId;
|
|
148
|
+
rejections.push(`${nodeId}: status=${String(record.status)}`);
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
if (error.code === "ENOENT") {
|
|
152
|
+
rejections.push(`${nodeId}: file missing`);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
throw new Error(`frontend prewrite gate no FINISHED candidate: ${rejections.join("; ")}`);
|
|
159
|
+
}
|
|
160
|
+
async function readNodeText(runDir, nodeId) {
|
|
161
|
+
const record = JSON.parse(await readFile(path.join(runDir, `${nodeId}.json`), "utf8"));
|
|
162
|
+
if (record.status !== "FINISHED") {
|
|
163
|
+
throw new Error(`frontend prewrite gate requires FINISHED node ${nodeId} (got ${String(record.status)})`);
|
|
164
|
+
}
|
|
165
|
+
const text = [record.assistantText, record.stdout]
|
|
166
|
+
.filter((value) => Boolean(value?.trim()))
|
|
167
|
+
.join("\n");
|
|
168
|
+
if (!text)
|
|
169
|
+
throw new Error(`frontend prewrite gate empty output from ${nodeId}`);
|
|
170
|
+
return text;
|
|
171
|
+
}
|
|
172
|
+
async function readNodeRawText(runDir, nodeId) {
|
|
173
|
+
const record = JSON.parse(await readFile(path.join(runDir, `${nodeId}.json`), "utf8"));
|
|
174
|
+
return record.assistantText ?? record.stdout ?? "";
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Same shape predicate as the internal `isContract` inside
|
|
178
|
+
* `extractFrontendImplementationJson` (frontend-implementation-contract.ts):
|
|
179
|
+
* schemaVersion 1 + a plain `targets` object + `requirements` and
|
|
180
|
+
* `verificationTargets` arrays. A merge-patch delta does not carry these
|
|
181
|
+
* fields, so this is the deterministic boundary between a full contract and a
|
|
182
|
+
* patch. Keep the two predicates in sync.
|
|
183
|
+
*/
|
|
184
|
+
function isFullContractShape(value) {
|
|
185
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
const record = value;
|
|
189
|
+
const targets = record.targets;
|
|
190
|
+
return (record.schemaVersion === 1 &&
|
|
191
|
+
targets !== null &&
|
|
192
|
+
typeof targets === "object" &&
|
|
193
|
+
!Array.isArray(targets) &&
|
|
194
|
+
Array.isArray(record.requirements) &&
|
|
195
|
+
Array.isArray(record.verificationTargets));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Shared merge pipeline for revisionPatch mode and content-driven
|
|
199
|
+
* compatibility: read the original contract node, extract the original
|
|
200
|
+
* contract and the effective node's patch, apply the RFC 7386 merge-patch, and
|
|
201
|
+
* serialize deterministically. Throws on any failure; callers map the error to
|
|
202
|
+
* their own classification (retryable-invalid for explicit revisionPatch mode,
|
|
203
|
+
* blocked for content-driven fallback).
|
|
204
|
+
*/
|
|
205
|
+
async function mergeRevisionPatch(runDir, planText, originalNodeId) {
|
|
206
|
+
const originalText = await readNodeText(runDir, originalNodeId);
|
|
207
|
+
const originalValue = extractFrontendImplementationJson(originalText);
|
|
208
|
+
const patchValue = extractFrontendImplementationJson(planText);
|
|
209
|
+
const merged = applyFrontendImplementationContractPatch(originalValue, patchValue);
|
|
210
|
+
return serializeDeterministicJson(merged);
|
|
211
|
+
}
|
|
212
|
+
function firstNonEmptyVerdictLine(text) {
|
|
213
|
+
const lines = text
|
|
214
|
+
.split(/\r?\n/)
|
|
215
|
+
.map((line) => line.trim())
|
|
216
|
+
.filter(Boolean);
|
|
217
|
+
// Emphasis stripping (backtick + asterisk) is shared with the runIf
|
|
218
|
+
// selector and node-level output-protocol validation via
|
|
219
|
+
// normalizeVerdictCandidateLine. The gate keeps its own loose
|
|
220
|
+
// pass/request-revision normalization below (prefix match + trailing
|
|
221
|
+
// prose tolerance) for deterministic fail-closed behavior.
|
|
222
|
+
const normalizedLines = lines.map(normalizeVerdictCandidateLine);
|
|
223
|
+
const first = normalizedLines[0] ?? "";
|
|
224
|
+
// The prompt requires VERDICT to be the first non-empty line, but model
|
|
225
|
+
// output can still prepend a summary. Keep the protocol strict in the
|
|
226
|
+
// prompt while making the deterministic gate resilient to that drift.
|
|
227
|
+
const verdictLine = normalizedLines.find((line) => /^VERDICT:/.test(line)) ?? first;
|
|
228
|
+
if (/^VERDICT:\s*pass(?:\s*[.!?。!?]|\s+|$)/i.test(verdictLine))
|
|
229
|
+
return "VERDICT: pass";
|
|
230
|
+
if (/^VERDICT:\s*request-revision(?:\s*[.!?。!?]|\s+|$)/i.test(verdictLine))
|
|
231
|
+
return "VERDICT: request-revision";
|
|
232
|
+
return verdictLine;
|
|
233
|
+
}
|
|
234
|
+
function eventArgs(event) {
|
|
235
|
+
return event.args ?? event.toolInput ?? event.input ?? {};
|
|
236
|
+
}
|
|
237
|
+
function toRepoRelativePath(filePath, repoRoot) {
|
|
238
|
+
const resolved = path.resolve(repoRoot, filePath);
|
|
239
|
+
const relative = path.relative(repoRoot, resolved);
|
|
240
|
+
if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
return relative.replaceAll(path.sep, "/");
|
|
244
|
+
}
|
|
245
|
+
function isFailedToolResult(event) {
|
|
246
|
+
return (event.isError === true ||
|
|
247
|
+
event.toolResult?.error != null ||
|
|
248
|
+
event.toolResult?.ok === false ||
|
|
249
|
+
event.result?.error != null ||
|
|
250
|
+
event.result?.ok === false);
|
|
251
|
+
}
|
|
252
|
+
async function collectOpenspecReadPaths(input) {
|
|
253
|
+
const { runDir, planNodeId, reviewNodeId, repoRoot } = input;
|
|
254
|
+
const matched = new Set();
|
|
255
|
+
for (const nodeId of [planNodeId, reviewNodeId]) {
|
|
256
|
+
const eventsPath = path.join(runDir, nodeId, "session-events.jsonl");
|
|
257
|
+
try {
|
|
258
|
+
const raw = await readFile(eventsPath, "utf8");
|
|
259
|
+
const startedReads = new Map();
|
|
260
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
261
|
+
const trimmed = line.trim();
|
|
262
|
+
if (!trimmed)
|
|
263
|
+
continue;
|
|
264
|
+
let event;
|
|
265
|
+
try {
|
|
266
|
+
event = JSON.parse(trimmed);
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (event.type === "tool_execution_start" &&
|
|
272
|
+
event.toolName === "read" &&
|
|
273
|
+
event.toolCallId) {
|
|
274
|
+
const readPath = eventArgs(event).path;
|
|
275
|
+
if (typeof readPath === "string") {
|
|
276
|
+
startedReads.set(event.toolCallId, readPath);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
else if (event.type === "tool_execution_end" &&
|
|
280
|
+
event.toolName === "read" &&
|
|
281
|
+
event.toolCallId !== undefined) {
|
|
282
|
+
const readPath = startedReads.get(event.toolCallId);
|
|
283
|
+
const relativePath = readPath
|
|
284
|
+
? toRepoRelativePath(readPath, repoRoot)
|
|
285
|
+
: null;
|
|
286
|
+
if (relativePath &&
|
|
287
|
+
!isFailedToolResult(event) &&
|
|
288
|
+
isOpenspecSpecFilePath(relativePath)) {
|
|
289
|
+
matched.add(relativePath);
|
|
290
|
+
}
|
|
291
|
+
startedReads.delete(event.toolCallId);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
if (error.code === "ENOENT")
|
|
297
|
+
continue;
|
|
298
|
+
throw error;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return [...matched];
|
|
302
|
+
}
|
|
303
|
+
async function checkOpenspecReadEvidence(input) {
|
|
304
|
+
const { runDir, candidatePaths, planNodeId, reviewNodeId, repoRoot } = input;
|
|
305
|
+
if (candidatePaths.length === 0)
|
|
306
|
+
return [];
|
|
307
|
+
const allReadPaths = await collectOpenspecReadPaths({
|
|
308
|
+
runDir,
|
|
309
|
+
planNodeId,
|
|
310
|
+
reviewNodeId,
|
|
311
|
+
repoRoot,
|
|
312
|
+
});
|
|
313
|
+
const normalizedCandidates = new Set(candidatePaths
|
|
314
|
+
.map((candidate) => toRepoRelativePath(candidate, repoRoot))
|
|
315
|
+
.filter((candidate) => Boolean(candidate && isOpenspecSpecFilePath(candidate))));
|
|
316
|
+
return allReadPaths.filter((readPath) => normalizedCandidates.has(readPath));
|
|
317
|
+
}
|
|
318
|
+
function normalizeCitationPath(rawPath, repoRoot) {
|
|
319
|
+
let candidate = rawPath.trim();
|
|
320
|
+
const hashIndex = candidate.indexOf("#");
|
|
321
|
+
if (hashIndex >= 0)
|
|
322
|
+
candidate = candidate.slice(0, hashIndex);
|
|
323
|
+
candidate = candidate.replace(/\\/g, "/");
|
|
324
|
+
if (!candidate)
|
|
325
|
+
return null;
|
|
326
|
+
if (repoRoot) {
|
|
327
|
+
const relative = toRepoRelativePath(candidate, repoRoot);
|
|
328
|
+
return relative ? relative.replace(/\\/g, "/") : null;
|
|
329
|
+
}
|
|
330
|
+
return candidate;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Parses the deterministic openspec-citations fence from the effective plan
|
|
334
|
+
* output. Each non-empty line must be one JSON object {"path","section","line"}.
|
|
335
|
+
* Rows whose normalized path is not a supported openspec spec file are ignored
|
|
336
|
+
* (out of scope); rows that are invalid JSON or lack a string path mark the
|
|
337
|
+
* block unparseable (fail-closed when candidates are non-empty).
|
|
338
|
+
*/
|
|
339
|
+
export function parseOpenspecCitations(planText, repoRoot) {
|
|
340
|
+
const citations = [];
|
|
341
|
+
let blockPresent = false;
|
|
342
|
+
let unparseable = false;
|
|
343
|
+
const fenceRe = /```openspec-citations[ \t]*\r?\n([\s\S]*?)\r?\n```/g;
|
|
344
|
+
let match;
|
|
345
|
+
while ((match = fenceRe.exec(planText)) !== null) {
|
|
346
|
+
blockPresent = true;
|
|
347
|
+
const body = match[1] ?? "";
|
|
348
|
+
for (const rawLine of body.split(/\r?\n/)) {
|
|
349
|
+
const line = rawLine.trim();
|
|
350
|
+
if (!line)
|
|
351
|
+
continue;
|
|
352
|
+
let parsed;
|
|
353
|
+
try {
|
|
354
|
+
parsed = JSON.parse(line);
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
unparseable = true;
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
361
|
+
unparseable = true;
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
const rawPath = parsed.path;
|
|
365
|
+
if (typeof rawPath !== "string" || !rawPath.trim()) {
|
|
366
|
+
unparseable = true;
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
const normalized = normalizeCitationPath(rawPath, repoRoot);
|
|
370
|
+
if (!normalized || !isOpenspecSpecFilePath(normalized))
|
|
371
|
+
continue;
|
|
372
|
+
const section = typeof parsed.section === "string"
|
|
373
|
+
? parsed.section
|
|
374
|
+
: "";
|
|
375
|
+
const lineValue = parsed.line;
|
|
376
|
+
const citationLine = typeof lineValue === "number" && Number.isInteger(lineValue)
|
|
377
|
+
? lineValue
|
|
378
|
+
: null;
|
|
379
|
+
citations.push({ path: normalized, section, line: citationLine });
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return { blockPresent, unparseable, citations };
|
|
383
|
+
}
|
|
384
|
+
async function finalizePrewrite(input, pending) {
|
|
385
|
+
const sourceBindingSha256 = input.sourceBinding
|
|
386
|
+
? deterministicSha256(input.sourceBinding)
|
|
387
|
+
: null;
|
|
388
|
+
const writeSetDigest = input.config.implementationWriteSet
|
|
389
|
+
? deterministicSha256([...new Set(input.config.implementationWriteSet)].sort())
|
|
390
|
+
: null;
|
|
391
|
+
const prewriteResult = frontendPrewriteResultV1Schema.parse({
|
|
392
|
+
schemaVersion: 1,
|
|
393
|
+
schemaId: FRONTEND_PREWRITE_RESULT_SCHEMA_ID,
|
|
394
|
+
classification: pending.classification,
|
|
395
|
+
normalizationActions: pending.normalizationActions,
|
|
396
|
+
candidateRawSha256: pending.candidateRawSha256,
|
|
397
|
+
candidateJsonSha256: pending.candidateJsonSha256,
|
|
398
|
+
canonicalSha256: pending.canonicalSha256,
|
|
399
|
+
selectedPlanNodeId: pending.planNodeId,
|
|
400
|
+
sourceBindingSha256,
|
|
401
|
+
writeSetDigest,
|
|
402
|
+
retryCount: 0,
|
|
403
|
+
maxRetryCount: 1,
|
|
404
|
+
failureReason: pending.failureReason,
|
|
405
|
+
failureCode: pending.failureCode,
|
|
406
|
+
digestAlgorithm: "sha256",
|
|
407
|
+
});
|
|
408
|
+
const written = await writeDeterministicJsonArtifact(input.runDir, path.posix.join(input.config.outputDir, FRONTEND_PREWRITE_RESULT_ARTIFACT_NAME), prewriteResult);
|
|
409
|
+
return {
|
|
410
|
+
ok: true,
|
|
411
|
+
classification: pending.classification,
|
|
412
|
+
planNodeId: pending.planNodeId,
|
|
413
|
+
reviewNodeId: pending.reviewNodeId,
|
|
414
|
+
verdict: pending.verdict,
|
|
415
|
+
mockStrategy: pending.mockStrategy,
|
|
416
|
+
artifact: pending.artifact,
|
|
417
|
+
prewriteResult: {
|
|
418
|
+
path: written.path,
|
|
419
|
+
sha256: written.sha256,
|
|
420
|
+
schemaId: FRONTEND_PREWRITE_RESULT_SCHEMA_ID,
|
|
421
|
+
},
|
|
422
|
+
failureReason: pending.failureReason,
|
|
423
|
+
failureCode: pending.failureCode,
|
|
424
|
+
normalizationActions: pending.normalizationActions,
|
|
425
|
+
candidateRawSha256: pending.candidateRawSha256,
|
|
426
|
+
candidateJsonSha256: pending.candidateJsonSha256,
|
|
427
|
+
canonicalSha256: pending.canonicalSha256,
|
|
428
|
+
openspecReadPaths: pending.openspecReadPaths,
|
|
429
|
+
openspecCandidatePaths: pending.openspecCandidatePaths,
|
|
430
|
+
openspecPolicy: pending.openspecPolicy,
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
export async function runFrontendPrewriteGate(input) {
|
|
434
|
+
const workspaceRoot = input.workspaceRoot ?? input.repoRoot;
|
|
435
|
+
// selectNode throws for a scheduling defect (no FINISHED plan/review). That
|
|
436
|
+
// remains an ERROR and is intentionally not classified into prewrite-result.
|
|
437
|
+
const planNodeId = await selectNode(input.runDir, input.config.planFromNodeId, input.config.planFallbackFromNodeIds);
|
|
438
|
+
const reviewNodeId = await selectNode(input.runDir, input.config.reviewFromNodeId, input.config.reviewFallbackFromNodeIds);
|
|
439
|
+
const candidateRawSha256 = sha256Hex(await readNodeRawText(input.runDir, planNodeId));
|
|
440
|
+
const openspecPolicy = input.config.openspecPolicy ?? "scan-strict";
|
|
441
|
+
const basePending = {
|
|
442
|
+
planNodeId,
|
|
443
|
+
reviewNodeId,
|
|
444
|
+
verdict: "",
|
|
445
|
+
candidateRawSha256,
|
|
446
|
+
candidateJsonSha256: null,
|
|
447
|
+
canonicalSha256: null,
|
|
448
|
+
normalizationActions: [],
|
|
449
|
+
mockStrategy: undefined,
|
|
450
|
+
artifact: undefined,
|
|
451
|
+
failureReason: null,
|
|
452
|
+
failureCode: null,
|
|
453
|
+
classification: "accepted",
|
|
454
|
+
openspecReadPaths: [],
|
|
455
|
+
openspecCandidatePaths: input.config.openspecCandidatePaths ?? [],
|
|
456
|
+
openspecPolicy,
|
|
457
|
+
};
|
|
458
|
+
let planText;
|
|
459
|
+
try {
|
|
460
|
+
planText = await readNodeText(input.runDir, planNodeId);
|
|
461
|
+
}
|
|
462
|
+
catch (error) {
|
|
463
|
+
return finalizePrewrite(input, {
|
|
464
|
+
...basePending,
|
|
465
|
+
classification: "retryable-invalid",
|
|
466
|
+
failureReason: error instanceof Error ? error.message : String(error),
|
|
467
|
+
failureCode: "plan-text-unreadable",
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
let reviewText;
|
|
471
|
+
try {
|
|
472
|
+
reviewText = await readNodeText(input.runDir, reviewNodeId);
|
|
473
|
+
}
|
|
474
|
+
catch (error) {
|
|
475
|
+
return finalizePrewrite(input, {
|
|
476
|
+
...basePending,
|
|
477
|
+
classification: "blocked",
|
|
478
|
+
failureReason: `frontend prewrite gate blocked by ${reviewNodeId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
479
|
+
failureCode: "review-text-unreadable",
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
const verdict = firstNonEmptyVerdictLine(reviewText);
|
|
483
|
+
if (verdict !== "VERDICT: pass") {
|
|
484
|
+
return finalizePrewrite(input, {
|
|
485
|
+
...basePending,
|
|
486
|
+
verdict,
|
|
487
|
+
classification: "blocked",
|
|
488
|
+
failureReason: `frontend prewrite gate blocked by ${reviewNodeId}: ${verdict || "missing VERDICT"}`,
|
|
489
|
+
failureCode: "verdict-not-pass",
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
// revisionPatch mode: the effective plan node emits an RFC 7386 merge-patch
|
|
493
|
+
// delta against the original contract node (planFallbackFromNodeIds[0]).
|
|
494
|
+
// Legacy DAGs without revisionPatch (undefined) keep full-contract semantics.
|
|
495
|
+
const revisionPatchMode = input.config.revisionPatch === true &&
|
|
496
|
+
planNodeId === input.config.planFromNodeId &&
|
|
497
|
+
input.config.planFallbackFromNodeIds.length > 0;
|
|
498
|
+
let effectiveContractText = null;
|
|
499
|
+
if (revisionPatchMode) {
|
|
500
|
+
const originalNodeId = input.config.planFallbackFromNodeIds[0];
|
|
501
|
+
try {
|
|
502
|
+
effectiveContractText = await mergeRevisionPatch(input.runDir, planText, originalNodeId);
|
|
503
|
+
}
|
|
504
|
+
catch (error) {
|
|
505
|
+
return finalizePrewrite(input, {
|
|
506
|
+
...basePending,
|
|
507
|
+
verdict,
|
|
508
|
+
classification: "retryable-invalid",
|
|
509
|
+
failureReason: `frontend prewrite gate revisionPatch mode requires original contract node ${originalNodeId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
510
|
+
failureCode: "contract-invalid",
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
// Content-driven compatibility (Bug 1): legacy DAGs without
|
|
516
|
+
// revisionPatch can still receive a merge-patch delta from the revision
|
|
517
|
+
// node. Detect the output shape instead of trusting the DAG flag alone.
|
|
518
|
+
// - Full contract shape → keep legacy full-contract semantics unchanged.
|
|
519
|
+
// - Patch shape with a usable original contract node → auto-merge and
|
|
520
|
+
// run the existing analysis/materialization pipeline.
|
|
521
|
+
// - Patch shape but unmergeable → blocked + revision-patch-unmergeable
|
|
522
|
+
// (no retryable loop).
|
|
523
|
+
let planJsonValue = null;
|
|
524
|
+
try {
|
|
525
|
+
planJsonValue = extractFrontendImplementationJson(planText);
|
|
526
|
+
}
|
|
527
|
+
catch {
|
|
528
|
+
// Not machine-readable JSON: fall back to the legacy full-contract
|
|
529
|
+
// path where analyzeFrontendImplementationContract surfaces the
|
|
530
|
+
// original diagnostic (fail-closed without a new failure mode).
|
|
531
|
+
}
|
|
532
|
+
if (planJsonValue !== null && !isFullContractShape(planJsonValue)) {
|
|
533
|
+
const originalNodeId = input.config.planFallbackFromNodeIds[0];
|
|
534
|
+
if (!originalNodeId || originalNodeId === planNodeId) {
|
|
535
|
+
return finalizePrewrite(input, {
|
|
536
|
+
...basePending,
|
|
537
|
+
verdict,
|
|
538
|
+
classification: "blocked",
|
|
539
|
+
failureReason: "frontend prewrite gate: the effective plan output is a merge-patch delta but no distinct original contract node is available. Check the DAG revisionPatch/planFallbackFromNodeIds configuration or regenerate the DAG.",
|
|
540
|
+
failureCode: "revision-patch-unmergeable",
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
try {
|
|
544
|
+
const originalText = await readNodeText(input.runDir, originalNodeId);
|
|
545
|
+
const originalValue = extractFrontendImplementationJson(originalText);
|
|
546
|
+
if (!isFullContractShape(originalValue)) {
|
|
547
|
+
throw new Error(`original contract node ${originalNodeId} is not a full frontend implementation contract`);
|
|
548
|
+
}
|
|
549
|
+
effectiveContractText = await mergeRevisionPatch(input.runDir, planText, originalNodeId);
|
|
550
|
+
}
|
|
551
|
+
catch (error) {
|
|
552
|
+
return finalizePrewrite(input, {
|
|
553
|
+
...basePending,
|
|
554
|
+
verdict,
|
|
555
|
+
classification: "blocked",
|
|
556
|
+
failureReason: `frontend prewrite gate: the effective plan output is a merge-patch delta but it cannot be merged onto the original contract node ${originalNodeId}: ${error instanceof Error ? error.message : String(error)}. Check the DAG revisionPatch/planFallbackFromNodeIds configuration or regenerate the DAG.`,
|
|
557
|
+
failureCode: "revision-patch-unmergeable",
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
const requirementIdSearchText = effectiveContractText ?? planText;
|
|
563
|
+
const missingIds = input.config.requiredRequirementIds.filter((id) => !requirementIdSearchText.includes(id));
|
|
564
|
+
if (missingIds.length > 0) {
|
|
565
|
+
return finalizePrewrite(input, {
|
|
566
|
+
...basePending,
|
|
567
|
+
verdict,
|
|
568
|
+
classification: "blocked",
|
|
569
|
+
failureReason: `frontend prewrite gate missing requirement ids: ${missingIds.join(", ")}`,
|
|
570
|
+
failureCode: "missing-requirement-ids",
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
if (workspaceRoot) {
|
|
574
|
+
if (input.config.requireSourceFreshness) {
|
|
575
|
+
if (!input.sourceBinding) {
|
|
576
|
+
throw new Error("frontend prewrite gate requires sourceBinding for freshness check");
|
|
577
|
+
}
|
|
578
|
+
try {
|
|
579
|
+
await assertFrontendSourceBindingFresh({
|
|
580
|
+
workspaceRoot,
|
|
581
|
+
binding: input.sourceBinding,
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
catch (error) {
|
|
585
|
+
return finalizePrewrite(input, {
|
|
586
|
+
...basePending,
|
|
587
|
+
verdict,
|
|
588
|
+
classification: "blocked",
|
|
589
|
+
failureReason: error instanceof Error ? error.message : String(error),
|
|
590
|
+
failureCode: "source-binding-not-fresh",
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
let hasGitMetadata = true;
|
|
595
|
+
try {
|
|
596
|
+
await stat(path.join(workspaceRoot, ".git"));
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
if (error instanceof Error && error.message.includes("ENOENT"))
|
|
600
|
+
hasGitMetadata = false;
|
|
601
|
+
else
|
|
602
|
+
throw error;
|
|
603
|
+
}
|
|
604
|
+
if (hasGitMetadata)
|
|
605
|
+
await captureFrontendWorktreeBaseline({
|
|
606
|
+
runDir: input.runDir,
|
|
607
|
+
workspaceRoot,
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
// Candidate -> canonical conversion. The gate consumes the selected
|
|
611
|
+
// plan/revision assistant output directly and is the only conversion point.
|
|
612
|
+
let analysis;
|
|
613
|
+
try {
|
|
614
|
+
analysis = await analyzeFrontendImplementationContract({
|
|
615
|
+
runDir: input.runDir,
|
|
616
|
+
fromNodeId: effectiveContractText ? undefined : planNodeId,
|
|
617
|
+
rawContractText: effectiveContractText ?? undefined,
|
|
618
|
+
sourceBinding: input.sourceBinding,
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
catch (error) {
|
|
622
|
+
if (error instanceof FrontendContractFailure) {
|
|
623
|
+
return finalizePrewrite(input, {
|
|
624
|
+
...basePending,
|
|
625
|
+
verdict,
|
|
626
|
+
classification: error.kind,
|
|
627
|
+
failureReason: error.message,
|
|
628
|
+
failureCode: error.kind === "retryable-invalid"
|
|
629
|
+
? "contract-invalid"
|
|
630
|
+
: "contract-blocked",
|
|
631
|
+
candidateJsonSha256: error.candidateJsonSha256,
|
|
632
|
+
normalizationActions: [],
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
throw error;
|
|
636
|
+
}
|
|
637
|
+
// Size guard: a canonical contract above 64KB is a retryable-invalid defect
|
|
638
|
+
// (compress the contract) rather than a writer authorization failure.
|
|
639
|
+
const contractSizeBytes = Buffer.byteLength(serializeDeterministicJson(analysis.canonical), "utf8");
|
|
640
|
+
if (contractSizeBytes > FRONTEND_CONTRACT_MAX_BYTES) {
|
|
641
|
+
return finalizePrewrite(input, {
|
|
642
|
+
...basePending,
|
|
643
|
+
verdict,
|
|
644
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
645
|
+
normalizationActions: [],
|
|
646
|
+
mockStrategy: analysis.canonical.mockApi.strategy,
|
|
647
|
+
classification: "retryable-invalid",
|
|
648
|
+
failureReason: `frontend prewrite gate: canonical contract serialization is ${contractSizeBytes} bytes, exceeding the ${FRONTEND_CONTRACT_MAX_BYTES}-byte limit. 压缩契约(移除冗余 prose、重复目标或过长描述)后重试。`,
|
|
649
|
+
failureCode: "contract-too-large",
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
const mockStrategy = analysis.canonical.mockApi.strategy;
|
|
653
|
+
if (!input.config.allowedMockStrategies.includes(mockStrategy)) {
|
|
654
|
+
const quotedAllowed = input.config.allowedMockStrategies
|
|
655
|
+
.map((strategy) => JSON.stringify(strategy))
|
|
656
|
+
.join(", ");
|
|
657
|
+
const forcedNotNeeded = input.config.allowedMockStrategies.length === 1 &&
|
|
658
|
+
input.config.allowedMockStrategies[0] === "not-needed";
|
|
659
|
+
const reason = forcedNotNeeded
|
|
660
|
+
? "the task is auto/not-required or lacks authorized deterministic Mock verification commands"
|
|
661
|
+
: `allowed strategies are [${quotedAllowed}]`;
|
|
662
|
+
return finalizePrewrite(input, {
|
|
663
|
+
...basePending,
|
|
664
|
+
verdict,
|
|
665
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
666
|
+
normalizationActions: [],
|
|
667
|
+
mockStrategy,
|
|
668
|
+
classification: "blocked",
|
|
669
|
+
failureReason: `frontend contract mock strategy "${mockStrategy}" is incompatible with the generated allowed strategies [${quotedAllowed}]; ${reason}. Regenerate the DAG or set frontendMock.policy=required with authorized Mock verification commands.`,
|
|
670
|
+
failureCode: "mock-strategy-outside-allowed",
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
// Mock command binding (main): a non-not-needed strategy can only be proven
|
|
674
|
+
// by the DAG's frozen Mock verification commands. Block before any write is
|
|
675
|
+
// authorized when none were materialized at generation time.
|
|
676
|
+
if (mockStrategy !== "not-needed" &&
|
|
677
|
+
(input.config.mockCommandLabels?.length ?? 0) === 0) {
|
|
678
|
+
return finalizePrewrite(input, {
|
|
679
|
+
...basePending,
|
|
680
|
+
verdict,
|
|
681
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
682
|
+
normalizationActions: [],
|
|
683
|
+
mockStrategy,
|
|
684
|
+
classification: "blocked",
|
|
685
|
+
failureReason: `frontend prewrite gate blocked: contract selected Mock strategy ${mockStrategy} but the DAG has no authorized Mock verification commands; add frontendMock.verifyCommands or a project mock script, or select not-needed`,
|
|
686
|
+
failureCode: "mock-strategy-no-verification-commands",
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
if (input.config.implementationWriteSet) {
|
|
690
|
+
const writeSet = new Set(input.config.implementationWriteSet);
|
|
691
|
+
const contractTargets = new Set(analysis.canonical.targets.files);
|
|
692
|
+
const uncoveredTargets = [...contractTargets].filter((target) => ![...writeSet].some((pattern) => pathMatchesPattern(target, pattern) || target === pattern));
|
|
693
|
+
if (uncoveredTargets.length > 0) {
|
|
694
|
+
return finalizePrewrite(input, {
|
|
695
|
+
...basePending,
|
|
696
|
+
verdict,
|
|
697
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
698
|
+
normalizationActions: [],
|
|
699
|
+
mockStrategy,
|
|
700
|
+
classification: "blocked",
|
|
701
|
+
failureReason: `frontend prewrite gate contract target is outside implementation writeSet: ${uncoveredTargets.join(", ")}`,
|
|
702
|
+
failureCode: "target-outside-write-set",
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
const nonStaticVTs = analysis.canonical.verificationTargets.filter((vt) => vt.type !== "static");
|
|
706
|
+
const uncoveredVTs = nonStaticVTs.filter((vt) => ![...writeSet].some((pattern) => pathMatchesPattern(vt.file, pattern) || vt.file === pattern));
|
|
707
|
+
if (uncoveredVTs.length > 0) {
|
|
708
|
+
return finalizePrewrite(input, {
|
|
709
|
+
...basePending,
|
|
710
|
+
verdict,
|
|
711
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
712
|
+
normalizationActions: [],
|
|
713
|
+
mockStrategy,
|
|
714
|
+
classification: "blocked",
|
|
715
|
+
failureReason: `frontend prewrite gate verification target is outside implementation writeSet: ${uncoveredVTs.map((vt) => vt.file).join(", ")}`,
|
|
716
|
+
failureCode: "verification-target-outside-write-set",
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
// Effective plan/review must actually read the candidate openspec paths when
|
|
721
|
+
// any exist. This fail-closes BEFORE the canonical contract is materialized
|
|
722
|
+
// so a writer is never authorized on top of unread normative evidence.
|
|
723
|
+
const candidatePaths = input.config.openspecCandidatePaths ?? [];
|
|
724
|
+
const candidateRoot = workspaceRoot ?? process.cwd();
|
|
725
|
+
// Drift precheck: candidates are frozen at generation time. A candidate that
|
|
726
|
+
// no longer exists on disk was deleted/renamed after generation and is a
|
|
727
|
+
// generation-contract defect, not an "unread" failure.
|
|
728
|
+
const missingCandidates = [];
|
|
729
|
+
if (candidatePaths.length > 0) {
|
|
730
|
+
for (const candidate of candidatePaths) {
|
|
731
|
+
try {
|
|
732
|
+
await stat(path.join(candidateRoot, candidate));
|
|
733
|
+
}
|
|
734
|
+
catch {
|
|
735
|
+
missingCandidates.push(candidate);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
if (missingCandidates.length > 0) {
|
|
740
|
+
return finalizePrewrite(input, {
|
|
741
|
+
...basePending,
|
|
742
|
+
verdict,
|
|
743
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
744
|
+
normalizationActions: [],
|
|
745
|
+
mockStrategy,
|
|
746
|
+
classification: "blocked",
|
|
747
|
+
failureReason: `frontend prewrite gate blocked: openspec candidate paths frozen at generation time no longer exist on disk: ${missingCandidates.join(", ")}. 候选集在生成期冻结,这些候选在生成后被删除/改名,请修正后重新生成 DAG。`,
|
|
748
|
+
failureCode: "candidate-missing-drift",
|
|
749
|
+
openspecReadPaths: [],
|
|
750
|
+
openspecCandidatePaths: candidatePaths,
|
|
751
|
+
});
|
|
752
|
+
}
|
|
753
|
+
let openspecReadPaths;
|
|
754
|
+
if (openspecPolicy === "cited") {
|
|
755
|
+
openspecReadPaths = await collectOpenspecReadPaths({
|
|
756
|
+
runDir: input.runDir,
|
|
757
|
+
planNodeId,
|
|
758
|
+
reviewNodeId,
|
|
759
|
+
repoRoot: candidateRoot,
|
|
760
|
+
});
|
|
761
|
+
if (candidatePaths.length > 0) {
|
|
762
|
+
const parsed = parseOpenspecCitations(planText, candidateRoot);
|
|
763
|
+
if (!parsed.blockPresent || parsed.unparseable) {
|
|
764
|
+
return finalizePrewrite(input, {
|
|
765
|
+
...basePending,
|
|
766
|
+
verdict,
|
|
767
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
768
|
+
normalizationActions: [],
|
|
769
|
+
mockStrategy,
|
|
770
|
+
classification: "retryable-invalid",
|
|
771
|
+
failureReason: `frontend prewrite gate: the effective plan output must end with a parseable \`\`\`openspec-citations fenced block (one JSON {"path","section","line"} per line). ${parsed.blockPresent
|
|
772
|
+
? "The block is present but contains unparseable lines."
|
|
773
|
+
: "No openspec-citations block was found."}`,
|
|
774
|
+
failureCode: "openspec-citation-block-unparseable",
|
|
775
|
+
openspecReadPaths,
|
|
776
|
+
openspecCandidatePaths: candidatePaths,
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
const citedPaths = new Set(parsed.citations.map((citation) => citation.path));
|
|
780
|
+
const notCited = candidatePaths.filter((candidate) => !citedPaths.has(candidate));
|
|
781
|
+
if (notCited.length > 0) {
|
|
782
|
+
return finalizePrewrite(input, {
|
|
783
|
+
...basePending,
|
|
784
|
+
verdict,
|
|
785
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
786
|
+
normalizationActions: [],
|
|
787
|
+
mockStrategy,
|
|
788
|
+
classification: "retryable-invalid",
|
|
789
|
+
failureReason: `frontend prewrite gate: these openspec candidate paths were not cited in the plan openspec-citations block: ${notCited.join(", ")}`,
|
|
790
|
+
failureCode: "openspec-not-cited",
|
|
791
|
+
openspecReadPaths,
|
|
792
|
+
openspecCandidatePaths: candidatePaths,
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
const readSet = new Set(openspecReadPaths);
|
|
796
|
+
const uncorroborated = [
|
|
797
|
+
...new Set(parsed.citations
|
|
798
|
+
.filter((citation) => !readSet.has(citation.path))
|
|
799
|
+
.map((citation) => citation.path)),
|
|
800
|
+
];
|
|
801
|
+
if (uncorroborated.length > 0) {
|
|
802
|
+
return finalizePrewrite(input, {
|
|
803
|
+
...basePending,
|
|
804
|
+
verdict,
|
|
805
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
806
|
+
normalizationActions: [],
|
|
807
|
+
mockStrategy,
|
|
808
|
+
classification: "retryable-invalid",
|
|
809
|
+
failureReason: `frontend prewrite gate: these openspec paths were cited in the plan but have no successful read event in the effective plan/review: ${uncorroborated.join(", ")}`,
|
|
810
|
+
failureCode: "openspec-citation-not-read",
|
|
811
|
+
openspecReadPaths,
|
|
812
|
+
openspecCandidatePaths: candidatePaths,
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
// cited with empty candidates: no read enforcement. The generation step
|
|
817
|
+
// emits an advisory instead of failing the gate.
|
|
818
|
+
}
|
|
819
|
+
else {
|
|
820
|
+
openspecReadPaths = await checkOpenspecReadEvidence({
|
|
821
|
+
runDir: input.runDir,
|
|
822
|
+
candidatePaths,
|
|
823
|
+
planNodeId,
|
|
824
|
+
reviewNodeId,
|
|
825
|
+
repoRoot: candidateRoot,
|
|
826
|
+
});
|
|
827
|
+
if (candidatePaths.length > 0) {
|
|
828
|
+
const readSet = new Set(openspecReadPaths);
|
|
829
|
+
const unread = candidatePaths.filter((candidate) => !readSet.has(candidate));
|
|
830
|
+
if (unread.length > 0) {
|
|
831
|
+
const governanceRoot = await resolveOpenspecGovernanceRoot(candidateRoot);
|
|
832
|
+
const excludedGovernanceCount = await countExcludedGovernanceSpecFiles(candidateRoot, governanceRoot);
|
|
833
|
+
return finalizePrewrite(input, {
|
|
834
|
+
...basePending,
|
|
835
|
+
verdict,
|
|
836
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
837
|
+
normalizationActions: [],
|
|
838
|
+
mockStrategy,
|
|
839
|
+
classification: "retryable-invalid",
|
|
840
|
+
failureReason: `frontend prewrite gate: effective plan/review did not read these openspec candidate paths: ${unread.join(", ")}. Read each candidate and report applicable rules plus hit path/section/line number, conflicts, and missing specifications, then rerun. 实际成功读取: ${openspecReadPaths.length > 0 ? openspecReadPaths.join(", ") : "(none)"}; 候选总数: ${candidatePaths.length}; 排除治理目录 ${governanceRoot} 下 ${excludedGovernanceCount} 个文件(运行期诊断口径); 候选集在生成期冻结,若候选与本任务无关属于生成期契约配置问题,应修正后重新生成 DAG。`,
|
|
841
|
+
failureCode: "openspec-not-read",
|
|
842
|
+
openspecReadPaths,
|
|
843
|
+
openspecCandidatePaths: candidatePaths,
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
// Component selection spec conformance (ADR 0016). Deterministic cross-check
|
|
849
|
+
// that declared component/token selections trace to the frontend spec
|
|
850
|
+
// (openspec/ai_workspace component + theme) instead of a model's ad-hoc
|
|
851
|
+
// "better" choice. Runs after the openspec read gate so citation + read
|
|
852
|
+
// evidence are already resolved.
|
|
853
|
+
const componentChoices = analysis.canonical.uiComponentChoices ?? [];
|
|
854
|
+
const componentSpecCandidates = input.config.componentSpecCandidatePaths ?? [];
|
|
855
|
+
const hasUiVisibleWork = analysis.canonical.uiStates.some((state) => state.applicable) ||
|
|
856
|
+
analysis.canonical.interactions.length > 0;
|
|
857
|
+
if (componentSpecCandidates.length > 0 &&
|
|
858
|
+
hasUiVisibleWork &&
|
|
859
|
+
componentChoices.length === 0) {
|
|
860
|
+
return finalizePrewrite(input, {
|
|
861
|
+
...basePending,
|
|
862
|
+
verdict,
|
|
863
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
864
|
+
normalizationActions: [],
|
|
865
|
+
mockStrategy,
|
|
866
|
+
classification: "retryable-invalid",
|
|
867
|
+
failureReason: "frontend prewrite gate: the canonical contract has UI-visible work but uiComponentChoices is missing or empty while the generation-frozen component/theme specification bucket is non-empty. 为每个 UI 用途声明组件选型(decision: specified | reuse-existing | new),specified 必须给 specReference.path/section/line,new 必须给 rationale 声明偏差。",
|
|
868
|
+
failureCode: "component-choices-missing",
|
|
869
|
+
openspecReadPaths,
|
|
870
|
+
openspecCandidatePaths: candidatePaths,
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
const componentSpecReferences = componentChoices
|
|
874
|
+
.map((choice) => ({
|
|
875
|
+
raw: choice.specReference?.path ?? "",
|
|
876
|
+
normalized: choice.specReference?.path
|
|
877
|
+
? normalizeCitationPath(choice.specReference.path, candidateRoot)
|
|
878
|
+
: null,
|
|
879
|
+
}))
|
|
880
|
+
.filter((ref) => ref.raw.length > 0);
|
|
881
|
+
if (componentSpecReferences.length > 0) {
|
|
882
|
+
const invalidRefs = [
|
|
883
|
+
...new Set(componentSpecReferences
|
|
884
|
+
.filter((ref) => !ref.normalized ||
|
|
885
|
+
!isOpenspecSpecFilePath(ref.normalized))
|
|
886
|
+
.map((ref) => ref.raw)),
|
|
887
|
+
];
|
|
888
|
+
if (invalidRefs.length > 0) {
|
|
889
|
+
return finalizePrewrite(input, {
|
|
890
|
+
...basePending,
|
|
891
|
+
verdict,
|
|
892
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
893
|
+
normalizationActions: [],
|
|
894
|
+
mockStrategy,
|
|
895
|
+
classification: "retryable-invalid",
|
|
896
|
+
failureReason: `frontend prewrite gate: these uiComponentChoices specReference paths are not supported openspec/ai_workspace spec files: ${invalidRefs.join(", ")}`,
|
|
897
|
+
failureCode: "component-spec-reference-invalid",
|
|
898
|
+
openspecReadPaths,
|
|
899
|
+
openspecCandidatePaths: candidatePaths,
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
if (openspecPolicy === "cited") {
|
|
903
|
+
const parsedCitations = parseOpenspecCitations(planText, candidateRoot);
|
|
904
|
+
const citedPaths = new Set(parsedCitations.citations.map((citation) => citation.path));
|
|
905
|
+
const readSet = new Set(openspecReadPaths);
|
|
906
|
+
const uncorroborated = [
|
|
907
|
+
...new Set(componentSpecReferences
|
|
908
|
+
.filter((ref) => !ref.normalized ||
|
|
909
|
+
!citedPaths.has(ref.normalized) ||
|
|
910
|
+
!readSet.has(ref.normalized))
|
|
911
|
+
.map((ref) => ref.raw)),
|
|
912
|
+
];
|
|
913
|
+
if (uncorroborated.length > 0) {
|
|
914
|
+
return finalizePrewrite(input, {
|
|
915
|
+
...basePending,
|
|
916
|
+
verdict,
|
|
917
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
918
|
+
normalizationActions: [],
|
|
919
|
+
mockStrategy,
|
|
920
|
+
classification: "retryable-invalid",
|
|
921
|
+
failureReason: `frontend prewrite gate: these uiComponentChoices specReference paths were not cited in the plan openspec-citations block or lack a successful read event: ${uncorroborated.join(", ")}`,
|
|
922
|
+
failureCode: "component-spec-not-cited",
|
|
923
|
+
openspecReadPaths,
|
|
924
|
+
openspecCandidatePaths: candidatePaths,
|
|
925
|
+
});
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
// Render the deterministic plan.md from the canonical contract (fail-closed
|
|
930
|
+
// before any artifact is written: no contract, no writer authorization).
|
|
931
|
+
let planMarkdown;
|
|
932
|
+
try {
|
|
933
|
+
planMarkdown = renderFrontendPlanMarkdown(analysis.canonical);
|
|
934
|
+
}
|
|
935
|
+
catch (error) {
|
|
936
|
+
return finalizePrewrite(input, {
|
|
937
|
+
...basePending,
|
|
938
|
+
verdict,
|
|
939
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
940
|
+
normalizationActions: [],
|
|
941
|
+
mockStrategy,
|
|
942
|
+
classification: "retryable-invalid",
|
|
943
|
+
failureReason: `frontend prewrite gate: failed to render ${input.config.planMdArtifactName ?? "frontend-plan.md"}: ${error instanceof Error ? error.message : String(error)}`,
|
|
944
|
+
failureCode: "contract-invalid",
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
// Materialize the canonical contract only after every governance check passed.
|
|
948
|
+
const artifact = await writeFrontendImplementationContractArtifact({
|
|
949
|
+
runDir: input.runDir,
|
|
950
|
+
outputDir: input.config.outputDir,
|
|
951
|
+
artifactName: input.config.artifactName,
|
|
952
|
+
canonical: analysis.canonical,
|
|
953
|
+
});
|
|
954
|
+
// Materialize the rendered plan.md in the same outputDir as the contract.
|
|
955
|
+
await writeTextArtifactFile(path.join(input.runDir, path.posix.join(input.config.outputDir, input.config.planMdArtifactName ?? "frontend-plan.md")), planMarkdown);
|
|
956
|
+
const classification = analysis.normalizationActions.length > 0 ? "accepted-normalized" : "accepted";
|
|
957
|
+
return finalizePrewrite(input, {
|
|
958
|
+
...basePending,
|
|
959
|
+
verdict,
|
|
960
|
+
classification,
|
|
961
|
+
failureReason: null,
|
|
962
|
+
candidateJsonSha256: analysis.candidateJsonSha256,
|
|
963
|
+
canonicalSha256: artifact.sha256,
|
|
964
|
+
normalizationActions: analysis.normalizationActions,
|
|
965
|
+
mockStrategy,
|
|
966
|
+
artifact,
|
|
967
|
+
openspecReadPaths,
|
|
968
|
+
openspecCandidatePaths: candidatePaths,
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
export function formatFrontendPrewriteGateStdout(result) {
|
|
972
|
+
const lines = [];
|
|
973
|
+
if (result.classification === "accepted" ||
|
|
974
|
+
result.classification === "accepted-normalized") {
|
|
975
|
+
lines.push("Frontend prewrite gate: pass");
|
|
976
|
+
}
|
|
977
|
+
else if (result.classification === "blocked") {
|
|
978
|
+
lines.push("Frontend prewrite gate: blocked");
|
|
979
|
+
}
|
|
980
|
+
else {
|
|
981
|
+
lines.push("Frontend prewrite gate: retryable-invalid");
|
|
982
|
+
}
|
|
983
|
+
lines.push(`Classification: ${result.classification}`);
|
|
984
|
+
lines.push(`Plan: ${result.planNodeId}`);
|
|
985
|
+
lines.push(`Review: ${result.reviewNodeId}`);
|
|
986
|
+
if (result.mockStrategy)
|
|
987
|
+
lines.push(`Mock strategy: ${result.mockStrategy}`);
|
|
988
|
+
if (result.artifact) {
|
|
989
|
+
lines.push(`Structured artifact: ${result.artifact.path}`);
|
|
990
|
+
lines.push(`Schema: ${result.artifact.schemaId}`);
|
|
991
|
+
lines.push(`SHA-256: ${result.artifact.sha256}`);
|
|
992
|
+
}
|
|
993
|
+
lines.push(`Prewrite result: ${result.prewriteResult.path}`);
|
|
994
|
+
lines.push(`Openspec policy: ${result.openspecPolicy}`);
|
|
995
|
+
if (result.failureReason)
|
|
996
|
+
lines.push(`Failure reason: ${result.failureReason}`);
|
|
997
|
+
if (result.openspecReadPaths.length > 0) {
|
|
998
|
+
lines.push(`openspec read: ${result.openspecReadPaths.join(", ")}`);
|
|
999
|
+
}
|
|
1000
|
+
if (result.openspecCandidatePaths.length > 0) {
|
|
1001
|
+
const readSet = new Set(result.openspecReadPaths);
|
|
1002
|
+
const unread = result.openspecCandidatePaths.filter((candidate) => !readSet.has(candidate));
|
|
1003
|
+
if (unread.length > 0) {
|
|
1004
|
+
lines.push(`openspec unread: ${unread.join(", ")}`);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
else {
|
|
1008
|
+
lines.push("openspec: unavailable");
|
|
1009
|
+
}
|
|
1010
|
+
return lines.join("\n");
|
|
1011
|
+
}
|