@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.
Files changed (1066) hide show
  1. package/CHANGELOG.md +64 -1
  2. package/LICENSE +55 -12
  3. package/README.md +33 -25
  4. package/dist/cli/commands/inspect.d.ts +4 -0
  5. package/dist/cli/commands/inspect.js +144 -0
  6. package/dist/cli/commands/install.d.ts +19 -12
  7. package/dist/cli/commands/install.js +148 -102
  8. package/dist/cli/commands/job.d.ts +3 -0
  9. package/dist/cli/commands/job.js +120 -0
  10. package/dist/cli/commands/offline.d.ts +15 -0
  11. package/dist/cli/commands/offline.js +132 -0
  12. package/dist/cli/commands/serve.js +4 -0
  13. package/dist/cli/commands/spec.js +1 -1
  14. package/dist/cli/commands/storage.d.ts +3 -0
  15. package/dist/cli/commands/storage.js +102 -0
  16. package/dist/cli/commands/uninstall.d.ts +10 -0
  17. package/dist/cli/commands/uninstall.js +93 -7
  18. package/dist/cli/commands/validate.js +1 -1
  19. package/dist/cli/index.js +2 -0
  20. package/dist/cli/router.js +9 -3
  21. package/dist/config/crash-shield-framework-rules.json +93 -0
  22. package/dist/config/environment-schema.json +147 -0
  23. package/dist/config/hardcode-exceptions.json +4 -0
  24. package/dist/config/native-release-public-key.pem +3 -0
  25. package/dist/config/native-targets.json +87 -0
  26. package/dist/config/official-sdd-tools.d.ts +4 -0
  27. package/dist/config/official-sdd-tools.js +35 -0
  28. package/dist/config/product-public.d.ts +225 -0
  29. package/dist/config/product-public.js +147 -0
  30. package/dist/config/product-public.json +283 -0
  31. package/dist/config/registries/hosts/codex.json +20 -363
  32. package/dist/config/release-compatibility.json +13 -0
  33. package/dist/config/release-policy.json +108 -0
  34. package/dist/config/runtime-policy.json +55 -0
  35. package/dist/config/skill-templates/planu-resume-work.md +2 -2
  36. package/dist/config/skill-templates/planu-validate.md +7 -4
  37. package/dist/config/subagent-templates/planu-spec-implementer.md +7 -3
  38. package/dist/config/subagent-templates/planu-validator.md +10 -5
  39. package/dist/config/technology-registry.json +120 -0
  40. package/dist/config/version.js +7 -8
  41. package/dist/core/index.d.ts +1 -1
  42. package/dist/core/spec-validator.d.ts +4 -4
  43. package/dist/core/spec-validator.js +1 -1
  44. package/dist/engine/abortable-process-runner.d.ts +20 -2
  45. package/dist/engine/abortable-process-runner.js +267 -67
  46. package/dist/engine/advanced-testing/accessibility-checker.js +12 -14
  47. package/dist/engine/advanced-testing/mutation-advisor.js +3 -4
  48. package/dist/engine/advanced-testing/property-based.js +2 -3
  49. package/dist/engine/advanced-testing/test-data-advisor.js +2 -3
  50. package/dist/engine/agent-generator.js +2 -1
  51. package/dist/engine/agent-handoff-store.js +2 -1
  52. package/dist/engine/agent-prompt-generator.js +7 -5
  53. package/dist/engine/agent-telemetry.js +2 -1
  54. package/dist/engine/ai-integration/gemini/extensions-advisor.js +41 -9
  55. package/dist/engine/ambiguity-detector.js +12 -11
  56. package/dist/engine/ambiguity-scorer.js +4 -26
  57. package/dist/engine/analyzer/db-engine.js +2 -3
  58. package/dist/engine/analyzer/detectors.js +13 -14
  59. package/dist/engine/analyzer/env-setup.js +9 -10
  60. package/dist/engine/analyzer-env-scanner/env-example.js +7 -8
  61. package/dist/engine/api-spec-generator/graphql-parser.js +2 -2
  62. package/dist/engine/api-validation/graphql-schema-validator.js +2 -1
  63. package/dist/engine/api-validation/openapi-impl-validator.js +6 -7
  64. package/dist/engine/architecture-detector.js +10 -8
  65. package/dist/engine/auth/config.d.ts +1 -1
  66. package/dist/engine/auth/config.js +4 -3
  67. package/dist/engine/auth/scope-mapper.js +1 -7
  68. package/dist/engine/auto-updater/atomic-upgrade.d.ts +8 -0
  69. package/dist/engine/auto-updater/atomic-upgrade.js +381 -0
  70. package/dist/engine/auto-updater/config-detector.js +9 -3
  71. package/dist/engine/auto-updater/config-patcher.d.ts +0 -4
  72. package/dist/engine/auto-updater/config-patcher.js +10 -15
  73. package/dist/engine/auto-updater/index.d.ts +3 -1
  74. package/dist/engine/auto-updater/index.js +44 -30
  75. package/dist/engine/auto-updater/npm-registry.js +10 -2
  76. package/dist/engine/auto-updater/release-verifier.d.ts +3 -0
  77. package/dist/engine/auto-updater/release-verifier.js +112 -0
  78. package/dist/engine/auto-updater/upgrade-lock.d.ts +6 -0
  79. package/dist/engine/auto-updater/upgrade-lock.js +28 -0
  80. package/dist/engine/auto-updater/upgrade-trust-state.d.ts +7 -0
  81. package/dist/engine/auto-updater/upgrade-trust-state.js +59 -0
  82. package/dist/engine/autopilot/audit-logger.js +2 -5
  83. package/dist/engine/autopilot/state-updater.js +4 -4
  84. package/dist/engine/best-practices-library.js +2 -1
  85. package/dist/engine/browser-validator.js +2 -1
  86. package/dist/engine/build-tool-detector.js +3 -2
  87. package/dist/engine/cascade-hooks/hooks/review-enricher.hook.js +9 -6
  88. package/dist/engine/cascade-hooks/state-drift-detector.d.ts +3 -3
  89. package/dist/engine/cascade-hooks/state-drift-detector.js +1 -1
  90. package/dist/engine/ci-generator/context-builders.js +7 -5
  91. package/dist/engine/ci-generator/planu-config.js +1 -7
  92. package/dist/engine/ci-generator/stack-detector.js +0 -2
  93. package/dist/engine/ci-generator/yaml-builder.js +0 -2
  94. package/dist/engine/clarification-gate/gate.d.ts +3 -3
  95. package/dist/engine/claude-config-auditor/rules-auditor.js +4 -3
  96. package/dist/engine/code-scanner/layer-scanner.js +6 -22
  97. package/dist/engine/code-transforms/typescript/ast-utils.js +2 -3
  98. package/dist/engine/complexity-budget/trivial-detector.js +2 -1
  99. package/dist/engine/compliance-test-generator/index.js +7 -2
  100. package/dist/engine/compliance-test-generator/test-formatter.js +2 -2
  101. package/dist/engine/config-health/mcp-config-checker.js +2 -1
  102. package/dist/engine/config-health/ts-checker-scripts.js +4 -3
  103. package/dist/engine/config-health/ts-checker.js +3 -2
  104. package/dist/engine/convention-injector.js +5 -7
  105. package/dist/engine/convention-scanner/convention-parser.js +3 -2
  106. package/dist/engine/core-bridge-duplicate-blocks.d.ts +3 -0
  107. package/dist/engine/core-bridge-duplicate-blocks.js +57 -0
  108. package/dist/engine/core-bridge-gaps.d.ts +4 -0
  109. package/dist/engine/core-bridge-gaps.js +75 -0
  110. package/dist/engine/core-bridge.d.ts +10 -10
  111. package/dist/engine/core-bridge.js +196 -283
  112. package/dist/engine/cost-guardrails.d.ts +1 -1
  113. package/dist/engine/cost-guardrails.js +1 -1
  114. package/dist/engine/cost-tracking/ledger.js +2 -5
  115. package/dist/engine/coverage-gap-analyzer.js +10 -1
  116. package/dist/engine/crash-shield/detectors/framework-detector.d.ts +2 -0
  117. package/dist/engine/crash-shield/detectors/framework-detector.js +110 -192
  118. package/dist/engine/crash-shield/detectors/typescript-detector.js +2 -1
  119. package/dist/engine/criterion-identity.d.ts +1 -0
  120. package/dist/engine/criterion-identity.js +7 -0
  121. package/dist/engine/dashboard/data-loader.js +4 -8
  122. package/dist/engine/dashboard/templates-layout.js +0 -3
  123. package/dist/engine/dashboard/templates-project.js +1 -13
  124. package/dist/engine/data-projects-gc/gc-runner.d.ts +7 -0
  125. package/dist/engine/data-projects-gc/gc-runner.js +113 -3
  126. package/dist/engine/data-projects-gc/scanner.js +5 -1
  127. package/dist/engine/decision-store.js +11 -14
  128. package/dist/engine/deleter/core.js +5 -5
  129. package/dist/engine/dep-auditor/abandonment-data.js +2 -1
  130. package/dist/engine/dep-auditor/abandonment-registry.js +3 -1
  131. package/dist/engine/dep-auditor/cve-fetcher.js +3 -0
  132. package/dist/engine/dep-auditor/dep-duplicates-detector.js +36 -4
  133. package/dist/engine/dep-auditor/license-registry.js +2 -0
  134. package/dist/engine/dependency-evaluator.d.ts +14 -0
  135. package/dist/engine/dependency-evaluator.js +81 -0
  136. package/dist/engine/deploy/providers/fly.js +7 -7
  137. package/dist/engine/deploy/providers/netlify.js +7 -7
  138. package/dist/engine/deploy/providers/railway.js +10 -12
  139. package/dist/engine/deploy/providers/vercel.js +7 -9
  140. package/dist/engine/deprecation-scanner/pattern-loader.js +0 -2
  141. package/dist/engine/desktop-detector.js +2 -3
  142. package/dist/engine/detect-duplication.js +2 -1
  143. package/dist/engine/detectors/advanced-framework-detector/css-state-detector.js +2 -1
  144. package/dist/engine/detectors/advanced-framework-detector/legacy-detector.js +2 -3
  145. package/dist/engine/detectors/advanced-framework-detector/modern-detector.js +3 -4
  146. package/dist/engine/detectors/agent-framework-detector.js +3 -2
  147. package/dist/engine/detectors/ai-native-detector.js +4 -6
  148. package/dist/engine/detectors/cache-db-detector.js +4 -3
  149. package/dist/engine/detectors/cicd-detector.js +4 -3
  150. package/dist/engine/detectors/deployment-detector.js +11 -12
  151. package/dist/engine/detectors/frontend-perf-detector.js +14 -9
  152. package/dist/engine/detectors/library-detector-multilang-a.js +16 -3
  153. package/dist/engine/detectors/library-detector-node.js +14 -4
  154. package/dist/engine/detectors/library-detector-python.js +7 -1
  155. package/dist/engine/detectors/library-detector.js +0 -2
  156. package/dist/engine/detectors/llm-detector/provider-maps.js +3 -2
  157. package/dist/engine/detectors/mcp-candidate-detector.js +12 -16
  158. package/dist/engine/detectors/mfe-detector.js +6 -7
  159. package/dist/engine/detectors/monitoring-detector.js +4 -3
  160. package/dist/engine/detectors/otel-detector.js +3 -2
  161. package/dist/engine/detectors/otel-ecosystem-detectors.d.ts +2 -2
  162. package/dist/engine/detectors/otel-ecosystem-detectors.js +4 -3
  163. package/dist/engine/detectors/platform-specialty-detector.js +3 -5
  164. package/dist/engine/detectors/template-engine-detector.js +3 -4
  165. package/dist/engine/doc-generator/builders.js +2 -3
  166. package/dist/engine/doc-generator/mobile-distribution-guide.js +13 -17
  167. package/dist/engine/doc-generator/portal/dirty-flag-map.d.ts +2 -2
  168. package/dist/engine/doc-generator/portal/portal-regenerator.js +3 -47
  169. package/dist/engine/docs-site-generator/data-collector.d.ts +1 -1
  170. package/dist/engine/docs-site-generator/data-collector.js +7 -28
  171. package/dist/engine/docs-site-generator/tools-renderer.js +3 -10
  172. package/dist/engine/domain-detector.js +3 -6
  173. package/dist/engine/dynamic-knowledge/knowledge-cache.js +3 -4
  174. package/dist/engine/dynamic-knowledge/knowledge-merger.js +17 -2
  175. package/dist/engine/dynamic-knowledge/web-researcher.js +15 -14
  176. package/dist/engine/dynamic-migration-detector/manifest-readers-extended.js +0 -2
  177. package/dist/engine/e2e-test-generator.js +4 -3
  178. package/dist/engine/ecosystem-absorber/knowledge-cache.js +2 -1
  179. package/dist/engine/ecosystem-absorber/platform-crawler.js +2 -2
  180. package/dist/engine/escalator/retry-counter.js +2 -1
  181. package/dist/engine/evidence-gates/artifact-reader.d.ts +16 -1
  182. package/dist/engine/evidence-gates/artifact-reader.js +220 -23
  183. package/dist/engine/evidence-gates/lifecycle-gate.d.ts +2 -1
  184. package/dist/engine/evidence-gates/lifecycle-gate.js +58 -3
  185. package/dist/engine/evidence-gates/reconciliation-freshness.d.ts +11 -0
  186. package/dist/engine/evidence-gates/reconciliation-freshness.js +72 -0
  187. package/dist/engine/evidence-index/done-drift.d.ts +1 -1
  188. package/dist/engine/evidence-index/done-drift.js +40 -18
  189. package/dist/engine/execution/context.d.ts +19 -0
  190. package/dist/engine/execution/context.js +130 -0
  191. package/dist/engine/execution/deadline-io.d.ts +21 -0
  192. package/dist/engine/execution/deadline-io.js +45 -0
  193. package/dist/engine/execution/durable-job-heartbeat-runtime.d.ts +4 -0
  194. package/dist/engine/execution/durable-job-heartbeat-runtime.js +400 -0
  195. package/dist/engine/execution/job-executor.d.ts +16 -0
  196. package/dist/engine/execution/job-executor.js +140 -0
  197. package/dist/engine/execution/job-runtime.d.ts +108 -0
  198. package/dist/engine/execution/job-runtime.js +328 -0
  199. package/dist/engine/execution/native-relevance-scorer.d.ts +6 -0
  200. package/dist/engine/execution/native-relevance-scorer.js +64 -0
  201. package/dist/engine/execution/native-worker-dispatch.d.ts +3 -0
  202. package/dist/engine/execution/native-worker-dispatch.js +46 -0
  203. package/dist/engine/execution/native-worker-protocol.d.ts +6 -0
  204. package/dist/engine/execution/native-worker-protocol.js +33 -0
  205. package/dist/engine/execution/native-worker-runtime.d.ts +4 -0
  206. package/dist/engine/execution/native-worker-runtime.js +177 -0
  207. package/dist/engine/execution/native-worker-thread.d.ts +2 -0
  208. package/dist/engine/execution/native-worker-thread.js +66 -0
  209. package/dist/engine/execution/operation-journal.d.ts +66 -0
  210. package/dist/engine/execution/operation-journal.js +260 -0
  211. package/dist/engine/execution/outbox-worker.d.ts +31 -0
  212. package/dist/engine/execution/outbox-worker.js +192 -0
  213. package/dist/engine/execution/public-job-sanitizer.d.ts +4 -0
  214. package/dist/engine/execution/public-job-sanitizer.js +31 -0
  215. package/dist/engine/execution/validate-job-executor.d.ts +35 -0
  216. package/dist/engine/execution/validate-job-executor.js +805 -0
  217. package/dist/engine/execution/validate-job-payload.d.ts +5 -0
  218. package/dist/engine/execution/validate-job-payload.js +144 -0
  219. package/dist/engine/execution/validate-job-recovery.d.ts +4 -0
  220. package/dist/engine/execution/validate-job-recovery.js +47 -0
  221. package/dist/engine/execution/validate-worker-runtime.d.ts +10 -0
  222. package/dist/engine/execution/validate-worker-runtime.js +188 -0
  223. package/dist/engine/execution/validate-worker-thread.d.ts +2 -0
  224. package/dist/engine/execution/validate-worker-thread.js +64 -0
  225. package/dist/engine/execution-plan/desktop-distribution.js +3 -7
  226. package/dist/engine/execution-plan/mobile-distribution.js +4 -9
  227. package/dist/engine/execution-plan/phases.js +4 -5
  228. package/dist/engine/execution-plan/plan-utils.js +8 -5
  229. package/dist/engine/facilitate/context-loader.js +3 -9
  230. package/dist/engine/figma/code-connect-fetcher.js +9 -8
  231. package/dist/engine/filesystem-watcher/index.d.ts +3 -3
  232. package/dist/engine/filesystem-watcher/index.js +5 -5
  233. package/dist/engine/framework-detector.js +14 -15
  234. package/dist/engine/git/planu-autocommit.js +8 -7
  235. package/dist/engine/git/repository-probe.d.ts +3 -0
  236. package/dist/engine/git/repository-probe.js +13 -0
  237. package/dist/engine/global-rules-manager.js +2 -2
  238. package/dist/engine/handoff-artifacts/io.js +2 -3
  239. package/dist/engine/handoff-artifacts/schemas/red-tests-handoff.js +8 -1
  240. package/dist/engine/handoff-artifacts/schemas.d.ts +6 -1
  241. package/dist/engine/handoff-artifacts/schemas.js +38 -0
  242. package/dist/engine/handoff-packager.d.ts +19 -0
  243. package/dist/engine/handoff-packager.js +415 -13
  244. package/dist/engine/hook-generator/stack-hook-templates.js +4 -4
  245. package/dist/engine/hooks/config-loader.js +1 -1
  246. package/dist/engine/hooks/context-injector.js +4 -7
  247. package/dist/engine/hooks/effort-configurator.js +1 -1
  248. package/dist/engine/hooks/file-watcher.js +1 -14
  249. package/dist/engine/hooks-reconciler.js +6 -4
  250. package/dist/engine/impact-detector/test-break-predictor.js +3 -3
  251. package/dist/engine/impact-detector/tool-registration.js +1 -1
  252. package/dist/engine/implementation-contract/renderer.js +23 -8
  253. package/dist/engine/infrastructure/component-mapper.js +5 -7
  254. package/dist/engine/infrastructure/docker-compose-generator.js +8 -10
  255. package/dist/engine/infrastructure/index.js +6 -3
  256. package/dist/engine/infrastructure/kubernetes-generator.js +2 -2
  257. package/dist/engine/infrastructure/railway-generator.js +10 -8
  258. package/dist/engine/infrastructure/signal-detector.js +6 -8
  259. package/dist/engine/infrastructure/terraform-generator.js +6 -8
  260. package/dist/engine/legal-compliance/detector.js +3 -2
  261. package/dist/engine/lifecycle-reconciliation-io.d.ts +11 -0
  262. package/dist/engine/lifecycle-reconciliation-io.js +180 -0
  263. package/dist/engine/lifecycle-reconciliation.d.ts +16 -0
  264. package/dist/engine/lifecycle-reconciliation.js +406 -0
  265. package/dist/engine/local-first/storage-advisor.js +5 -6
  266. package/dist/engine/local-first/tool-classification.js +2 -0
  267. package/dist/engine/macos-keychain-native-port.d.ts +10 -0
  268. package/dist/engine/macos-keychain-native-port.js +38 -0
  269. package/dist/engine/marketplace-fetcher/cache.js +3 -1
  270. package/dist/engine/mcp-config/mcp-config-writer.d.ts +2 -2
  271. package/dist/engine/mcp-config/mcp-config-writer.js +10 -8
  272. package/dist/engine/migration/db-migrator.js +2 -5
  273. package/dist/engine/migration/equivalence-mapper.js +12 -13
  274. package/dist/engine/migration/service-catalogs.js +6 -7
  275. package/dist/engine/migration/service-migrator-catalogs.js +6 -7
  276. package/dist/engine/migrations/remove-commercial-state.d.ts +3 -0
  277. package/dist/engine/migrations/remove-commercial-state.js +343 -0
  278. package/dist/engine/mobile-detector-ios.js +2 -3
  279. package/dist/engine/mobile-detector.js +16 -4
  280. package/dist/engine/model-router/complexity-analyzer.js +4 -7
  281. package/dist/engine/multi-agent-review/security-analyzer.js +3 -1
  282. package/dist/engine/multi-app-detector/app-type.js +26 -21
  283. package/dist/engine/multi-app-detector/core.js +3 -2
  284. package/dist/engine/multi-teammate-review/disagreement-counter.js +2 -1
  285. package/dist/engine/multi-teammate-review/panel-orchestrator.js +0 -2
  286. package/dist/engine/mutation-config-generator.js +10 -7
  287. package/dist/engine/native-capability-policy.d.ts +4 -0
  288. package/dist/engine/native-capability-policy.js +24 -0
  289. package/dist/engine/native-platform.d.ts +3 -0
  290. package/dist/engine/native-platform.js +44 -0
  291. package/dist/engine/native-runtime-handshake.d.ts +20 -0
  292. package/dist/engine/native-runtime-handshake.js +230 -0
  293. package/dist/engine/network-policy.d.ts +27 -0
  294. package/dist/engine/network-policy.js +175 -0
  295. package/dist/engine/next-spec-resolver/dependency-filter.js +2 -22
  296. package/dist/engine/nfr-profile-detector.js +12 -16
  297. package/dist/engine/nli-keywords.js +8 -9
  298. package/dist/engine/oauth/config-guard.js +4 -5
  299. package/dist/engine/observability/local-execution-spans.d.ts +15 -0
  300. package/dist/engine/observability/local-execution-spans.js +63 -0
  301. package/dist/engine/orchestrator/runtime.js +0 -1
  302. package/dist/engine/package-registry.js +2 -6
  303. package/dist/engine/performance-analyzer.js +2 -5
  304. package/dist/engine/permissions-merger/stack-detectors.js +5 -5
  305. package/dist/engine/planu-core.darwin-arm64.node.manifest.json +39 -0
  306. package/dist/engine/planu-core.darwin-arm64.node.sbom.json +1310 -0
  307. package/dist/engine/planu-core.darwin-x64.node.manifest.json +39 -0
  308. package/dist/engine/planu-core.darwin-x64.node.sbom.json +1310 -0
  309. package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +38 -0
  310. package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +1310 -0
  311. package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +38 -0
  312. package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +1310 -0
  313. package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +38 -0
  314. package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +1310 -0
  315. package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +38 -0
  316. package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +1310 -0
  317. package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +38 -0
  318. package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +1310 -0
  319. package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +38 -0
  320. package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +1310 -0
  321. package/dist/engine/platform-detector/desktop.js +15 -2
  322. package/dist/engine/platform-detector/extensions.js +2 -1
  323. package/dist/engine/platform-detector/games.js +2 -1
  324. package/dist/engine/platform-detector.js +3 -2
  325. package/dist/engine/platform-engineering/idp-detector.js +2 -1
  326. package/dist/engine/plugin-installer/stack-matcher.js +9 -17
  327. package/dist/engine/plugins/lifecycle.js +6 -2
  328. package/dist/engine/prior-decisions/contradiction-detector.js +60 -30
  329. package/dist/engine/project-dna/stack-detector.js +15 -17
  330. package/dist/engine/project-graph/builder.js +11 -0
  331. package/dist/engine/project-graph/cache.js +1 -1
  332. package/dist/engine/project-graph/freshness-projection.d.ts +16 -0
  333. package/dist/engine/project-graph/freshness-projection.js +95 -0
  334. package/dist/engine/project-graph/index.d.ts +1 -0
  335. package/dist/engine/project-graph/index.js +1 -0
  336. package/dist/engine/project-graph/query.js +15 -25
  337. package/dist/engine/project-health-checker.js +3 -4
  338. package/dist/engine/project-scanner/stack-detector.js +17 -17
  339. package/dist/engine/property-test-generator.js +2 -3
  340. package/dist/engine/qa-gate.d.ts +1 -0
  341. package/dist/engine/qa-gate.js +6 -4
  342. package/dist/engine/quality-gates/gate-catalog.js +47 -46
  343. package/dist/engine/quality-gates/gate-injector.js +9 -4
  344. package/dist/engine/readiness-checker.d.ts +1 -16
  345. package/dist/engine/readiness-checker.js +27 -88
  346. package/dist/engine/registry/core.js +0 -2
  347. package/dist/engine/registry/loader.js +9 -12
  348. package/dist/engine/registry/matcher.js +129 -24
  349. package/dist/engine/resilience-detector/concurrency-detector.js +4 -4
  350. package/dist/engine/resilience-detector/middleware-detector.js +11 -13
  351. package/dist/engine/resilience-detector/validation-detector.js +17 -4
  352. package/dist/engine/reverse-engineer/config-analyzer.js +9 -8
  353. package/dist/engine/reverse-engineer/orchestrator.js +5 -9
  354. package/dist/engine/reverse-engineer/test-file-parser.js +6 -3
  355. package/dist/engine/rules-generator/index.js +6 -5
  356. package/dist/engine/runtime-policy.d.ts +9 -0
  357. package/dist/engine/runtime-policy.js +138 -0
  358. package/dist/engine/runtime-security/checkers/content-security.js +21 -6
  359. package/dist/engine/runtime-security/checkers/file-permissions.js +0 -2
  360. package/dist/engine/runtime-security/rate-limiter.js +0 -1
  361. package/dist/engine/safety/atomic-write-file.js +20 -9
  362. package/dist/engine/safety/atomic-writer.js +10 -3
  363. package/dist/engine/safety/contained-project-file.d.ts +3 -0
  364. package/dist/engine/safety/contained-project-file.js +23 -0
  365. package/dist/engine/safety/cross-process-lock.d.ts +3 -40
  366. package/dist/engine/safety/cross-process-lock.js +268 -272
  367. package/dist/engine/safety/file-mutex.d.ts +2 -9
  368. package/dist/engine/safety/file-mutex.js +155 -87
  369. package/dist/engine/safety/health-monitor.js +15 -6
  370. package/dist/engine/safety/lock-lease-store.d.ts +79 -0
  371. package/dist/engine/safety/lock-lease-store.js +372 -0
  372. package/dist/engine/safety/lock-scavenger.d.ts +2 -5
  373. package/dist/engine/safety/lock-scavenger.js +158 -76
  374. package/dist/engine/safety/lock-staleness.js +4 -1
  375. package/dist/engine/safety/obsolete-lock-guard.d.ts +8 -0
  376. package/dist/engine/safety/obsolete-lock-guard.js +31 -0
  377. package/dist/engine/safety/transaction.js +3 -3
  378. package/dist/engine/sandbox/index.js +2 -1
  379. package/dist/engine/sandbox/runner-detect.js +3 -2
  380. package/dist/engine/sandbox/runner-docker.js +4 -3
  381. package/dist/engine/scan-project/module-discoverer.js +3 -2
  382. package/dist/engine/schema-generator.js +16 -9
  383. package/dist/engine/scope-boundaries/contradiction-checker.js +63 -1
  384. package/dist/engine/scope-boundaries/scope-validator.js +45 -7
  385. package/dist/engine/security-analyzer/criteria-generator.js +2 -3
  386. package/dist/engine/self-healing/healer.js +4 -4
  387. package/dist/engine/session/checkpoint-writer.js +0 -9
  388. package/dist/engine/shared-agent-memory.js +66 -74
  389. package/dist/engine/skill-adapter/command-rewriter.js +3 -2
  390. package/dist/engine/skill-adapter/index.js +3 -3
  391. package/dist/engine/skill-adapter/placeholder-map.js +3 -2
  392. package/dist/engine/skill-bootstrap/stack-matcher.js +47 -48
  393. package/dist/engine/skill-generation/stack-content-generator.js +0 -2
  394. package/dist/engine/skill-generator/workflow-skill-generator.js +2 -1
  395. package/dist/engine/skill-registry/ttl-refresh.js +3 -1
  396. package/dist/engine/skills/skills-fetcher.js +3 -6
  397. package/dist/engine/skills-reconciler.js +19 -39
  398. package/dist/engine/spec-coverage/test-finder.js +7 -6
  399. package/dist/engine/spec-diff-engine.js +3 -3
  400. package/dist/engine/spec-format/acceptance-criteria.d.ts +6 -2
  401. package/dist/engine/spec-format/acceptance-criteria.js +77 -18
  402. package/dist/engine/spec-format/markdown-sections.d.ts +14 -0
  403. package/dist/engine/spec-format/markdown-sections.js +105 -0
  404. package/dist/engine/spec-format/read-technical-section.js +33 -5
  405. package/dist/engine/spec-format/technical-md-populator.js +3 -2
  406. package/dist/engine/spec-format/unified-spec-builder.d.ts +7 -0
  407. package/dist/engine/spec-format/unified-spec-builder.js +202 -0
  408. package/dist/engine/spec-generator/api-key-resolver.d.ts +1 -1
  409. package/dist/engine/spec-generator/api-key-resolver.js +3 -24
  410. package/dist/engine/spec-generators/issue-extractor.js +9 -3
  411. package/dist/engine/spec-migrator/canonical-deduplicator.d.ts +18 -0
  412. package/dist/engine/spec-migrator/canonical-deduplicator.js +479 -0
  413. package/dist/engine/spec-migrator/drift-detector.js +5 -13
  414. package/dist/engine/spec-migrator/filesystem-import.d.ts +4 -8
  415. package/dist/engine/spec-migrator/filesystem-import.js +134 -23
  416. package/dist/engine/spec-migrator/frontmatter-parser.js +32 -15
  417. package/dist/engine/spec-migrator/index.d.ts +1 -0
  418. package/dist/engine/spec-migrator/index.js +1 -0
  419. package/dist/engine/spec-migrator/planu-canonical-policy.js +10 -1
  420. package/dist/engine/spec-migrator/strict-planu-cleanup.js +24 -25
  421. package/dist/engine/spec-registry/adapter.d.ts +0 -5
  422. package/dist/engine/spec-registry/adapter.js +45 -46
  423. package/dist/engine/spec-registry/client.js +2 -0
  424. package/dist/engine/spec-source-sync.js +3 -2
  425. package/dist/engine/spec-state-machine/transition-spec.d.ts +6 -1
  426. package/dist/engine/spec-state-machine/transition-spec.js +10 -1
  427. package/dist/engine/spec-templates/custom-loader.js +2 -3
  428. package/dist/engine/spec-templates/templates-domain-specific.js +8 -5
  429. package/dist/engine/spec-templates/templates-perf-integration.js +2 -3
  430. package/dist/engine/stack-auditor/manifest-reader.js +0 -2
  431. package/dist/engine/staleness/stale-implementing.js +7 -7
  432. package/dist/engine/tdd-scaffold-generator.js +24 -11
  433. package/dist/engine/teammate-router/green-phase-verifier.js +2 -1
  434. package/dist/engine/teammate-router/red-phase-verifier.js +2 -1
  435. package/dist/engine/technical-enricher/index.js +16 -8
  436. package/dist/engine/technical-enricher/render-enriched.d.ts +1 -0
  437. package/dist/engine/technical-enricher/render-enriched.js +42 -14
  438. package/dist/engine/technology-registry.d.ts +11 -0
  439. package/dist/engine/technology-registry.js +142 -0
  440. package/dist/engine/telemetry/error-reporter.d.ts +1 -2
  441. package/dist/engine/telemetry/error-reporter.js +11 -18
  442. package/dist/engine/telemetry/health-checker.js +58 -31
  443. package/dist/engine/telemetry/index.d.ts +0 -1
  444. package/dist/engine/telemetry/index.js +0 -1
  445. package/dist/engine/telemetry/stance.js +3 -2
  446. package/dist/engine/telemetry/telemetry-client.d.ts +1 -5
  447. package/dist/engine/telemetry/telemetry-client.js +69 -35
  448. package/dist/engine/telemetry/telemetry-store.d.ts +3 -3
  449. package/dist/engine/telemetry/telemetry-store.js +30 -23
  450. package/dist/engine/test-framework-detector/detectors.js +8 -8
  451. package/dist/engine/test-framework-detector/strategy.js +8 -9
  452. package/dist/engine/test-generators/agent-test-templates.js +2 -3
  453. package/dist/engine/test-generators/contract-test-generator.d.ts +1 -1
  454. package/dist/engine/test-generators/contract-test-generator.js +9 -202
  455. package/dist/engine/test-generators/platform-test-templates-b.js +2 -3
  456. package/dist/engine/test-generators/platform-test-templates.js +2 -5
  457. package/dist/engine/test-mocks-generator.js +4 -3
  458. package/dist/engine/test-plan-generator.js +30 -12
  459. package/dist/engine/test-scaffold-generator/advanced-scaffold.js +4 -5
  460. package/dist/engine/test-scaffold-generator/unit-scaffold.js +5 -6
  461. package/dist/engine/text-signal-boundaries.d.ts +2 -0
  462. package/dist/engine/text-signal-boundaries.js +25 -2
  463. package/dist/engine/time/relative-date.d.ts +3 -0
  464. package/dist/engine/time/relative-date.js +16 -0
  465. package/dist/engine/timing/budget.d.ts +17 -17
  466. package/dist/engine/timing/budget.js +98 -64
  467. package/dist/engine/token-optimizer/analytics.d.ts +1 -1
  468. package/dist/engine/token-optimizer/analytics.js +5 -6
  469. package/dist/engine/tool-groups/group-manager.js +3 -3
  470. package/dist/engine/universal-rules/installer.js +1 -1
  471. package/dist/engine/universal-rules/rules/planu-modes.js +2 -0
  472. package/dist/engine/universal-rules/rules/planu-release-policy.js +1 -0
  473. package/dist/engine/update-notifier.js +8 -5
  474. package/dist/engine/usage-tracker/core.d.ts +2 -2
  475. package/dist/engine/usage-tracker/core.js +1 -2
  476. package/dist/engine/usage-tracker/index.d.ts +0 -3
  477. package/dist/engine/usage-tracker/index.js +0 -3
  478. package/dist/engine/usage-tracker/stats.d.ts +2 -2
  479. package/dist/engine/usage-tracker/stats.js +1 -28
  480. package/dist/engine/validation/approved-spec-portability.d.ts +12 -0
  481. package/dist/engine/validation/approved-spec-portability.js +107 -0
  482. package/dist/engine/validation/durable-validation.d.ts +36 -0
  483. package/dist/engine/validation/durable-validation.js +256 -0
  484. package/dist/engine/validation/validation-freshness.d.ts +46 -0
  485. package/dist/engine/validation/validation-freshness.js +567 -0
  486. package/dist/engine/validation/validation-receipt-codec.d.ts +13 -0
  487. package/dist/engine/validation/validation-receipt-codec.js +182 -0
  488. package/dist/engine/validation/validation-receipt.d.ts +62 -0
  489. package/dist/engine/validation/validation-receipt.js +342 -0
  490. package/dist/engine/validation/validation-source-digest.d.ts +2 -0
  491. package/dist/engine/validation/validation-source-digest.js +86 -0
  492. package/dist/engine/validation/validation-source-policy.d.ts +4 -0
  493. package/dist/engine/validation/validation-source-policy.js +16 -0
  494. package/dist/engine/validation/validation-submission.d.ts +37 -0
  495. package/dist/engine/validation/validation-submission.js +142 -0
  496. package/dist/engine/validation/validation-worktree.d.ts +21 -0
  497. package/dist/engine/validation/validation-worktree.js +260 -0
  498. package/dist/engine/validation-evidence-ledger.js +41 -0
  499. package/dist/engine/validation-impact-planner.d.ts +14 -2
  500. package/dist/engine/validation-impact-planner.js +23 -10
  501. package/dist/engine/validator/dor-dod.d.ts +1 -0
  502. package/dist/engine/validator/dor-dod.js +5 -3
  503. package/dist/engine/validator/extractors.d.ts +1 -5
  504. package/dist/engine/validator/extractors.js +24 -69
  505. package/dist/engine/validator/spec-compliance-runner.d.ts +13 -25
  506. package/dist/engine/validator/spec-compliance-runner.js +442 -215
  507. package/dist/engine/validator/validation-report-writer.js +1 -1
  508. package/dist/engine/validator.js +37 -23
  509. package/dist/engine/verify-integrations/index.js +1 -1
  510. package/dist/engine/version-resolver.js +5 -6
  511. package/dist/engine/web-fetcher/stack-advisor.js +156 -92
  512. package/dist/engine/web-fetcher/stack-detector.js +114 -54
  513. package/dist/engine/workspace-manager.js +3 -2
  514. package/dist/errors/classified-degradation.d.ts +3 -0
  515. package/dist/errors/classified-degradation.js +10 -0
  516. package/dist/errors/degradation-sink.d.ts +3 -0
  517. package/dist/errors/degradation-sink.js +5 -0
  518. package/dist/errors/error-taxonomy.d.ts +12 -0
  519. package/dist/errors/error-taxonomy.js +62 -0
  520. package/dist/hosts/claude-code/ux/mcp-prompts.js +10 -4
  521. package/dist/hosts/claude-code/ux/mcp-resources.js +4 -2
  522. package/dist/hosts/codex/config-scaffold.js +4 -3
  523. package/dist/hosts/gemini/config-scaffold.js +2 -1
  524. package/dist/hosts/gemini/multimodal-spec-flow.js +7 -4
  525. package/dist/index.js +23 -20
  526. package/dist/resources/patterns.js +3 -1
  527. package/dist/resources/specs.js +3 -1
  528. package/dist/resources/templates.js +3 -1
  529. package/dist/resources/usage-stats-resource.js +2 -18
  530. package/dist/security/adapters/environment.d.ts +12 -0
  531. package/dist/security/adapters/environment.js +25 -0
  532. package/dist/security/adapters/linux-secret-service.d.ts +8 -0
  533. package/dist/security/adapters/linux-secret-service.js +64 -0
  534. package/dist/security/adapters/macos-keychain.d.ts +18 -0
  535. package/dist/security/adapters/macos-keychain.js +90 -0
  536. package/dist/security/adapters/windows-credential-manager.d.ts +8 -0
  537. package/dist/security/adapters/windows-credential-manager.js +60 -0
  538. package/dist/security/redactor.d.ts +5 -0
  539. package/dist/security/redactor.js +58 -0
  540. package/dist/security/secret-field.d.ts +5 -0
  541. package/dist/security/secret-field.js +17 -0
  542. package/dist/security/secret-migration.d.ts +3 -0
  543. package/dist/security/secret-migration.js +123 -0
  544. package/dist/security/secret-provider.d.ts +23 -0
  545. package/dist/security/secret-provider.js +145 -0
  546. package/dist/security/secure-json.d.ts +3 -0
  547. package/dist/security/secure-json.js +29 -0
  548. package/dist/server/routes/specs.js +10 -0
  549. package/dist/storage/api-surfaces-store.js +2 -2
  550. package/dist/storage/approval-operation-lock.d.ts +1 -1
  551. package/dist/storage/approval-operation-lock.js +5 -3
  552. package/dist/storage/audit-trail-store.d.ts +1 -1
  553. package/dist/storage/audit-trail-store.js +48 -62
  554. package/dist/storage/autopilot-log-store.js +12 -5
  555. package/dist/storage/base-store.d.ts +9 -9
  556. package/dist/storage/base-store.js +58 -21
  557. package/dist/storage/checkpoint-store.js +5 -2
  558. package/dist/storage/comments-store.js +2 -2
  559. package/dist/storage/compliance-audit-store.js +5 -2
  560. package/dist/storage/compliance-gate-config-store.js +7 -4
  561. package/dist/storage/compliance-store.js +2 -2
  562. package/dist/storage/context-profile-store.js +2 -2
  563. package/dist/storage/crash-shield-store.js +8 -4
  564. package/dist/storage/feedback-remote.d.ts +2 -3
  565. package/dist/storage/feedback-remote.js +45 -31
  566. package/dist/storage/feedback-store.js +10 -6
  567. package/dist/storage/figma-store.js +8 -4
  568. package/dist/storage/file-mutex.js +9 -1
  569. package/dist/storage/gaps-log.js +7 -4
  570. package/dist/storage/global-projects-store.js +4 -2
  571. package/dist/storage/global-store.d.ts +1 -17
  572. package/dist/storage/global-store.js +1 -42
  573. package/dist/storage/ideas-store.js +2 -2
  574. package/dist/storage/index.d.ts +5 -2
  575. package/dist/storage/index.js +5 -2
  576. package/dist/storage/knowledge-store/knowledge.js +27 -33
  577. package/dist/storage/lessons-store.js +2 -2
  578. package/dist/storage/migrations/canonical-storage.d.ts +15 -0
  579. package/dist/storage/migrations/canonical-storage.js +712 -0
  580. package/dist/storage/oauth-store.js +36 -8
  581. package/dist/storage/path-resolver.js +16 -3
  582. package/dist/storage/pr-store.js +2 -2
  583. package/dist/storage/project-drift-store.js +20 -8
  584. package/dist/storage/project-identity.d.ts +32 -0
  585. package/dist/storage/project-identity.js +194 -0
  586. package/dist/storage/project-resolver.js +14 -7
  587. package/dist/storage/release-notes-store.js +2 -6
  588. package/dist/storage/runtime-db.d.ts +195 -0
  589. package/dist/storage/runtime-db.js +1110 -0
  590. package/dist/storage/schema-registry.d.ts +5 -0
  591. package/dist/storage/schema-registry.js +74 -0
  592. package/dist/storage/sentry-store.js +20 -9
  593. package/dist/storage/session-state-store.js +12 -5
  594. package/dist/storage/skill-registry-storage.d.ts +1 -1
  595. package/dist/storage/skill-registry-storage.js +13 -11
  596. package/dist/storage/slack-store.js +10 -5
  597. package/dist/storage/spec-store.d.ts +14 -2
  598. package/dist/storage/spec-store.js +134 -37
  599. package/dist/storage/status-store/atomic-status-write.d.ts +5 -0
  600. package/dist/storage/status-store/atomic-status-write.js +57 -0
  601. package/dist/storage/status-store/file-lock.js +61 -20
  602. package/dist/storage/status-store/self-healing.js +13 -8
  603. package/dist/storage/status-store/version-sync.d.ts +2 -1
  604. package/dist/storage/status-store/version-sync.js +36 -39
  605. package/dist/storage/steering-store.js +2 -2
  606. package/dist/storage/storage-bundle.d.ts +5 -0
  607. package/dist/storage/storage-bundle.js +117 -0
  608. package/dist/storage/storage-catalog-validation.d.ts +3 -0
  609. package/dist/storage/storage-catalog-validation.js +20 -0
  610. package/dist/storage/storage-catalog.d.ts +25 -0
  611. package/dist/storage/storage-catalog.js +390 -0
  612. package/dist/storage/storage-layout.d.ts +24 -0
  613. package/dist/storage/storage-layout.js +101 -0
  614. package/dist/storage/storybook-store.js +2 -2
  615. package/dist/storage/supabase-store.js +24 -6
  616. package/dist/storage/tdd-policy-store.js +8 -6
  617. package/dist/storage/tech-debt-store.js +3 -3
  618. package/dist/storage/technology-selection-store.d.ts +1 -1
  619. package/dist/storage/technology-selection-store.js +6 -3
  620. package/dist/storage/token-cache-store.js +3 -3
  621. package/dist/storage/token-ledger-store.js +13 -8
  622. package/dist/storage/transition-log.js +7 -4
  623. package/dist/storage/trash-store.js +15 -6
  624. package/dist/storage/usage-store.d.ts +1 -5
  625. package/dist/storage/usage-store.js +0 -35
  626. package/dist/storage/vector-store/migrator.js +7 -2
  627. package/dist/storage/vector-store/sqlite-adapter.js +4 -1
  628. package/dist/storage/webhook-server-store.js +2 -2
  629. package/dist/tools/api-spec-generator-handler.js +3 -2
  630. package/dist/tools/auto-update-handler.d.ts +4 -4
  631. package/dist/tools/auto-update-handler.js +4 -4
  632. package/dist/tools/browser-validate-handler.js +2 -1
  633. package/dist/tools/challenge-spec/platform-challenge-scenarios-b.js +8 -5
  634. package/dist/tools/challenge-spec/resilience-challenge-scenarios.d.ts +2 -1
  635. package/dist/tools/challenge-spec/resilience-challenge-scenarios.js +10 -7
  636. package/dist/tools/challenge-spec/scenario-collector.js +1 -1
  637. package/dist/tools/challenge-spec/scenarios-data.js +1 -1
  638. package/dist/tools/challenge-spec/scenarios-desktop.js +8 -3
  639. package/dist/tools/challenge-spec/scenarios-failure.js +7 -2
  640. package/dist/tools/challenge-spec/scenarios-utils.d.ts +1 -1
  641. package/dist/tools/challenge-spec/scenarios-utils.js +35 -11
  642. package/dist/tools/challenge-spec/security-challenge-scenarios.js +3 -3
  643. package/dist/tools/challenge-spec.js +5 -5
  644. package/dist/tools/check-readiness.js +1 -1
  645. package/dist/tools/clarify-requirements/multiple-choice.js +53 -41
  646. package/dist/tools/comments-handler.js +2 -3
  647. package/dist/tools/compliance-test-handler.js +2 -2
  648. package/dist/tools/configure-telemetry.js +41 -13
  649. package/dist/tools/create-spec/auto-pipeline.js +13 -1
  650. package/dist/tools/create-spec/autopilot-analyzer.d.ts +1 -1
  651. package/dist/tools/create-spec/autopilot-analyzer.js +2 -4
  652. package/dist/tools/create-spec/mcp-tool-contract.d.ts +10 -4
  653. package/dist/tools/create-spec/mcp-tool-contract.js +7 -36
  654. package/dist/tools/create-spec/post-creation.d.ts +2 -1
  655. package/dist/tools/create-spec/post-creation.js +56 -54
  656. package/dist/tools/create-spec/relevance-scorer.d.ts +1 -1
  657. package/dist/tools/create-spec/relevance-scorer.js +17 -1
  658. package/dist/tools/create-spec/spec-builder.js +2 -23
  659. package/dist/tools/create-spec/spec-created-outbox-consumer.d.ts +14 -0
  660. package/dist/tools/create-spec/spec-created-outbox-consumer.js +176 -0
  661. package/dist/tools/create-spec.d.ts +1 -0
  662. package/dist/tools/create-spec.js +802 -732
  663. package/dist/tools/define-ui-contract/agent-interaction-contract.js +2 -4
  664. package/dist/tools/define-ui-contract-desktop/desktop-contract.js +12 -4
  665. package/dist/tools/define-ui-contract-desktop/native-contract.js +7 -3
  666. package/dist/tools/define-ui-contract-extensions.js +2 -3
  667. package/dist/tools/define-ui-contract-mobile.js +5 -9
  668. package/dist/tools/define-ui-contract-web/component-tree.js +4 -3
  669. package/dist/tools/define-ui-contract.js +7 -4
  670. package/dist/tools/deploy/deploy-spec.js +2 -4
  671. package/dist/tools/deploy/deploy-status.js +2 -4
  672. package/dist/tools/design-schema/nosql-category-schemas.js +2 -3
  673. package/dist/tools/design-schema-sql/migrations.js +3 -2
  674. package/dist/tools/design-schema-sql/tables.js +4 -1
  675. package/dist/tools/design-schema.js +4 -3
  676. package/dist/tools/feedback-handler.js +2 -4
  677. package/dist/tools/gc-data-projects.js +5 -5
  678. package/dist/tools/generate-execution-plan.js +3 -4
  679. package/dist/tools/generate-sub-agent.js +2 -1
  680. package/dist/tools/generate-tests/generators/a11y-tests-generator.js +5 -4
  681. package/dist/tools/generate-tests/generators/advanced-testing-generator.js +5 -4
  682. package/dist/tools/generate-tests/generators/concurrency-test-generator/js-templates.js +9 -4
  683. package/dist/tools/generate-tests/generators/concurrency-test-generator.js +8 -4
  684. package/dist/tools/generate-tests/generators/database/detectors.js +9 -3
  685. package/dist/tools/generate-tests/generators/database/index.js +2 -4
  686. package/dist/tools/generate-tests/generators/event-test-generator.js +5 -4
  687. package/dist/tools/generate-tests/generators/game-tests-generator.js +2 -1
  688. package/dist/tools/generate-tests/generators/graphql-test-generator.js +11 -5
  689. package/dist/tools/generate-tests/generators/grpc-test-generator.js +2 -3
  690. package/dist/tools/generate-tests/generators/llm-security-test-generator.js +4 -3
  691. package/dist/tools/generate-tests/generators/local-first-test-generator.js +4 -3
  692. package/dist/tools/generate-tests/generators/mcp-tests-generator.js +11 -9
  693. package/dist/tools/generate-tests/generators/microservices/index.js +2 -3
  694. package/dist/tools/generate-tests/generators/otel-test-generator.js +6 -3
  695. package/dist/tools/generate-tests/generators/security/detectors.js +2 -5
  696. package/dist/tools/generate-tests/generators/security/index.js +2 -4
  697. package/dist/tools/generate-tests/generators/supply-chain-test-generator.js +2 -3
  698. package/dist/tools/generate-tests/generators/visual-regression-generator.js +14 -17
  699. package/dist/tools/generate-tests/generators/websocket-test-generator.js +2 -3
  700. package/dist/tools/generate-tests/test-helpers.js +11 -12
  701. package/dist/tools/generate-tests-content.js +4 -3
  702. package/dist/tools/generate-tests.js +7 -4
  703. package/dist/tools/git/branch-ops.d.ts +1 -1
  704. package/dist/tools/git/branch-ops.js +3 -2
  705. package/dist/tools/git/git-helpers.d.ts +0 -2
  706. package/dist/tools/git/git-helpers.js +7 -7
  707. package/dist/tools/github-pr-handler.js +10 -3
  708. package/dist/tools/heal-spec-docs.js +6 -53
  709. package/dist/tools/hook-generator-handler.js +6 -6
  710. package/dist/tools/init-constitution/platform-principles.js +4 -2
  711. package/dist/tools/init-project/agents-md-writer.js +14 -5
  712. package/dist/tools/init-project/claude-md-generator.js +19 -12
  713. package/dist/tools/init-project/handler.js +165 -75
  714. package/dist/tools/init-project/host-assets-writer.d.ts +1 -1
  715. package/dist/tools/init-project/host-assets-writer.js +30 -3
  716. package/dist/tools/init-project/lifecycle-helpers.js +3 -5
  717. package/dist/tools/init-project/lint-scaffolder.d.ts +3 -3
  718. package/dist/tools/init-project/lint-scaffolder.js +6 -2
  719. package/dist/tools/init-project/migration-runner.d.ts +8 -1
  720. package/dist/tools/init-project/migration-runner.js +68 -2
  721. package/dist/tools/init-project/per-client-files-writer.js +14 -4
  722. package/dist/tools/init-project/portable-index-reconciler.d.ts +4 -0
  723. package/dist/tools/init-project/portable-index-reconciler.js +14 -0
  724. package/dist/tools/init-project/result-builder.js +1 -3
  725. package/dist/tools/init-project/rules-generator.js +10 -2
  726. package/dist/tools/init-project/scaffold-writer.d.ts +1 -1
  727. package/dist/tools/init-project/scaffold-writer.js +17 -15
  728. package/dist/tools/jobs/handlers.d.ts +15 -0
  729. package/dist/tools/jobs/handlers.js +158 -0
  730. package/dist/tools/list-specs.js +39 -59
  731. package/dist/tools/manage-plugins-handler.js +17 -9
  732. package/dist/tools/merge-risk-handler.js +2 -2
  733. package/dist/tools/migrate-tech/advanced-handlers.js +3 -2
  734. package/dist/tools/migrate-tech/build-tool-handlers.js +3 -2
  735. package/dist/tools/migrate-tech/core-handlers.js +5 -2
  736. package/dist/tools/migrate-tech/data-handlers.js +6 -3
  737. package/dist/tools/migrate-tech-advanced/rollback-handlers.js +3 -2
  738. package/dist/tools/migrate-tech-advanced/service-handlers.js +5 -2
  739. package/dist/tools/oauth-handler.js +7 -1
  740. package/dist/tools/package-handoff.js +2 -0
  741. package/dist/tools/reconcile-spec.js +0 -27
  742. package/dist/tools/register-agent-squad-tools.js +2 -2
  743. package/dist/tools/register-platform-tools/design-stack-tools.js +11 -11
  744. package/dist/tools/register-platform-tools/lifecycle-infra-tools.js +7 -7
  745. package/dist/tools/register-sdd-tools.d.ts +1 -1
  746. package/dist/tools/register-sdd-tools.js +2 -24
  747. package/dist/tools/register-spec-tools/analysis-tools.js +8 -8
  748. package/dist/tools/register-spec-tools/core-spec-tools.js +48 -8
  749. package/dist/tools/registry/auth.js +13 -5
  750. package/dist/tools/registry/publish.js +7 -4
  751. package/dist/tools/resolve-project-path.d.ts +2 -2
  752. package/dist/tools/resolve-project-path.js +7 -7
  753. package/dist/tools/reverse-engineer/analyzer.js +14 -14
  754. package/dist/tools/rollback-release.js +3 -2
  755. package/dist/tools/safe-handler.d.ts +5 -13
  756. package/dist/tools/safe-handler.js +302 -194
  757. package/dist/tools/schema-generator-handler.js +2 -1
  758. package/dist/tools/schemas/index.d.ts +1 -1
  759. package/dist/tools/schemas/index.js +1 -1
  760. package/dist/tools/schemas/output-schemas.d.ts +88 -105
  761. package/dist/tools/schemas/output-schemas.js +12 -122
  762. package/dist/tools/schemas/plugins-schemas.js +0 -2
  763. package/dist/tools/schemas/registry.js +0 -2
  764. package/dist/tools/schemas/skill-registry-schemas.js +0 -2
  765. package/dist/tools/schemas/spec.d.ts +4 -0
  766. package/dist/tools/schemas/spec.js +3 -0
  767. package/dist/tools/schemas/validate-output-schema.d.ts +267 -0
  768. package/dist/tools/schemas/validate-output-schema.js +219 -0
  769. package/dist/tools/sentry-handler.js +6 -1
  770. package/dist/tools/skill-bootstrap-handler.js +7 -4
  771. package/dist/tools/spec-prompt-handler.js +3 -3
  772. package/dist/tools/status-handler.js +4 -0
  773. package/dist/tools/storage-bundle-handler.d.ts +9 -0
  774. package/dist/tools/storage-bundle-handler.js +29 -0
  775. package/dist/tools/storage-paths-handler.d.ts +9 -0
  776. package/dist/tools/storage-paths-handler.js +17 -0
  777. package/dist/tools/suggest-mcp-server.js +11 -5
  778. package/dist/tools/suggest-mcps.js +29 -9
  779. package/dist/tools/suggest-tooling/advanced-testing-catalog.js +4 -5
  780. package/dist/tools/suggest-tooling/build-tool-catalog.js +2 -1
  781. package/dist/tools/suggest-tooling/css-framework-catalog.js +13 -7
  782. package/dist/tools/suggest-tooling/framework-catalog.js +3 -5
  783. package/dist/tools/suggest-tooling/frontend-perf-catalog.js +2 -6
  784. package/dist/tools/suggest-tooling/handler.js +10 -4
  785. package/dist/tools/suggest-tooling/hypermedia-catalog.js +11 -3
  786. package/dist/tools/suggest-tooling/linting-catalog.js +4 -7
  787. package/dist/tools/suggest-tooling/llm-security-catalog.js +2 -1
  788. package/dist/tools/suggest-tooling/local-first-catalog.js +7 -5
  789. package/dist/tools/suggest-tooling/observability-catalog.js +3 -4
  790. package/dist/tools/suggest-tooling/otel-catalog.js +4 -1
  791. package/dist/tools/suggest-tooling/resilience-catalog.js +16 -5
  792. package/dist/tools/suggest-tooling/skills-catalog.js +10 -9
  793. package/dist/tools/suggest-tooling/supply-chain-catalog.js +2 -3
  794. package/dist/tools/supabase-handler.js +2 -1
  795. package/dist/tools/sync-spec-state-handler.d.ts +1 -1
  796. package/dist/tools/sync-spec-state-handler.js +1 -1
  797. package/dist/tools/token-intelligence-handler.js +2 -2
  798. package/dist/tools/token-recording.js +2 -2
  799. package/dist/tools/token-savings-handler.js +2 -2
  800. package/dist/tools/tool-entry.d.ts +4 -4
  801. package/dist/tools/tool-entry.js +3 -3
  802. package/dist/tools/tool-registry/core-tools.js +162 -15
  803. package/dist/tools/tool-registry/group-infra.js +37 -122
  804. package/dist/tools/tool-registry/group-quality-compliance.js +31 -38
  805. package/dist/tools/tool-registry/inventory.d.ts +2 -0
  806. package/dist/tools/tool-registry/inventory.js +2 -0
  807. package/dist/tools/tool-registry-helpers.d.ts +3 -3
  808. package/dist/tools/tool-registry-helpers.js +3 -3
  809. package/dist/tools/tool-usage-report/registered-tools.d.ts +1 -1
  810. package/dist/tools/tool-usage-report/registered-tools.js +3 -15
  811. package/dist/tools/update-status/approval-gates.d.ts +13 -0
  812. package/dist/tools/update-status/approval-gates.js +84 -0
  813. package/dist/tools/update-status/batch.js +4 -2
  814. package/dist/tools/update-status/dod-gates.d.ts +6 -24
  815. package/dist/tools/update-status/dod-gates.js +60 -135
  816. package/dist/tools/update-status/done-receipt-verifier.d.ts +15 -0
  817. package/dist/tools/update-status/done-receipt-verifier.js +158 -0
  818. package/dist/tools/update-status/evidence-gate.js +190 -3
  819. package/dist/tools/update-status/file-sync.d.ts +2 -1
  820. package/dist/tools/update-status/file-sync.js +80 -18
  821. package/dist/tools/update-status/gate-harness.d.ts +7 -0
  822. package/dist/tools/update-status/gate-harness.js +8 -0
  823. package/dist/tools/update-status/index.d.ts +2 -0
  824. package/dist/tools/update-status/index.js +307 -367
  825. package/dist/tools/update-status/qa-gate.d.ts +1 -1
  826. package/dist/tools/update-status/qa-gate.js +2 -2
  827. package/dist/tools/update-status/response-builder.js +3 -3
  828. package/dist/tools/update-status/side-effects.d.ts +2 -0
  829. package/dist/tools/update-status/side-effects.js +32 -39
  830. package/dist/tools/update-status/transition-guard.d.ts +4 -2
  831. package/dist/tools/update-status/transition-guard.js +89 -25
  832. package/dist/tools/update-status-actions.d.ts +4 -2
  833. package/dist/tools/update-status-actions.js +16 -14
  834. package/dist/tools/update-status-convention-gate.js +24 -23
  835. package/dist/tools/update-status-reconcile.js +2 -2
  836. package/dist/tools/usage-report.js +1 -16
  837. package/dist/tools/usage-stats.js +1 -18
  838. package/dist/tools/usage-tracking.d.ts +4 -0
  839. package/dist/tools/usage-tracking.js +20 -0
  840. package/dist/tools/validate-api-contract-handler.js +3 -3
  841. package/dist/tools/validate-lint.d.ts +1 -0
  842. package/dist/tools/validate-lint.js +21 -14
  843. package/dist/tools/validate.d.ts +4 -1
  844. package/dist/tools/validate.js +319 -31
  845. package/dist/transports/http-transport.js +87 -66
  846. package/dist/transports/mcp-types.d.ts +0 -2
  847. package/dist/transports/middleware/with-telemetry.js +3 -2
  848. package/dist/transports/session-context.js +1 -1
  849. package/dist/types/abortable-process.d.ts +2 -0
  850. package/dist/types/advanced-framework.js +0 -2
  851. package/dist/types/atomic-upgrade.d.ts +71 -0
  852. package/dist/types/atomic-upgrade.js +2 -0
  853. package/dist/types/cascade-hooks.d.ts +1 -1
  854. package/dist/types/ci.d.ts +0 -4
  855. package/dist/types/ci.js +0 -2
  856. package/dist/types/clarification-token.d.ts +1 -1
  857. package/dist/types/claude-code-runtime.d.ts +0 -27
  858. package/dist/types/commercial-migration.d.ts +17 -0
  859. package/dist/types/commercial-migration.js +2 -0
  860. package/dist/types/common/primitives.d.ts +0 -2
  861. package/dist/types/core-bridge.d.ts +81 -10
  862. package/dist/types/crash-shield-framework-rules.d.ts +24 -0
  863. package/dist/types/crash-shield-framework-rules.js +2 -0
  864. package/dist/types/dashboard.d.ts +3 -7
  865. package/dist/types/data-gc.d.ts +16 -0
  866. package/dist/types/deploy.js +0 -2
  867. package/dist/types/docs.d.ts +0 -1
  868. package/dist/types/durable-job.d.ts +78 -0
  869. package/dist/types/durable-job.js +2 -0
  870. package/dist/types/durable-validation.d.ts +158 -0
  871. package/dist/types/durable-validation.js +166 -0
  872. package/dist/types/errors/structured-error.d.ts +3 -3
  873. package/dist/types/estimation.d.ts +4 -0
  874. package/dist/types/evidence-gates.d.ts +17 -1
  875. package/dist/types/execution.d.ts +45 -0
  876. package/dist/types/gemini-integration.d.ts +0 -11
  877. package/dist/types/handoff-artifacts.d.ts +43 -0
  878. package/dist/types/hooks-advanced.d.ts +0 -13
  879. package/dist/types/impact-detection.d.ts +2 -2
  880. package/dist/types/index.d.ts +4 -6
  881. package/dist/types/index.js +3 -5
  882. package/dist/types/infrastructure.js +0 -2
  883. package/dist/types/kiro-integration.d.ts +0 -6
  884. package/dist/types/lifecycle.js +0 -2
  885. package/dist/types/migration/canonical-storage.d.ts +37 -0
  886. package/dist/types/migration/canonical-storage.js +2 -0
  887. package/dist/types/migration/index.d.ts +1 -1
  888. package/dist/types/native-worker.d.ts +48 -0
  889. package/dist/types/native-worker.js +2 -0
  890. package/dist/types/network-policy.d.ts +12 -0
  891. package/dist/types/network-policy.js +2 -0
  892. package/dist/types/oauth.js +0 -2
  893. package/dist/types/observability.d.ts +32 -0
  894. package/dist/types/outbox-worker.d.ts +35 -0
  895. package/dist/types/outbox-worker.js +11 -0
  896. package/dist/types/permissions-config.d.ts +0 -27
  897. package/dist/types/permissions-config.js +0 -2
  898. package/dist/types/plugin-install.d.ts +0 -11
  899. package/dist/types/plugin-install.js +0 -2
  900. package/dist/types/portal.d.ts +1 -0
  901. package/dist/types/product-public.d.ts +75 -0
  902. package/dist/types/product-public.js +2 -0
  903. package/dist/types/project/inputs.d.ts +2 -0
  904. package/dist/types/project/lint-scaffolder.d.ts +1 -1
  905. package/dist/types/project/mfe-detection.js +0 -2
  906. package/dist/types/project/platform-mobile.js +0 -2
  907. package/dist/types/project/platform-specialty.js +0 -2
  908. package/dist/types/project-knowledge-graph.d.ts +7 -0
  909. package/dist/types/runtime-database.d.ts +10 -0
  910. package/dist/types/runtime-database.js +2 -0
  911. package/dist/types/runtime-policy.d.ts +51 -0
  912. package/dist/types/runtime-policy.js +2 -0
  913. package/dist/types/safety.d.ts +4 -5
  914. package/dist/types/schema-registry.d.ts +12 -0
  915. package/dist/types/schema-registry.js +2 -0
  916. package/dist/types/security.d.ts +52 -0
  917. package/dist/types/session-safeguard.d.ts +0 -31
  918. package/dist/types/skill-registry.js +0 -2
  919. package/dist/types/spec/canonical-repair.d.ts +81 -0
  920. package/dist/types/spec/canonical-repair.js +2 -0
  921. package/dist/types/spec/core.d.ts +14 -0
  922. package/dist/types/spec/index.d.ts +1 -0
  923. package/dist/types/spec/index.js +1 -0
  924. package/dist/types/spec/inputs.d.ts +31 -0
  925. package/dist/types/spec-format.d.ts +24 -0
  926. package/dist/types/spec-lock-v2.d.ts +13 -7
  927. package/dist/types/spec-lock-v2.js +1 -1
  928. package/dist/types/spec-registry.js +0 -2
  929. package/dist/types/storage-bundle.d.ts +13 -0
  930. package/dist/types/storage-bundle.js +2 -0
  931. package/dist/types/storage-catalog.d.ts +18 -0
  932. package/dist/types/storage-catalog.js +2 -0
  933. package/dist/types/team-planner.js +0 -2
  934. package/dist/types/technology-registry.d.ts +35 -0
  935. package/dist/types/technology-registry.js +2 -0
  936. package/dist/types/technology-symbols.generated.d.ts +117 -0
  937. package/dist/types/technology-symbols.generated.js +2 -0
  938. package/dist/types/telemetry.d.ts +7 -4
  939. package/dist/types/transport.d.ts +2 -2
  940. package/dist/types/usage.d.ts +1 -36
  941. package/dist/types/usage.js +1 -1
  942. package/dist/types/validate-worker.d.ts +50 -0
  943. package/dist/types/validate-worker.js +2 -0
  944. package/dist/types/validation-evidence.d.ts +1 -1
  945. package/dist/types/validation-receipt.d.ts +104 -0
  946. package/dist/types/validation-receipt.js +2 -0
  947. package/dist/types/validation.d.ts +2 -2
  948. package/package.json +36 -21
  949. package/planu-native.json +1 -1
  950. package/planu-plugin.json +23 -40
  951. package/scripts/lib/pending-release-file.mjs +93 -0
  952. package/src/i18n/messages/en.json +0 -41
  953. package/src/i18n/messages/es.json +0 -41
  954. package/src/i18n/messages/pt.json +0 -41
  955. package/dist/cli/commands/activate.d.ts +0 -14
  956. package/dist/cli/commands/activate.js +0 -174
  957. package/dist/config/license-plans.json +0 -244
  958. package/dist/config/server-instructions.ts +0 -121
  959. package/dist/config/version-defaults.ts +0 -76
  960. package/dist/config/version.ts +0 -18
  961. package/dist/engine/ai-integration/gemini/settings-generator.d.ts +0 -4
  962. package/dist/engine/ai-integration/gemini/settings-generator.js +0 -195
  963. package/dist/engine/ai-integration/kiro/hooks-generator.d.ts +0 -6
  964. package/dist/engine/ai-integration/kiro/hooks-generator.js +0 -75
  965. package/dist/engine/hooks/full-spectrum-generator.d.ts +0 -32
  966. package/dist/engine/hooks/full-spectrum-generator.js +0 -117
  967. package/dist/engine/license-validator/config-loader.d.ts +0 -5
  968. package/dist/engine/license-validator/config-loader.js +0 -16
  969. package/dist/engine/license-validator/core.d.ts +0 -15
  970. package/dist/engine/license-validator/core.js +0 -151
  971. package/dist/engine/license-validator/fingerprint.d.ts +0 -3
  972. package/dist/engine/license-validator/fingerprint.js +0 -17
  973. package/dist/engine/license-validator/lemon-squeezy.d.ts +0 -5
  974. package/dist/engine/license-validator/lemon-squeezy.js +0 -55
  975. package/dist/engine/license-validator.d.ts +0 -5
  976. package/dist/engine/license-validator.js +0 -6
  977. package/dist/engine/product-intelligence/index.d.ts +0 -7
  978. package/dist/engine/product-intelligence/index.js +0 -211
  979. package/dist/engine/session/auto-save.d.ts +0 -18
  980. package/dist/engine/session/auto-save.js +0 -98
  981. package/dist/engine/session/context-snapshot.d.ts +0 -8
  982. package/dist/engine/session/context-snapshot.js +0 -49
  983. package/dist/engine/session/memory-sync.d.ts +0 -12
  984. package/dist/engine/session/memory-sync.js +0 -34
  985. package/dist/engine/session/session-diff.d.ts +0 -11
  986. package/dist/engine/session/session-diff.js +0 -42
  987. package/dist/engine/session/session-merge.d.ts +0 -12
  988. package/dist/engine/session/session-merge.js +0 -55
  989. package/dist/engine/session-safeguard/checkpoint-runner.d.ts +0 -4
  990. package/dist/engine/session-safeguard/checkpoint-runner.js +0 -70
  991. package/dist/engine/session-safeguard/learnings-buffer.d.ts +0 -16
  992. package/dist/engine/session-safeguard/learnings-buffer.js +0 -114
  993. package/dist/engine/session-safeguard/precompaction-drain.d.ts +0 -10
  994. package/dist/engine/session-safeguard/precompaction-drain.js +0 -82
  995. package/dist/engine/session-safeguard/unpushed-detector.d.ts +0 -7
  996. package/dist/engine/session-safeguard/unpushed-detector.js +0 -59
  997. package/dist/engine/spec-changelog/core.d.ts +0 -16
  998. package/dist/engine/spec-changelog/core.js +0 -176
  999. package/dist/engine/spec-changelog/diff.d.ts +0 -18
  1000. package/dist/engine/spec-changelog/diff.js +0 -121
  1001. package/dist/engine/spec-changelog/index.d.ts +0 -3
  1002. package/dist/engine/spec-changelog/index.js +0 -4
  1003. package/dist/engine/telemetry/geo-resolver.d.ts +0 -9
  1004. package/dist/engine/telemetry/geo-resolver.js +0 -43
  1005. package/dist/engine/trial-engine.d.ts +0 -5
  1006. package/dist/engine/trial-engine.js +0 -14
  1007. package/dist/engine/usage-tracker/rate-check.d.ts +0 -7
  1008. package/dist/engine/usage-tracker/rate-check.js +0 -18
  1009. package/dist/engine/usage-tracker/rate-limiter.d.ts +0 -14
  1010. package/dist/engine/usage-tracker/rate-limiter.js +0 -73
  1011. package/dist/engine/usage-tracker/trial.d.ts +0 -27
  1012. package/dist/engine/usage-tracker/trial.js +0 -49
  1013. package/dist/engine/webhook/event-handlers.d.ts +0 -25
  1014. package/dist/engine/webhook/event-handlers.js +0 -89
  1015. package/dist/engine/webhook/index.d.ts +0 -4
  1016. package/dist/engine/webhook/index.js +0 -5
  1017. package/dist/engine/webhook/server.d.ts +0 -12
  1018. package/dist/engine/webhook/server.js +0 -249
  1019. package/dist/engine/webhook/signature.d.ts +0 -16
  1020. package/dist/engine/webhook/signature.js +0 -49
  1021. package/dist/storage/data-dir-discovery.d.ts +0 -31
  1022. package/dist/storage/data-dir-discovery.js +0 -140
  1023. package/dist/storage/license-store.d.ts +0 -6
  1024. package/dist/storage/license-store.js +0 -91
  1025. package/dist/storage/migrations/cwd-to-absolute.d.ts +0 -25
  1026. package/dist/storage/migrations/cwd-to-absolute.js +0 -281
  1027. package/dist/storage/session-store.d.ts +0 -20
  1028. package/dist/storage/session-store.js +0 -128
  1029. package/dist/tools/activate-license.d.ts +0 -6
  1030. package/dist/tools/activate-license.js +0 -132
  1031. package/dist/tools/checkpoint-handler.d.ts +0 -3
  1032. package/dist/tools/checkpoint-handler.js +0 -130
  1033. package/dist/tools/create-spec/adapters/prior-decisions-hint.d.ts +0 -14
  1034. package/dist/tools/create-spec/adapters/prior-decisions-hint.js +0 -30
  1035. package/dist/tools/export-session.d.ts +0 -3
  1036. package/dist/tools/export-session.js +0 -90
  1037. package/dist/tools/init-project/ancestor-data-detector.d.ts +0 -22
  1038. package/dist/tools/init-project/ancestor-data-detector.js +0 -81
  1039. package/dist/tools/license-gate.d.ts +0 -18
  1040. package/dist/tools/license-gate.js +0 -222
  1041. package/dist/tools/license-status.d.ts +0 -3
  1042. package/dist/tools/license-status.js +0 -93
  1043. package/dist/tools/list-sessions.d.ts +0 -3
  1044. package/dist/tools/list-sessions.js +0 -46
  1045. package/dist/tools/planu-session-checkpoint.d.ts +0 -6
  1046. package/dist/tools/planu-session-checkpoint.js +0 -42
  1047. package/dist/tools/restore-session.d.ts +0 -3
  1048. package/dist/tools/restore-session.js +0 -71
  1049. package/dist/tools/spec-history.d.ts +0 -3
  1050. package/dist/tools/spec-history.js +0 -59
  1051. package/dist/tools/update-status/force-done-audit.d.ts +0 -2
  1052. package/dist/tools/update-status/force-done-audit.js +0 -23
  1053. package/dist/tools/webhook.d.ts +0 -6
  1054. package/dist/tools/webhook.js +0 -150
  1055. package/dist/types/changelog.d.ts +0 -49
  1056. package/dist/types/changelog.js +0 -3
  1057. package/dist/types/licensing.d.ts +0 -109
  1058. package/dist/types/licensing.js +0 -4
  1059. package/dist/types/migration/cwd-to-absolute.d.ts +0 -8
  1060. package/dist/types/migration/cwd-to-absolute.js +0 -3
  1061. package/dist/types/product-intelligence.d.ts +0 -60
  1062. package/dist/types/product-intelligence.js +0 -3
  1063. package/dist/types/session.d.ts +0 -84
  1064. package/dist/types/session.js +0 -3
  1065. package/dist/types/webhook.d.ts +0 -62
  1066. 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 { runValidateGate, checkDoneGates, checkComplianceGate, checkQaGate, checkApprovedFormatGate, readApprovedValidationReportGate, checkSpecReviewGate, writeSpecReviewArtifact, } from './dod-gates.js';
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, buildValidateBlockedResponse, buildDryRunResponse, } from './response-builder.js';
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 { scanCrashRisks } from '../../engine/crash-shield/index.js';
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 { validateStrictLayoutOrError } from '../validate-helpers.js';
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('data', 'projects', projectId, 'version-snapshots', `${tag}.json`);
145
- await mkdir(dirname(snapshotPath), { recursive: true });
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.knowledge?.projectPath),
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 = knowledge?.projectPath ?? args.projectPath;
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 = knowledge?.projectPath ?? projectPath;
336
+ const effectiveProjectPath = projectPath ?? knowledge?.projectPath;
322
337
  for (const spec of specs) {
323
- const hasPendingWork = (spec.statusHistory ?? []).some((receipt) => receipt.transitionId && receipt.pendingBackgroundActions?.length);
324
- if (!hasPendingWork) {
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 ?? projectPath ?? process.cwd(), spec.id, { reason: 'recover pending post-commit tasks' });
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 || !receipt.pendingBackgroundActions?.length) {
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(() => undefined);
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
- /** SPEC-628: Check crash scan rate-limit and return skip reason if within window. */
409
- async function checkCrashScanRateLimit(newStatus, effectiveGatePath) {
410
- if (newStatus !== 'done' || !effectiveGatePath) {
411
- return null;
412
- }
413
- const skipCheck = await shouldSkipCrashScan(effectiveGatePath).catch(() => ({
414
- skip: false,
415
- }));
416
- return skipCheck.skip ? (skipCheck.reason ?? 'recently scanned') : null;
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(() => null), 5_000, null);
472
- }
473
- function shouldSkipSddRoutingGateForLegacyTestHarness() {
474
- return process.env.VITEST === 'true' && process.env.PLANU_TEST_STRICT_SDD_GATES !== 'true';
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
- if (effectiveProjectPath) {
497
- try {
498
- const { runStrictPlanuCleanup } = await import('../../engine/spec-migrator/index.js');
499
- await runStrictPlanuCleanup(effectiveProjectPath);
500
- }
501
- catch {
502
- /* strict cleanup is best-effort here; validate fails closed if artifacts remain */
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
- error: error instanceof Error ? error.message : String(error),
628
+ projectPath: transitionProjectPath,
629
+ context: currentReconciliationInvocationContext(),
630
+ syncSpecFiles,
509
631
  });
510
- });
511
- return withApprovalSpecLock(effectiveProjectPath, specId, async () => {
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(effectiveProjectPath, specId);
640
+ const lockError = await checkSpecLockGate(transitionProjectPath, specId);
515
641
  if (lockError) {
516
642
  return lockError;
517
643
  }
518
- // SPEC-731: dry_run never acquires the cross-process lock.
519
- // SPEC-719: Cross-process disk lock acquire before any spec.md mutation.
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
- let crossProcessLockHandle = null;
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(effectiveProjectPath, specId).catch(() => null);
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
- // Reload only after the per-spec lock is held. This snapshot is the sole
566
- // input for gates, transition persistence, and rollback compensation.
567
- const spec = crossProcessLockHandle !== null && typeof specStore.getSpecFresh === 'function'
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: effectiveProjectPath,
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
- const allSpecsForDepGuard = await specStore.listSpecs(projectId);
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 = knowledge?.projectPath ?? params.projectPath;
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 (!shouldSkipSddRoutingGateForLegacyTestHarness()) {
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 (!shouldSkipEvidenceGateForLegacyTestHarness()) {
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
- // SPEC-642: QA gate block done if typecheck + test:coverage have not passed
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(() => null)
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
- // BATCH B (parallel): validate + crash-shield + compliance — independent of
794
- // each other, all need spec/projectPath (available from Batch A outputs)
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
- let validateScore = null;
800
- let validateScoreSource = null;
801
- let crashShieldWarning = null;
802
- let crashShieldSkipReason = null;
909
+ const validateScore = null;
910
+ const validateScoreSource = null;
911
+ const crashShieldWarning = null;
803
912
  let complianceGateResult = null;
804
- let validationReportGate = null;
805
- // SPEC-628: Rate-limit crash scan check before entering the parallel batch
806
- crashShieldSkipReason = await checkCrashScanRateLimit(newStatus, effectiveGatePath ?? null);
807
- const [validateGateResult, crashRisksReport, complianceResult] = await Promise.all([
808
- // Validate: only on 'done'.
809
- // SPEC-721: timeout lives inside runValidateGate (Promise.race) — do NOT wrap with
810
- // withToolTimeout here, which would silently convert timeout into blocked:false (fail-open).
811
- newStatus === 'done'
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
- // SPEC-190: Run all compliance gates in parallel (convention + constitution + compile + lint + test, non-blocking)
882
- // runComplianceGates internally skips heavy commands (compile/lint/test) for non-done transitions,
883
- // but 'approved' still needs constitutionWarnings so run for 'done' and 'approved' only.
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
- ? validateGateResult === null
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, { deferSideEffects: true })
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
- // SPEC-721: Audit-trail entry when forceStatus bypassed the validate gate
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 ?? undefined,
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
- /* best-effortaudit must never block transition */
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 ?? undefined,
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
- /* best-effortaudit must never block transition */
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
- /* best-effortanalytics must never block transition */
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
- // Commit status and non-status fields in one store mutation, then pair it
1137
- // with an atomic spec.md write while the per-spec lock is still held.
1138
- const transitionRecord = await transitionSpec(projectId, specId, newStatus, {
1139
- trigger: trigger,
1140
- actor,
1141
- viaSync,
1142
- reason: params.reason,
1143
- updates: nonStatusUpdates,
1144
- pendingBackgroundActions: plannedBackgroundActions,
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
- const updatedSpec = transitionRecord.spec;
1148
- const syncResult = await syncSpecFiles(updatedSpec, originalStatus, newStatus, effectiveGatePath);
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
- void appendTransitionEvent({
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
- /* best-effort — never block the committed acknowledgement */
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
- void appendTransitionEvent({
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
- console.warn('[planu:transition] reopen_event_append_failed', {
1201
- specId,
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
- if (validateGateResult !== null) {
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
- void recordTerminalTransitionEvent({
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
- }).catch(() => {
1276
- /* best-effort — never block the transition */
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
- // SPEC-719: Release cross-process lock in all exit paths (return, throw)
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