@planu/cli 4.13.0 → 5.0.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/CHANGELOG.md +64 -1
- package/LICENSE +55 -12
- package/README.md +33 -25
- package/dist/cli/commands/inspect.d.ts +4 -0
- package/dist/cli/commands/inspect.js +144 -0
- package/dist/cli/commands/install.d.ts +19 -12
- package/dist/cli/commands/install.js +148 -102
- package/dist/cli/commands/job.d.ts +3 -0
- package/dist/cli/commands/job.js +120 -0
- package/dist/cli/commands/offline.d.ts +15 -0
- package/dist/cli/commands/offline.js +132 -0
- package/dist/cli/commands/serve.js +4 -0
- package/dist/cli/commands/spec.js +1 -1
- package/dist/cli/commands/storage.d.ts +3 -0
- package/dist/cli/commands/storage.js +102 -0
- package/dist/cli/commands/uninstall.d.ts +10 -0
- package/dist/cli/commands/uninstall.js +93 -7
- package/dist/cli/commands/validate.js +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/router.js +9 -3
- package/dist/config/crash-shield-framework-rules.json +93 -0
- package/dist/config/environment-schema.json +147 -0
- package/dist/config/hardcode-exceptions.json +4 -0
- package/dist/config/native-release-public-key.pem +3 -0
- package/dist/config/native-targets.json +87 -0
- package/dist/config/official-sdd-tools.d.ts +4 -0
- package/dist/config/official-sdd-tools.js +35 -0
- package/dist/config/product-public.d.ts +225 -0
- package/dist/config/product-public.js +147 -0
- package/dist/config/product-public.json +283 -0
- package/dist/config/registries/hosts/codex.json +20 -363
- package/dist/config/release-compatibility.json +13 -0
- package/dist/config/release-policy.json +108 -0
- package/dist/config/runtime-policy.json +55 -0
- package/dist/config/skill-templates/planu-resume-work.md +2 -2
- package/dist/config/skill-templates/planu-validate.md +7 -4
- package/dist/config/subagent-templates/planu-spec-implementer.md +7 -3
- package/dist/config/subagent-templates/planu-validator.md +10 -5
- package/dist/config/technology-registry.json +120 -0
- package/dist/config/version.js +7 -8
- package/dist/core/index.d.ts +1 -1
- package/dist/core/spec-validator.d.ts +4 -4
- package/dist/core/spec-validator.js +1 -1
- package/dist/engine/abortable-process-runner.d.ts +20 -2
- package/dist/engine/abortable-process-runner.js +267 -67
- package/dist/engine/advanced-testing/accessibility-checker.js +12 -14
- package/dist/engine/advanced-testing/mutation-advisor.js +3 -4
- package/dist/engine/advanced-testing/property-based.js +2 -3
- package/dist/engine/advanced-testing/test-data-advisor.js +2 -3
- package/dist/engine/agent-generator.js +2 -1
- package/dist/engine/agent-handoff-store.js +2 -1
- package/dist/engine/agent-prompt-generator.js +7 -5
- package/dist/engine/agent-telemetry.js +2 -1
- package/dist/engine/ai-integration/gemini/extensions-advisor.js +41 -9
- package/dist/engine/ambiguity-detector.js +12 -11
- package/dist/engine/ambiguity-scorer.js +4 -26
- package/dist/engine/analyzer/db-engine.js +2 -3
- package/dist/engine/analyzer/detectors.js +13 -14
- package/dist/engine/analyzer/env-setup.js +9 -10
- package/dist/engine/analyzer-env-scanner/env-example.js +7 -8
- package/dist/engine/api-spec-generator/graphql-parser.js +2 -2
- package/dist/engine/api-validation/graphql-schema-validator.js +2 -1
- package/dist/engine/api-validation/openapi-impl-validator.js +6 -7
- package/dist/engine/architecture-detector.js +10 -8
- package/dist/engine/auth/config.d.ts +1 -1
- package/dist/engine/auth/config.js +4 -3
- package/dist/engine/auth/scope-mapper.js +1 -7
- package/dist/engine/auto-updater/atomic-upgrade.d.ts +8 -0
- package/dist/engine/auto-updater/atomic-upgrade.js +381 -0
- package/dist/engine/auto-updater/config-detector.js +9 -3
- package/dist/engine/auto-updater/config-patcher.d.ts +0 -4
- package/dist/engine/auto-updater/config-patcher.js +10 -15
- package/dist/engine/auto-updater/index.d.ts +3 -1
- package/dist/engine/auto-updater/index.js +44 -30
- package/dist/engine/auto-updater/npm-registry.js +10 -2
- package/dist/engine/auto-updater/release-verifier.d.ts +3 -0
- package/dist/engine/auto-updater/release-verifier.js +112 -0
- package/dist/engine/auto-updater/upgrade-lock.d.ts +6 -0
- package/dist/engine/auto-updater/upgrade-lock.js +28 -0
- package/dist/engine/auto-updater/upgrade-trust-state.d.ts +7 -0
- package/dist/engine/auto-updater/upgrade-trust-state.js +59 -0
- package/dist/engine/autopilot/audit-logger.js +2 -5
- package/dist/engine/autopilot/state-updater.js +4 -4
- package/dist/engine/best-practices-library.js +2 -1
- package/dist/engine/browser-validator.js +2 -1
- package/dist/engine/build-tool-detector.js +3 -2
- package/dist/engine/cascade-hooks/hooks/review-enricher.hook.js +9 -6
- package/dist/engine/cascade-hooks/state-drift-detector.d.ts +3 -3
- package/dist/engine/cascade-hooks/state-drift-detector.js +1 -1
- package/dist/engine/ci-generator/context-builders.js +7 -5
- package/dist/engine/ci-generator/planu-config.js +1 -7
- package/dist/engine/ci-generator/stack-detector.js +0 -2
- package/dist/engine/ci-generator/yaml-builder.js +0 -2
- package/dist/engine/clarification-gate/gate.d.ts +3 -3
- package/dist/engine/claude-config-auditor/rules-auditor.js +4 -3
- package/dist/engine/code-scanner/layer-scanner.js +6 -22
- package/dist/engine/code-transforms/typescript/ast-utils.js +2 -3
- package/dist/engine/complexity-budget/trivial-detector.js +2 -1
- package/dist/engine/compliance-test-generator/index.js +7 -2
- package/dist/engine/compliance-test-generator/test-formatter.js +2 -2
- package/dist/engine/config-health/mcp-config-checker.js +2 -1
- package/dist/engine/config-health/ts-checker-scripts.js +4 -3
- package/dist/engine/config-health/ts-checker.js +3 -2
- package/dist/engine/convention-injector.js +5 -7
- package/dist/engine/convention-scanner/convention-parser.js +3 -2
- package/dist/engine/core-bridge-duplicate-blocks.d.ts +3 -0
- package/dist/engine/core-bridge-duplicate-blocks.js +57 -0
- package/dist/engine/core-bridge-gaps.d.ts +4 -0
- package/dist/engine/core-bridge-gaps.js +75 -0
- package/dist/engine/core-bridge.d.ts +10 -10
- package/dist/engine/core-bridge.js +196 -283
- package/dist/engine/cost-guardrails.d.ts +1 -1
- package/dist/engine/cost-guardrails.js +1 -1
- package/dist/engine/cost-tracking/ledger.js +2 -5
- package/dist/engine/coverage-gap-analyzer.js +10 -1
- package/dist/engine/crash-shield/detectors/framework-detector.d.ts +2 -0
- package/dist/engine/crash-shield/detectors/framework-detector.js +110 -192
- package/dist/engine/crash-shield/detectors/typescript-detector.js +2 -1
- package/dist/engine/criterion-identity.d.ts +1 -0
- package/dist/engine/criterion-identity.js +7 -0
- package/dist/engine/dashboard/data-loader.js +4 -8
- package/dist/engine/dashboard/templates-layout.js +0 -3
- package/dist/engine/dashboard/templates-project.js +1 -13
- package/dist/engine/data-projects-gc/gc-runner.d.ts +7 -0
- package/dist/engine/data-projects-gc/gc-runner.js +113 -3
- package/dist/engine/data-projects-gc/scanner.js +5 -1
- package/dist/engine/decision-store.js +11 -14
- package/dist/engine/deleter/core.js +5 -5
- package/dist/engine/dep-auditor/abandonment-data.js +2 -1
- package/dist/engine/dep-auditor/abandonment-registry.js +3 -1
- package/dist/engine/dep-auditor/cve-fetcher.js +3 -0
- package/dist/engine/dep-auditor/dep-duplicates-detector.js +36 -4
- package/dist/engine/dep-auditor/license-registry.js +2 -0
- package/dist/engine/dependency-evaluator.d.ts +14 -0
- package/dist/engine/dependency-evaluator.js +81 -0
- package/dist/engine/deploy/providers/fly.js +7 -7
- package/dist/engine/deploy/providers/netlify.js +7 -7
- package/dist/engine/deploy/providers/railway.js +10 -12
- package/dist/engine/deploy/providers/vercel.js +7 -9
- package/dist/engine/deprecation-scanner/pattern-loader.js +0 -2
- package/dist/engine/desktop-detector.js +2 -3
- package/dist/engine/detect-duplication.js +2 -1
- package/dist/engine/detectors/advanced-framework-detector/css-state-detector.js +2 -1
- package/dist/engine/detectors/advanced-framework-detector/legacy-detector.js +2 -3
- package/dist/engine/detectors/advanced-framework-detector/modern-detector.js +3 -4
- package/dist/engine/detectors/agent-framework-detector.js +3 -2
- package/dist/engine/detectors/ai-native-detector.js +4 -6
- package/dist/engine/detectors/cache-db-detector.js +4 -3
- package/dist/engine/detectors/cicd-detector.js +4 -3
- package/dist/engine/detectors/deployment-detector.js +11 -12
- package/dist/engine/detectors/frontend-perf-detector.js +14 -9
- package/dist/engine/detectors/library-detector-multilang-a.js +16 -3
- package/dist/engine/detectors/library-detector-node.js +14 -4
- package/dist/engine/detectors/library-detector-python.js +7 -1
- package/dist/engine/detectors/library-detector.js +0 -2
- package/dist/engine/detectors/llm-detector/provider-maps.js +3 -2
- package/dist/engine/detectors/mcp-candidate-detector.js +12 -16
- package/dist/engine/detectors/mfe-detector.js +6 -7
- package/dist/engine/detectors/monitoring-detector.js +4 -3
- package/dist/engine/detectors/otel-detector.js +3 -2
- package/dist/engine/detectors/otel-ecosystem-detectors.d.ts +2 -2
- package/dist/engine/detectors/otel-ecosystem-detectors.js +4 -3
- package/dist/engine/detectors/platform-specialty-detector.js +3 -5
- package/dist/engine/detectors/template-engine-detector.js +3 -4
- package/dist/engine/doc-generator/builders.js +2 -3
- package/dist/engine/doc-generator/mobile-distribution-guide.js +13 -17
- package/dist/engine/doc-generator/portal/dirty-flag-map.d.ts +2 -2
- package/dist/engine/doc-generator/portal/portal-regenerator.js +3 -47
- package/dist/engine/docs-site-generator/data-collector.d.ts +1 -1
- package/dist/engine/docs-site-generator/data-collector.js +7 -28
- package/dist/engine/docs-site-generator/tools-renderer.js +3 -10
- package/dist/engine/domain-detector.js +3 -6
- package/dist/engine/dynamic-knowledge/knowledge-cache.js +3 -4
- package/dist/engine/dynamic-knowledge/knowledge-merger.js +17 -2
- package/dist/engine/dynamic-knowledge/web-researcher.js +15 -14
- package/dist/engine/dynamic-migration-detector/manifest-readers-extended.js +0 -2
- package/dist/engine/e2e-test-generator.js +4 -3
- package/dist/engine/ecosystem-absorber/knowledge-cache.js +2 -1
- package/dist/engine/ecosystem-absorber/platform-crawler.js +2 -2
- package/dist/engine/escalator/retry-counter.js +2 -1
- package/dist/engine/evidence-gates/artifact-reader.d.ts +16 -1
- package/dist/engine/evidence-gates/artifact-reader.js +220 -23
- package/dist/engine/evidence-gates/lifecycle-gate.d.ts +2 -1
- package/dist/engine/evidence-gates/lifecycle-gate.js +58 -3
- package/dist/engine/evidence-gates/reconciliation-freshness.d.ts +11 -0
- package/dist/engine/evidence-gates/reconciliation-freshness.js +72 -0
- package/dist/engine/evidence-index/done-drift.d.ts +1 -1
- package/dist/engine/evidence-index/done-drift.js +40 -18
- package/dist/engine/execution/context.d.ts +19 -0
- package/dist/engine/execution/context.js +130 -0
- package/dist/engine/execution/deadline-io.d.ts +21 -0
- package/dist/engine/execution/deadline-io.js +45 -0
- package/dist/engine/execution/durable-job-heartbeat-runtime.d.ts +4 -0
- package/dist/engine/execution/durable-job-heartbeat-runtime.js +400 -0
- package/dist/engine/execution/job-executor.d.ts +16 -0
- package/dist/engine/execution/job-executor.js +140 -0
- package/dist/engine/execution/job-runtime.d.ts +108 -0
- package/dist/engine/execution/job-runtime.js +328 -0
- package/dist/engine/execution/native-relevance-scorer.d.ts +6 -0
- package/dist/engine/execution/native-relevance-scorer.js +64 -0
- package/dist/engine/execution/native-worker-dispatch.d.ts +3 -0
- package/dist/engine/execution/native-worker-dispatch.js +46 -0
- package/dist/engine/execution/native-worker-protocol.d.ts +6 -0
- package/dist/engine/execution/native-worker-protocol.js +33 -0
- package/dist/engine/execution/native-worker-runtime.d.ts +4 -0
- package/dist/engine/execution/native-worker-runtime.js +177 -0
- package/dist/engine/execution/native-worker-thread.d.ts +2 -0
- package/dist/engine/execution/native-worker-thread.js +66 -0
- package/dist/engine/execution/operation-journal.d.ts +66 -0
- package/dist/engine/execution/operation-journal.js +260 -0
- package/dist/engine/execution/outbox-worker.d.ts +31 -0
- package/dist/engine/execution/outbox-worker.js +192 -0
- package/dist/engine/execution/public-job-sanitizer.d.ts +4 -0
- package/dist/engine/execution/public-job-sanitizer.js +31 -0
- package/dist/engine/execution/validate-job-executor.d.ts +35 -0
- package/dist/engine/execution/validate-job-executor.js +805 -0
- package/dist/engine/execution/validate-job-payload.d.ts +5 -0
- package/dist/engine/execution/validate-job-payload.js +144 -0
- package/dist/engine/execution/validate-job-recovery.d.ts +4 -0
- package/dist/engine/execution/validate-job-recovery.js +47 -0
- package/dist/engine/execution/validate-worker-runtime.d.ts +10 -0
- package/dist/engine/execution/validate-worker-runtime.js +188 -0
- package/dist/engine/execution/validate-worker-thread.d.ts +2 -0
- package/dist/engine/execution/validate-worker-thread.js +64 -0
- package/dist/engine/execution-plan/desktop-distribution.js +3 -7
- package/dist/engine/execution-plan/mobile-distribution.js +4 -9
- package/dist/engine/execution-plan/phases.js +4 -5
- package/dist/engine/execution-plan/plan-utils.js +8 -5
- package/dist/engine/facilitate/context-loader.js +3 -9
- package/dist/engine/figma/code-connect-fetcher.js +9 -8
- package/dist/engine/filesystem-watcher/index.d.ts +3 -3
- package/dist/engine/filesystem-watcher/index.js +5 -5
- package/dist/engine/framework-detector.js +14 -15
- package/dist/engine/git/planu-autocommit.js +8 -7
- package/dist/engine/git/repository-probe.d.ts +3 -0
- package/dist/engine/git/repository-probe.js +13 -0
- package/dist/engine/global-rules-manager.js +2 -2
- package/dist/engine/handoff-artifacts/io.js +2 -3
- package/dist/engine/handoff-artifacts/schemas/red-tests-handoff.js +8 -1
- package/dist/engine/handoff-artifacts/schemas.d.ts +6 -1
- package/dist/engine/handoff-artifacts/schemas.js +38 -0
- package/dist/engine/handoff-packager.d.ts +19 -0
- package/dist/engine/handoff-packager.js +415 -13
- package/dist/engine/hook-generator/stack-hook-templates.js +4 -4
- package/dist/engine/hooks/config-loader.js +1 -1
- package/dist/engine/hooks/context-injector.js +4 -7
- package/dist/engine/hooks/effort-configurator.js +1 -1
- package/dist/engine/hooks/file-watcher.js +1 -14
- package/dist/engine/hooks-reconciler.js +6 -4
- package/dist/engine/impact-detector/test-break-predictor.js +3 -3
- package/dist/engine/impact-detector/tool-registration.js +1 -1
- package/dist/engine/implementation-contract/renderer.js +23 -8
- package/dist/engine/infrastructure/component-mapper.js +5 -7
- package/dist/engine/infrastructure/docker-compose-generator.js +8 -10
- package/dist/engine/infrastructure/index.js +6 -3
- package/dist/engine/infrastructure/kubernetes-generator.js +2 -2
- package/dist/engine/infrastructure/railway-generator.js +10 -8
- package/dist/engine/infrastructure/signal-detector.js +6 -8
- package/dist/engine/infrastructure/terraform-generator.js +6 -8
- package/dist/engine/legal-compliance/detector.js +3 -2
- package/dist/engine/lifecycle-reconciliation-io.d.ts +11 -0
- package/dist/engine/lifecycle-reconciliation-io.js +180 -0
- package/dist/engine/lifecycle-reconciliation.d.ts +16 -0
- package/dist/engine/lifecycle-reconciliation.js +406 -0
- package/dist/engine/local-first/storage-advisor.js +5 -6
- package/dist/engine/local-first/tool-classification.js +2 -0
- package/dist/engine/macos-keychain-native-port.d.ts +10 -0
- package/dist/engine/macos-keychain-native-port.js +38 -0
- package/dist/engine/marketplace-fetcher/cache.js +3 -1
- package/dist/engine/mcp-config/mcp-config-writer.d.ts +2 -2
- package/dist/engine/mcp-config/mcp-config-writer.js +10 -8
- package/dist/engine/migration/db-migrator.js +2 -5
- package/dist/engine/migration/equivalence-mapper.js +12 -13
- package/dist/engine/migration/service-catalogs.js +6 -7
- package/dist/engine/migration/service-migrator-catalogs.js +6 -7
- package/dist/engine/migrations/remove-commercial-state.d.ts +3 -0
- package/dist/engine/migrations/remove-commercial-state.js +343 -0
- package/dist/engine/mobile-detector-ios.js +2 -3
- package/dist/engine/mobile-detector.js +16 -4
- package/dist/engine/model-router/complexity-analyzer.js +4 -7
- package/dist/engine/multi-agent-review/security-analyzer.js +3 -1
- package/dist/engine/multi-app-detector/app-type.js +26 -21
- package/dist/engine/multi-app-detector/core.js +3 -2
- package/dist/engine/multi-teammate-review/disagreement-counter.js +2 -1
- package/dist/engine/multi-teammate-review/panel-orchestrator.js +0 -2
- package/dist/engine/mutation-config-generator.js +10 -7
- package/dist/engine/native-capability-policy.d.ts +4 -0
- package/dist/engine/native-capability-policy.js +24 -0
- package/dist/engine/native-platform.d.ts +3 -0
- package/dist/engine/native-platform.js +44 -0
- package/dist/engine/native-runtime-handshake.d.ts +20 -0
- package/dist/engine/native-runtime-handshake.js +230 -0
- package/dist/engine/network-policy.d.ts +27 -0
- package/dist/engine/network-policy.js +175 -0
- package/dist/engine/next-spec-resolver/dependency-filter.js +2 -22
- package/dist/engine/nfr-profile-detector.js +12 -16
- package/dist/engine/nli-keywords.js +8 -9
- package/dist/engine/oauth/config-guard.js +4 -5
- package/dist/engine/observability/local-execution-spans.d.ts +15 -0
- package/dist/engine/observability/local-execution-spans.js +63 -0
- package/dist/engine/orchestrator/runtime.js +0 -1
- package/dist/engine/package-registry.js +2 -6
- package/dist/engine/performance-analyzer.js +2 -5
- package/dist/engine/permissions-merger/stack-detectors.js +5 -5
- package/dist/engine/planu-core.darwin-arm64.node.manifest.json +39 -0
- package/dist/engine/planu-core.darwin-arm64.node.sbom.json +1310 -0
- package/dist/engine/planu-core.darwin-x64.node.manifest.json +39 -0
- package/dist/engine/planu-core.darwin-x64.node.sbom.json +1310 -0
- package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +38 -0
- package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +1310 -0
- package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +38 -0
- package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +1310 -0
- package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +38 -0
- package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +1310 -0
- package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +38 -0
- package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +1310 -0
- package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +38 -0
- package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +1310 -0
- package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +38 -0
- package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +1310 -0
- package/dist/engine/platform-detector/desktop.js +15 -2
- package/dist/engine/platform-detector/extensions.js +2 -1
- package/dist/engine/platform-detector/games.js +2 -1
- package/dist/engine/platform-detector.js +3 -2
- package/dist/engine/platform-engineering/idp-detector.js +2 -1
- package/dist/engine/plugin-installer/stack-matcher.js +9 -17
- package/dist/engine/plugins/lifecycle.js +6 -2
- package/dist/engine/prior-decisions/contradiction-detector.js +60 -30
- package/dist/engine/project-dna/stack-detector.js +15 -17
- package/dist/engine/project-graph/builder.js +11 -0
- package/dist/engine/project-graph/cache.js +1 -1
- package/dist/engine/project-graph/freshness-projection.d.ts +16 -0
- package/dist/engine/project-graph/freshness-projection.js +95 -0
- package/dist/engine/project-graph/index.d.ts +1 -0
- package/dist/engine/project-graph/index.js +1 -0
- package/dist/engine/project-graph/query.js +15 -25
- package/dist/engine/project-health-checker.js +3 -4
- package/dist/engine/project-scanner/stack-detector.js +17 -17
- package/dist/engine/property-test-generator.js +2 -3
- package/dist/engine/qa-gate.d.ts +1 -0
- package/dist/engine/qa-gate.js +6 -4
- package/dist/engine/quality-gates/gate-catalog.js +47 -46
- package/dist/engine/quality-gates/gate-injector.js +9 -4
- package/dist/engine/readiness-checker.d.ts +1 -16
- package/dist/engine/readiness-checker.js +27 -88
- package/dist/engine/registry/core.js +0 -2
- package/dist/engine/registry/loader.js +9 -12
- package/dist/engine/registry/matcher.js +129 -24
- package/dist/engine/resilience-detector/concurrency-detector.js +4 -4
- package/dist/engine/resilience-detector/middleware-detector.js +11 -13
- package/dist/engine/resilience-detector/validation-detector.js +17 -4
- package/dist/engine/reverse-engineer/config-analyzer.js +9 -8
- package/dist/engine/reverse-engineer/orchestrator.js +5 -9
- package/dist/engine/reverse-engineer/test-file-parser.js +6 -3
- package/dist/engine/rules-generator/index.js +6 -5
- package/dist/engine/runtime-policy.d.ts +9 -0
- package/dist/engine/runtime-policy.js +138 -0
- package/dist/engine/runtime-security/checkers/content-security.js +21 -6
- package/dist/engine/runtime-security/checkers/file-permissions.js +0 -2
- package/dist/engine/runtime-security/rate-limiter.js +0 -1
- package/dist/engine/safety/atomic-write-file.js +20 -9
- package/dist/engine/safety/atomic-writer.js +10 -3
- package/dist/engine/safety/contained-project-file.d.ts +3 -0
- package/dist/engine/safety/contained-project-file.js +23 -0
- package/dist/engine/safety/cross-process-lock.d.ts +3 -40
- package/dist/engine/safety/cross-process-lock.js +268 -272
- package/dist/engine/safety/file-mutex.d.ts +2 -9
- package/dist/engine/safety/file-mutex.js +155 -87
- package/dist/engine/safety/health-monitor.js +15 -6
- package/dist/engine/safety/lock-lease-store.d.ts +79 -0
- package/dist/engine/safety/lock-lease-store.js +372 -0
- package/dist/engine/safety/lock-scavenger.d.ts +2 -5
- package/dist/engine/safety/lock-scavenger.js +158 -76
- package/dist/engine/safety/lock-staleness.js +4 -1
- package/dist/engine/safety/obsolete-lock-guard.d.ts +8 -0
- package/dist/engine/safety/obsolete-lock-guard.js +31 -0
- package/dist/engine/safety/transaction.js +3 -3
- package/dist/engine/sandbox/index.js +2 -1
- package/dist/engine/sandbox/runner-detect.js +3 -2
- package/dist/engine/sandbox/runner-docker.js +4 -3
- package/dist/engine/scan-project/module-discoverer.js +3 -2
- package/dist/engine/schema-generator.js +16 -9
- package/dist/engine/scope-boundaries/contradiction-checker.js +63 -1
- package/dist/engine/scope-boundaries/scope-validator.js +45 -7
- package/dist/engine/security-analyzer/criteria-generator.js +2 -3
- package/dist/engine/self-healing/healer.js +4 -4
- package/dist/engine/session/checkpoint-writer.js +0 -9
- package/dist/engine/shared-agent-memory.js +66 -74
- package/dist/engine/skill-adapter/command-rewriter.js +3 -2
- package/dist/engine/skill-adapter/index.js +3 -3
- package/dist/engine/skill-adapter/placeholder-map.js +3 -2
- package/dist/engine/skill-bootstrap/stack-matcher.js +47 -48
- package/dist/engine/skill-generation/stack-content-generator.js +0 -2
- package/dist/engine/skill-generator/workflow-skill-generator.js +2 -1
- package/dist/engine/skill-registry/ttl-refresh.js +3 -1
- package/dist/engine/skills/skills-fetcher.js +3 -6
- package/dist/engine/skills-reconciler.js +19 -39
- package/dist/engine/spec-coverage/test-finder.js +7 -6
- package/dist/engine/spec-diff-engine.js +3 -3
- package/dist/engine/spec-format/acceptance-criteria.d.ts +6 -2
- package/dist/engine/spec-format/acceptance-criteria.js +77 -18
- package/dist/engine/spec-format/markdown-sections.d.ts +14 -0
- package/dist/engine/spec-format/markdown-sections.js +105 -0
- package/dist/engine/spec-format/read-technical-section.js +33 -5
- package/dist/engine/spec-format/technical-md-populator.js +3 -2
- package/dist/engine/spec-format/unified-spec-builder.d.ts +7 -0
- package/dist/engine/spec-format/unified-spec-builder.js +202 -0
- package/dist/engine/spec-generator/api-key-resolver.d.ts +1 -1
- package/dist/engine/spec-generator/api-key-resolver.js +3 -24
- package/dist/engine/spec-generators/issue-extractor.js +9 -3
- package/dist/engine/spec-migrator/canonical-deduplicator.d.ts +18 -0
- package/dist/engine/spec-migrator/canonical-deduplicator.js +479 -0
- package/dist/engine/spec-migrator/drift-detector.js +5 -13
- package/dist/engine/spec-migrator/filesystem-import.d.ts +4 -8
- package/dist/engine/spec-migrator/filesystem-import.js +134 -23
- package/dist/engine/spec-migrator/frontmatter-parser.js +32 -15
- package/dist/engine/spec-migrator/index.d.ts +1 -0
- package/dist/engine/spec-migrator/index.js +1 -0
- package/dist/engine/spec-migrator/planu-canonical-policy.js +10 -1
- package/dist/engine/spec-migrator/strict-planu-cleanup.js +24 -25
- package/dist/engine/spec-registry/adapter.d.ts +0 -5
- package/dist/engine/spec-registry/adapter.js +45 -46
- package/dist/engine/spec-registry/client.js +2 -0
- package/dist/engine/spec-source-sync.js +3 -2
- package/dist/engine/spec-state-machine/transition-spec.d.ts +6 -1
- package/dist/engine/spec-state-machine/transition-spec.js +10 -1
- package/dist/engine/spec-templates/custom-loader.js +2 -3
- package/dist/engine/spec-templates/templates-domain-specific.js +8 -5
- package/dist/engine/spec-templates/templates-perf-integration.js +2 -3
- package/dist/engine/stack-auditor/manifest-reader.js +0 -2
- package/dist/engine/staleness/stale-implementing.js +7 -7
- package/dist/engine/tdd-scaffold-generator.js +24 -11
- package/dist/engine/teammate-router/green-phase-verifier.js +2 -1
- package/dist/engine/teammate-router/red-phase-verifier.js +2 -1
- package/dist/engine/technical-enricher/index.js +16 -8
- package/dist/engine/technical-enricher/render-enriched.d.ts +1 -0
- package/dist/engine/technical-enricher/render-enriched.js +42 -14
- package/dist/engine/technology-registry.d.ts +11 -0
- package/dist/engine/technology-registry.js +142 -0
- package/dist/engine/telemetry/error-reporter.d.ts +1 -2
- package/dist/engine/telemetry/error-reporter.js +11 -18
- package/dist/engine/telemetry/health-checker.js +58 -31
- package/dist/engine/telemetry/index.d.ts +0 -1
- package/dist/engine/telemetry/index.js +0 -1
- package/dist/engine/telemetry/stance.js +3 -2
- package/dist/engine/telemetry/telemetry-client.d.ts +1 -5
- package/dist/engine/telemetry/telemetry-client.js +69 -35
- package/dist/engine/telemetry/telemetry-store.d.ts +3 -3
- package/dist/engine/telemetry/telemetry-store.js +30 -23
- package/dist/engine/test-framework-detector/detectors.js +8 -8
- package/dist/engine/test-framework-detector/strategy.js +8 -9
- package/dist/engine/test-generators/agent-test-templates.js +2 -3
- package/dist/engine/test-generators/contract-test-generator.d.ts +1 -1
- package/dist/engine/test-generators/contract-test-generator.js +9 -202
- package/dist/engine/test-generators/platform-test-templates-b.js +2 -3
- package/dist/engine/test-generators/platform-test-templates.js +2 -5
- package/dist/engine/test-mocks-generator.js +4 -3
- package/dist/engine/test-plan-generator.js +30 -12
- package/dist/engine/test-scaffold-generator/advanced-scaffold.js +4 -5
- package/dist/engine/test-scaffold-generator/unit-scaffold.js +5 -6
- package/dist/engine/text-signal-boundaries.d.ts +2 -0
- package/dist/engine/text-signal-boundaries.js +25 -2
- package/dist/engine/time/relative-date.d.ts +3 -0
- package/dist/engine/time/relative-date.js +16 -0
- package/dist/engine/timing/budget.d.ts +17 -17
- package/dist/engine/timing/budget.js +98 -64
- package/dist/engine/token-optimizer/analytics.d.ts +1 -1
- package/dist/engine/token-optimizer/analytics.js +5 -6
- package/dist/engine/tool-groups/group-manager.js +3 -3
- package/dist/engine/universal-rules/installer.js +1 -1
- package/dist/engine/universal-rules/rules/planu-modes.js +2 -0
- package/dist/engine/universal-rules/rules/planu-release-policy.js +1 -0
- package/dist/engine/update-notifier.js +8 -5
- package/dist/engine/usage-tracker/core.d.ts +2 -2
- package/dist/engine/usage-tracker/core.js +1 -2
- package/dist/engine/usage-tracker/index.d.ts +0 -3
- package/dist/engine/usage-tracker/index.js +0 -3
- package/dist/engine/usage-tracker/stats.d.ts +2 -2
- package/dist/engine/usage-tracker/stats.js +1 -28
- package/dist/engine/validation/approved-spec-portability.d.ts +12 -0
- package/dist/engine/validation/approved-spec-portability.js +107 -0
- package/dist/engine/validation/durable-validation.d.ts +36 -0
- package/dist/engine/validation/durable-validation.js +256 -0
- package/dist/engine/validation/validation-freshness.d.ts +46 -0
- package/dist/engine/validation/validation-freshness.js +567 -0
- package/dist/engine/validation/validation-receipt-codec.d.ts +13 -0
- package/dist/engine/validation/validation-receipt-codec.js +182 -0
- package/dist/engine/validation/validation-receipt.d.ts +62 -0
- package/dist/engine/validation/validation-receipt.js +342 -0
- package/dist/engine/validation/validation-source-digest.d.ts +2 -0
- package/dist/engine/validation/validation-source-digest.js +86 -0
- package/dist/engine/validation/validation-source-policy.d.ts +4 -0
- package/dist/engine/validation/validation-source-policy.js +16 -0
- package/dist/engine/validation/validation-submission.d.ts +37 -0
- package/dist/engine/validation/validation-submission.js +142 -0
- package/dist/engine/validation/validation-worktree.d.ts +21 -0
- package/dist/engine/validation/validation-worktree.js +260 -0
- package/dist/engine/validation-evidence-ledger.js +41 -0
- package/dist/engine/validation-impact-planner.d.ts +14 -2
- package/dist/engine/validation-impact-planner.js +23 -10
- package/dist/engine/validator/dor-dod.d.ts +1 -0
- package/dist/engine/validator/dor-dod.js +5 -3
- package/dist/engine/validator/extractors.d.ts +1 -5
- package/dist/engine/validator/extractors.js +24 -69
- package/dist/engine/validator/spec-compliance-runner.d.ts +13 -25
- package/dist/engine/validator/spec-compliance-runner.js +442 -215
- package/dist/engine/validator/validation-report-writer.js +1 -1
- package/dist/engine/validator.js +37 -23
- package/dist/engine/verify-integrations/index.js +1 -1
- package/dist/engine/version-resolver.js +5 -6
- package/dist/engine/web-fetcher/stack-advisor.js +156 -92
- package/dist/engine/web-fetcher/stack-detector.js +114 -54
- package/dist/engine/workspace-manager.js +3 -2
- package/dist/errors/classified-degradation.d.ts +3 -0
- package/dist/errors/classified-degradation.js +10 -0
- package/dist/errors/degradation-sink.d.ts +3 -0
- package/dist/errors/degradation-sink.js +5 -0
- package/dist/errors/error-taxonomy.d.ts +12 -0
- package/dist/errors/error-taxonomy.js +62 -0
- package/dist/hosts/claude-code/ux/mcp-prompts.js +10 -4
- package/dist/hosts/claude-code/ux/mcp-resources.js +4 -2
- package/dist/hosts/codex/config-scaffold.js +4 -3
- package/dist/hosts/gemini/config-scaffold.js +2 -1
- package/dist/hosts/gemini/multimodal-spec-flow.js +7 -4
- package/dist/index.js +23 -20
- package/dist/resources/patterns.js +3 -1
- package/dist/resources/specs.js +3 -1
- package/dist/resources/templates.js +3 -1
- package/dist/resources/usage-stats-resource.js +2 -18
- package/dist/security/adapters/environment.d.ts +12 -0
- package/dist/security/adapters/environment.js +25 -0
- package/dist/security/adapters/linux-secret-service.d.ts +8 -0
- package/dist/security/adapters/linux-secret-service.js +64 -0
- package/dist/security/adapters/macos-keychain.d.ts +18 -0
- package/dist/security/adapters/macos-keychain.js +90 -0
- package/dist/security/adapters/windows-credential-manager.d.ts +8 -0
- package/dist/security/adapters/windows-credential-manager.js +60 -0
- package/dist/security/redactor.d.ts +5 -0
- package/dist/security/redactor.js +58 -0
- package/dist/security/secret-field.d.ts +5 -0
- package/dist/security/secret-field.js +17 -0
- package/dist/security/secret-migration.d.ts +3 -0
- package/dist/security/secret-migration.js +123 -0
- package/dist/security/secret-provider.d.ts +23 -0
- package/dist/security/secret-provider.js +145 -0
- package/dist/security/secure-json.d.ts +3 -0
- package/dist/security/secure-json.js +29 -0
- package/dist/server/routes/specs.js +10 -0
- package/dist/storage/api-surfaces-store.js +2 -2
- package/dist/storage/approval-operation-lock.d.ts +1 -1
- package/dist/storage/approval-operation-lock.js +5 -3
- package/dist/storage/audit-trail-store.d.ts +1 -1
- package/dist/storage/audit-trail-store.js +48 -62
- package/dist/storage/autopilot-log-store.js +12 -5
- package/dist/storage/base-store.d.ts +9 -9
- package/dist/storage/base-store.js +58 -21
- package/dist/storage/checkpoint-store.js +5 -2
- package/dist/storage/comments-store.js +2 -2
- package/dist/storage/compliance-audit-store.js +5 -2
- package/dist/storage/compliance-gate-config-store.js +7 -4
- package/dist/storage/compliance-store.js +2 -2
- package/dist/storage/context-profile-store.js +2 -2
- package/dist/storage/crash-shield-store.js +8 -4
- package/dist/storage/feedback-remote.d.ts +2 -3
- package/dist/storage/feedback-remote.js +45 -31
- package/dist/storage/feedback-store.js +10 -6
- package/dist/storage/figma-store.js +8 -4
- package/dist/storage/file-mutex.js +9 -1
- package/dist/storage/gaps-log.js +7 -4
- package/dist/storage/global-projects-store.js +4 -2
- package/dist/storage/global-store.d.ts +1 -17
- package/dist/storage/global-store.js +1 -42
- package/dist/storage/ideas-store.js +2 -2
- package/dist/storage/index.d.ts +5 -2
- package/dist/storage/index.js +5 -2
- package/dist/storage/knowledge-store/knowledge.js +27 -33
- package/dist/storage/lessons-store.js +2 -2
- package/dist/storage/migrations/canonical-storage.d.ts +15 -0
- package/dist/storage/migrations/canonical-storage.js +712 -0
- package/dist/storage/oauth-store.js +36 -8
- package/dist/storage/path-resolver.js +16 -3
- package/dist/storage/pr-store.js +2 -2
- package/dist/storage/project-drift-store.js +20 -8
- package/dist/storage/project-identity.d.ts +32 -0
- package/dist/storage/project-identity.js +194 -0
- package/dist/storage/project-resolver.js +14 -7
- package/dist/storage/release-notes-store.js +2 -6
- package/dist/storage/runtime-db.d.ts +195 -0
- package/dist/storage/runtime-db.js +1110 -0
- package/dist/storage/schema-registry.d.ts +5 -0
- package/dist/storage/schema-registry.js +74 -0
- package/dist/storage/sentry-store.js +20 -9
- package/dist/storage/session-state-store.js +12 -5
- package/dist/storage/skill-registry-storage.d.ts +1 -1
- package/dist/storage/skill-registry-storage.js +13 -11
- package/dist/storage/slack-store.js +10 -5
- package/dist/storage/spec-store.d.ts +14 -2
- package/dist/storage/spec-store.js +134 -37
- package/dist/storage/status-store/atomic-status-write.d.ts +5 -0
- package/dist/storage/status-store/atomic-status-write.js +57 -0
- package/dist/storage/status-store/file-lock.js +61 -20
- package/dist/storage/status-store/self-healing.js +13 -8
- package/dist/storage/status-store/version-sync.d.ts +2 -1
- package/dist/storage/status-store/version-sync.js +36 -39
- package/dist/storage/steering-store.js +2 -2
- package/dist/storage/storage-bundle.d.ts +5 -0
- package/dist/storage/storage-bundle.js +117 -0
- package/dist/storage/storage-catalog-validation.d.ts +3 -0
- package/dist/storage/storage-catalog-validation.js +20 -0
- package/dist/storage/storage-catalog.d.ts +25 -0
- package/dist/storage/storage-catalog.js +390 -0
- package/dist/storage/storage-layout.d.ts +24 -0
- package/dist/storage/storage-layout.js +101 -0
- package/dist/storage/storybook-store.js +2 -2
- package/dist/storage/supabase-store.js +24 -6
- package/dist/storage/tdd-policy-store.js +8 -6
- package/dist/storage/tech-debt-store.js +3 -3
- package/dist/storage/technology-selection-store.d.ts +1 -1
- package/dist/storage/technology-selection-store.js +6 -3
- package/dist/storage/token-cache-store.js +3 -3
- package/dist/storage/token-ledger-store.js +13 -8
- package/dist/storage/transition-log.js +7 -4
- package/dist/storage/trash-store.js +15 -6
- package/dist/storage/usage-store.d.ts +1 -5
- package/dist/storage/usage-store.js +0 -35
- package/dist/storage/vector-store/migrator.js +7 -2
- package/dist/storage/vector-store/sqlite-adapter.js +4 -1
- package/dist/storage/webhook-server-store.js +2 -2
- package/dist/tools/api-spec-generator-handler.js +3 -2
- package/dist/tools/auto-update-handler.d.ts +4 -4
- package/dist/tools/auto-update-handler.js +4 -4
- package/dist/tools/browser-validate-handler.js +2 -1
- package/dist/tools/challenge-spec/platform-challenge-scenarios-b.js +8 -5
- package/dist/tools/challenge-spec/resilience-challenge-scenarios.d.ts +2 -1
- package/dist/tools/challenge-spec/resilience-challenge-scenarios.js +10 -7
- package/dist/tools/challenge-spec/scenario-collector.js +1 -1
- package/dist/tools/challenge-spec/scenarios-data.js +1 -1
- package/dist/tools/challenge-spec/scenarios-desktop.js +8 -3
- package/dist/tools/challenge-spec/scenarios-failure.js +7 -2
- package/dist/tools/challenge-spec/scenarios-utils.d.ts +1 -1
- package/dist/tools/challenge-spec/scenarios-utils.js +35 -11
- package/dist/tools/challenge-spec/security-challenge-scenarios.js +3 -3
- package/dist/tools/challenge-spec.js +5 -5
- package/dist/tools/check-readiness.js +1 -1
- package/dist/tools/clarify-requirements/multiple-choice.js +53 -41
- package/dist/tools/comments-handler.js +2 -3
- package/dist/tools/compliance-test-handler.js +2 -2
- package/dist/tools/configure-telemetry.js +41 -13
- package/dist/tools/create-spec/auto-pipeline.js +13 -1
- package/dist/tools/create-spec/autopilot-analyzer.d.ts +1 -1
- package/dist/tools/create-spec/autopilot-analyzer.js +2 -4
- package/dist/tools/create-spec/mcp-tool-contract.d.ts +10 -4
- package/dist/tools/create-spec/mcp-tool-contract.js +7 -36
- package/dist/tools/create-spec/post-creation.d.ts +2 -1
- package/dist/tools/create-spec/post-creation.js +56 -54
- package/dist/tools/create-spec/relevance-scorer.d.ts +1 -1
- package/dist/tools/create-spec/relevance-scorer.js +17 -1
- package/dist/tools/create-spec/spec-builder.js +2 -23
- package/dist/tools/create-spec/spec-created-outbox-consumer.d.ts +14 -0
- package/dist/tools/create-spec/spec-created-outbox-consumer.js +176 -0
- package/dist/tools/create-spec.d.ts +1 -0
- package/dist/tools/create-spec.js +802 -732
- package/dist/tools/define-ui-contract/agent-interaction-contract.js +2 -4
- package/dist/tools/define-ui-contract-desktop/desktop-contract.js +12 -4
- package/dist/tools/define-ui-contract-desktop/native-contract.js +7 -3
- package/dist/tools/define-ui-contract-extensions.js +2 -3
- package/dist/tools/define-ui-contract-mobile.js +5 -9
- package/dist/tools/define-ui-contract-web/component-tree.js +4 -3
- package/dist/tools/define-ui-contract.js +7 -4
- package/dist/tools/deploy/deploy-spec.js +2 -4
- package/dist/tools/deploy/deploy-status.js +2 -4
- package/dist/tools/design-schema/nosql-category-schemas.js +2 -3
- package/dist/tools/design-schema-sql/migrations.js +3 -2
- package/dist/tools/design-schema-sql/tables.js +4 -1
- package/dist/tools/design-schema.js +4 -3
- package/dist/tools/feedback-handler.js +2 -4
- package/dist/tools/gc-data-projects.js +5 -5
- package/dist/tools/generate-execution-plan.js +3 -4
- package/dist/tools/generate-sub-agent.js +2 -1
- package/dist/tools/generate-tests/generators/a11y-tests-generator.js +5 -4
- package/dist/tools/generate-tests/generators/advanced-testing-generator.js +5 -4
- package/dist/tools/generate-tests/generators/concurrency-test-generator/js-templates.js +9 -4
- package/dist/tools/generate-tests/generators/concurrency-test-generator.js +8 -4
- package/dist/tools/generate-tests/generators/database/detectors.js +9 -3
- package/dist/tools/generate-tests/generators/database/index.js +2 -4
- package/dist/tools/generate-tests/generators/event-test-generator.js +5 -4
- package/dist/tools/generate-tests/generators/game-tests-generator.js +2 -1
- package/dist/tools/generate-tests/generators/graphql-test-generator.js +11 -5
- package/dist/tools/generate-tests/generators/grpc-test-generator.js +2 -3
- package/dist/tools/generate-tests/generators/llm-security-test-generator.js +4 -3
- package/dist/tools/generate-tests/generators/local-first-test-generator.js +4 -3
- package/dist/tools/generate-tests/generators/mcp-tests-generator.js +11 -9
- package/dist/tools/generate-tests/generators/microservices/index.js +2 -3
- package/dist/tools/generate-tests/generators/otel-test-generator.js +6 -3
- package/dist/tools/generate-tests/generators/security/detectors.js +2 -5
- package/dist/tools/generate-tests/generators/security/index.js +2 -4
- package/dist/tools/generate-tests/generators/supply-chain-test-generator.js +2 -3
- package/dist/tools/generate-tests/generators/visual-regression-generator.js +14 -17
- package/dist/tools/generate-tests/generators/websocket-test-generator.js +2 -3
- package/dist/tools/generate-tests/test-helpers.js +11 -12
- package/dist/tools/generate-tests-content.js +4 -3
- package/dist/tools/generate-tests.js +7 -4
- package/dist/tools/git/branch-ops.d.ts +1 -1
- package/dist/tools/git/branch-ops.js +3 -2
- package/dist/tools/git/git-helpers.d.ts +0 -2
- package/dist/tools/git/git-helpers.js +7 -7
- package/dist/tools/github-pr-handler.js +10 -3
- package/dist/tools/heal-spec-docs.js +6 -53
- package/dist/tools/hook-generator-handler.js +6 -6
- package/dist/tools/init-constitution/platform-principles.js +4 -2
- package/dist/tools/init-project/agents-md-writer.js +14 -5
- package/dist/tools/init-project/claude-md-generator.js +19 -12
- package/dist/tools/init-project/handler.js +165 -75
- package/dist/tools/init-project/host-assets-writer.d.ts +1 -1
- package/dist/tools/init-project/host-assets-writer.js +30 -3
- package/dist/tools/init-project/lifecycle-helpers.js +3 -5
- package/dist/tools/init-project/lint-scaffolder.d.ts +3 -3
- package/dist/tools/init-project/lint-scaffolder.js +6 -2
- package/dist/tools/init-project/migration-runner.d.ts +8 -1
- package/dist/tools/init-project/migration-runner.js +68 -2
- package/dist/tools/init-project/per-client-files-writer.js +14 -4
- package/dist/tools/init-project/portable-index-reconciler.d.ts +4 -0
- package/dist/tools/init-project/portable-index-reconciler.js +14 -0
- package/dist/tools/init-project/result-builder.js +1 -3
- package/dist/tools/init-project/rules-generator.js +10 -2
- package/dist/tools/init-project/scaffold-writer.d.ts +1 -1
- package/dist/tools/init-project/scaffold-writer.js +17 -15
- package/dist/tools/jobs/handlers.d.ts +15 -0
- package/dist/tools/jobs/handlers.js +158 -0
- package/dist/tools/list-specs.js +39 -59
- package/dist/tools/manage-plugins-handler.js +17 -9
- package/dist/tools/merge-risk-handler.js +2 -2
- package/dist/tools/migrate-tech/advanced-handlers.js +3 -2
- package/dist/tools/migrate-tech/build-tool-handlers.js +3 -2
- package/dist/tools/migrate-tech/core-handlers.js +5 -2
- package/dist/tools/migrate-tech/data-handlers.js +6 -3
- package/dist/tools/migrate-tech-advanced/rollback-handlers.js +3 -2
- package/dist/tools/migrate-tech-advanced/service-handlers.js +5 -2
- package/dist/tools/oauth-handler.js +7 -1
- package/dist/tools/package-handoff.js +2 -0
- package/dist/tools/reconcile-spec.js +0 -27
- package/dist/tools/register-agent-squad-tools.js +2 -2
- package/dist/tools/register-platform-tools/design-stack-tools.js +11 -11
- package/dist/tools/register-platform-tools/lifecycle-infra-tools.js +7 -7
- package/dist/tools/register-sdd-tools.d.ts +1 -1
- package/dist/tools/register-sdd-tools.js +2 -24
- package/dist/tools/register-spec-tools/analysis-tools.js +8 -8
- package/dist/tools/register-spec-tools/core-spec-tools.js +48 -8
- package/dist/tools/registry/auth.js +13 -5
- package/dist/tools/registry/publish.js +7 -4
- package/dist/tools/resolve-project-path.d.ts +2 -2
- package/dist/tools/resolve-project-path.js +7 -7
- package/dist/tools/reverse-engineer/analyzer.js +14 -14
- package/dist/tools/rollback-release.js +3 -2
- package/dist/tools/safe-handler.d.ts +5 -13
- package/dist/tools/safe-handler.js +302 -194
- package/dist/tools/schema-generator-handler.js +2 -1
- package/dist/tools/schemas/index.d.ts +1 -1
- package/dist/tools/schemas/index.js +1 -1
- package/dist/tools/schemas/output-schemas.d.ts +88 -105
- package/dist/tools/schemas/output-schemas.js +12 -122
- package/dist/tools/schemas/plugins-schemas.js +0 -2
- package/dist/tools/schemas/registry.js +0 -2
- package/dist/tools/schemas/skill-registry-schemas.js +0 -2
- package/dist/tools/schemas/spec.d.ts +4 -0
- package/dist/tools/schemas/spec.js +3 -0
- package/dist/tools/schemas/validate-output-schema.d.ts +267 -0
- package/dist/tools/schemas/validate-output-schema.js +219 -0
- package/dist/tools/sentry-handler.js +6 -1
- package/dist/tools/skill-bootstrap-handler.js +7 -4
- package/dist/tools/spec-prompt-handler.js +3 -3
- package/dist/tools/status-handler.js +4 -0
- package/dist/tools/storage-bundle-handler.d.ts +9 -0
- package/dist/tools/storage-bundle-handler.js +29 -0
- package/dist/tools/storage-paths-handler.d.ts +9 -0
- package/dist/tools/storage-paths-handler.js +17 -0
- package/dist/tools/suggest-mcp-server.js +11 -5
- package/dist/tools/suggest-mcps.js +29 -9
- package/dist/tools/suggest-tooling/advanced-testing-catalog.js +4 -5
- package/dist/tools/suggest-tooling/build-tool-catalog.js +2 -1
- package/dist/tools/suggest-tooling/css-framework-catalog.js +13 -7
- package/dist/tools/suggest-tooling/framework-catalog.js +3 -5
- package/dist/tools/suggest-tooling/frontend-perf-catalog.js +2 -6
- package/dist/tools/suggest-tooling/handler.js +10 -4
- package/dist/tools/suggest-tooling/hypermedia-catalog.js +11 -3
- package/dist/tools/suggest-tooling/linting-catalog.js +4 -7
- package/dist/tools/suggest-tooling/llm-security-catalog.js +2 -1
- package/dist/tools/suggest-tooling/local-first-catalog.js +7 -5
- package/dist/tools/suggest-tooling/observability-catalog.js +3 -4
- package/dist/tools/suggest-tooling/otel-catalog.js +4 -1
- package/dist/tools/suggest-tooling/resilience-catalog.js +16 -5
- package/dist/tools/suggest-tooling/skills-catalog.js +10 -9
- package/dist/tools/suggest-tooling/supply-chain-catalog.js +2 -3
- package/dist/tools/supabase-handler.js +2 -1
- package/dist/tools/sync-spec-state-handler.d.ts +1 -1
- package/dist/tools/sync-spec-state-handler.js +1 -1
- package/dist/tools/token-intelligence-handler.js +2 -2
- package/dist/tools/token-recording.js +2 -2
- package/dist/tools/token-savings-handler.js +2 -2
- package/dist/tools/tool-entry.d.ts +4 -4
- package/dist/tools/tool-entry.js +3 -3
- package/dist/tools/tool-registry/core-tools.js +162 -15
- package/dist/tools/tool-registry/group-infra.js +37 -122
- package/dist/tools/tool-registry/group-quality-compliance.js +31 -38
- package/dist/tools/tool-registry/inventory.d.ts +2 -0
- package/dist/tools/tool-registry/inventory.js +2 -0
- package/dist/tools/tool-registry-helpers.d.ts +3 -3
- package/dist/tools/tool-registry-helpers.js +3 -3
- package/dist/tools/tool-usage-report/registered-tools.d.ts +1 -1
- package/dist/tools/tool-usage-report/registered-tools.js +3 -15
- package/dist/tools/update-status/approval-gates.d.ts +13 -0
- package/dist/tools/update-status/approval-gates.js +84 -0
- package/dist/tools/update-status/batch.js +4 -2
- package/dist/tools/update-status/dod-gates.d.ts +6 -24
- package/dist/tools/update-status/dod-gates.js +60 -135
- package/dist/tools/update-status/done-receipt-verifier.d.ts +15 -0
- package/dist/tools/update-status/done-receipt-verifier.js +158 -0
- package/dist/tools/update-status/evidence-gate.js +190 -3
- package/dist/tools/update-status/file-sync.d.ts +2 -1
- package/dist/tools/update-status/file-sync.js +80 -18
- package/dist/tools/update-status/gate-harness.d.ts +7 -0
- package/dist/tools/update-status/gate-harness.js +8 -0
- package/dist/tools/update-status/index.d.ts +2 -0
- package/dist/tools/update-status/index.js +307 -367
- package/dist/tools/update-status/qa-gate.d.ts +1 -1
- package/dist/tools/update-status/qa-gate.js +2 -2
- package/dist/tools/update-status/response-builder.js +3 -3
- package/dist/tools/update-status/side-effects.d.ts +2 -0
- package/dist/tools/update-status/side-effects.js +32 -39
- package/dist/tools/update-status/transition-guard.d.ts +4 -2
- package/dist/tools/update-status/transition-guard.js +89 -25
- package/dist/tools/update-status-actions.d.ts +4 -2
- package/dist/tools/update-status-actions.js +16 -14
- package/dist/tools/update-status-convention-gate.js +24 -23
- package/dist/tools/update-status-reconcile.js +2 -2
- package/dist/tools/usage-report.js +1 -16
- package/dist/tools/usage-stats.js +1 -18
- package/dist/tools/usage-tracking.d.ts +4 -0
- package/dist/tools/usage-tracking.js +20 -0
- package/dist/tools/validate-api-contract-handler.js +3 -3
- package/dist/tools/validate-lint.d.ts +1 -0
- package/dist/tools/validate-lint.js +21 -14
- package/dist/tools/validate.d.ts +4 -1
- package/dist/tools/validate.js +319 -31
- package/dist/transports/http-transport.js +87 -66
- package/dist/transports/mcp-types.d.ts +0 -2
- package/dist/transports/middleware/with-telemetry.js +3 -2
- package/dist/transports/session-context.js +1 -1
- package/dist/types/abortable-process.d.ts +2 -0
- package/dist/types/advanced-framework.js +0 -2
- package/dist/types/atomic-upgrade.d.ts +71 -0
- package/dist/types/atomic-upgrade.js +2 -0
- package/dist/types/cascade-hooks.d.ts +1 -1
- package/dist/types/ci.d.ts +0 -4
- package/dist/types/ci.js +0 -2
- package/dist/types/clarification-token.d.ts +1 -1
- package/dist/types/claude-code-runtime.d.ts +0 -27
- package/dist/types/commercial-migration.d.ts +17 -0
- package/dist/types/commercial-migration.js +2 -0
- package/dist/types/common/primitives.d.ts +0 -2
- package/dist/types/core-bridge.d.ts +81 -10
- package/dist/types/crash-shield-framework-rules.d.ts +24 -0
- package/dist/types/crash-shield-framework-rules.js +2 -0
- package/dist/types/dashboard.d.ts +3 -7
- package/dist/types/data-gc.d.ts +16 -0
- package/dist/types/deploy.js +0 -2
- package/dist/types/docs.d.ts +0 -1
- package/dist/types/durable-job.d.ts +78 -0
- package/dist/types/durable-job.js +2 -0
- package/dist/types/durable-validation.d.ts +158 -0
- package/dist/types/durable-validation.js +166 -0
- package/dist/types/errors/structured-error.d.ts +3 -3
- package/dist/types/estimation.d.ts +4 -0
- package/dist/types/evidence-gates.d.ts +17 -1
- package/dist/types/execution.d.ts +45 -0
- package/dist/types/gemini-integration.d.ts +0 -11
- package/dist/types/handoff-artifacts.d.ts +43 -0
- package/dist/types/hooks-advanced.d.ts +0 -13
- package/dist/types/impact-detection.d.ts +2 -2
- package/dist/types/index.d.ts +4 -6
- package/dist/types/index.js +3 -5
- package/dist/types/infrastructure.js +0 -2
- package/dist/types/kiro-integration.d.ts +0 -6
- package/dist/types/lifecycle.js +0 -2
- package/dist/types/migration/canonical-storage.d.ts +37 -0
- package/dist/types/migration/canonical-storage.js +2 -0
- package/dist/types/migration/index.d.ts +1 -1
- package/dist/types/native-worker.d.ts +48 -0
- package/dist/types/native-worker.js +2 -0
- package/dist/types/network-policy.d.ts +12 -0
- package/dist/types/network-policy.js +2 -0
- package/dist/types/oauth.js +0 -2
- package/dist/types/observability.d.ts +32 -0
- package/dist/types/outbox-worker.d.ts +35 -0
- package/dist/types/outbox-worker.js +11 -0
- package/dist/types/permissions-config.d.ts +0 -27
- package/dist/types/permissions-config.js +0 -2
- package/dist/types/plugin-install.d.ts +0 -11
- package/dist/types/plugin-install.js +0 -2
- package/dist/types/portal.d.ts +1 -0
- package/dist/types/product-public.d.ts +75 -0
- package/dist/types/product-public.js +2 -0
- package/dist/types/project/inputs.d.ts +2 -0
- package/dist/types/project/lint-scaffolder.d.ts +1 -1
- package/dist/types/project/mfe-detection.js +0 -2
- package/dist/types/project/platform-mobile.js +0 -2
- package/dist/types/project/platform-specialty.js +0 -2
- package/dist/types/project-knowledge-graph.d.ts +7 -0
- package/dist/types/runtime-database.d.ts +10 -0
- package/dist/types/runtime-database.js +2 -0
- package/dist/types/runtime-policy.d.ts +51 -0
- package/dist/types/runtime-policy.js +2 -0
- package/dist/types/safety.d.ts +4 -5
- package/dist/types/schema-registry.d.ts +12 -0
- package/dist/types/schema-registry.js +2 -0
- package/dist/types/security.d.ts +52 -0
- package/dist/types/session-safeguard.d.ts +0 -31
- package/dist/types/skill-registry.js +0 -2
- package/dist/types/spec/canonical-repair.d.ts +81 -0
- package/dist/types/spec/canonical-repair.js +2 -0
- package/dist/types/spec/core.d.ts +14 -0
- package/dist/types/spec/index.d.ts +1 -0
- package/dist/types/spec/index.js +1 -0
- package/dist/types/spec/inputs.d.ts +31 -0
- package/dist/types/spec-format.d.ts +24 -0
- package/dist/types/spec-lock-v2.d.ts +13 -7
- package/dist/types/spec-lock-v2.js +1 -1
- package/dist/types/spec-registry.js +0 -2
- package/dist/types/storage-bundle.d.ts +13 -0
- package/dist/types/storage-bundle.js +2 -0
- package/dist/types/storage-catalog.d.ts +18 -0
- package/dist/types/storage-catalog.js +2 -0
- package/dist/types/team-planner.js +0 -2
- package/dist/types/technology-registry.d.ts +35 -0
- package/dist/types/technology-registry.js +2 -0
- package/dist/types/technology-symbols.generated.d.ts +117 -0
- package/dist/types/technology-symbols.generated.js +2 -0
- package/dist/types/telemetry.d.ts +7 -4
- package/dist/types/transport.d.ts +2 -2
- package/dist/types/usage.d.ts +1 -36
- package/dist/types/usage.js +1 -1
- package/dist/types/validate-worker.d.ts +50 -0
- package/dist/types/validate-worker.js +2 -0
- package/dist/types/validation-evidence.d.ts +1 -1
- package/dist/types/validation-receipt.d.ts +104 -0
- package/dist/types/validation-receipt.js +2 -0
- package/dist/types/validation.d.ts +2 -2
- package/package.json +36 -21
- package/planu-native.json +1 -1
- package/planu-plugin.json +23 -40
- package/scripts/lib/pending-release-file.mjs +93 -0
- package/src/i18n/messages/en.json +0 -41
- package/src/i18n/messages/es.json +0 -41
- package/src/i18n/messages/pt.json +0 -41
- package/dist/cli/commands/activate.d.ts +0 -14
- package/dist/cli/commands/activate.js +0 -174
- package/dist/config/license-plans.json +0 -244
- package/dist/config/server-instructions.ts +0 -121
- package/dist/config/version-defaults.ts +0 -76
- package/dist/config/version.ts +0 -18
- package/dist/engine/ai-integration/gemini/settings-generator.d.ts +0 -4
- package/dist/engine/ai-integration/gemini/settings-generator.js +0 -195
- package/dist/engine/ai-integration/kiro/hooks-generator.d.ts +0 -6
- package/dist/engine/ai-integration/kiro/hooks-generator.js +0 -75
- package/dist/engine/hooks/full-spectrum-generator.d.ts +0 -32
- package/dist/engine/hooks/full-spectrum-generator.js +0 -117
- package/dist/engine/license-validator/config-loader.d.ts +0 -5
- package/dist/engine/license-validator/config-loader.js +0 -16
- package/dist/engine/license-validator/core.d.ts +0 -15
- package/dist/engine/license-validator/core.js +0 -151
- package/dist/engine/license-validator/fingerprint.d.ts +0 -3
- package/dist/engine/license-validator/fingerprint.js +0 -17
- package/dist/engine/license-validator/lemon-squeezy.d.ts +0 -5
- package/dist/engine/license-validator/lemon-squeezy.js +0 -55
- package/dist/engine/license-validator.d.ts +0 -5
- package/dist/engine/license-validator.js +0 -6
- package/dist/engine/product-intelligence/index.d.ts +0 -7
- package/dist/engine/product-intelligence/index.js +0 -211
- package/dist/engine/session/auto-save.d.ts +0 -18
- package/dist/engine/session/auto-save.js +0 -98
- package/dist/engine/session/context-snapshot.d.ts +0 -8
- package/dist/engine/session/context-snapshot.js +0 -49
- package/dist/engine/session/memory-sync.d.ts +0 -12
- package/dist/engine/session/memory-sync.js +0 -34
- package/dist/engine/session/session-diff.d.ts +0 -11
- package/dist/engine/session/session-diff.js +0 -42
- package/dist/engine/session/session-merge.d.ts +0 -12
- package/dist/engine/session/session-merge.js +0 -55
- package/dist/engine/session-safeguard/checkpoint-runner.d.ts +0 -4
- package/dist/engine/session-safeguard/checkpoint-runner.js +0 -70
- package/dist/engine/session-safeguard/learnings-buffer.d.ts +0 -16
- package/dist/engine/session-safeguard/learnings-buffer.js +0 -114
- package/dist/engine/session-safeguard/precompaction-drain.d.ts +0 -10
- package/dist/engine/session-safeguard/precompaction-drain.js +0 -82
- package/dist/engine/session-safeguard/unpushed-detector.d.ts +0 -7
- package/dist/engine/session-safeguard/unpushed-detector.js +0 -59
- package/dist/engine/spec-changelog/core.d.ts +0 -16
- package/dist/engine/spec-changelog/core.js +0 -176
- package/dist/engine/spec-changelog/diff.d.ts +0 -18
- package/dist/engine/spec-changelog/diff.js +0 -121
- package/dist/engine/spec-changelog/index.d.ts +0 -3
- package/dist/engine/spec-changelog/index.js +0 -4
- package/dist/engine/telemetry/geo-resolver.d.ts +0 -9
- package/dist/engine/telemetry/geo-resolver.js +0 -43
- package/dist/engine/trial-engine.d.ts +0 -5
- package/dist/engine/trial-engine.js +0 -14
- package/dist/engine/usage-tracker/rate-check.d.ts +0 -7
- package/dist/engine/usage-tracker/rate-check.js +0 -18
- package/dist/engine/usage-tracker/rate-limiter.d.ts +0 -14
- package/dist/engine/usage-tracker/rate-limiter.js +0 -73
- package/dist/engine/usage-tracker/trial.d.ts +0 -27
- package/dist/engine/usage-tracker/trial.js +0 -49
- package/dist/engine/webhook/event-handlers.d.ts +0 -25
- package/dist/engine/webhook/event-handlers.js +0 -89
- package/dist/engine/webhook/index.d.ts +0 -4
- package/dist/engine/webhook/index.js +0 -5
- package/dist/engine/webhook/server.d.ts +0 -12
- package/dist/engine/webhook/server.js +0 -249
- package/dist/engine/webhook/signature.d.ts +0 -16
- package/dist/engine/webhook/signature.js +0 -49
- package/dist/storage/data-dir-discovery.d.ts +0 -31
- package/dist/storage/data-dir-discovery.js +0 -140
- package/dist/storage/license-store.d.ts +0 -6
- package/dist/storage/license-store.js +0 -91
- package/dist/storage/migrations/cwd-to-absolute.d.ts +0 -25
- package/dist/storage/migrations/cwd-to-absolute.js +0 -281
- package/dist/storage/session-store.d.ts +0 -20
- package/dist/storage/session-store.js +0 -128
- package/dist/tools/activate-license.d.ts +0 -6
- package/dist/tools/activate-license.js +0 -132
- package/dist/tools/checkpoint-handler.d.ts +0 -3
- package/dist/tools/checkpoint-handler.js +0 -130
- package/dist/tools/create-spec/adapters/prior-decisions-hint.d.ts +0 -14
- package/dist/tools/create-spec/adapters/prior-decisions-hint.js +0 -30
- package/dist/tools/export-session.d.ts +0 -3
- package/dist/tools/export-session.js +0 -90
- package/dist/tools/init-project/ancestor-data-detector.d.ts +0 -22
- package/dist/tools/init-project/ancestor-data-detector.js +0 -81
- package/dist/tools/license-gate.d.ts +0 -18
- package/dist/tools/license-gate.js +0 -222
- package/dist/tools/license-status.d.ts +0 -3
- package/dist/tools/license-status.js +0 -93
- package/dist/tools/list-sessions.d.ts +0 -3
- package/dist/tools/list-sessions.js +0 -46
- package/dist/tools/planu-session-checkpoint.d.ts +0 -6
- package/dist/tools/planu-session-checkpoint.js +0 -42
- package/dist/tools/restore-session.d.ts +0 -3
- package/dist/tools/restore-session.js +0 -71
- package/dist/tools/spec-history.d.ts +0 -3
- package/dist/tools/spec-history.js +0 -59
- package/dist/tools/update-status/force-done-audit.d.ts +0 -2
- package/dist/tools/update-status/force-done-audit.js +0 -23
- package/dist/tools/webhook.d.ts +0 -6
- package/dist/tools/webhook.js +0 -150
- package/dist/types/changelog.d.ts +0 -49
- package/dist/types/changelog.js +0 -3
- package/dist/types/licensing.d.ts +0 -109
- package/dist/types/licensing.js +0 -4
- package/dist/types/migration/cwd-to-absolute.d.ts +0 -8
- package/dist/types/migration/cwd-to-absolute.js +0 -3
- package/dist/types/product-intelligence.d.ts +0 -60
- package/dist/types/product-intelligence.js +0 -3
- package/dist/types/session.d.ts +0 -84
- package/dist/types/session.js +0 -3
- package/dist/types/webhook.d.ts +0 -62
- package/dist/types/webhook.js +0 -4
|
@@ -2,36 +2,32 @@ import { elicitOrFallback, buildEnumSchema } from '../../engine/elicitation/elic
|
|
|
2
2
|
import { ti } from '../../i18n/index.js';
|
|
3
3
|
import { AutopilotSummaryCollector } from '../../engine/autopilot/summary-collector.js';
|
|
4
4
|
import { specStore, knowledgeStore } from '../../storage/index.js';
|
|
5
|
+
import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
|
|
5
6
|
import { rollbackTransitionSpec, transitionSpec, } from '../../engine/spec-state-machine/transition-spec.js';
|
|
6
7
|
import { calculateAccuracy } from '../../engine/estimator.js';
|
|
7
8
|
import { cascadeCheck } from '../../engine/spec-versioner.js';
|
|
8
9
|
import { runComplianceGates } from '../update-status-convention-gate.js';
|
|
9
10
|
import { runDoneActions, runDoneSideEffects, runImplementingActions, runImplementingSideEffects, } from '../update-status-actions.js';
|
|
10
11
|
import { compactObj } from '../../engine/compact-obj.js';
|
|
11
|
-
import { checkTransition, checkDorGate, checkAmbiguityGate, checkReadinessGate, checkChallengeGate, resolveAutoAdvanceSteps, isReverseTransition, validateReverseTransition, } from './transition-guard.js';
|
|
12
|
+
import { checkTransition, checkDorGate, checkAmbiguityGate, checkReadinessGate, checkChallengeGate, checkImplementationDependencyGate, resolveAutoAdvanceSteps, isReverseTransition, validateReverseTransition, } from './transition-guard.js';
|
|
12
13
|
import { checkApprovedDepGate } from '../../engine/dep-guard/index.js';
|
|
13
14
|
import { checkApprovalGate } from '../../engine/approval-workflow.js';
|
|
14
15
|
import * as approvalStore from '../../storage/approval-store.js';
|
|
15
16
|
import { withApprovalSpecLock } from '../../storage/approval-operation-lock.js';
|
|
16
17
|
import { isLocked, getLock } from '../../storage/spec-lock-store.js';
|
|
17
|
-
import {
|
|
18
|
-
import { writeImplementationReviewReport } from '../../engine/validator/validation-report-writer.js';
|
|
18
|
+
import { checkDoneGates, checkComplianceGate, checkApprovedFormatGate, checkSpecReviewGate, writeSpecReviewArtifact, } from './dod-gates.js';
|
|
19
19
|
import { checkLifecycleEvidenceTransitionGate } from './evidence-gate.js';
|
|
20
|
-
import { buildStatusResponse,
|
|
20
|
+
import { buildStatusResponse, buildDryRunResponse } from './response-builder.js';
|
|
21
21
|
import { recordDoneMetrics, syncSpecFiles, tryReconcile, recordTerminalTransitionEvent, } from './file-sync.js';
|
|
22
22
|
import { appendEntry, getLastHash } from '../../storage/audit-trail-store.js';
|
|
23
23
|
import { appendTransitionEvent } from '../../storage/transition-log.js';
|
|
24
24
|
import { createHash, randomUUID as uuid } from 'node:crypto';
|
|
25
|
-
import { updateFrontmatterField } from '../../engine/frontmatter-parser.js';
|
|
26
25
|
import { atomicWriteFile } from '../../engine/safety/atomic-write-file.js';
|
|
27
26
|
import { recordForceUsage } from '../../storage/force-analytics-store.js';
|
|
28
27
|
import { maybeSafePushOnDone, queuePostCommitTasks, runCascadeForResponse, } from './side-effects.js';
|
|
29
28
|
import { formatKeyValue } from '../output-formatter.js';
|
|
30
29
|
import { checkCodeReality } from '../../engine/code-scanner/index.js';
|
|
31
|
-
import {
|
|
32
|
-
import { shouldSkipCrashScan, recordCrashScanRun, } from '../../engine/autopilot/crash-shield-rate-limiter.js';
|
|
33
|
-
import { mkdir, writeFile } from 'node:fs/promises';
|
|
34
|
-
import { join, dirname } from 'node:path';
|
|
30
|
+
import { join, resolve } from 'node:path';
|
|
35
31
|
import { trackCost } from '../../engine/cost-tracking/operation-tracker.js';
|
|
36
32
|
import { resolveProjectIdOrAutoDetect } from '../resolve-project-id.js';
|
|
37
33
|
import { withToolTimeout } from '../safe-handler.js';
|
|
@@ -39,7 +35,11 @@ import { detectHost } from '../../engine/host-detection/detect-host.js';
|
|
|
39
35
|
import { shellHygieneReminder } from '../../hosts/claude-code/coach.js';
|
|
40
36
|
import { buildTransitionEvidenceMeta, checkSddModelRoutingGate, } from '../../engine/sdd-model-routing.js';
|
|
41
37
|
import { acquireLock, releaseLock, isLocked as isCrossProcessLocked, LockBusyError, } from '../../engine/safety/cross-process-lock.js';
|
|
42
|
-
import {
|
|
38
|
+
import { projectDataDir } from '../../storage/base-store.js';
|
|
39
|
+
import { assertExecutionCanCommit } from '../../engine/execution/context.js';
|
|
40
|
+
import { shouldSkipGateForExplicitLegacyHarness } from './gate-harness.js';
|
|
41
|
+
import { assertValidationFreshnessBarrier, closeValidationFreshnessLease, } from '../../engine/validation/validation-freshness.js';
|
|
42
|
+
import { currentReconciliationInvocationContext, reconcileImplementingSpec, } from '../../engine/lifecycle-reconciliation.js';
|
|
43
43
|
/**
|
|
44
44
|
* SPEC-280: Silently traverse intermediate states so callers can jump forward
|
|
45
45
|
* (e.g. draft → approved) without receiving an error.
|
|
@@ -141,9 +141,8 @@ async function createVersionSnapshot(specId, projectId, tag) {
|
|
|
141
141
|
if (!spec) {
|
|
142
142
|
return;
|
|
143
143
|
}
|
|
144
|
-
const snapshotPath = join(
|
|
145
|
-
await
|
|
146
|
-
await writeFile(snapshotPath, JSON.stringify(spec, null, 2), 'utf-8');
|
|
144
|
+
const snapshotPath = join(projectDataDir(projectId), 'version-snapshots', `${tag}.json`);
|
|
145
|
+
await atomicWriteFile(snapshotPath, `${JSON.stringify(spec, null, 2)}\n`);
|
|
147
146
|
}
|
|
148
147
|
function checkIdempotentOrTransition(projectId, spec, target) {
|
|
149
148
|
if (spec.status === target) {
|
|
@@ -200,6 +199,18 @@ function planBackgroundActions(args) {
|
|
|
200
199
|
}
|
|
201
200
|
return actions;
|
|
202
201
|
}
|
|
202
|
+
/** Bind deferred lifecycle work to one normalized absolute root without persisting that path. */
|
|
203
|
+
export function computeTransitionRootBinding(projectPath) {
|
|
204
|
+
return createHash('sha256')
|
|
205
|
+
.update('planu:transition-root:v1\0')
|
|
206
|
+
.update(resolve(projectPath))
|
|
207
|
+
.digest('hex');
|
|
208
|
+
}
|
|
209
|
+
function receiptMatchesTransitionRoot(receipt, projectPath) {
|
|
210
|
+
return (projectPath !== undefined &&
|
|
211
|
+
receipt.transitionRootBinding !== undefined &&
|
|
212
|
+
receipt.transitionRootBinding === computeTransitionRootBinding(projectPath));
|
|
213
|
+
}
|
|
203
214
|
function buildPostCommitTasks(args) {
|
|
204
215
|
const enabled = new Set(args.actionNames);
|
|
205
216
|
const tasks = [];
|
|
@@ -213,13 +224,13 @@ function buildPostCommitTasks(args) {
|
|
|
213
224
|
if (enabled.has('implementing-side-effects')) {
|
|
214
225
|
tasks.push({
|
|
215
226
|
name: 'implementing-side-effects',
|
|
216
|
-
run: () => runImplementingSideEffects(args.projectId, args.spec.id),
|
|
227
|
+
run: () => runImplementingSideEffects(args.projectId, args.spec.id, args.effectiveProjectPath),
|
|
217
228
|
});
|
|
218
229
|
}
|
|
219
230
|
if (enabled.has('done-side-effects')) {
|
|
220
231
|
tasks.push({
|
|
221
232
|
name: 'done-side-effects',
|
|
222
|
-
run: () => runDoneSideEffects(args.projectId, args.spec.id, args.spec.gitBranch),
|
|
233
|
+
run: () => runDoneSideEffects(args.projectId, args.spec.id, args.spec.gitBranch, args.effectiveProjectPath),
|
|
223
234
|
});
|
|
224
235
|
}
|
|
225
236
|
if (enabled.has('reconcile')) {
|
|
@@ -232,7 +243,7 @@ function buildPostCommitTasks(args) {
|
|
|
232
243
|
if (enabled.has('record-done-metrics') && actuals) {
|
|
233
244
|
tasks.push({
|
|
234
245
|
name: 'record-done-metrics',
|
|
235
|
-
run: () => recordDoneMetrics(args.projectId, args.spec.id, args.spec, actuals, args.
|
|
246
|
+
run: () => recordDoneMetrics(args.projectId, args.spec.id, args.spec, actuals, args.effectiveProjectPath),
|
|
236
247
|
});
|
|
237
248
|
}
|
|
238
249
|
const effectiveProjectPath = args.effectiveProjectPath;
|
|
@@ -254,6 +265,7 @@ function buildPostCommitTasks(args) {
|
|
|
254
265
|
projectId: args.projectId,
|
|
255
266
|
spec: args.spec,
|
|
256
267
|
currentStatus: args.previousStatus,
|
|
268
|
+
projectPath: args.effectiveProjectPath,
|
|
257
269
|
}),
|
|
258
270
|
});
|
|
259
271
|
}
|
|
@@ -292,7 +304,10 @@ async function replayIdempotentPostCommitTasks(args) {
|
|
|
292
304
|
return;
|
|
293
305
|
}
|
|
294
306
|
const knowledge = await knowledgeStore.getKnowledge(args.projectId);
|
|
295
|
-
const effectiveProjectPath =
|
|
307
|
+
const effectiveProjectPath = args.projectPath ?? knowledge?.projectPath;
|
|
308
|
+
if (!receiptMatchesTransitionRoot(receipt, effectiveProjectPath)) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
296
311
|
const specAtTransition = { ...args.spec, status: receipt.status };
|
|
297
312
|
const tasks = buildPostCommitTasks({
|
|
298
313
|
actionNames: receipt.pendingBackgroundActions,
|
|
@@ -318,13 +333,17 @@ async function recoverPendingPostCommitTasks(projectId, projectPath) {
|
|
|
318
333
|
knowledgeStore.getKnowledge(projectId),
|
|
319
334
|
specStore.listSpecs(projectId),
|
|
320
335
|
]);
|
|
321
|
-
const effectiveProjectPath =
|
|
336
|
+
const effectiveProjectPath = projectPath ?? knowledge?.projectPath;
|
|
322
337
|
for (const spec of specs) {
|
|
323
|
-
const
|
|
324
|
-
|
|
338
|
+
const recoverableReceipts = (spec.statusHistory ?? []).filter((receipt) => receipt.transitionId &&
|
|
339
|
+
receipt.pendingBackgroundActions?.length &&
|
|
340
|
+
receiptMatchesTransitionRoot(receipt, effectiveProjectPath));
|
|
341
|
+
if (recoverableReceipts.length === 0 || !effectiveProjectPath) {
|
|
325
342
|
continue;
|
|
326
343
|
}
|
|
327
|
-
const recoveryLock = await acquireLock(effectiveProjectPath
|
|
344
|
+
const recoveryLock = await acquireLock(effectiveProjectPath, spec.id, {
|
|
345
|
+
reason: 'recover pending post-commit tasks',
|
|
346
|
+
});
|
|
328
347
|
if (recoveryLock === null) {
|
|
329
348
|
continue;
|
|
330
349
|
}
|
|
@@ -336,7 +355,9 @@ async function recoverPendingPostCommitTasks(projectId, projectPath) {
|
|
|
336
355
|
continue;
|
|
337
356
|
}
|
|
338
357
|
for (const receipt of currentSpec.statusHistory ?? []) {
|
|
339
|
-
if (!receipt.transitionId ||
|
|
358
|
+
if (!receipt.transitionId ||
|
|
359
|
+
!receipt.pendingBackgroundActions?.length ||
|
|
360
|
+
!receiptMatchesTransitionRoot(receipt, effectiveProjectPath)) {
|
|
340
361
|
continue;
|
|
341
362
|
}
|
|
342
363
|
const specAtTransition = { ...currentSpec, status: receipt.status };
|
|
@@ -361,7 +382,10 @@ async function recoverPendingPostCommitTasks(projectId, projectPath) {
|
|
|
361
382
|
}
|
|
362
383
|
}
|
|
363
384
|
finally {
|
|
364
|
-
await releaseLock(recoveryLock).catch(() =>
|
|
385
|
+
await releaseLock(recoveryLock).catch((error) => {
|
|
386
|
+
/* reliability-cleanup: RECOVERY_LOCK_RELEASE — lease expiry remains the recovery boundary */
|
|
387
|
+
reportClassifiedDegradation('RECOVERY_LOCK_RELEASE', error);
|
|
388
|
+
});
|
|
365
389
|
}
|
|
366
390
|
}
|
|
367
391
|
}
|
|
@@ -381,6 +405,18 @@ export async function recoverPendingPostCommitTasksAtStartup() {
|
|
|
381
405
|
});
|
|
382
406
|
}
|
|
383
407
|
}
|
|
408
|
+
async function runTransitionMaintenance(transitionProjectPath) {
|
|
409
|
+
if (transitionProjectPath) {
|
|
410
|
+
try {
|
|
411
|
+
const { runStrictPlanuCleanup } = await import('../../engine/spec-migrator/index.js');
|
|
412
|
+
await runStrictPlanuCleanup(transitionProjectPath);
|
|
413
|
+
}
|
|
414
|
+
catch (error) {
|
|
415
|
+
/* reliability-cleanup: PRE_TRANSITION_STRICT_CLEANUP — validate remains fail-closed */
|
|
416
|
+
reportClassifiedDegradation('PRE_TRANSITION_STRICT_CLEANUP', error);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
384
420
|
function buildPersistenceFailureResponse(args) {
|
|
385
421
|
const committed = args.recoveryRequired ? null : false;
|
|
386
422
|
const message = args.recoveryRequired
|
|
@@ -405,15 +441,106 @@ function buildPersistenceFailureResponse(args) {
|
|
|
405
441
|
},
|
|
406
442
|
};
|
|
407
443
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
444
|
+
async function commitTransitionWithNarrowLock(args) {
|
|
445
|
+
return withApprovalSpecLock(args.projectPath, args.specId, async () => {
|
|
446
|
+
const lock = await acquireLock(args.projectPath, args.specId, {
|
|
447
|
+
reason: `update_status(${args.newStatus}) commit`,
|
|
448
|
+
});
|
|
449
|
+
if (lock === null) {
|
|
450
|
+
return {
|
|
451
|
+
ok: false,
|
|
452
|
+
error: {
|
|
453
|
+
content: [
|
|
454
|
+
{
|
|
455
|
+
type: 'text',
|
|
456
|
+
text: `Spec ${args.specId} is locked by another process (cross-process lock). Retry later.`,
|
|
457
|
+
},
|
|
458
|
+
],
|
|
459
|
+
isError: true,
|
|
460
|
+
},
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
try {
|
|
464
|
+
const freshSpec = typeof specStore.getSpecFresh === 'function'
|
|
465
|
+
? await specStore.getSpecFresh(args.projectId, args.specId)
|
|
466
|
+
: await specStore.getSpec(args.projectId, args.specId);
|
|
467
|
+
if (freshSpec?.status !== args.expectedSpec.status ||
|
|
468
|
+
freshSpec.updatedAt !== args.expectedSpec.updatedAt) {
|
|
469
|
+
return {
|
|
470
|
+
ok: false,
|
|
471
|
+
error: {
|
|
472
|
+
content: [
|
|
473
|
+
{
|
|
474
|
+
type: 'text',
|
|
475
|
+
text: `Spec ${args.specId} changed while lifecycle gates were running. Retry with the fresh state.`,
|
|
476
|
+
},
|
|
477
|
+
],
|
|
478
|
+
isError: true,
|
|
479
|
+
structuredContent: { error: 'TRANSITION_CONFLICT', code: 409 },
|
|
480
|
+
},
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
if (args.newStatus === 'done' &&
|
|
484
|
+
(!args.freshnessLease || !(await assertValidationFreshnessBarrier(args.freshnessLease))) &&
|
|
485
|
+
!shouldSkipGateForExplicitLegacyHarness('evidence')) {
|
|
486
|
+
return {
|
|
487
|
+
ok: false,
|
|
488
|
+
error: {
|
|
489
|
+
content: [
|
|
490
|
+
{
|
|
491
|
+
type: 'text',
|
|
492
|
+
text: `Validation inputs for ${args.specId} changed before commit. Re-run validate.`,
|
|
493
|
+
},
|
|
494
|
+
],
|
|
495
|
+
isError: true,
|
|
496
|
+
structuredContent: { error: 'VALIDATION_RECEIPT_STALE', code: 409 },
|
|
497
|
+
},
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
assertExecutionCanCommit();
|
|
501
|
+
const transitionRecord = await transitionSpec(args.projectId, args.specId, args.newStatus, {
|
|
502
|
+
...args.options,
|
|
503
|
+
expectedSpec: freshSpec,
|
|
504
|
+
});
|
|
505
|
+
const updatedSpec = transitionRecord.spec;
|
|
506
|
+
const syncResult = await syncSpecFiles(updatedSpec, args.originalStatus, args.newStatus, args.projectPath, args.qualityWarnings);
|
|
507
|
+
if (!syncResult.warning) {
|
|
508
|
+
return { ok: true, transitionRecord, updatedSpec };
|
|
509
|
+
}
|
|
510
|
+
try {
|
|
511
|
+
await rollbackTransitionSpec(transitionRecord);
|
|
512
|
+
return {
|
|
513
|
+
ok: false,
|
|
514
|
+
error: buildPersistenceFailureResponse({
|
|
515
|
+
specId: args.specId,
|
|
516
|
+
previousStatus: args.originalStatus,
|
|
517
|
+
newStatus: args.newStatus,
|
|
518
|
+
reason: syncResult.warning.reason,
|
|
519
|
+
recoveryRequired: false,
|
|
520
|
+
}),
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
catch (rollbackError) {
|
|
524
|
+
return {
|
|
525
|
+
ok: false,
|
|
526
|
+
error: buildPersistenceFailureResponse({
|
|
527
|
+
specId: args.specId,
|
|
528
|
+
previousStatus: args.originalStatus,
|
|
529
|
+
newStatus: args.newStatus,
|
|
530
|
+
reason: `${syncResult.warning.reason}; compensation failed: ` +
|
|
531
|
+
(rollbackError instanceof Error ? rollbackError.message : String(rollbackError)),
|
|
532
|
+
recoveryRequired: true,
|
|
533
|
+
}),
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
finally {
|
|
538
|
+
await releaseLock(lock).catch((error) => {
|
|
539
|
+
/* reliability-cleanup: UPDATE_STATUS_LOCK_RELEASE — lease expiry remains the recovery boundary */
|
|
540
|
+
reportClassifiedDegradation('UPDATE_STATUS_LOCK_RELEASE', error);
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
});
|
|
417
544
|
}
|
|
418
545
|
/** Build fallback interactiveQuestion for status confirmation (SPEC-595). */
|
|
419
546
|
function buildStatusConfirmFallback(specId, newStatus) {
|
|
@@ -468,20 +595,15 @@ async function resolveOrchestrationPlan(newStatus, specScope, specId, projectPat
|
|
|
468
595
|
}
|
|
469
596
|
return withToolTimeout(import('../orchestrate-agents-handler.js')
|
|
470
597
|
.then(({ buildOrchestrationPlanSummary }) => buildOrchestrationPlanSummary(specId, projectPath))
|
|
471
|
-
.catch(() =>
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
}
|
|
476
|
-
function shouldSkipEvidenceGateForLegacyTestHarness() {
|
|
477
|
-
return process.env.VITEST === 'true' && process.env.PLANU_TEST_STRICT_EVIDENCE_GATES !== 'true';
|
|
478
|
-
}
|
|
479
|
-
function shouldSkipStrictLayoutGateForLegacyTestHarness() {
|
|
480
|
-
return process.env.VITEST === 'true' && process.env.PLANU_TEST_STRICT_LAYOUT_GATE !== 'true';
|
|
598
|
+
.catch((error) => {
|
|
599
|
+
// reliability-optional: ORCHESTRATION_PLAN_SUMMARY — summary enrichment is non-authoritative
|
|
600
|
+
reportClassifiedDegradation('ORCHESTRATION_PLAN_SUMMARY', error);
|
|
601
|
+
return null;
|
|
602
|
+
}), 5_000, null);
|
|
481
603
|
}
|
|
482
604
|
/* eslint-disable complexity, max-lines-per-function */
|
|
483
605
|
export async function handleUpdateStatus(params, server) {
|
|
484
|
-
return trackCost(params.projectPath ?? '', 'update_status', async () => {
|
|
606
|
+
return trackCost(params.projectPath?.trim() ?? '', 'update_status', async () => {
|
|
485
607
|
const { specId, status: newStatus, actuals, reviewNotes } = params;
|
|
486
608
|
// SPEC-509: auto-detect project from git root when projectPath/projectId are omitted
|
|
487
609
|
const resolved = await resolveProjectIdOrAutoDetect({
|
|
@@ -493,55 +615,43 @@ export async function handleUpdateStatus(params, server) {
|
|
|
493
615
|
}
|
|
494
616
|
const projectId = resolved.projectId;
|
|
495
617
|
const effectiveProjectPath = resolved.projectPath;
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
await recoverPendingPostCommitTasks(projectId, effectiveProjectPath).catch((error) => {
|
|
506
|
-
console.warn('[planu:post-commit] automatic recovery scan failed', {
|
|
618
|
+
const knowledge = await knowledgeStore.getKnowledge(projectId);
|
|
619
|
+
const transitionProjectPath = (params.projectPath?.trim()
|
|
620
|
+
? effectiveProjectPath
|
|
621
|
+
: (knowledge?.projectPath ?? effectiveProjectPath)) || undefined;
|
|
622
|
+
if (params.reconciliationRequestId ||
|
|
623
|
+
params.expectedImplementingTransitionId ||
|
|
624
|
+
params.implementationReviewDigest) {
|
|
625
|
+
return reconcileImplementingSpec({
|
|
626
|
+
input: params,
|
|
507
627
|
projectId,
|
|
508
|
-
|
|
628
|
+
projectPath: transitionProjectPath,
|
|
629
|
+
context: currentReconciliationInvocationContext(),
|
|
630
|
+
syncSpecFiles,
|
|
509
631
|
});
|
|
510
|
-
}
|
|
511
|
-
|
|
632
|
+
}
|
|
633
|
+
if (newStatus !== 'done') {
|
|
634
|
+
await runTransitionMaintenance(transitionProjectPath);
|
|
635
|
+
}
|
|
636
|
+
let doneFreshnessLease;
|
|
637
|
+
return (async () => {
|
|
512
638
|
try {
|
|
513
639
|
// SPEC-301: Reject status changes when spec is locked by another holder (legacy manual lock)
|
|
514
|
-
const lockError = await checkSpecLockGate(
|
|
640
|
+
const lockError = await checkSpecLockGate(transitionProjectPath, specId);
|
|
515
641
|
if (lockError) {
|
|
516
642
|
return lockError;
|
|
517
643
|
}
|
|
518
|
-
//
|
|
519
|
-
//
|
|
520
|
-
// Released in finally below. Best-effort when no projectPath is available.
|
|
644
|
+
// Dry-run checks availability without acquiring. Real mutations acquire only
|
|
645
|
+
// around the compare-and-swap plus spec/store commit below.
|
|
521
646
|
const isDryRun = params.dry_run === true;
|
|
522
|
-
|
|
523
|
-
if (!isDryRun) {
|
|
524
|
-
crossProcessLockHandle = await acquireLock(effectiveProjectPath, specId, {
|
|
525
|
-
reason: `update_status(${newStatus})`,
|
|
526
|
-
});
|
|
527
|
-
if (crossProcessLockHandle === null) {
|
|
528
|
-
// acquireLock returns null only when another live session holds the lock
|
|
529
|
-
// For dry_run, return a special response indicating lock is busy
|
|
530
|
-
return {
|
|
531
|
-
content: [
|
|
532
|
-
{
|
|
533
|
-
type: 'text',
|
|
534
|
-
text: `Spec ${specId} is locked by another process (cross-process lock). Retry later or inspect data/.locks/planu/${specId}.lock`,
|
|
535
|
-
},
|
|
536
|
-
],
|
|
537
|
-
isError: true,
|
|
538
|
-
};
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
else {
|
|
647
|
+
if (isDryRun) {
|
|
542
648
|
// SPEC-731: dry_run checks lock availability without acquiring it.
|
|
543
649
|
// isLocked returns null when no lockfile exists (available), or a LockInfo when locked.
|
|
544
|
-
const lockInfo = await isCrossProcessLocked(
|
|
650
|
+
const lockInfo = await isCrossProcessLocked(transitionProjectPath ?? projectId, specId).catch((error) => {
|
|
651
|
+
// reliability-optional: DRY_RUN_LOCK_PROBE — null conservatively avoids stale lock claims
|
|
652
|
+
reportClassifiedDegradation('DRY_RUN_LOCK_PROBE', error);
|
|
653
|
+
return null;
|
|
654
|
+
});
|
|
545
655
|
const lockIsBusy = lockInfo !== null && !lockInfo.stale;
|
|
546
656
|
if (lockIsBusy) {
|
|
547
657
|
// Lock is busy — return dry_run result indicating this without blocking
|
|
@@ -562,11 +672,9 @@ export async function handleUpdateStatus(params, server) {
|
|
|
562
672
|
}
|
|
563
673
|
}
|
|
564
674
|
try {
|
|
565
|
-
//
|
|
566
|
-
//
|
|
567
|
-
const spec =
|
|
568
|
-
? await specStore.getSpecFresh(projectId, specId)
|
|
569
|
-
: await specStore.getSpec(projectId, specId);
|
|
675
|
+
// Gates consume an unlocked snapshot. Commit revalidates this snapshot
|
|
676
|
+
// under the narrow mutation lock before compare-and-swap.
|
|
677
|
+
const spec = await specStore.getSpec(projectId, specId);
|
|
570
678
|
if (!spec) {
|
|
571
679
|
return {
|
|
572
680
|
content: [{ type: 'text', text: ti('spec.notFound', { id: specId }) }],
|
|
@@ -578,7 +686,7 @@ export async function handleUpdateStatus(params, server) {
|
|
|
578
686
|
await replayIdempotentPostCommitTasks({
|
|
579
687
|
projectId,
|
|
580
688
|
spec,
|
|
581
|
-
projectPath:
|
|
689
|
+
projectPath: transitionProjectPath,
|
|
582
690
|
});
|
|
583
691
|
const idempotentResult = checkIdempotentOrTransition(projectId, spec, newStatus);
|
|
584
692
|
if (idempotentResult) {
|
|
@@ -672,9 +780,12 @@ export async function handleUpdateStatus(params, server) {
|
|
|
672
780
|
}
|
|
673
781
|
// SPEC-728: DepGuard — block 'approved' if spec participates in a dependency cycle
|
|
674
782
|
let depGuardResult = null;
|
|
783
|
+
let allSpecsForDependencyGate = null;
|
|
784
|
+
if (plannedStatuses.includes('approved') || plannedStatuses.includes('implementing')) {
|
|
785
|
+
allSpecsForDependencyGate = await specStore.listSpecs(projectId);
|
|
786
|
+
}
|
|
675
787
|
if (plannedStatuses.includes('approved')) {
|
|
676
|
-
|
|
677
|
-
depGuardResult = checkApprovedDepGate(spec, allSpecsForDepGuard);
|
|
788
|
+
depGuardResult = checkApprovedDepGate(spec, allSpecsForDependencyGate ?? []);
|
|
678
789
|
if (depGuardResult.blocked) {
|
|
679
790
|
return {
|
|
680
791
|
content: [{ type: 'text', text: `DepGuard blocked: ${depGuardResult.narrative}` }],
|
|
@@ -689,6 +800,12 @@ export async function handleUpdateStatus(params, server) {
|
|
|
689
800
|
};
|
|
690
801
|
}
|
|
691
802
|
}
|
|
803
|
+
if (plannedStatuses.includes('implementing')) {
|
|
804
|
+
const dependencyGate = checkImplementationDependencyGate(spec, allSpecsForDependencyGate ?? [], 'implementing');
|
|
805
|
+
if (dependencyGate) {
|
|
806
|
+
return dependencyGate;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
692
809
|
// SPEC-964: Challenge gate — block 'review' if challenge_spec was never run
|
|
693
810
|
const challengeGateStatus = plannedStatuses.includes('review') ? 'review' : newStatus;
|
|
694
811
|
const challengeGate = checkChallengeGate(spec, challengeGateStatus);
|
|
@@ -706,17 +823,15 @@ export async function handleUpdateStatus(params, server) {
|
|
|
706
823
|
if (elicitResult) {
|
|
707
824
|
return elicitResult;
|
|
708
825
|
}
|
|
709
|
-
// Load knowledge for project path (needed for DoD gates, validate trigger and HTML regen)
|
|
710
|
-
const knowledge = await knowledgeStore.getKnowledge(projectId);
|
|
711
826
|
// Resolve effective project path once — used across all gates below
|
|
712
|
-
const effectiveGatePath =
|
|
827
|
+
const effectiveGatePath = transitionProjectPath;
|
|
713
828
|
// SPEC-1044: SDD model-routing + context continuity hard gate.
|
|
714
829
|
const sddRoutingGate = {
|
|
715
830
|
blockResult: null,
|
|
716
831
|
gateResults: { sddModelRouting: 'skip' },
|
|
717
832
|
forcedReasons: [],
|
|
718
833
|
};
|
|
719
|
-
if (!
|
|
834
|
+
if (!shouldSkipGateForExplicitLegacyHarness('routing')) {
|
|
720
835
|
const routedStatuses = plannedStatuses.filter((status) => status === 'approved' || status === 'implementing' || status === 'done');
|
|
721
836
|
for (const status of routedStatuses) {
|
|
722
837
|
const gate = await checkSddModelRoutingGate({
|
|
@@ -737,7 +852,7 @@ export async function handleUpdateStatus(params, server) {
|
|
|
737
852
|
// SPEC-1054: BDD/SDD evidence gates. Non-trivial specs must carry
|
|
738
853
|
// Discovery before approval, task-plan before implementation, and
|
|
739
854
|
// traceability/contract evidence before done.
|
|
740
|
-
if (!
|
|
855
|
+
if (!shouldSkipGateForExplicitLegacyHarness('evidence')) {
|
|
741
856
|
const evidenceStatuses = plannedStatuses.filter((status) => status === 'approved' || status === 'implementing' || status === 'done');
|
|
742
857
|
for (const transition of evidenceStatuses) {
|
|
743
858
|
const evidenceGate = await checkLifecycleEvidenceTransitionGate({
|
|
@@ -757,24 +872,21 @@ export async function handleUpdateStatus(params, server) {
|
|
|
757
872
|
// SPEC-441: Code reality check before transitioning to 'implementing'
|
|
758
873
|
// SPEC-335: DoD + security gates before transitioning to 'done'
|
|
759
874
|
// ---------------------------------------------------------------------------
|
|
760
|
-
//
|
|
761
|
-
//
|
|
762
|
-
if (newStatus === 'done') {
|
|
763
|
-
const qaGateResult = await checkQaGate(spec, effectiveGatePath, params.force ?? false);
|
|
764
|
-
if (qaGateResult !== null) {
|
|
765
|
-
return qaGateResult;
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
// ---------------------------------------------------------------------------
|
|
875
|
+
// `done` consumes the immutable validation receipt below. Validation, QA,
|
|
876
|
+
// security and repository scans belong to the durable validation worker.
|
|
769
877
|
let codeRealityWarning = null;
|
|
770
878
|
let forcedBypassWarning = null;
|
|
771
879
|
const [codeRealityResult, doneGatesResult] = await Promise.all([
|
|
772
880
|
// Code reality: only relevant for 'implementing'
|
|
773
881
|
newStatus === 'implementing' && !reverseTransition && effectiveGatePath
|
|
774
|
-
? checkCodeReality(effectiveGatePath, spec.title).catch(() =>
|
|
882
|
+
? checkCodeReality(effectiveGatePath, spec.title).catch((error) => {
|
|
883
|
+
// reliability-optional: CODE_REALITY_ENRICHMENT — downstream evidence gates remain binding
|
|
884
|
+
reportClassifiedDegradation('CODE_REALITY_ENRICHMENT', error);
|
|
885
|
+
return null;
|
|
886
|
+
})
|
|
775
887
|
: Promise.resolve(null),
|
|
776
888
|
// Done gates: only relevant for 'done'
|
|
777
|
-
newStatus === 'done'
|
|
889
|
+
newStatus === 'done' && !shouldSkipGateForExplicitLegacyHarness('evidence')
|
|
778
890
|
? checkDoneGates(spec, specId, projectId, effectiveGatePath, params.force, params.forceStatusReason ?? params.reason ?? 'No force reason provided')
|
|
779
891
|
: Promise.resolve(null),
|
|
780
892
|
]);
|
|
@@ -788,89 +900,24 @@ export async function handleUpdateStatus(params, server) {
|
|
|
788
900
|
return doneGatesResult.blocked;
|
|
789
901
|
}
|
|
790
902
|
forcedBypassWarning = doneGatesResult.forcedBypassWarning;
|
|
903
|
+
doneFreshnessLease = doneGatesResult.freshnessLease ?? undefined;
|
|
791
904
|
}
|
|
792
905
|
// ---------------------------------------------------------------------------
|
|
793
|
-
//
|
|
794
|
-
//
|
|
795
|
-
// SPEC-222: Auto-validate before marking done
|
|
796
|
-
// SPEC-442: Crash Shield warning on 'done'
|
|
797
|
-
// SPEC-447: Compliance gate on 'review' or 'implementing'
|
|
906
|
+
// Review-only heuristic compliance. `done` must remain an O(1) receipt
|
|
907
|
+
// consumer and therefore must not execute commands or scan the repository.
|
|
798
908
|
// ---------------------------------------------------------------------------
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
let crashShieldSkipReason = null;
|
|
909
|
+
const validateScore = null;
|
|
910
|
+
const validateScoreSource = null;
|
|
911
|
+
const crashShieldWarning = null;
|
|
803
912
|
let complianceGateResult = null;
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
? runValidateGate(spec, effectiveGatePath ?? '', params.forceStatus ?? false, params.forceStatusReason, 9_000, { projectId, specId })
|
|
813
|
-
: Promise.resolve(null),
|
|
814
|
-
// Crash shield: only on 'done', skipped if rate-limited (SPEC-628)
|
|
815
|
-
newStatus === 'done' && effectiveGatePath && !crashShieldSkipReason
|
|
816
|
-
? withToolTimeout(scanCrashRisks(effectiveGatePath).catch(() => null), 9_000, null)
|
|
817
|
-
: Promise.resolve(null),
|
|
818
|
-
// The heuristic scorer is a review aid. Done relies on the authoritative validate report.
|
|
819
|
-
plannedStatuses.includes('review')
|
|
820
|
-
? withToolTimeout(checkComplianceGate(specId, projectId, effectiveGatePath), 9_000, {
|
|
821
|
-
skipped: true,
|
|
822
|
-
blocked: false,
|
|
823
|
-
score: null,
|
|
824
|
-
issues: [],
|
|
825
|
-
})
|
|
826
|
-
: Promise.resolve(null),
|
|
827
|
-
]);
|
|
828
|
-
// Process validate result — may block (SPEC-721: fail-closed)
|
|
829
|
-
let forcedValidateBypass = null;
|
|
830
|
-
if (validateGateResult !== null) {
|
|
831
|
-
if (validateGateResult.blocked) {
|
|
832
|
-
return buildValidateBlockedResponse(specId, validateGateResult);
|
|
833
|
-
}
|
|
834
|
-
validateScore = validateGateResult.score;
|
|
835
|
-
if (validateGateResult.forced) {
|
|
836
|
-
validateScoreSource = validateGateResult.scoreSource;
|
|
837
|
-
forcedValidateBypass = {
|
|
838
|
-
reason: validateGateResult.forcedReason,
|
|
839
|
-
observedScore: validateGateResult.score,
|
|
840
|
-
};
|
|
841
|
-
}
|
|
842
|
-
else {
|
|
843
|
-
validateScoreSource = 'validateSpec';
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
if (newStatus === 'done' &&
|
|
847
|
-
effectiveGatePath &&
|
|
848
|
-
!shouldSkipStrictLayoutGateForLegacyTestHarness()) {
|
|
849
|
-
const strictLayoutError = await validateStrictLayoutOrError({
|
|
850
|
-
projectPath: effectiveGatePath,
|
|
851
|
-
specId,
|
|
852
|
-
specPath: spec.specPath,
|
|
853
|
-
failClosedOnCrash: true,
|
|
854
|
-
});
|
|
855
|
-
if (strictLayoutError) {
|
|
856
|
-
return strictLayoutError;
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
// Process crash shield result — record run timestamp on success (SPEC-628)
|
|
860
|
-
/* c8 ignore next */
|
|
861
|
-
if (crashRisksReport !== null) {
|
|
862
|
-
if (crashRisksReport.score < 80) {
|
|
863
|
-
const criticalCount = crashRisksReport.risks.filter((r) => r.severity === 'CRITICAL').length;
|
|
864
|
-
crashShieldWarning =
|
|
865
|
-
`Crash Shield: score ${String(crashRisksReport.score)}/100 — ${String(criticalCount)} critical risk(s) detected. ` +
|
|
866
|
-
`Run \`scan_crash_risks\` for details.`;
|
|
867
|
-
}
|
|
868
|
-
if (effectiveGatePath) {
|
|
869
|
-
void recordCrashScanRun(effectiveGatePath).catch(() => {
|
|
870
|
-
/* best-effort */
|
|
871
|
-
});
|
|
872
|
-
}
|
|
873
|
-
}
|
|
913
|
+
const complianceResult = plannedStatuses.includes('review')
|
|
914
|
+
? await withToolTimeout(checkComplianceGate(specId, projectId, effectiveGatePath), 9_000, {
|
|
915
|
+
skipped: true,
|
|
916
|
+
blocked: false,
|
|
917
|
+
score: null,
|
|
918
|
+
issues: [],
|
|
919
|
+
})
|
|
920
|
+
: null;
|
|
874
921
|
// Process compliance gate result — may block on 'review'
|
|
875
922
|
if (complianceResult !== null) {
|
|
876
923
|
complianceGateResult = complianceResult;
|
|
@@ -878,10 +925,9 @@ export async function handleUpdateStatus(params, server) {
|
|
|
878
925
|
return buildBlockedByComplianceResponse(specId, complianceResult);
|
|
879
926
|
}
|
|
880
927
|
}
|
|
881
|
-
//
|
|
882
|
-
//
|
|
883
|
-
|
|
884
|
-
const { conventionWarnings, constitutionWarnings, compileWarnings, lintWarnings, testWarnings, } = newStatus === 'done' || plannedStatuses.includes('approved')
|
|
928
|
+
// Approved still needs constitution warnings. Done relies exclusively on
|
|
929
|
+
// the validation receipt and never invokes this legacy command runner.
|
|
930
|
+
const { conventionWarnings, constitutionWarnings, compileWarnings, lintWarnings, testWarnings, } = plannedStatuses.includes('approved')
|
|
885
931
|
? await runComplianceGates(projectId, spec.title, spec.tags, newStatus, specId)
|
|
886
932
|
: {
|
|
887
933
|
conventionWarnings: [],
|
|
@@ -890,38 +936,13 @@ export async function handleUpdateStatus(params, server) {
|
|
|
890
936
|
lintWarnings: [],
|
|
891
937
|
testWarnings: [],
|
|
892
938
|
};
|
|
893
|
-
if (newStatus === 'done' && !(params.force ?? params.forceStatus ?? false)) {
|
|
894
|
-
if (!isDryRun && effectiveGatePath) {
|
|
895
|
-
await writeImplementationReviewReport({
|
|
896
|
-
projectId,
|
|
897
|
-
specId,
|
|
898
|
-
spec,
|
|
899
|
-
projectPath: effectiveGatePath,
|
|
900
|
-
score: validateScore,
|
|
901
|
-
lintPassed: lintWarnings.length === 0,
|
|
902
|
-
conventionRegression: conventionWarnings.length > 0,
|
|
903
|
-
});
|
|
904
|
-
}
|
|
905
|
-
validationReportGate = await readApprovedValidationReportGate(specId, projectId, false);
|
|
906
|
-
if (!validationReportGate.ok) {
|
|
907
|
-
return validationReportGate.error;
|
|
908
|
-
}
|
|
909
|
-
if (validationReportGate.score !== null) {
|
|
910
|
-
validateScore = validationReportGate.score;
|
|
911
|
-
validateScoreSource = 'validation-report';
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
939
|
// SPEC-731: dry_run short-circuit — all gates have been evaluated above.
|
|
915
940
|
// Do NOT call transitionSpec, appendTransitionEvent, or acquire any lock.
|
|
916
941
|
if (isDryRun) {
|
|
917
942
|
const dryRunGates = {
|
|
918
943
|
dod: newStatus === 'done' ? (doneGatesResult?.blocked ? 'fail' : 'pass') : 'skip',
|
|
919
|
-
validate: newStatus === 'done'
|
|
920
|
-
|
|
921
|
-
? 'skip'
|
|
922
|
-
: 'pass' // blocked case already returned above (line 615)
|
|
923
|
-
: 'skip',
|
|
924
|
-
qa: newStatus === 'done' ? 'pass' : 'skip', // QA gate runs above — if we reach here, it passed
|
|
944
|
+
validate: newStatus === 'done' ? 'pass' : 'skip',
|
|
945
|
+
qa: newStatus === 'done' ? 'pass' : 'skip',
|
|
925
946
|
security: newStatus === 'done' ? (doneGatesResult?.blocked ? 'fail' : 'pass') : 'skip',
|
|
926
947
|
lock: 'available',
|
|
927
948
|
compliance: complianceGateResult === null
|
|
@@ -952,11 +973,15 @@ export async function handleUpdateStatus(params, server) {
|
|
|
952
973
|
const resolvedActuals = actuals;
|
|
953
974
|
// Run only fast, read-only transition checks before persistence.
|
|
954
975
|
const implActions = newStatus === 'implementing'
|
|
955
|
-
? await runImplementingActions(projectId, specId, {
|
|
976
|
+
? await runImplementingActions(projectId, specId, {
|
|
977
|
+
deferSideEffects: true,
|
|
978
|
+
projectPath: effectiveGatePath,
|
|
979
|
+
})
|
|
956
980
|
: null;
|
|
957
981
|
const doneActions = newStatus === 'done'
|
|
958
982
|
? await runDoneActions(projectId, specId, spec.gitBranch, {
|
|
959
983
|
deferSideEffects: true,
|
|
984
|
+
projectPath: effectiveGatePath,
|
|
960
985
|
})
|
|
961
986
|
: null;
|
|
962
987
|
const trigger = reverseTransition
|
|
@@ -987,39 +1012,7 @@ export async function handleUpdateStatus(params, server) {
|
|
|
987
1012
|
if (resolvedActuals) {
|
|
988
1013
|
nonStatusUpdates.actuals = resolvedActuals;
|
|
989
1014
|
}
|
|
990
|
-
|
|
991
|
-
let forceStatusAuditId = null;
|
|
992
|
-
if (newStatus === 'done' && forcedValidateBypass !== null) {
|
|
993
|
-
try {
|
|
994
|
-
const auditId = uuid();
|
|
995
|
-
const prevHash = getLastHash();
|
|
996
|
-
// Hash this entry minimally — full chain hashing is handled by the audit engine on export
|
|
997
|
-
const entry = {
|
|
998
|
-
id: auditId,
|
|
999
|
-
timestamp: new Date().toISOString(),
|
|
1000
|
-
toolName: 'update_status',
|
|
1001
|
-
inputSummary: `validate_gate_forced_bypass specId=${specId} score=${String(forcedValidateBypass.observedScore)} reason="${forcedValidateBypass.reason.slice(0, 80)}"`,
|
|
1002
|
-
outputType: 'success',
|
|
1003
|
-
durationMs: 0,
|
|
1004
|
-
specId,
|
|
1005
|
-
projectPath: effectiveGatePath ?? undefined,
|
|
1006
|
-
prevHash,
|
|
1007
|
-
hash: '',
|
|
1008
|
-
event: 'validate_gate_forced_bypass',
|
|
1009
|
-
details: {
|
|
1010
|
-
reason: forcedValidateBypass.reason,
|
|
1011
|
-
observedScore: forcedValidateBypass.observedScore,
|
|
1012
|
-
fromStatus: originalStatus,
|
|
1013
|
-
toStatus: newStatus,
|
|
1014
|
-
},
|
|
1015
|
-
};
|
|
1016
|
-
appendEntry(entry);
|
|
1017
|
-
forceStatusAuditId = auditId;
|
|
1018
|
-
}
|
|
1019
|
-
catch {
|
|
1020
|
-
/* best-effort — audit must never block transition */
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1015
|
+
const forceStatusAuditId = null;
|
|
1023
1016
|
// SPEC-780: Audit-trail entry when forceApprove bypassed readiness/format gates
|
|
1024
1017
|
let forceApproveAuditId = null;
|
|
1025
1018
|
if (newStatus === 'approved' && params.forceApprove) {
|
|
@@ -1042,7 +1035,7 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1042
1035
|
outputType: 'success',
|
|
1043
1036
|
durationMs: 0,
|
|
1044
1037
|
specId,
|
|
1045
|
-
projectPath: effectiveGatePath
|
|
1038
|
+
projectPath: effectiveGatePath,
|
|
1046
1039
|
prevHash,
|
|
1047
1040
|
hash: '',
|
|
1048
1041
|
event: 'approve_gate_forced_bypass',
|
|
@@ -1059,8 +1052,9 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1059
1052
|
appendEntry(entry);
|
|
1060
1053
|
forceApproveAuditId = auditId;
|
|
1061
1054
|
}
|
|
1062
|
-
catch {
|
|
1063
|
-
/*
|
|
1055
|
+
catch (error) {
|
|
1056
|
+
/* reliability-optional: FORCE_APPROVAL_AUDIT — transition receipt remains authoritative */
|
|
1057
|
+
reportClassifiedDegradation('FORCE_APPROVAL_AUDIT', error);
|
|
1064
1058
|
}
|
|
1065
1059
|
}
|
|
1066
1060
|
}
|
|
@@ -1078,7 +1072,7 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1078
1072
|
outputType: 'success',
|
|
1079
1073
|
durationMs: 0,
|
|
1080
1074
|
specId,
|
|
1081
|
-
projectPath: effectiveGatePath
|
|
1075
|
+
projectPath: effectiveGatePath,
|
|
1082
1076
|
prevHash,
|
|
1083
1077
|
hash: '',
|
|
1084
1078
|
event: 'sdd_model_routing_forced_bypass',
|
|
@@ -1093,8 +1087,9 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1093
1087
|
appendEntry(entry);
|
|
1094
1088
|
sddRoutingAuditId = auditId;
|
|
1095
1089
|
}
|
|
1096
|
-
catch {
|
|
1097
|
-
/*
|
|
1090
|
+
catch (error) {
|
|
1091
|
+
/* reliability-optional: SDD_ROUTING_AUDIT — transition receipt remains authoritative */
|
|
1092
|
+
reportClassifiedDegradation('SDD_ROUTING_AUDIT', error);
|
|
1098
1093
|
}
|
|
1099
1094
|
}
|
|
1100
1095
|
// SPEC-969: Track forceStatus / forceApprove usage
|
|
@@ -1115,8 +1110,9 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1115
1110
|
`Consider re-running validate within 24h.`;
|
|
1116
1111
|
}
|
|
1117
1112
|
}
|
|
1118
|
-
catch {
|
|
1119
|
-
/*
|
|
1113
|
+
catch (error) {
|
|
1114
|
+
/* reliability-optional: BYPASS_ANALYTICS — lifecycle gates remain authoritative */
|
|
1115
|
+
reportClassifiedDegradation('BYPASS_ANALYTICS', error);
|
|
1120
1116
|
}
|
|
1121
1117
|
}
|
|
1122
1118
|
const versionSnapshotTag = newStatus === 'approved'
|
|
@@ -1133,45 +1129,43 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1133
1129
|
hasProjectPath: Boolean(effectiveGatePath),
|
|
1134
1130
|
shouldAutoStage,
|
|
1135
1131
|
});
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1132
|
+
const transitionRootBinding = plannedBackgroundActions.length > 0 && effectiveGatePath
|
|
1133
|
+
? computeTransitionRootBinding(effectiveGatePath)
|
|
1134
|
+
: undefined;
|
|
1135
|
+
const qualityWarningsToWrite = newStatus === 'approved'
|
|
1136
|
+
? [...readinessGate.qualityWarnings, ...formatGate.qualityWarnings]
|
|
1137
|
+
: [];
|
|
1138
|
+
const persistence = await commitTransitionWithNarrowLock({
|
|
1139
|
+
projectPath: effectiveGatePath ?? projectId,
|
|
1140
|
+
projectId,
|
|
1141
|
+
specId,
|
|
1142
|
+
newStatus,
|
|
1143
|
+
originalStatus,
|
|
1145
1144
|
expectedSpec: spec,
|
|
1145
|
+
qualityWarnings: qualityWarningsToWrite,
|
|
1146
|
+
options: {
|
|
1147
|
+
trigger: trigger,
|
|
1148
|
+
actor,
|
|
1149
|
+
viaSync,
|
|
1150
|
+
reason: params.reason,
|
|
1151
|
+
updates: nonStatusUpdates,
|
|
1152
|
+
pendingBackgroundActions: plannedBackgroundActions,
|
|
1153
|
+
transitionRootBinding,
|
|
1154
|
+
expectedSpec: spec,
|
|
1155
|
+
},
|
|
1156
|
+
...(doneFreshnessLease ? { freshnessLease: doneFreshnessLease } : {}),
|
|
1146
1157
|
});
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
if (syncResult.warning) {
|
|
1150
|
-
try {
|
|
1151
|
-
await rollbackTransitionSpec(transitionRecord);
|
|
1152
|
-
return buildPersistenceFailureResponse({
|
|
1153
|
-
specId,
|
|
1154
|
-
previousStatus: originalStatus,
|
|
1155
|
-
newStatus,
|
|
1156
|
-
reason: syncResult.warning.reason,
|
|
1157
|
-
recoveryRequired: false,
|
|
1158
|
-
});
|
|
1159
|
-
}
|
|
1160
|
-
catch (rollbackError) {
|
|
1161
|
-
return buildPersistenceFailureResponse({
|
|
1162
|
-
specId,
|
|
1163
|
-
previousStatus: originalStatus,
|
|
1164
|
-
newStatus,
|
|
1165
|
-
reason: `${syncResult.warning.reason}; compensation failed: ` +
|
|
1166
|
-
(rollbackError instanceof Error ? rollbackError.message : String(rollbackError)),
|
|
1167
|
-
recoveryRequired: true,
|
|
1168
|
-
});
|
|
1169
|
-
}
|
|
1158
|
+
if (!persistence.ok) {
|
|
1159
|
+
return persistence.error;
|
|
1170
1160
|
}
|
|
1161
|
+
const { transitionRecord, updatedSpec } = persistence;
|
|
1171
1162
|
const frontmatterSyncWarnings = [];
|
|
1172
1163
|
const transitionId = transitionRecord.transitionId;
|
|
1173
1164
|
const committedAt = transitionRecord.timestamp;
|
|
1174
|
-
|
|
1165
|
+
if (newStatus === 'done') {
|
|
1166
|
+
await runTransitionMaintenance(transitionProjectPath);
|
|
1167
|
+
}
|
|
1168
|
+
await appendTransitionEvent({
|
|
1175
1169
|
projectId,
|
|
1176
1170
|
specId,
|
|
1177
1171
|
eventType: 'transition',
|
|
@@ -1183,11 +1177,12 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1183
1177
|
modelId: params.modelId,
|
|
1184
1178
|
gateResults: sddRoutingGate.gateResults,
|
|
1185
1179
|
meta: { ...transitionEvidenceMeta, transitionId, committedAt },
|
|
1186
|
-
}).catch(() => {
|
|
1187
|
-
/*
|
|
1180
|
+
}).catch((error) => {
|
|
1181
|
+
/* reliability-optional: SDD_ROUTING_REPORT — never block committed acknowledgement */
|
|
1182
|
+
reportClassifiedDegradation('SDD_ROUTING_REPORT', error);
|
|
1188
1183
|
});
|
|
1189
1184
|
if (reverseTransition && params.reason) {
|
|
1190
|
-
|
|
1185
|
+
await appendTransitionEvent({
|
|
1191
1186
|
projectId,
|
|
1192
1187
|
specId,
|
|
1193
1188
|
eventType: 'reopen',
|
|
@@ -1197,42 +1192,10 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1197
1192
|
reason: params.reason,
|
|
1198
1193
|
meta: { transitionId, committedAt },
|
|
1199
1194
|
}).catch((err) => {
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
error: err instanceof Error ? err.message : String(err),
|
|
1203
|
-
});
|
|
1195
|
+
/* reliability-optional: REOPEN_EVENT_APPEND — transition receipt remains authoritative */
|
|
1196
|
+
reportClassifiedDegradation('REOPEN_EVENT_APPEND', err);
|
|
1204
1197
|
});
|
|
1205
1198
|
}
|
|
1206
|
-
// SPEC-1044: Keep the reconstructible context packet fresh on every phase change.
|
|
1207
|
-
if (effectiveGatePath) {
|
|
1208
|
-
void import('../../engine/session-context-generator.js')
|
|
1209
|
-
.then(({ generateSessionContext }) => generateSessionContext(effectiveGatePath, projectId))
|
|
1210
|
-
.catch(() => {
|
|
1211
|
-
/* best-effort — context gate blocks later phases if this cannot be reconstructed */
|
|
1212
|
-
});
|
|
1213
|
-
}
|
|
1214
|
-
// SPEC-769/SPEC-780: Write qualityWarnings to spec.md frontmatter when force-approved (best-effort)
|
|
1215
|
-
const qualityWarningsToWrite = [
|
|
1216
|
-
...readinessGate.qualityWarnings,
|
|
1217
|
-
...formatGate.qualityWarnings,
|
|
1218
|
-
];
|
|
1219
|
-
const specPathForWarnings = updatedSpec.specPath;
|
|
1220
|
-
if (newStatus === 'approved' &&
|
|
1221
|
-
qualityWarningsToWrite.length > 0 &&
|
|
1222
|
-
specPathForWarnings) {
|
|
1223
|
-
void (async () => {
|
|
1224
|
-
try {
|
|
1225
|
-
const { readFile: fsReadFile } = await import('node:fs/promises');
|
|
1226
|
-
const content = await fsReadFile(specPathForWarnings, 'utf-8');
|
|
1227
|
-
const warningsJson = JSON.stringify(qualityWarningsToWrite);
|
|
1228
|
-
const updated = updateFrontmatterField(content, 'qualityWarnings', warningsJson);
|
|
1229
|
-
await atomicWriteFile(specPathForWarnings, updated);
|
|
1230
|
-
}
|
|
1231
|
-
catch {
|
|
1232
|
-
// best-effort — never blocks the transition
|
|
1233
|
-
}
|
|
1234
|
-
})();
|
|
1235
|
-
}
|
|
1236
1199
|
// SPEC-723: Record terminal transition in hash-chained log (best-effort, fire-and-forget)
|
|
1237
1200
|
// SPEC-734: Thread enriched payload — sessionId, modelId, gateResults
|
|
1238
1201
|
if (newStatus === 'done' || newStatus === 'discarded') {
|
|
@@ -1240,10 +1203,7 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1240
1203
|
const terminalGateResults = {};
|
|
1241
1204
|
if (newStatus === 'done') {
|
|
1242
1205
|
Object.assign(terminalGateResults, sddRoutingGate.gateResults);
|
|
1243
|
-
|
|
1244
|
-
// At this point blocked === false (we returned earlier if blocked was true)
|
|
1245
|
-
terminalGateResults.validate = validateGateResult.forced ? 'forced' : 'pass';
|
|
1246
|
-
}
|
|
1206
|
+
terminalGateResults.validate = 'pass';
|
|
1247
1207
|
if (complianceGateResult !== null) {
|
|
1248
1208
|
terminalGateResults.compliance = complianceGateResult.skipped
|
|
1249
1209
|
? 'skip'
|
|
@@ -1251,15 +1211,8 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1251
1211
|
? 'fail'
|
|
1252
1212
|
: 'pass';
|
|
1253
1213
|
}
|
|
1254
|
-
if (crashRisksReport !== null) {
|
|
1255
|
-
terminalGateResults['crash-shield'] =
|
|
1256
|
-
crashRisksReport.score >= 80 ? 'pass' : 'fail';
|
|
1257
|
-
}
|
|
1258
|
-
else if (crashShieldSkipReason) {
|
|
1259
|
-
terminalGateResults['crash-shield'] = 'skip';
|
|
1260
|
-
}
|
|
1261
1214
|
}
|
|
1262
|
-
|
|
1215
|
+
await recordTerminalTransitionEvent({
|
|
1263
1216
|
projectId,
|
|
1264
1217
|
specId,
|
|
1265
1218
|
specPath: updatedSpec.specPath,
|
|
@@ -1272,8 +1225,10 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1272
1225
|
modelId: params.modelId,
|
|
1273
1226
|
gateResults: Object.keys(terminalGateResults).length > 0 ? terminalGateResults : undefined,
|
|
1274
1227
|
meta: transitionEvidenceMeta,
|
|
1275
|
-
|
|
1276
|
-
|
|
1228
|
+
projectPath: effectiveGatePath,
|
|
1229
|
+
}).catch((error) => {
|
|
1230
|
+
/* reliability-optional: TERMINAL_VALIDATION_REPORT — canonical receipt is authoritative */
|
|
1231
|
+
reportClassifiedDegradation('TERMINAL_VALIDATION_REPORT', error);
|
|
1277
1232
|
});
|
|
1278
1233
|
}
|
|
1279
1234
|
const allSpecs = await specStore.listSpecs(projectId);
|
|
@@ -1301,15 +1256,6 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1301
1256
|
// SPEC-469: Collect autopilot summary for done-transition side effects
|
|
1302
1257
|
const collector = new AutopilotSummaryCollector();
|
|
1303
1258
|
if (newStatus === 'done') {
|
|
1304
|
-
if (validateScore !== null) {
|
|
1305
|
-
collector.pushOk('validate', `Validate score: ${String(validateScore)}/100`);
|
|
1306
|
-
}
|
|
1307
|
-
if (crashShieldWarning) {
|
|
1308
|
-
collector.pushFail('crash-shield', crashShieldWarning);
|
|
1309
|
-
}
|
|
1310
|
-
else if (crashShieldSkipReason) {
|
|
1311
|
-
collector.pushOk('crash-shield', `scan_crash_risks: skipped (${crashShieldSkipReason})`);
|
|
1312
|
-
}
|
|
1313
1259
|
if (doneActions?.mergeWarning) {
|
|
1314
1260
|
collector.pushFail('merge-check', doneActions.mergeWarning);
|
|
1315
1261
|
}
|
|
@@ -1392,26 +1338,12 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1392
1338
|
...(collector.hasEntries() ? { autopilotSummary: collector.getMessages() } : {}),
|
|
1393
1339
|
});
|
|
1394
1340
|
// SPEC-772 Scenario 4: surface validate failure from cascade as explicit warning
|
|
1395
|
-
const autopilotValidateWarning = validateScore !== null && validateScore < 100
|
|
1396
|
-
? `Validate score ${String(validateScore)}/100 — below threshold. Check workspace_alerts for cascade details.`
|
|
1397
|
-
: null;
|
|
1398
|
-
if (autopilotValidateWarning) {
|
|
1399
|
-
result.autopilotValidateWarning = autopilotValidateWarning;
|
|
1400
|
-
}
|
|
1401
1341
|
// SPEC-754: Append shell-hygiene reminder when transitioning to done on claude-code host
|
|
1402
1342
|
const shellHygieneHint = newStatus === 'done' && detectHost() === 'claude-code' ? shellHygieneReminder() : null;
|
|
1403
1343
|
return buildStatusResponse(result, specId, originalStatus, newStatus, null, spec.title, shellHygieneHint);
|
|
1404
1344
|
}
|
|
1405
1345
|
finally {
|
|
1406
|
-
//
|
|
1407
|
-
if (crossProcessLockHandle !== null) {
|
|
1408
|
-
await releaseLock(crossProcessLockHandle).catch((err) => {
|
|
1409
|
-
console.warn('[planu:lock] update_status release error', {
|
|
1410
|
-
specId,
|
|
1411
|
-
error: err instanceof Error ? err.message : String(err),
|
|
1412
|
-
});
|
|
1413
|
-
});
|
|
1414
|
-
}
|
|
1346
|
+
// Expensive gates intentionally execute without a mutation lock.
|
|
1415
1347
|
}
|
|
1416
1348
|
}
|
|
1417
1349
|
catch (error) {
|
|
@@ -1432,7 +1364,15 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1432
1364
|
isError: true,
|
|
1433
1365
|
};
|
|
1434
1366
|
}
|
|
1435
|
-
|
|
1367
|
+
finally {
|
|
1368
|
+
if (doneFreshnessLease) {
|
|
1369
|
+
await closeValidationFreshnessLease(doneFreshnessLease).catch((error) => {
|
|
1370
|
+
/* reliability-cleanup: freshness expiry remains the recovery boundary */
|
|
1371
|
+
reportClassifiedDegradation('VALIDATION_FRESHNESS_CHECK_FAILED', error);
|
|
1372
|
+
});
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
})();
|
|
1436
1376
|
}); // end trackCost
|
|
1437
1377
|
}
|
|
1438
1378
|
//# sourceMappingURL=index.js.map
|