@planu/cli 4.13.0 → 4.14.1
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 +29 -0
- package/README.md +24 -24
- 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 -1
- package/dist/cli/commands/install.js +145 -43
- package/dist/cli/commands/job.d.ts +3 -0
- package/dist/cli/commands/job.js +119 -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 -1
- package/dist/config/crash-shield-framework-rules.json +93 -0
- package/dist/config/environment-schema.json +149 -0
- package/dist/config/hardcode-exceptions.json +4 -0
- package/dist/config/license-plans.json +7 -0
- package/dist/config/native-release-public-key.pem +3 -0
- package/dist/config/native-targets.json +87 -0
- package/dist/config/product-public.d.ts +89 -0
- package/dist/config/product-public.js +140 -0
- package/dist/config/product-public.json +312 -0
- package/dist/config/product-public.ts +148 -0
- package/dist/config/release-compatibility.json +13 -0
- package/dist/config/release-policy.json +26 -0
- package/dist/config/runtime-policy.json +44 -0
- 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/config/version.ts +10 -7
- package/dist/engine/abortable-process-runner.js +40 -9
- 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/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/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/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/ci-generator/context-builders.js +7 -5
- package/dist/engine/ci-generator/stack-detector.js +0 -2
- package/dist/engine/ci-generator/yaml-builder.js +0 -2
- package/dist/engine/claude-config-auditor/rules-auditor.js +4 -3
- 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 +9 -9
- package/dist/engine/core-bridge.js +196 -283
- 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/dashboard/data-loader.js +2 -1
- 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/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 +6 -0
- package/dist/engine/evidence-gates/artifact-reader.js +105 -21
- package/dist/engine/evidence-gates/lifecycle-gate.d.ts +2 -1
- package/dist/engine/evidence-gates/lifecycle-gate.js +54 -0
- package/dist/engine/execution/context.d.ts +19 -0
- package/dist/engine/execution/context.js +127 -0
- package/dist/engine/execution/deadline-io.d.ts +21 -0
- package/dist/engine/execution/deadline-io.js +45 -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 +78 -0
- package/dist/engine/execution/job-runtime.js +220 -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/validate-job-executor.d.ts +24 -0
- package/dist/engine/execution/validate-job-executor.js +342 -0
- package/dist/engine/execution/validate-job-payload.d.ts +5 -0
- package/dist/engine/execution/validate-job-payload.js +87 -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 +5 -0
- package/dist/engine/execution/validate-worker-runtime.js +100 -0
- package/dist/engine/execution/validate-worker-thread.d.ts +2 -0
- package/dist/engine/execution/validate-worker-thread.js +71 -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 +4 -0
- package/dist/engine/handoff-artifacts/schemas.js +5 -0
- 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/file-watcher.js +1 -14
- package/dist/engine/hooks-reconciler.js +6 -4
- 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/local-first/storage-advisor.js +5 -6
- package/dist/engine/macos-keychain-native-port.d.ts +5 -0
- package/dist/engine/macos-keychain-native-port.js +26 -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/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 +174 -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/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 +7 -0
- package/dist/engine/runtime-policy.js +101 -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/safety/atomic-write-file.js +20 -9
- package/dist/engine/safety/atomic-writer.js +10 -3
- 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/security-analyzer/criteria-generator.js +2 -3
- package/dist/engine/self-healing/healer.js +4 -4
- package/dist/engine/session-safeguard/learnings-buffer.d.ts +1 -2
- package/dist/engine/session-safeguard/learnings-buffer.js +42 -65
- 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-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/drift-detector.js +5 -13
- package/dist/engine/spec-migrator/filesystem-import.js +14 -10
- 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-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/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 +5 -14
- 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 +45 -29
- 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/timing/budget.d.ts +6 -17
- package/dist/engine/timing/budget.js +80 -64
- 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/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 +335 -0
- package/dist/engine/validation/validation-freshness.d.ts +36 -0
- package/dist/engine/validation/validation-freshness.js +427 -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 +59 -0
- package/dist/engine/validation/validation-receipt.js +282 -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 +36 -0
- package/dist/engine/validation/validation-submission.js +128 -0
- package/dist/engine/validation-evidence-ledger.js +41 -0
- package/dist/engine/validation-impact-planner.js +25 -9
- package/dist/engine/validator/spec-compliance-runner.d.ts +1 -1
- package/dist/engine/validator/spec-compliance-runner.js +17 -8
- package/dist/engine/validator/validation-report-writer.js +1 -1
- package/dist/engine/validator.js +2 -1
- 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 +21 -6
- package/dist/resources/patterns.js +3 -1
- package/dist/resources/specs.js +3 -1
- package/dist/resources/templates.js +3 -1
- 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 +60 -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 +58 -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/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 +8 -8
- package/dist/storage/base-store.js +57 -20
- 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-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/ideas-store.js +2 -2
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.js +5 -0
- package/dist/storage/knowledge-store/knowledge.js +27 -33
- package/dist/storage/lessons-store.js +2 -2
- package/dist/storage/license-store.js +13 -41
- package/dist/storage/migrations/canonical-storage.d.ts +15 -0
- package/dist/storage/migrations/canonical-storage.js +599 -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 +186 -0
- package/dist/storage/runtime-db.js +1054 -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/session-store.js +12 -4
- 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.js +31 -24
- package/dist/storage/status-store/file-lock.js +31 -9
- package/dist/storage/status-store/self-healing.js +10 -5
- package/dist/storage/status-store/version-sync.js +8 -6
- 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/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 +1 -1
- package/dist/tools/auto-update-handler.js +1 -1
- 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/scenarios-desktop.js +8 -3
- package/dist/tools/challenge-spec/scenarios-failure.js +7 -2
- package/dist/tools/challenge-spec/security-challenge-scenarios.js +3 -3
- 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 +11 -11
- 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 -12
- 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.js +385 -520
- 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/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 -73
- package/dist/tools/init-project/host-assets-writer.d.ts +1 -1
- package/dist/tools/init-project/host-assets-writer.js +4 -2
- package/dist/tools/init-project/lifecycle-helpers.js +3 -5
- package/dist/tools/init-project/lint-scaffolder.js +6 -2
- package/dist/tools/init-project/migration-runner.d.ts +10 -1
- package/dist/tools/init-project/migration-runner.js +68 -3
- package/dist/tools/init-project/per-client-files-writer.js +14 -4
- 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 +126 -0
- package/dist/tools/list-specs.js +35 -34
- package/dist/tools/manage-plugins-handler.js +17 -9
- 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/register-sdd-tools.d.ts +1 -1
- package/dist/tools/register-sdd-tools.js +5 -0
- package/dist/tools/register-spec-tools/core-spec-tools.js +31 -0
- 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.js +295 -171
- package/dist/tools/schema-generator-handler.js +2 -1
- package/dist/tools/schemas/output-schemas.d.ts +88 -82
- package/dist/tools/schemas/output-schemas.js +12 -94
- 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/validate-output-schema.d.ts +256 -0
- package/dist/tools/schemas/validate-output-schema.js +212 -0
- package/dist/tools/sentry-handler.js +6 -1
- package/dist/tools/skill-bootstrap-handler.js +7 -4
- 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/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-registry/core-tools.js +131 -0
- package/dist/tools/tool-registry/group-infra.js +10 -12
- package/dist/tools/tool-registry/group-quality-compliance.js +5 -12
- package/dist/tools/update-status/approval-gates.d.ts +13 -0
- package/dist/tools/update-status/approval-gates.js +81 -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 +145 -0
- package/dist/tools/update-status/evidence-gate.js +154 -2
- package/dist/tools/update-status/file-sync.js +23 -12
- 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.js +228 -325
- 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/side-effects.js +30 -37
- package/dist/tools/update-status/transition-guard.d.ts +4 -2
- package/dist/tools/update-status/transition-guard.js +57 -10
- package/dist/tools/update-status-convention-gate.js +24 -23
- package/dist/tools/update-status-reconcile.js +2 -2
- package/dist/tools/validate-api-contract-handler.js +3 -3
- package/dist/tools/validate-lint.js +20 -13
- package/dist/tools/validate.d.ts +3 -1
- package/dist/tools/validate.js +213 -5
- package/dist/transports/http-transport.js +84 -61
- package/dist/transports/middleware/with-telemetry.js +3 -2
- 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/ci.js +0 -2
- package/dist/types/core-bridge.d.ts +78 -1
- package/dist/types/crash-shield-framework-rules.d.ts +24 -0
- package/dist/types/crash-shield-framework-rules.js +2 -0
- package/dist/types/data-gc.d.ts +16 -0
- package/dist/types/deploy.js +0 -2
- package/dist/types/durable-job.d.ts +78 -0
- package/dist/types/durable-job.js +2 -0
- package/dist/types/durable-validation.d.ts +60 -0
- package/dist/types/durable-validation.js +2 -0
- package/dist/types/estimation.d.ts +2 -0
- package/dist/types/evidence-gates.d.ts +9 -1
- package/dist/types/execution.d.ts +43 -0
- package/dist/types/handoff-artifacts.d.ts +2 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/infrastructure.js +0 -2
- 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/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 +40 -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/skill-registry.js +0 -2
- package/dist/types/spec/inputs.d.ts +2 -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 +3 -3
- package/dist/types/transport.d.ts +2 -0
- package/dist/types/validate-worker.d.ts +44 -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/package.json +31 -20
- package/planu-native.json +1 -1
- package/planu-plugin.json +1 -1
- package/dist/engine/telemetry/geo-resolver.d.ts +0 -9
- package/dist/engine/telemetry/geo-resolver.js +0 -43
- package/dist/storage/data-dir-discovery.d.ts +0 -31
- package/dist/storage/data-dir-discovery.js +0 -140
- package/dist/storage/migrations/cwd-to-absolute.d.ts +0 -25
- package/dist/storage/migrations/cwd-to-absolute.js +0 -281
- 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/init-project/ancestor-data-detector.d.ts +0 -22
- package/dist/tools/init-project/ancestor-data-detector.js +0 -81
- 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/types/migration/cwd-to-absolute.d.ts +0 -8
- package/dist/types/migration/cwd-to-absolute.js +0 -3
|
@@ -2,22 +2,22 @@ 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';
|
|
@@ -28,10 +28,7 @@ import { recordForceUsage } from '../../storage/force-analytics-store.js';
|
|
|
28
28
|
import { maybeSafePushOnDone, queuePostCommitTasks, runCascadeForResponse, } from './side-effects.js';
|
|
29
29
|
import { formatKeyValue } from '../output-formatter.js';
|
|
30
30
|
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';
|
|
31
|
+
import { join } from 'node:path';
|
|
35
32
|
import { trackCost } from '../../engine/cost-tracking/operation-tracker.js';
|
|
36
33
|
import { resolveProjectIdOrAutoDetect } from '../resolve-project-id.js';
|
|
37
34
|
import { withToolTimeout } from '../safe-handler.js';
|
|
@@ -39,7 +36,10 @@ import { detectHost } from '../../engine/host-detection/detect-host.js';
|
|
|
39
36
|
import { shellHygieneReminder } from '../../hosts/claude-code/coach.js';
|
|
40
37
|
import { buildTransitionEvidenceMeta, checkSddModelRoutingGate, } from '../../engine/sdd-model-routing.js';
|
|
41
38
|
import { acquireLock, releaseLock, isLocked as isCrossProcessLocked, LockBusyError, } from '../../engine/safety/cross-process-lock.js';
|
|
42
|
-
import {
|
|
39
|
+
import { projectDataDir } from '../../storage/base-store.js';
|
|
40
|
+
import { assertExecutionCanCommit } from '../../engine/execution/context.js';
|
|
41
|
+
import { shouldSkipGateForExplicitLegacyHarness } from './gate-harness.js';
|
|
42
|
+
import { assertValidationFreshnessBarrier, } from '../../engine/validation/validation-freshness.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) {
|
|
@@ -361,7 +360,10 @@ async function recoverPendingPostCommitTasks(projectId, projectPath) {
|
|
|
361
360
|
}
|
|
362
361
|
}
|
|
363
362
|
finally {
|
|
364
|
-
await releaseLock(recoveryLock).catch(() =>
|
|
363
|
+
await releaseLock(recoveryLock).catch((error) => {
|
|
364
|
+
/* reliability-cleanup: RECOVERY_LOCK_RELEASE — lease expiry remains the recovery boundary */
|
|
365
|
+
reportClassifiedDegradation('RECOVERY_LOCK_RELEASE', error);
|
|
366
|
+
});
|
|
365
367
|
}
|
|
366
368
|
}
|
|
367
369
|
}
|
|
@@ -405,15 +407,106 @@ function buildPersistenceFailureResponse(args) {
|
|
|
405
407
|
},
|
|
406
408
|
};
|
|
407
409
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
410
|
+
async function commitTransitionWithNarrowLock(args) {
|
|
411
|
+
return withApprovalSpecLock(args.projectPath, args.specId, async () => {
|
|
412
|
+
const lock = await acquireLock(args.projectPath, args.specId, {
|
|
413
|
+
reason: `update_status(${args.newStatus}) commit`,
|
|
414
|
+
});
|
|
415
|
+
if (lock === null) {
|
|
416
|
+
return {
|
|
417
|
+
ok: false,
|
|
418
|
+
error: {
|
|
419
|
+
content: [
|
|
420
|
+
{
|
|
421
|
+
type: 'text',
|
|
422
|
+
text: `Spec ${args.specId} is locked by another process (cross-process lock). Retry later.`,
|
|
423
|
+
},
|
|
424
|
+
],
|
|
425
|
+
isError: true,
|
|
426
|
+
},
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
try {
|
|
430
|
+
const freshSpec = typeof specStore.getSpecFresh === 'function'
|
|
431
|
+
? await specStore.getSpecFresh(args.projectId, args.specId)
|
|
432
|
+
: await specStore.getSpec(args.projectId, args.specId);
|
|
433
|
+
if (freshSpec?.status !== args.expectedSpec.status ||
|
|
434
|
+
freshSpec.updatedAt !== args.expectedSpec.updatedAt) {
|
|
435
|
+
return {
|
|
436
|
+
ok: false,
|
|
437
|
+
error: {
|
|
438
|
+
content: [
|
|
439
|
+
{
|
|
440
|
+
type: 'text',
|
|
441
|
+
text: `Spec ${args.specId} changed while lifecycle gates were running. Retry with the fresh state.`,
|
|
442
|
+
},
|
|
443
|
+
],
|
|
444
|
+
isError: true,
|
|
445
|
+
structuredContent: { error: 'TRANSITION_CONFLICT', code: 409 },
|
|
446
|
+
},
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
if (args.newStatus === 'done' &&
|
|
450
|
+
(!args.freshnessLease || !(await assertValidationFreshnessBarrier(args.freshnessLease))) &&
|
|
451
|
+
!shouldSkipGateForExplicitLegacyHarness('evidence')) {
|
|
452
|
+
return {
|
|
453
|
+
ok: false,
|
|
454
|
+
error: {
|
|
455
|
+
content: [
|
|
456
|
+
{
|
|
457
|
+
type: 'text',
|
|
458
|
+
text: `Validation inputs for ${args.specId} changed before commit. Re-run validate.`,
|
|
459
|
+
},
|
|
460
|
+
],
|
|
461
|
+
isError: true,
|
|
462
|
+
structuredContent: { error: 'VALIDATION_RECEIPT_STALE', code: 409 },
|
|
463
|
+
},
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
assertExecutionCanCommit();
|
|
467
|
+
const transitionRecord = await transitionSpec(args.projectId, args.specId, args.newStatus, {
|
|
468
|
+
...args.options,
|
|
469
|
+
expectedSpec: freshSpec,
|
|
470
|
+
});
|
|
471
|
+
const updatedSpec = transitionRecord.spec;
|
|
472
|
+
const syncResult = await syncSpecFiles(updatedSpec, args.originalStatus, args.newStatus, args.projectPath);
|
|
473
|
+
if (!syncResult.warning) {
|
|
474
|
+
return { ok: true, transitionRecord, updatedSpec };
|
|
475
|
+
}
|
|
476
|
+
try {
|
|
477
|
+
await rollbackTransitionSpec(transitionRecord);
|
|
478
|
+
return {
|
|
479
|
+
ok: false,
|
|
480
|
+
error: buildPersistenceFailureResponse({
|
|
481
|
+
specId: args.specId,
|
|
482
|
+
previousStatus: args.originalStatus,
|
|
483
|
+
newStatus: args.newStatus,
|
|
484
|
+
reason: syncResult.warning.reason,
|
|
485
|
+
recoveryRequired: false,
|
|
486
|
+
}),
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
catch (rollbackError) {
|
|
490
|
+
return {
|
|
491
|
+
ok: false,
|
|
492
|
+
error: buildPersistenceFailureResponse({
|
|
493
|
+
specId: args.specId,
|
|
494
|
+
previousStatus: args.originalStatus,
|
|
495
|
+
newStatus: args.newStatus,
|
|
496
|
+
reason: `${syncResult.warning.reason}; compensation failed: ` +
|
|
497
|
+
(rollbackError instanceof Error ? rollbackError.message : String(rollbackError)),
|
|
498
|
+
recoveryRequired: true,
|
|
499
|
+
}),
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
finally {
|
|
504
|
+
await releaseLock(lock).catch((error) => {
|
|
505
|
+
/* reliability-cleanup: UPDATE_STATUS_LOCK_RELEASE — lease expiry remains the recovery boundary */
|
|
506
|
+
reportClassifiedDegradation('UPDATE_STATUS_LOCK_RELEASE', error);
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
});
|
|
417
510
|
}
|
|
418
511
|
/** Build fallback interactiveQuestion for status confirmation (SPEC-595). */
|
|
419
512
|
function buildStatusConfirmFallback(specId, newStatus) {
|
|
@@ -468,20 +561,15 @@ async function resolveOrchestrationPlan(newStatus, specScope, specId, projectPat
|
|
|
468
561
|
}
|
|
469
562
|
return withToolTimeout(import('../orchestrate-agents-handler.js')
|
|
470
563
|
.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';
|
|
564
|
+
.catch((error) => {
|
|
565
|
+
// reliability-optional: ORCHESTRATION_PLAN_SUMMARY — summary enrichment is non-authoritative
|
|
566
|
+
reportClassifiedDegradation('ORCHESTRATION_PLAN_SUMMARY', error);
|
|
567
|
+
return null;
|
|
568
|
+
}), 5_000, null);
|
|
481
569
|
}
|
|
482
570
|
/* eslint-disable complexity, max-lines-per-function */
|
|
483
571
|
export async function handleUpdateStatus(params, server) {
|
|
484
|
-
return trackCost(params.projectPath ?? '', 'update_status', async () => {
|
|
572
|
+
return trackCost(params.projectPath?.trim() ?? '', 'update_status', async () => {
|
|
485
573
|
const { specId, status: newStatus, actuals, reviewNotes } = params;
|
|
486
574
|
// SPEC-509: auto-detect project from git root when projectPath/projectId are omitted
|
|
487
575
|
const resolved = await resolveProjectIdOrAutoDetect({
|
|
@@ -498,50 +586,33 @@ export async function handleUpdateStatus(params, server) {
|
|
|
498
586
|
const { runStrictPlanuCleanup } = await import('../../engine/spec-migrator/index.js');
|
|
499
587
|
await runStrictPlanuCleanup(effectiveProjectPath);
|
|
500
588
|
}
|
|
501
|
-
catch {
|
|
502
|
-
/*
|
|
589
|
+
catch (error) {
|
|
590
|
+
/* reliability-cleanup: PRE_TRANSITION_STRICT_CLEANUP — validate remains fail-closed */
|
|
591
|
+
reportClassifiedDegradation('PRE_TRANSITION_STRICT_CLEANUP', error);
|
|
503
592
|
}
|
|
504
593
|
}
|
|
505
594
|
await recoverPendingPostCommitTasks(projectId, effectiveProjectPath).catch((error) => {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
error: error instanceof Error ? error.message : String(error),
|
|
509
|
-
});
|
|
595
|
+
/* reliability-optional: POST_COMMIT_RECOVERY_SCAN — durable tasks remain retryable */
|
|
596
|
+
reportClassifiedDegradation('POST_COMMIT_RECOVERY_SCAN', error);
|
|
510
597
|
});
|
|
511
|
-
return
|
|
598
|
+
return (async () => {
|
|
512
599
|
try {
|
|
513
600
|
// SPEC-301: Reject status changes when spec is locked by another holder (legacy manual lock)
|
|
514
601
|
const lockError = await checkSpecLockGate(effectiveProjectPath, specId);
|
|
515
602
|
if (lockError) {
|
|
516
603
|
return lockError;
|
|
517
604
|
}
|
|
518
|
-
//
|
|
519
|
-
//
|
|
520
|
-
// Released in finally below. Best-effort when no projectPath is available.
|
|
605
|
+
// Dry-run checks availability without acquiring. Real mutations acquire only
|
|
606
|
+
// around the compare-and-swap plus spec/store commit below.
|
|
521
607
|
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 {
|
|
608
|
+
if (isDryRun) {
|
|
542
609
|
// SPEC-731: dry_run checks lock availability without acquiring it.
|
|
543
610
|
// isLocked returns null when no lockfile exists (available), or a LockInfo when locked.
|
|
544
|
-
const lockInfo = await isCrossProcessLocked(effectiveProjectPath, specId).catch(() =>
|
|
611
|
+
const lockInfo = await isCrossProcessLocked(effectiveProjectPath, specId).catch((error) => {
|
|
612
|
+
// reliability-optional: DRY_RUN_LOCK_PROBE — null conservatively avoids stale lock claims
|
|
613
|
+
reportClassifiedDegradation('DRY_RUN_LOCK_PROBE', error);
|
|
614
|
+
return null;
|
|
615
|
+
});
|
|
545
616
|
const lockIsBusy = lockInfo !== null && !lockInfo.stale;
|
|
546
617
|
if (lockIsBusy) {
|
|
547
618
|
// Lock is busy — return dry_run result indicating this without blocking
|
|
@@ -562,11 +633,9 @@ export async function handleUpdateStatus(params, server) {
|
|
|
562
633
|
}
|
|
563
634
|
}
|
|
564
635
|
try {
|
|
565
|
-
//
|
|
566
|
-
//
|
|
567
|
-
const spec =
|
|
568
|
-
? await specStore.getSpecFresh(projectId, specId)
|
|
569
|
-
: await specStore.getSpec(projectId, specId);
|
|
636
|
+
// Gates consume an unlocked snapshot. Commit revalidates this snapshot
|
|
637
|
+
// under the narrow mutation lock before compare-and-swap.
|
|
638
|
+
const spec = await specStore.getSpec(projectId, specId);
|
|
570
639
|
if (!spec) {
|
|
571
640
|
return {
|
|
572
641
|
content: [{ type: 'text', text: ti('spec.notFound', { id: specId }) }],
|
|
@@ -672,9 +741,12 @@ export async function handleUpdateStatus(params, server) {
|
|
|
672
741
|
}
|
|
673
742
|
// SPEC-728: DepGuard — block 'approved' if spec participates in a dependency cycle
|
|
674
743
|
let depGuardResult = null;
|
|
744
|
+
let allSpecsForDependencyGate = null;
|
|
745
|
+
if (plannedStatuses.includes('approved') || plannedStatuses.includes('implementing')) {
|
|
746
|
+
allSpecsForDependencyGate = await specStore.listSpecs(projectId);
|
|
747
|
+
}
|
|
675
748
|
if (plannedStatuses.includes('approved')) {
|
|
676
|
-
|
|
677
|
-
depGuardResult = checkApprovedDepGate(spec, allSpecsForDepGuard);
|
|
749
|
+
depGuardResult = checkApprovedDepGate(spec, allSpecsForDependencyGate ?? []);
|
|
678
750
|
if (depGuardResult.blocked) {
|
|
679
751
|
return {
|
|
680
752
|
content: [{ type: 'text', text: `DepGuard blocked: ${depGuardResult.narrative}` }],
|
|
@@ -689,6 +761,12 @@ export async function handleUpdateStatus(params, server) {
|
|
|
689
761
|
};
|
|
690
762
|
}
|
|
691
763
|
}
|
|
764
|
+
if (plannedStatuses.includes('implementing')) {
|
|
765
|
+
const dependencyGate = checkImplementationDependencyGate(spec, allSpecsForDependencyGate ?? [], 'implementing');
|
|
766
|
+
if (dependencyGate) {
|
|
767
|
+
return dependencyGate;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
692
770
|
// SPEC-964: Challenge gate — block 'review' if challenge_spec was never run
|
|
693
771
|
const challengeGateStatus = plannedStatuses.includes('review') ? 'review' : newStatus;
|
|
694
772
|
const challengeGate = checkChallengeGate(spec, challengeGateStatus);
|
|
@@ -709,14 +787,14 @@ export async function handleUpdateStatus(params, server) {
|
|
|
709
787
|
// Load knowledge for project path (needed for DoD gates, validate trigger and HTML regen)
|
|
710
788
|
const knowledge = await knowledgeStore.getKnowledge(projectId);
|
|
711
789
|
// Resolve effective project path once — used across all gates below
|
|
712
|
-
const effectiveGatePath = knowledge?.projectPath ??
|
|
790
|
+
const effectiveGatePath = knowledge?.projectPath ?? effectiveProjectPath;
|
|
713
791
|
// SPEC-1044: SDD model-routing + context continuity hard gate.
|
|
714
792
|
const sddRoutingGate = {
|
|
715
793
|
blockResult: null,
|
|
716
794
|
gateResults: { sddModelRouting: 'skip' },
|
|
717
795
|
forcedReasons: [],
|
|
718
796
|
};
|
|
719
|
-
if (!
|
|
797
|
+
if (!shouldSkipGateForExplicitLegacyHarness('routing')) {
|
|
720
798
|
const routedStatuses = plannedStatuses.filter((status) => status === 'approved' || status === 'implementing' || status === 'done');
|
|
721
799
|
for (const status of routedStatuses) {
|
|
722
800
|
const gate = await checkSddModelRoutingGate({
|
|
@@ -737,7 +815,7 @@ export async function handleUpdateStatus(params, server) {
|
|
|
737
815
|
// SPEC-1054: BDD/SDD evidence gates. Non-trivial specs must carry
|
|
738
816
|
// Discovery before approval, task-plan before implementation, and
|
|
739
817
|
// traceability/contract evidence before done.
|
|
740
|
-
if (!
|
|
818
|
+
if (!shouldSkipGateForExplicitLegacyHarness('evidence')) {
|
|
741
819
|
const evidenceStatuses = plannedStatuses.filter((status) => status === 'approved' || status === 'implementing' || status === 'done');
|
|
742
820
|
for (const transition of evidenceStatuses) {
|
|
743
821
|
const evidenceGate = await checkLifecycleEvidenceTransitionGate({
|
|
@@ -757,24 +835,22 @@ export async function handleUpdateStatus(params, server) {
|
|
|
757
835
|
// SPEC-441: Code reality check before transitioning to 'implementing'
|
|
758
836
|
// SPEC-335: DoD + security gates before transitioning to 'done'
|
|
759
837
|
// ---------------------------------------------------------------------------
|
|
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
|
-
// ---------------------------------------------------------------------------
|
|
838
|
+
// `done` consumes the immutable validation receipt below. Validation, QA,
|
|
839
|
+
// security and repository scans belong to the durable validation worker.
|
|
769
840
|
let codeRealityWarning = null;
|
|
770
841
|
let forcedBypassWarning = null;
|
|
842
|
+
let doneFreshnessLease;
|
|
771
843
|
const [codeRealityResult, doneGatesResult] = await Promise.all([
|
|
772
844
|
// Code reality: only relevant for 'implementing'
|
|
773
845
|
newStatus === 'implementing' && !reverseTransition && effectiveGatePath
|
|
774
|
-
? checkCodeReality(effectiveGatePath, spec.title).catch(() =>
|
|
846
|
+
? checkCodeReality(effectiveGatePath, spec.title).catch((error) => {
|
|
847
|
+
// reliability-optional: CODE_REALITY_ENRICHMENT — downstream evidence gates remain binding
|
|
848
|
+
reportClassifiedDegradation('CODE_REALITY_ENRICHMENT', error);
|
|
849
|
+
return null;
|
|
850
|
+
})
|
|
775
851
|
: Promise.resolve(null),
|
|
776
852
|
// Done gates: only relevant for 'done'
|
|
777
|
-
newStatus === 'done'
|
|
853
|
+
newStatus === 'done' && !shouldSkipGateForExplicitLegacyHarness('evidence')
|
|
778
854
|
? checkDoneGates(spec, specId, projectId, effectiveGatePath, params.force, params.forceStatusReason ?? params.reason ?? 'No force reason provided')
|
|
779
855
|
: Promise.resolve(null),
|
|
780
856
|
]);
|
|
@@ -788,89 +864,24 @@ export async function handleUpdateStatus(params, server) {
|
|
|
788
864
|
return doneGatesResult.blocked;
|
|
789
865
|
}
|
|
790
866
|
forcedBypassWarning = doneGatesResult.forcedBypassWarning;
|
|
867
|
+
doneFreshnessLease = doneGatesResult.freshnessLease ?? undefined;
|
|
791
868
|
}
|
|
792
869
|
// ---------------------------------------------------------------------------
|
|
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'
|
|
870
|
+
// Review-only heuristic compliance. `done` must remain an O(1) receipt
|
|
871
|
+
// consumer and therefore must not execute commands or scan the repository.
|
|
798
872
|
// ---------------------------------------------------------------------------
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
let crashShieldSkipReason = null;
|
|
873
|
+
const validateScore = null;
|
|
874
|
+
const validateScoreSource = null;
|
|
875
|
+
const crashShieldWarning = null;
|
|
803
876
|
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
|
-
}
|
|
877
|
+
const complianceResult = plannedStatuses.includes('review')
|
|
878
|
+
? await withToolTimeout(checkComplianceGate(specId, projectId, effectiveGatePath), 9_000, {
|
|
879
|
+
skipped: true,
|
|
880
|
+
blocked: false,
|
|
881
|
+
score: null,
|
|
882
|
+
issues: [],
|
|
883
|
+
})
|
|
884
|
+
: null;
|
|
874
885
|
// Process compliance gate result — may block on 'review'
|
|
875
886
|
if (complianceResult !== null) {
|
|
876
887
|
complianceGateResult = complianceResult;
|
|
@@ -878,10 +889,9 @@ export async function handleUpdateStatus(params, server) {
|
|
|
878
889
|
return buildBlockedByComplianceResponse(specId, complianceResult);
|
|
879
890
|
}
|
|
880
891
|
}
|
|
881
|
-
//
|
|
882
|
-
//
|
|
883
|
-
|
|
884
|
-
const { conventionWarnings, constitutionWarnings, compileWarnings, lintWarnings, testWarnings, } = newStatus === 'done' || plannedStatuses.includes('approved')
|
|
892
|
+
// Approved still needs constitution warnings. Done relies exclusively on
|
|
893
|
+
// the validation receipt and never invokes this legacy command runner.
|
|
894
|
+
const { conventionWarnings, constitutionWarnings, compileWarnings, lintWarnings, testWarnings, } = plannedStatuses.includes('approved')
|
|
885
895
|
? await runComplianceGates(projectId, spec.title, spec.tags, newStatus, specId)
|
|
886
896
|
: {
|
|
887
897
|
conventionWarnings: [],
|
|
@@ -890,38 +900,13 @@ export async function handleUpdateStatus(params, server) {
|
|
|
890
900
|
lintWarnings: [],
|
|
891
901
|
testWarnings: [],
|
|
892
902
|
};
|
|
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
903
|
// SPEC-731: dry_run short-circuit — all gates have been evaluated above.
|
|
915
904
|
// Do NOT call transitionSpec, appendTransitionEvent, or acquire any lock.
|
|
916
905
|
if (isDryRun) {
|
|
917
906
|
const dryRunGates = {
|
|
918
907
|
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
|
|
908
|
+
validate: newStatus === 'done' ? 'pass' : 'skip',
|
|
909
|
+
qa: newStatus === 'done' ? 'pass' : 'skip',
|
|
925
910
|
security: newStatus === 'done' ? (doneGatesResult?.blocked ? 'fail' : 'pass') : 'skip',
|
|
926
911
|
lock: 'available',
|
|
927
912
|
compliance: complianceGateResult === null
|
|
@@ -987,39 +972,7 @@ export async function handleUpdateStatus(params, server) {
|
|
|
987
972
|
if (resolvedActuals) {
|
|
988
973
|
nonStatusUpdates.actuals = resolvedActuals;
|
|
989
974
|
}
|
|
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
|
-
}
|
|
975
|
+
const forceStatusAuditId = null;
|
|
1023
976
|
// SPEC-780: Audit-trail entry when forceApprove bypassed readiness/format gates
|
|
1024
977
|
let forceApproveAuditId = null;
|
|
1025
978
|
if (newStatus === 'approved' && params.forceApprove) {
|
|
@@ -1042,7 +995,7 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1042
995
|
outputType: 'success',
|
|
1043
996
|
durationMs: 0,
|
|
1044
997
|
specId,
|
|
1045
|
-
projectPath: effectiveGatePath
|
|
998
|
+
projectPath: effectiveGatePath,
|
|
1046
999
|
prevHash,
|
|
1047
1000
|
hash: '',
|
|
1048
1001
|
event: 'approve_gate_forced_bypass',
|
|
@@ -1059,8 +1012,9 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1059
1012
|
appendEntry(entry);
|
|
1060
1013
|
forceApproveAuditId = auditId;
|
|
1061
1014
|
}
|
|
1062
|
-
catch {
|
|
1063
|
-
/*
|
|
1015
|
+
catch (error) {
|
|
1016
|
+
/* reliability-optional: FORCE_APPROVAL_AUDIT — transition receipt remains authoritative */
|
|
1017
|
+
reportClassifiedDegradation('FORCE_APPROVAL_AUDIT', error);
|
|
1064
1018
|
}
|
|
1065
1019
|
}
|
|
1066
1020
|
}
|
|
@@ -1078,7 +1032,7 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1078
1032
|
outputType: 'success',
|
|
1079
1033
|
durationMs: 0,
|
|
1080
1034
|
specId,
|
|
1081
|
-
projectPath: effectiveGatePath
|
|
1035
|
+
projectPath: effectiveGatePath,
|
|
1082
1036
|
prevHash,
|
|
1083
1037
|
hash: '',
|
|
1084
1038
|
event: 'sdd_model_routing_forced_bypass',
|
|
@@ -1093,8 +1047,9 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1093
1047
|
appendEntry(entry);
|
|
1094
1048
|
sddRoutingAuditId = auditId;
|
|
1095
1049
|
}
|
|
1096
|
-
catch {
|
|
1097
|
-
/*
|
|
1050
|
+
catch (error) {
|
|
1051
|
+
/* reliability-optional: SDD_ROUTING_AUDIT — transition receipt remains authoritative */
|
|
1052
|
+
reportClassifiedDegradation('SDD_ROUTING_AUDIT', error);
|
|
1098
1053
|
}
|
|
1099
1054
|
}
|
|
1100
1055
|
// SPEC-969: Track forceStatus / forceApprove usage
|
|
@@ -1115,8 +1070,9 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1115
1070
|
`Consider re-running validate within 24h.`;
|
|
1116
1071
|
}
|
|
1117
1072
|
}
|
|
1118
|
-
catch {
|
|
1119
|
-
/*
|
|
1073
|
+
catch (error) {
|
|
1074
|
+
/* reliability-optional: BYPASS_ANALYTICS — lifecycle gates remain authoritative */
|
|
1075
|
+
reportClassifiedDegradation('BYPASS_ANALYTICS', error);
|
|
1120
1076
|
}
|
|
1121
1077
|
}
|
|
1122
1078
|
const versionSnapshotTag = newStatus === 'approved'
|
|
@@ -1133,45 +1089,32 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1133
1089
|
hasProjectPath: Boolean(effectiveGatePath),
|
|
1134
1090
|
shouldAutoStage,
|
|
1135
1091
|
});
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
reason: params.reason,
|
|
1143
|
-
updates: nonStatusUpdates,
|
|
1144
|
-
pendingBackgroundActions: plannedBackgroundActions,
|
|
1092
|
+
const persistence = await commitTransitionWithNarrowLock({
|
|
1093
|
+
projectPath: effectiveProjectPath || projectId,
|
|
1094
|
+
projectId,
|
|
1095
|
+
specId,
|
|
1096
|
+
newStatus,
|
|
1097
|
+
originalStatus,
|
|
1145
1098
|
expectedSpec: spec,
|
|
1099
|
+
options: {
|
|
1100
|
+
trigger: trigger,
|
|
1101
|
+
actor,
|
|
1102
|
+
viaSync,
|
|
1103
|
+
reason: params.reason,
|
|
1104
|
+
updates: nonStatusUpdates,
|
|
1105
|
+
pendingBackgroundActions: plannedBackgroundActions,
|
|
1106
|
+
expectedSpec: spec,
|
|
1107
|
+
},
|
|
1108
|
+
...(doneFreshnessLease ? { freshnessLease: doneFreshnessLease } : {}),
|
|
1146
1109
|
});
|
|
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
|
-
}
|
|
1110
|
+
if (!persistence.ok) {
|
|
1111
|
+
return persistence.error;
|
|
1170
1112
|
}
|
|
1113
|
+
const { transitionRecord, updatedSpec } = persistence;
|
|
1171
1114
|
const frontmatterSyncWarnings = [];
|
|
1172
1115
|
const transitionId = transitionRecord.transitionId;
|
|
1173
1116
|
const committedAt = transitionRecord.timestamp;
|
|
1174
|
-
|
|
1117
|
+
await appendTransitionEvent({
|
|
1175
1118
|
projectId,
|
|
1176
1119
|
specId,
|
|
1177
1120
|
eventType: 'transition',
|
|
@@ -1183,11 +1126,12 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1183
1126
|
modelId: params.modelId,
|
|
1184
1127
|
gateResults: sddRoutingGate.gateResults,
|
|
1185
1128
|
meta: { ...transitionEvidenceMeta, transitionId, committedAt },
|
|
1186
|
-
}).catch(() => {
|
|
1187
|
-
/*
|
|
1129
|
+
}).catch((error) => {
|
|
1130
|
+
/* reliability-optional: SDD_ROUTING_REPORT — never block committed acknowledgement */
|
|
1131
|
+
reportClassifiedDegradation('SDD_ROUTING_REPORT', error);
|
|
1188
1132
|
});
|
|
1189
1133
|
if (reverseTransition && params.reason) {
|
|
1190
|
-
|
|
1134
|
+
await appendTransitionEvent({
|
|
1191
1135
|
projectId,
|
|
1192
1136
|
specId,
|
|
1193
1137
|
eventType: 'reopen',
|
|
@@ -1197,18 +1141,8 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1197
1141
|
reason: params.reason,
|
|
1198
1142
|
meta: { transitionId, committedAt },
|
|
1199
1143
|
}).catch((err) => {
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
error: err instanceof Error ? err.message : String(err),
|
|
1203
|
-
});
|
|
1204
|
-
});
|
|
1205
|
-
}
|
|
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 */
|
|
1144
|
+
/* reliability-optional: REOPEN_EVENT_APPEND — transition receipt remains authoritative */
|
|
1145
|
+
reportClassifiedDegradation('REOPEN_EVENT_APPEND', err);
|
|
1212
1146
|
});
|
|
1213
1147
|
}
|
|
1214
1148
|
// SPEC-769/SPEC-780: Write qualityWarnings to spec.md frontmatter when force-approved (best-effort)
|
|
@@ -1228,8 +1162,9 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1228
1162
|
const updated = updateFrontmatterField(content, 'qualityWarnings', warningsJson);
|
|
1229
1163
|
await atomicWriteFile(specPathForWarnings, updated);
|
|
1230
1164
|
}
|
|
1231
|
-
catch {
|
|
1232
|
-
//
|
|
1165
|
+
catch (error) {
|
|
1166
|
+
// reliability-optional: QUALITY_WARNING_FRONTMATTER — canonical receipt retains warnings
|
|
1167
|
+
reportClassifiedDegradation('QUALITY_WARNING_FRONTMATTER', error);
|
|
1233
1168
|
}
|
|
1234
1169
|
})();
|
|
1235
1170
|
}
|
|
@@ -1240,10 +1175,7 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1240
1175
|
const terminalGateResults = {};
|
|
1241
1176
|
if (newStatus === 'done') {
|
|
1242
1177
|
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
|
-
}
|
|
1178
|
+
terminalGateResults.validate = 'pass';
|
|
1247
1179
|
if (complianceGateResult !== null) {
|
|
1248
1180
|
terminalGateResults.compliance = complianceGateResult.skipped
|
|
1249
1181
|
? 'skip'
|
|
@@ -1251,15 +1183,8 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1251
1183
|
? 'fail'
|
|
1252
1184
|
: 'pass';
|
|
1253
1185
|
}
|
|
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
1186
|
}
|
|
1262
|
-
|
|
1187
|
+
await recordTerminalTransitionEvent({
|
|
1263
1188
|
projectId,
|
|
1264
1189
|
specId,
|
|
1265
1190
|
specPath: updatedSpec.specPath,
|
|
@@ -1272,8 +1197,9 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1272
1197
|
modelId: params.modelId,
|
|
1273
1198
|
gateResults: Object.keys(terminalGateResults).length > 0 ? terminalGateResults : undefined,
|
|
1274
1199
|
meta: transitionEvidenceMeta,
|
|
1275
|
-
}).catch(() => {
|
|
1276
|
-
/*
|
|
1200
|
+
}).catch((error) => {
|
|
1201
|
+
/* reliability-optional: TERMINAL_VALIDATION_REPORT — canonical receipt is authoritative */
|
|
1202
|
+
reportClassifiedDegradation('TERMINAL_VALIDATION_REPORT', error);
|
|
1277
1203
|
});
|
|
1278
1204
|
}
|
|
1279
1205
|
const allSpecs = await specStore.listSpecs(projectId);
|
|
@@ -1301,15 +1227,6 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1301
1227
|
// SPEC-469: Collect autopilot summary for done-transition side effects
|
|
1302
1228
|
const collector = new AutopilotSummaryCollector();
|
|
1303
1229
|
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
1230
|
if (doneActions?.mergeWarning) {
|
|
1314
1231
|
collector.pushFail('merge-check', doneActions.mergeWarning);
|
|
1315
1232
|
}
|
|
@@ -1392,26 +1309,12 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1392
1309
|
...(collector.hasEntries() ? { autopilotSummary: collector.getMessages() } : {}),
|
|
1393
1310
|
});
|
|
1394
1311
|
// 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
1312
|
// SPEC-754: Append shell-hygiene reminder when transitioning to done on claude-code host
|
|
1402
1313
|
const shellHygieneHint = newStatus === 'done' && detectHost() === 'claude-code' ? shellHygieneReminder() : null;
|
|
1403
1314
|
return buildStatusResponse(result, specId, originalStatus, newStatus, null, spec.title, shellHygieneHint);
|
|
1404
1315
|
}
|
|
1405
1316
|
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
|
-
}
|
|
1317
|
+
// Expensive gates intentionally execute without a mutation lock.
|
|
1415
1318
|
}
|
|
1416
1319
|
}
|
|
1417
1320
|
catch (error) {
|
|
@@ -1432,7 +1335,7 @@ export async function handleUpdateStatus(params, server) {
|
|
|
1432
1335
|
isError: true,
|
|
1433
1336
|
};
|
|
1434
1337
|
}
|
|
1435
|
-
});
|
|
1338
|
+
})();
|
|
1436
1339
|
}); // end trackCost
|
|
1437
1340
|
}
|
|
1438
1341
|
//# sourceMappingURL=index.js.map
|