@planu/cli 4.14.1 → 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 (424) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/LICENSE +55 -12
  3. package/README.md +10 -2
  4. package/dist/cli/commands/install.d.ts +1 -12
  5. package/dist/cli/commands/install.js +9 -65
  6. package/dist/cli/commands/job.js +4 -3
  7. package/dist/cli/commands/spec.js +2 -2
  8. package/dist/cli/commands/validate.js +2 -2
  9. package/dist/cli/router.js +1 -3
  10. package/dist/config/environment-schema.json +1 -3
  11. package/dist/config/official-sdd-tools.d.ts +4 -0
  12. package/dist/config/official-sdd-tools.js +35 -0
  13. package/dist/config/product-public.d.ts +139 -3
  14. package/dist/config/product-public.js +8 -1
  15. package/dist/config/product-public.json +7 -36
  16. package/dist/config/registries/hosts/codex.json +20 -363
  17. package/dist/config/release-policy.json +84 -2
  18. package/dist/config/runtime-policy.json +12 -1
  19. package/dist/config/skill-templates/planu-resume-work.md +2 -2
  20. package/dist/core/index.d.ts +1 -1
  21. package/dist/core/spec-validator.d.ts +4 -4
  22. package/dist/core/spec-validator.js +1 -1
  23. package/dist/engine/abortable-process-runner.d.ts +20 -2
  24. package/dist/engine/abortable-process-runner.js +243 -74
  25. package/dist/engine/ambiguity-scorer.js +4 -26
  26. package/dist/engine/auth/scope-mapper.js +1 -7
  27. package/dist/engine/autopilot/state-updater.js +4 -4
  28. package/dist/engine/cascade-hooks/hooks/review-enricher.hook.js +9 -6
  29. package/dist/engine/cascade-hooks/state-drift-detector.d.ts +3 -3
  30. package/dist/engine/cascade-hooks/state-drift-detector.js +1 -1
  31. package/dist/engine/ci-generator/planu-config.js +1 -7
  32. package/dist/engine/clarification-gate/gate.d.ts +3 -3
  33. package/dist/engine/code-scanner/layer-scanner.js +6 -22
  34. package/dist/engine/core-bridge.d.ts +3 -3
  35. package/dist/engine/cost-guardrails.d.ts +1 -1
  36. package/dist/engine/cost-guardrails.js +1 -1
  37. package/dist/engine/criterion-identity.d.ts +1 -0
  38. package/dist/engine/criterion-identity.js +7 -0
  39. package/dist/engine/dashboard/data-loader.js +2 -7
  40. package/dist/engine/dashboard/templates-layout.js +0 -3
  41. package/dist/engine/dashboard/templates-project.js +1 -13
  42. package/dist/engine/docs-site-generator/data-collector.d.ts +1 -1
  43. package/dist/engine/docs-site-generator/data-collector.js +7 -28
  44. package/dist/engine/docs-site-generator/tools-renderer.js +3 -10
  45. package/dist/engine/evidence-gates/artifact-reader.d.ts +10 -1
  46. package/dist/engine/evidence-gates/artifact-reader.js +115 -2
  47. package/dist/engine/evidence-gates/lifecycle-gate.js +4 -3
  48. package/dist/engine/evidence-gates/reconciliation-freshness.d.ts +11 -0
  49. package/dist/engine/evidence-gates/reconciliation-freshness.js +72 -0
  50. package/dist/engine/evidence-index/done-drift.d.ts +1 -1
  51. package/dist/engine/evidence-index/done-drift.js +40 -18
  52. package/dist/engine/execution/context.js +3 -0
  53. package/dist/engine/execution/durable-job-heartbeat-runtime.d.ts +4 -0
  54. package/dist/engine/execution/durable-job-heartbeat-runtime.js +400 -0
  55. package/dist/engine/execution/job-runtime.d.ts +30 -0
  56. package/dist/engine/execution/job-runtime.js +114 -6
  57. package/dist/engine/execution/public-job-sanitizer.d.ts +4 -0
  58. package/dist/engine/execution/public-job-sanitizer.js +31 -0
  59. package/dist/engine/execution/validate-job-executor.d.ts +12 -1
  60. package/dist/engine/execution/validate-job-executor.js +549 -86
  61. package/dist/engine/execution/validate-job-payload.js +107 -50
  62. package/dist/engine/execution/validate-job-recovery.js +1 -1
  63. package/dist/engine/execution/validate-worker-runtime.d.ts +5 -0
  64. package/dist/engine/execution/validate-worker-runtime.js +90 -2
  65. package/dist/engine/execution/validate-worker-thread.js +17 -24
  66. package/dist/engine/handoff-artifacts/schemas.d.ts +2 -1
  67. package/dist/engine/handoff-artifacts/schemas.js +33 -0
  68. package/dist/engine/handoff-packager.d.ts +19 -0
  69. package/dist/engine/handoff-packager.js +415 -13
  70. package/dist/engine/hooks/effort-configurator.js +1 -1
  71. package/dist/engine/impact-detector/test-break-predictor.js +3 -3
  72. package/dist/engine/impact-detector/tool-registration.js +1 -1
  73. package/dist/engine/implementation-contract/renderer.js +23 -8
  74. package/dist/engine/lifecycle-reconciliation-io.d.ts +11 -0
  75. package/dist/engine/lifecycle-reconciliation-io.js +180 -0
  76. package/dist/engine/lifecycle-reconciliation.d.ts +16 -0
  77. package/dist/engine/lifecycle-reconciliation.js +406 -0
  78. package/dist/engine/local-first/tool-classification.js +2 -0
  79. package/dist/engine/macos-keychain-native-port.d.ts +5 -0
  80. package/dist/engine/macos-keychain-native-port.js +19 -7
  81. package/dist/engine/migrations/remove-commercial-state.d.ts +3 -0
  82. package/dist/engine/migrations/remove-commercial-state.js +343 -0
  83. package/dist/engine/network-policy.js +1 -0
  84. package/dist/engine/planu-core.darwin-arm64.node.manifest.json +7 -7
  85. package/dist/engine/planu-core.darwin-arm64.node.sbom.json +10 -10
  86. package/dist/engine/planu-core.darwin-x64.node.manifest.json +7 -7
  87. package/dist/engine/planu-core.darwin-x64.node.sbom.json +10 -10
  88. package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +7 -7
  89. package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +10 -10
  90. package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +7 -7
  91. package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +10 -10
  92. package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +7 -7
  93. package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +10 -10
  94. package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +7 -7
  95. package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +10 -10
  96. package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +7 -7
  97. package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +10 -10
  98. package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +7 -7
  99. package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +10 -10
  100. package/dist/engine/readiness-checker.d.ts +1 -16
  101. package/dist/engine/readiness-checker.js +27 -88
  102. package/dist/engine/runtime-policy.d.ts +2 -0
  103. package/dist/engine/runtime-policy.js +42 -5
  104. package/dist/engine/runtime-security/rate-limiter.js +0 -1
  105. package/dist/engine/safety/contained-project-file.d.ts +3 -0
  106. package/dist/engine/safety/contained-project-file.js +23 -0
  107. package/dist/engine/scope-boundaries/contradiction-checker.js +63 -1
  108. package/dist/engine/scope-boundaries/scope-validator.js +45 -7
  109. package/dist/engine/session/checkpoint-writer.js +0 -9
  110. package/dist/engine/spec-format/acceptance-criteria.d.ts +6 -2
  111. package/dist/engine/spec-format/acceptance-criteria.js +77 -18
  112. package/dist/engine/spec-format/markdown-sections.d.ts +14 -0
  113. package/dist/engine/spec-format/markdown-sections.js +105 -0
  114. package/dist/engine/spec-format/read-technical-section.js +33 -5
  115. package/dist/engine/spec-format/technical-md-populator.js +3 -2
  116. package/dist/engine/spec-format/unified-spec-builder.d.ts +7 -0
  117. package/dist/engine/spec-format/unified-spec-builder.js +202 -0
  118. package/dist/engine/spec-migrator/canonical-deduplicator.d.ts +18 -0
  119. package/dist/engine/spec-migrator/canonical-deduplicator.js +479 -0
  120. package/dist/engine/spec-migrator/filesystem-import.d.ts +4 -8
  121. package/dist/engine/spec-migrator/filesystem-import.js +121 -14
  122. package/dist/engine/spec-migrator/frontmatter-parser.js +32 -15
  123. package/dist/engine/spec-migrator/index.d.ts +1 -0
  124. package/dist/engine/spec-migrator/index.js +1 -0
  125. package/dist/engine/spec-state-machine/transition-spec.d.ts +6 -1
  126. package/dist/engine/spec-state-machine/transition-spec.js +10 -1
  127. package/dist/engine/technical-enricher/index.js +16 -8
  128. package/dist/engine/technical-enricher/render-enriched.d.ts +1 -0
  129. package/dist/engine/technical-enricher/render-enriched.js +42 -14
  130. package/dist/engine/telemetry/health-checker.js +53 -17
  131. package/dist/engine/telemetry/telemetry-client.js +26 -8
  132. package/dist/engine/text-signal-boundaries.d.ts +2 -0
  133. package/dist/engine/text-signal-boundaries.js +25 -2
  134. package/dist/engine/time/relative-date.d.ts +3 -0
  135. package/dist/engine/time/relative-date.js +16 -0
  136. package/dist/engine/timing/budget.d.ts +11 -0
  137. package/dist/engine/timing/budget.js +27 -9
  138. package/dist/engine/token-optimizer/analytics.d.ts +1 -1
  139. package/dist/engine/token-optimizer/analytics.js +5 -6
  140. package/dist/engine/usage-tracker/core.d.ts +2 -2
  141. package/dist/engine/usage-tracker/core.js +1 -2
  142. package/dist/engine/usage-tracker/index.d.ts +0 -3
  143. package/dist/engine/usage-tracker/index.js +0 -3
  144. package/dist/engine/usage-tracker/stats.d.ts +2 -2
  145. package/dist/engine/usage-tracker/stats.js +1 -28
  146. package/dist/engine/validation/durable-validation.d.ts +1 -1
  147. package/dist/engine/validation/durable-validation.js +3 -82
  148. package/dist/engine/validation/validation-freshness.d.ts +11 -1
  149. package/dist/engine/validation/validation-freshness.js +231 -91
  150. package/dist/engine/validation/validation-receipt.d.ts +9 -6
  151. package/dist/engine/validation/validation-receipt.js +84 -24
  152. package/dist/engine/validation/validation-source-digest.d.ts +2 -0
  153. package/dist/engine/validation/validation-source-digest.js +86 -0
  154. package/dist/engine/validation/validation-submission.d.ts +5 -4
  155. package/dist/engine/validation/validation-submission.js +25 -11
  156. package/dist/engine/validation/validation-worktree.d.ts +21 -0
  157. package/dist/engine/validation/validation-worktree.js +260 -0
  158. package/dist/engine/validation-impact-planner.d.ts +14 -2
  159. package/dist/engine/validation-impact-planner.js +0 -3
  160. package/dist/engine/validator/dor-dod.d.ts +1 -0
  161. package/dist/engine/validator/dor-dod.js +5 -3
  162. package/dist/engine/validator/extractors.d.ts +1 -5
  163. package/dist/engine/validator/extractors.js +24 -69
  164. package/dist/engine/validator/spec-compliance-runner.d.ts +12 -24
  165. package/dist/engine/validator/spec-compliance-runner.js +429 -211
  166. package/dist/engine/validator.js +35 -22
  167. package/dist/index.js +4 -16
  168. package/dist/resources/usage-stats-resource.js +2 -18
  169. package/dist/security/adapters/linux-secret-service.js +7 -3
  170. package/dist/security/adapters/windows-credential-manager.js +6 -4
  171. package/dist/server/routes/specs.js +10 -0
  172. package/dist/storage/base-store.d.ts +1 -1
  173. package/dist/storage/base-store.js +1 -1
  174. package/dist/storage/feedback-remote.d.ts +2 -3
  175. package/dist/storage/feedback-remote.js +45 -31
  176. package/dist/storage/global-store.d.ts +1 -17
  177. package/dist/storage/global-store.js +1 -42
  178. package/dist/storage/index.d.ts +0 -2
  179. package/dist/storage/index.js +0 -2
  180. package/dist/storage/migrations/canonical-storage.js +124 -11
  181. package/dist/storage/runtime-db.d.ts +9 -0
  182. package/dist/storage/runtime-db.js +64 -8
  183. package/dist/storage/spec-store.d.ts +14 -2
  184. package/dist/storage/spec-store.js +104 -14
  185. package/dist/storage/status-store/atomic-status-write.d.ts +5 -0
  186. package/dist/storage/status-store/atomic-status-write.js +57 -0
  187. package/dist/storage/status-store/file-lock.js +30 -11
  188. package/dist/storage/status-store/self-healing.js +3 -3
  189. package/dist/storage/status-store/version-sync.d.ts +2 -1
  190. package/dist/storage/status-store/version-sync.js +35 -40
  191. package/dist/storage/usage-store.d.ts +1 -5
  192. package/dist/storage/usage-store.js +0 -35
  193. package/dist/tools/auto-update-handler.d.ts +3 -3
  194. package/dist/tools/auto-update-handler.js +3 -3
  195. package/dist/tools/challenge-spec/resilience-challenge-scenarios.d.ts +2 -1
  196. package/dist/tools/challenge-spec/resilience-challenge-scenarios.js +10 -7
  197. package/dist/tools/challenge-spec/scenario-collector.js +1 -1
  198. package/dist/tools/challenge-spec/scenarios-data.js +1 -1
  199. package/dist/tools/challenge-spec/scenarios-utils.d.ts +1 -1
  200. package/dist/tools/challenge-spec/scenarios-utils.js +35 -11
  201. package/dist/tools/challenge-spec.js +5 -5
  202. package/dist/tools/check-readiness.js +1 -1
  203. package/dist/tools/configure-telemetry.js +30 -2
  204. package/dist/tools/create-spec/spec-builder.js +0 -11
  205. package/dist/tools/create-spec.d.ts +1 -0
  206. package/dist/tools/create-spec.js +444 -239
  207. package/dist/tools/git/branch-ops.d.ts +1 -1
  208. package/dist/tools/git/branch-ops.js +3 -2
  209. package/dist/tools/init-project/handler.js +10 -12
  210. package/dist/tools/init-project/host-assets-writer.js +26 -1
  211. package/dist/tools/init-project/lint-scaffolder.d.ts +3 -3
  212. package/dist/tools/init-project/migration-runner.d.ts +2 -4
  213. package/dist/tools/init-project/migration-runner.js +3 -2
  214. package/dist/tools/init-project/portable-index-reconciler.d.ts +4 -0
  215. package/dist/tools/init-project/portable-index-reconciler.js +14 -0
  216. package/dist/tools/init-project/result-builder.js +1 -3
  217. package/dist/tools/jobs/handlers.js +38 -6
  218. package/dist/tools/list-specs.js +5 -26
  219. package/dist/tools/merge-risk-handler.js +2 -2
  220. package/dist/tools/package-handoff.js +2 -0
  221. package/dist/tools/reconcile-spec.js +0 -27
  222. package/dist/tools/register-agent-squad-tools.js +2 -2
  223. package/dist/tools/register-platform-tools/design-stack-tools.js +11 -11
  224. package/dist/tools/register-platform-tools/lifecycle-infra-tools.js +7 -7
  225. package/dist/tools/register-sdd-tools.d.ts +1 -1
  226. package/dist/tools/register-sdd-tools.js +2 -29
  227. package/dist/tools/register-spec-tools/analysis-tools.js +8 -8
  228. package/dist/tools/register-spec-tools/core-spec-tools.js +17 -8
  229. package/dist/tools/safe-handler.d.ts +5 -13
  230. package/dist/tools/safe-handler.js +7 -23
  231. package/dist/tools/schemas/index.d.ts +1 -1
  232. package/dist/tools/schemas/index.js +1 -1
  233. package/dist/tools/schemas/output-schemas.d.ts +0 -23
  234. package/dist/tools/schemas/output-schemas.js +0 -28
  235. package/dist/tools/schemas/spec.d.ts +4 -0
  236. package/dist/tools/schemas/spec.js +3 -0
  237. package/dist/tools/schemas/validate-output-schema.d.ts +11 -0
  238. package/dist/tools/schemas/validate-output-schema.js +7 -0
  239. package/dist/tools/spec-prompt-handler.js +3 -3
  240. package/dist/tools/sync-spec-state-handler.d.ts +1 -1
  241. package/dist/tools/sync-spec-state-handler.js +1 -1
  242. package/dist/tools/tool-entry.d.ts +4 -4
  243. package/dist/tools/tool-entry.js +3 -3
  244. package/dist/tools/tool-registry/core-tools.js +31 -15
  245. package/dist/tools/tool-registry/group-infra.js +27 -110
  246. package/dist/tools/tool-registry/group-quality-compliance.js +26 -26
  247. package/dist/tools/tool-registry/inventory.d.ts +2 -0
  248. package/dist/tools/tool-registry/inventory.js +2 -0
  249. package/dist/tools/tool-registry-helpers.d.ts +3 -3
  250. package/dist/tools/tool-registry-helpers.js +3 -3
  251. package/dist/tools/tool-usage-report/registered-tools.d.ts +1 -1
  252. package/dist/tools/tool-usage-report/registered-tools.js +3 -15
  253. package/dist/tools/update-status/approval-gates.js +3 -0
  254. package/dist/tools/update-status/done-receipt-verifier.js +40 -27
  255. package/dist/tools/update-status/evidence-gate.js +36 -1
  256. package/dist/tools/update-status/file-sync.d.ts +2 -1
  257. package/dist/tools/update-status/file-sync.js +57 -6
  258. package/dist/tools/update-status/index.d.ts +2 -0
  259. package/dist/tools/update-status/index.js +95 -58
  260. package/dist/tools/update-status/response-builder.js +3 -3
  261. package/dist/tools/update-status/side-effects.d.ts +2 -0
  262. package/dist/tools/update-status/side-effects.js +2 -2
  263. package/dist/tools/update-status/transition-guard.js +32 -15
  264. package/dist/tools/update-status-actions.d.ts +4 -2
  265. package/dist/tools/update-status-actions.js +16 -14
  266. package/dist/tools/usage-report.js +1 -16
  267. package/dist/tools/usage-stats.js +1 -18
  268. package/dist/tools/usage-tracking.d.ts +4 -0
  269. package/dist/tools/usage-tracking.js +20 -0
  270. package/dist/tools/validate-lint.d.ts +1 -0
  271. package/dist/tools/validate-lint.js +1 -1
  272. package/dist/tools/validate.d.ts +2 -1
  273. package/dist/tools/validate.js +114 -34
  274. package/dist/transports/http-transport.js +6 -8
  275. package/dist/transports/mcp-types.d.ts +0 -2
  276. package/dist/transports/session-context.js +1 -1
  277. package/dist/types/cascade-hooks.d.ts +1 -1
  278. package/dist/types/ci.d.ts +0 -4
  279. package/dist/types/clarification-token.d.ts +1 -1
  280. package/dist/types/claude-code-runtime.d.ts +0 -27
  281. package/dist/types/commercial-migration.d.ts +17 -0
  282. package/dist/types/commercial-migration.js +2 -0
  283. package/dist/types/common/primitives.d.ts +0 -2
  284. package/dist/types/core-bridge.d.ts +4 -10
  285. package/dist/types/dashboard.d.ts +3 -7
  286. package/dist/types/docs.d.ts +0 -1
  287. package/dist/types/durable-job.d.ts +4 -4
  288. package/dist/types/durable-validation.d.ts +100 -2
  289. package/dist/types/durable-validation.js +165 -1
  290. package/dist/types/errors/structured-error.d.ts +3 -3
  291. package/dist/types/estimation.d.ts +2 -0
  292. package/dist/types/evidence-gates.d.ts +9 -1
  293. package/dist/types/execution.d.ts +2 -0
  294. package/dist/types/gemini-integration.d.ts +0 -11
  295. package/dist/types/handoff-artifacts.d.ts +41 -0
  296. package/dist/types/hooks-advanced.d.ts +0 -13
  297. package/dist/types/impact-detection.d.ts +2 -2
  298. package/dist/types/index.d.ts +2 -6
  299. package/dist/types/index.js +1 -5
  300. package/dist/types/kiro-integration.d.ts +0 -6
  301. package/dist/types/network-policy.d.ts +1 -1
  302. package/dist/types/project/lint-scaffolder.d.ts +1 -1
  303. package/dist/types/runtime-policy.d.ts +11 -0
  304. package/dist/types/session-safeguard.d.ts +0 -31
  305. package/dist/types/spec/canonical-repair.d.ts +81 -0
  306. package/dist/types/spec/canonical-repair.js +2 -0
  307. package/dist/types/spec/core.d.ts +14 -0
  308. package/dist/types/spec/index.d.ts +1 -0
  309. package/dist/types/spec/index.js +1 -0
  310. package/dist/types/spec/inputs.d.ts +29 -0
  311. package/dist/types/spec-format.d.ts +24 -0
  312. package/dist/types/telemetry.d.ts +4 -1
  313. package/dist/types/transport.d.ts +0 -2
  314. package/dist/types/usage.d.ts +1 -36
  315. package/dist/types/usage.js +1 -1
  316. package/dist/types/validate-worker.d.ts +6 -0
  317. package/dist/types/validation-receipt.d.ts +1 -1
  318. package/dist/types/validation.d.ts +2 -2
  319. package/package.json +16 -12
  320. package/planu-native.json +1 -1
  321. package/planu-plugin.json +23 -40
  322. package/scripts/lib/pending-release-file.mjs +93 -0
  323. package/src/i18n/messages/en.json +0 -41
  324. package/src/i18n/messages/es.json +0 -41
  325. package/src/i18n/messages/pt.json +0 -41
  326. package/dist/cli/commands/activate.d.ts +0 -14
  327. package/dist/cli/commands/activate.js +0 -174
  328. package/dist/config/license-plans.json +0 -251
  329. package/dist/config/product-public.ts +0 -148
  330. package/dist/config/server-instructions.ts +0 -121
  331. package/dist/config/version-defaults.ts +0 -76
  332. package/dist/config/version.ts +0 -21
  333. package/dist/engine/ai-integration/gemini/settings-generator.d.ts +0 -4
  334. package/dist/engine/ai-integration/gemini/settings-generator.js +0 -195
  335. package/dist/engine/ai-integration/kiro/hooks-generator.d.ts +0 -6
  336. package/dist/engine/ai-integration/kiro/hooks-generator.js +0 -75
  337. package/dist/engine/hooks/full-spectrum-generator.d.ts +0 -32
  338. package/dist/engine/hooks/full-spectrum-generator.js +0 -117
  339. package/dist/engine/license-validator/config-loader.d.ts +0 -5
  340. package/dist/engine/license-validator/config-loader.js +0 -16
  341. package/dist/engine/license-validator/core.d.ts +0 -15
  342. package/dist/engine/license-validator/core.js +0 -151
  343. package/dist/engine/license-validator/fingerprint.d.ts +0 -3
  344. package/dist/engine/license-validator/fingerprint.js +0 -17
  345. package/dist/engine/license-validator/lemon-squeezy.d.ts +0 -5
  346. package/dist/engine/license-validator/lemon-squeezy.js +0 -55
  347. package/dist/engine/license-validator.d.ts +0 -5
  348. package/dist/engine/license-validator.js +0 -6
  349. package/dist/engine/product-intelligence/index.d.ts +0 -7
  350. package/dist/engine/product-intelligence/index.js +0 -211
  351. package/dist/engine/session/auto-save.d.ts +0 -18
  352. package/dist/engine/session/auto-save.js +0 -98
  353. package/dist/engine/session/context-snapshot.d.ts +0 -8
  354. package/dist/engine/session/context-snapshot.js +0 -49
  355. package/dist/engine/session/memory-sync.d.ts +0 -12
  356. package/dist/engine/session/memory-sync.js +0 -34
  357. package/dist/engine/session/session-diff.d.ts +0 -11
  358. package/dist/engine/session/session-diff.js +0 -42
  359. package/dist/engine/session/session-merge.d.ts +0 -12
  360. package/dist/engine/session/session-merge.js +0 -55
  361. package/dist/engine/session-safeguard/checkpoint-runner.d.ts +0 -4
  362. package/dist/engine/session-safeguard/checkpoint-runner.js +0 -70
  363. package/dist/engine/session-safeguard/learnings-buffer.d.ts +0 -15
  364. package/dist/engine/session-safeguard/learnings-buffer.js +0 -91
  365. package/dist/engine/session-safeguard/precompaction-drain.d.ts +0 -10
  366. package/dist/engine/session-safeguard/precompaction-drain.js +0 -82
  367. package/dist/engine/session-safeguard/unpushed-detector.d.ts +0 -7
  368. package/dist/engine/session-safeguard/unpushed-detector.js +0 -59
  369. package/dist/engine/spec-changelog/core.d.ts +0 -16
  370. package/dist/engine/spec-changelog/core.js +0 -176
  371. package/dist/engine/spec-changelog/diff.d.ts +0 -18
  372. package/dist/engine/spec-changelog/diff.js +0 -121
  373. package/dist/engine/spec-changelog/index.d.ts +0 -3
  374. package/dist/engine/spec-changelog/index.js +0 -4
  375. package/dist/engine/trial-engine.d.ts +0 -5
  376. package/dist/engine/trial-engine.js +0 -14
  377. package/dist/engine/usage-tracker/rate-check.d.ts +0 -7
  378. package/dist/engine/usage-tracker/rate-check.js +0 -18
  379. package/dist/engine/usage-tracker/rate-limiter.d.ts +0 -14
  380. package/dist/engine/usage-tracker/rate-limiter.js +0 -73
  381. package/dist/engine/usage-tracker/trial.d.ts +0 -27
  382. package/dist/engine/usage-tracker/trial.js +0 -49
  383. package/dist/engine/webhook/event-handlers.d.ts +0 -25
  384. package/dist/engine/webhook/event-handlers.js +0 -89
  385. package/dist/engine/webhook/index.d.ts +0 -4
  386. package/dist/engine/webhook/index.js +0 -5
  387. package/dist/engine/webhook/server.d.ts +0 -12
  388. package/dist/engine/webhook/server.js +0 -249
  389. package/dist/engine/webhook/signature.d.ts +0 -16
  390. package/dist/engine/webhook/signature.js +0 -49
  391. package/dist/storage/license-store.d.ts +0 -6
  392. package/dist/storage/license-store.js +0 -63
  393. package/dist/storage/session-store.d.ts +0 -20
  394. package/dist/storage/session-store.js +0 -136
  395. package/dist/tools/activate-license.d.ts +0 -6
  396. package/dist/tools/activate-license.js +0 -132
  397. package/dist/tools/checkpoint-handler.d.ts +0 -3
  398. package/dist/tools/checkpoint-handler.js +0 -130
  399. package/dist/tools/export-session.d.ts +0 -3
  400. package/dist/tools/export-session.js +0 -90
  401. package/dist/tools/license-gate.d.ts +0 -18
  402. package/dist/tools/license-gate.js +0 -222
  403. package/dist/tools/license-status.d.ts +0 -3
  404. package/dist/tools/license-status.js +0 -93
  405. package/dist/tools/list-sessions.d.ts +0 -3
  406. package/dist/tools/list-sessions.js +0 -46
  407. package/dist/tools/planu-session-checkpoint.d.ts +0 -6
  408. package/dist/tools/planu-session-checkpoint.js +0 -42
  409. package/dist/tools/restore-session.d.ts +0 -3
  410. package/dist/tools/restore-session.js +0 -71
  411. package/dist/tools/spec-history.d.ts +0 -3
  412. package/dist/tools/spec-history.js +0 -59
  413. package/dist/tools/webhook.d.ts +0 -6
  414. package/dist/tools/webhook.js +0 -150
  415. package/dist/types/changelog.d.ts +0 -49
  416. package/dist/types/changelog.js +0 -3
  417. package/dist/types/licensing.d.ts +0 -109
  418. package/dist/types/licensing.js +0 -4
  419. package/dist/types/product-intelligence.d.ts +0 -60
  420. package/dist/types/product-intelligence.js +0 -3
  421. package/dist/types/session.d.ts +0 -84
  422. package/dist/types/session.js +0 -3
  423. package/dist/types/webhook.d.ts +0 -62
  424. package/dist/types/webhook.js +0 -4
@@ -1,6 +1,6 @@
1
1
  import { technologyValue } from '../../engine/technology-registry.js';
2
2
  import { z } from 'zod';
3
- import { safeLicensed, safeTracked } from '../safe-handler.js';
3
+ import { safeGoverned, safeTracked } from '../safe-handler.js';
4
4
  import { projectIdSchema, withProject } from '../tool-registry-helpers.js';
5
5
  import { t } from '../../i18n/index.js';
6
6
  import { makeDeprecationStub } from './deprecated-stubs.js';
@@ -269,7 +269,7 @@ export function registerQualityComplianceGroupTools(s) {
269
269
  outputFormat: z.enum(['html', 'json']).optional().describe(FORMAT_DESCRIBE),
270
270
  },
271
271
  annotations: { title: 'Generate Compliance Report', readOnlyHint: true },
272
- }, safeLicensed('generate_compliance_report', (args) => Promise.resolve(handleGenerateComplianceReport(args))));
272
+ }, safeGoverned('generate_compliance_report', (args) => Promise.resolve(handleGenerateComplianceReport(args))));
273
273
  s.registerTool('audit_log_export', {
274
274
  description: 'Export the project audit trail in CSV, JSON, or JSON-LD format. ' +
275
275
  'Supports optional date range filtering. ' +
@@ -290,7 +290,7 @@ export function registerQualityComplianceGroupTools(s) {
290
290
  .describe('Optional date range filter for audit entries'),
291
291
  },
292
292
  annotations: { title: 'Export Audit Log', readOnlyHint: true },
293
- }, safeLicensed('audit_log_export', async (args) => handleAuditLogExport(args)));
293
+ }, safeGoverned('audit_log_export', async (args) => handleAuditLogExport(args)));
294
294
  s.registerTool('data_retention_policy', {
295
295
  description: 'Configure the data retention policy for the project. ' +
296
296
  'Specifies how long data should be retained and whether auto-deletion is enabled. ' +
@@ -320,7 +320,7 @@ export function registerQualityComplianceGroupTools(s) {
320
320
  .describe('Days before deletion to notify (default: 7)'),
321
321
  },
322
322
  annotations: { title: 'Configure Data Retention Policy', readOnlyHint: false },
323
- }, safeLicensed('data_retention_policy', async (args) => handleDataRetentionPolicy(args)));
323
+ }, safeGoverned('data_retention_policy', async (args) => handleDataRetentionPolicy(args)));
324
324
  // ── Compliance gate ───────────────────────────────────────────────────────────
325
325
  s.registerTool('configure_compliance_gate', {
326
326
  description: 'Configure the compliance gate that runs automatically when a spec is sent to review. ' +
@@ -329,9 +329,9 @@ export function registerQualityComplianceGroupTools(s) {
329
329
  'Pro feature.',
330
330
  inputSchema: ConfigureComplianceGateSchema.shape,
331
331
  annotations: { title: 'Configure Compliance Gate', destructiveHint: false },
332
- }, safeLicensed('configure_compliance_gate', async (args) => handleConfigureComplianceGate(args)));
332
+ }, safeGoverned('configure_compliance_gate', async (args) => handleConfigureComplianceGate(args)));
333
333
  s.registerTool('compliance_gate_status', {
334
- description: 'Check the compliance gate configuration for this project. Returns the current mode and threshold. Free tool — no license required.',
334
+ description: 'Check the compliance gate configuration for this project. Returns the current mode and threshold.',
335
335
  inputSchema: {
336
336
  projectPath: z.string().describe('Absolute path to the project root'),
337
337
  },
@@ -363,7 +363,7 @@ export function registerQualityComplianceGroupTools(s) {
363
363
  .describe(TEST_FORMAT_DESCRIBE),
364
364
  },
365
365
  annotations: { title: 'Generate Compliance Tests', readOnlyHint: true },
366
- }, safeLicensed('generate_compliance_tests', async (args) => handleGenerateComplianceTests(args)));
366
+ }, safeGoverned('generate_compliance_tests', async (args) => handleGenerateComplianceTests(args)));
367
367
  s.registerTool('compliance_coverage_report', {
368
368
  description: 'List all compliance controls for the requested frameworks, showing their IDs, ' +
369
369
  'titles, descriptions, and matching keywords. ' +
@@ -380,7 +380,7 @@ export function registerQualityComplianceGroupTools(s) {
380
380
  .describe(COMPLIANCE_TEST_FRAMEWORK_DESCRIBE),
381
381
  },
382
382
  annotations: { title: 'Compliance Coverage Report', readOnlyHint: true },
383
- }, safeLicensed('compliance_coverage_report', (args) => Promise.resolve(handleComplianceCoverageReport(args))));
383
+ }, safeGoverned('compliance_coverage_report', (args) => Promise.resolve(handleComplianceCoverageReport(args))));
384
384
  // ── Security ─────────────────────────────────────────────────────────────────
385
385
  s.registerTool('security_check', {
386
386
  description: t('tools.security_check.description'),
@@ -398,7 +398,7 @@ export function registerQualityComplianceGroupTools(s) {
398
398
  .optional()
399
399
  .describe('Absolute paths to code files to scan for insecure patterns'),
400
400
  },
401
- }, safeLicensed('security_check', withProject((args) => handleSecurityCheck(args))));
401
+ }, safeGoverned('security_check', withProject((args) => handleSecurityCheck(args))));
402
402
  // ── Audit trail ──────────────────────────────────────────────────────────────
403
403
  s.registerTool('audit_trail', {
404
404
  description: 'Query the immutable audit log for a project. Supports filtering by specId, userId, eventType, and date range. Returns events with SHA-256 chain integrity status.',
@@ -430,7 +430,7 @@ export function registerQualityComplianceGroupTools(s) {
430
430
  .optional()
431
431
  .describe('Maximum number of events to return (default: 100, max: 1000).'),
432
432
  },
433
- }, safeLicensed('audit_trail', withProject((args) => handleAuditTrail(args))));
433
+ }, safeGoverned('audit_trail', withProject((args) => handleAuditTrail(args))));
434
434
  s.registerTool('generate_attestation', {
435
435
  description: 'Generate a compliance attestation document for a specific spec. Includes full audit history, chain integrity verification, and event summary for SOC2/HIPAA/ISO27001 audits.',
436
436
  annotations: { readOnlyHint: true },
@@ -442,7 +442,7 @@ export function registerQualityComplianceGroupTools(s) {
442
442
  .max(500)
443
443
  .describe('Spec ID to generate attestation for (e.g. SPEC-042).'),
444
444
  },
445
- }, safeLicensed('generate_attestation', withProject((args) => handleGenerateAttestation(args))));
445
+ }, safeGoverned('generate_attestation', withProject((args) => handleGenerateAttestation(args))));
446
446
  s.registerTool('export_audit_trail', {
447
447
  description: 'Export the EU AI Act Article 12 immutable audit trail for every Planu tool invocation. ' +
448
448
  'Supports filtering by project, date range, or spec. Verifies SHA-256 chain integrity. ' +
@@ -478,7 +478,7 @@ export function registerQualityComplianceGroupTools(s) {
478
478
  .optional()
479
479
  .describe('Maximum number of entries to return.'),
480
480
  },
481
- }, safeLicensed('export_audit_trail', (args) => Promise.resolve(handleExportAuditTrail(args))));
481
+ }, safeGoverned('export_audit_trail', (args) => Promise.resolve(handleExportAuditTrail(args))));
482
482
  // ── Schema parity ────────────────────────────────────────────────────────────
483
483
  s.registerTool('audit_schema_type_parity', {
484
484
  description: 'Scans all register-*.ts tool files in the project for mismatches between Zod optional ' +
@@ -493,7 +493,7 @@ export function registerQualityComplianceGroupTools(s) {
493
493
  .max(4096)
494
494
  .describe('Absolute path to the project root to scan. The auditor will look for src/tools/register-*.ts and src/types/**/*.ts.'),
495
495
  },
496
- }, safeLicensed('audit_schema_type_parity', async (args) => handleAuditSchemaParity(args)));
496
+ }, safeGoverned('audit_schema_type_parity', async (args) => handleAuditSchemaParity(args)));
497
497
  s.registerTool('fix_schema_type_parity', {
498
498
  description: 'Automatically fixes Zod/TypeScript optional parity issues found by audit_schema_type_parity. ' +
499
499
  'Adds "?" to TypeScript type definitions for fields that are marked .optional() in Zod schemas. ' +
@@ -510,7 +510,7 @@ export function registerQualityComplianceGroupTools(s) {
510
510
  .default(true)
511
511
  .describe('When true (default), shows what would change without writing any files. Set to false to apply the fixes.'),
512
512
  },
513
- }, safeLicensed('fix_schema_type_parity', async (args) => handleFixSchemaParity(args)));
513
+ }, safeGoverned('fix_schema_type_parity', async (args) => handleFixSchemaParity(args)));
514
514
  // ── Schema generator ─────────────────────────────────────────────────────────
515
515
  s.registerTool('generate_validation_schema', {
516
516
  description: 'Analyze a spec and generate validation schema code (Zod, Yup, or Valibot). ' +
@@ -605,7 +605,7 @@ export function registerQualityComplianceGroupTools(s) {
605
605
  .describe('Spec ID to analyze (e.g., "SPEC-001"), or "all" to analyze every spec in the project'),
606
606
  },
607
607
  annotations: { title: 'Spec Test Coverage', readOnlyHint: true },
608
- }, safeLicensed('spec_coverage', withProject((args) => handleSpecCoverage(args))));
608
+ }, safeGoverned('spec_coverage', withProject((args) => handleSpecCoverage(args))));
609
609
  // ── Eval skill ───────────────────────────────────────────────────────────────
610
610
  s.registerTool('eval_skill', {
611
611
  description: 'Evaluate the quality of a Claude skill file against a set of test scenarios. ' +
@@ -838,7 +838,7 @@ export function registerQualityComplianceGroupTools(s) {
838
838
  .describe('Evaluation mode: strict (default) requires score >=70; lenient requires >=60'),
839
839
  },
840
840
  outputSchema: CheckReadinessOutputSchema,
841
- }, safeLicensed('check_readiness', withProject((args) => handleCheckReadiness(args))));
841
+ }, safeGoverned('check_readiness', withProject((args) => handleCheckReadiness(args))));
842
842
  // ── SPEC-961: Architecture lint ─────────────────────────────────────────────
843
843
  s.registerTool('architecture_lint', {
844
844
  description: 'Scan project codebase for Clean Architecture and SOLID principle violations. Reports handler bloat, layer violations, and missing repository patterns.',
@@ -857,7 +857,7 @@ export function registerQualityComplianceGroupTools(s) {
857
857
  .describe('Glob patterns to exclude (default: node_modules, .git, dist)'),
858
858
  failFast: z.boolean().optional().describe('Stop on first error (default: false)'),
859
859
  },
860
- }, safeLicensed('architecture_lint', withProject((args) => handleArchitectureLint(args))));
860
+ }, safeGoverned('architecture_lint', withProject((args) => handleArchitectureLint(args))));
861
861
  // ── SPEC-962: SOLID check ───────────────────────────────────────────────────
862
862
  s.registerTool('solid_check', {
863
863
  description: 'Scan project codebase for SOLID principle violations. Reports SRP, OCP, LSP, ISP, and DIP issues with a scored report (0-100) and per-principle breakdown.',
@@ -870,7 +870,7 @@ export function registerQualityComplianceGroupTools(s) {
870
870
  .describe('Glob patterns to exclude (default: node_modules, .git, dist)'),
871
871
  failFast: z.boolean().optional().describe('Stop on first error (default: false)'),
872
872
  },
873
- }, safeLicensed('solid_check', withProject((args) => handleSolidCheck({
873
+ }, safeGoverned('solid_check', withProject((args) => handleSolidCheck({
874
874
  projectPath: args.projectPath,
875
875
  exclude: args.exclude,
876
876
  failFast: args.failFast,
@@ -917,7 +917,7 @@ export function registerQualityComplianceGroupTools(s) {
917
917
  .optional()
918
918
  .describe('Fail on first failing endpoint (default: false)'),
919
919
  },
920
- }, safeLicensed('verify_integrations', withProject((args) => handleVerifyIntegrations({
920
+ }, safeGoverned('verify_integrations', withProject((args) => handleVerifyIntegrations({
921
921
  projectPath: args.projectPath,
922
922
  endpoints: args.endpoints,
923
923
  timeout: args.timeout,
@@ -954,7 +954,7 @@ export function registerQualityComplianceGroupTools(s) {
954
954
  ...projectIdSchema,
955
955
  specId: SpecIdSchema.describe('Spec ID to generate handoff package for'),
956
956
  },
957
- }, safeLicensed('package_handoff', withProject((args) => handlePackageHandoff(args))));
957
+ }, safeGoverned('package_handoff', withProject((args) => handlePackageHandoff(args))));
958
958
  // ── Approval ─────────────────────────────────────────────────────────────────
959
959
  s.registerTool('configure_approval_policy', {
960
960
  description: 'Define the approval policy for a project: how many approvals are required, ' +
@@ -980,7 +980,7 @@ export function registerQualityComplianceGroupTools(s) {
980
980
  .describe('Roles allowed to approve specs. If empty or omitted, any reviewer can approve.'),
981
981
  },
982
982
  annotations: { title: 'Configure Approval Policy', destructiveHint: false },
983
- }, safeLicensed('configure_approval_policy', (args) => handleConfigureApprovalPolicy(args)));
983
+ }, safeGoverned('configure_approval_policy', (args) => handleConfigureApprovalPolicy(args)));
984
984
  s.registerTool('issue_reviewer_token', {
985
985
  description: '[SPEC-722] Issue a signed reviewer token for approve_spec. ' +
986
986
  'Must be called from a DIFFERENT session than the one that created the spec. ' +
@@ -1002,7 +1002,7 @@ export function registerQualityComplianceGroupTools(s) {
1002
1002
  .describe('Host/agent platform identifier (e.g. "claude-code", "cursor").'),
1003
1003
  },
1004
1004
  annotations: { title: 'Issue Reviewer Token', destructiveHint: false },
1005
- }, safeLicensed('issue_reviewer_token', (args) => handleIssueReviewerToken(args)));
1005
+ }, safeGoverned('issue_reviewer_token', (args) => handleIssueReviewerToken(args)));
1006
1006
  s.registerTool('approve_spec', {
1007
1007
  description: '[SPEC-722] Record that a reviewer has approved a spec. ' +
1008
1008
  'Requires a signed reviewerToken (from issue_reviewer_token) and the plannerToken ' +
@@ -1036,7 +1036,7 @@ export function registerQualityComplianceGroupTools(s) {
1036
1036
  'Allows approval from the same model if the panel was heterogeneous.'),
1037
1037
  },
1038
1038
  annotations: { title: 'Approve Spec', destructiveHint: true },
1039
- }, safeLicensed('approve_spec', (args) => handleApproveSpec(args)));
1039
+ }, safeGoverned('approve_spec', (args) => handleApproveSpec(args)));
1040
1040
  s.registerTool('request_changes', {
1041
1041
  description: 'Request changes on a spec. The spec is moved back to draft and prior approvals are cleared. ' +
1042
1042
  'A comment explaining the required changes is mandatory.',
@@ -1068,7 +1068,7 @@ export function registerQualityComplianceGroupTools(s) {
1068
1068
  .describe('Role of the reviewer (e.g. "tech-lead", "qa").'),
1069
1069
  },
1070
1070
  annotations: { title: 'Request Changes', destructiveHint: true },
1071
- }, safeLicensed('request_changes', (args) => handleRequestChanges(args)));
1071
+ }, safeGoverned('request_changes', (args) => handleRequestChanges(args)));
1072
1072
  s.registerTool('approval_status', {
1073
1073
  description: 'Show the current approval status for a spec: who approved, how many are needed, ' +
1074
1074
  'time in review, and SLA breach warning if applicable.',
@@ -1103,7 +1103,7 @@ export function registerQualityComplianceGroupTools(s) {
1103
1103
  .optional()
1104
1104
  .describe('Raw spec content to analyze when specId is not available'),
1105
1105
  },
1106
- }, safeLicensed('data_governance', withProject((args) => handleDataGovernance(args))));
1106
+ }, safeGoverned('data_governance', withProject((args) => handleDataGovernance(args))));
1107
1107
  s.registerTool('legal_compliance_report', {
1108
1108
  description: 'Generate a legal compliance report for the project. ' +
1109
1109
  'Shows detected legal domains, applicable regulations by country, ' +
@@ -1113,7 +1113,7 @@ export function registerQualityComplianceGroupTools(s) {
1113
1113
  inputSchema: {
1114
1114
  ...projectIdSchema,
1115
1115
  },
1116
- }, safeLicensed('legal_compliance_report', withProject((args) => handleLegalComplianceReport(args))));
1116
+ }, safeGoverned('legal_compliance_report', withProject((args) => handleLegalComplianceReport(args))));
1117
1117
  // ── SPEC-322: API Contract Validation ────────────────────────────────────────
1118
1118
  s.registerTool('validate_api_contract', {
1119
1119
  description: 'Validate an OpenAPI 3.x/Swagger or GraphQL SDL contract against the actual implementation in a project. ' +
@@ -0,0 +1,2 @@
1
+ export { OFFICIAL_SDD_TOOL_NAMES, readCanonicalToolNames, } from '../../config/official-sdd-tools.js';
2
+ //# sourceMappingURL=inventory.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { OFFICIAL_SDD_TOOL_NAMES, readCanonicalToolNames, } from '../../config/official-sdd-tools.js';
2
+ //# sourceMappingURL=inventory.js.map
@@ -14,17 +14,17 @@ interface MaybeProjectArgs {
14
14
  * Wraps a handler that requires a resolved projectId.
15
15
  * Resolves projectId from projectId or projectPath; returns missingProjectIdError if neither.
16
16
  *
17
- * Usage (replaces the 5-line resolveProjectId block in each safeTracked/safeLicensed callback):
17
+ * Usage (replaces the 5-line resolveProjectId block in each safeTracked/safeGoverned callback):
18
18
  * ```ts
19
19
  * // Before:
20
- * safeLicensed('tool', async (args) => {
20
+ * safeGoverned('tool', async (args) => {
21
21
  * const pid = resolveProjectId(args as { projectId?: string; projectPath?: string });
22
22
  * if (!pid) return missingProjectIdError;
23
23
  * return handleFoo({ ...args, projectId: pid } as FooInput);
24
24
  * })
25
25
  *
26
26
  * // After:
27
- * safeLicensed('tool', withProject((args) => handleFoo(args as never)))
27
+ * safeGoverned('tool', withProject((args) => handleFoo(args as never)))
28
28
  * ```
29
29
  */
30
30
  export declare function withProject<T extends MaybeProjectArgs>(handler: (args: T & {
@@ -16,17 +16,17 @@ export const projectIdSchema = {
16
16
  * Wraps a handler that requires a resolved projectId.
17
17
  * Resolves projectId from projectId or projectPath; returns missingProjectIdError if neither.
18
18
  *
19
- * Usage (replaces the 5-line resolveProjectId block in each safeTracked/safeLicensed callback):
19
+ * Usage (replaces the 5-line resolveProjectId block in each safeTracked/safeGoverned callback):
20
20
  * ```ts
21
21
  * // Before:
22
- * safeLicensed('tool', async (args) => {
22
+ * safeGoverned('tool', async (args) => {
23
23
  * const pid = resolveProjectId(args as { projectId?: string; projectPath?: string });
24
24
  * if (!pid) return missingProjectIdError;
25
25
  * return handleFoo({ ...args, projectId: pid } as FooInput);
26
26
  * })
27
27
  *
28
28
  * // After:
29
- * safeLicensed('tool', withProject((args) => handleFoo(args as never)))
29
+ * safeGoverned('tool', withProject((args) => handleFoo(args as never)))
30
30
  * ```
31
31
  */
32
32
  export function withProject(handler) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Returns a deduplicated list of all tool names registered in license-plans.json.
2
+ * Returns the live tool inventory captured by the canonical registry.
3
3
  */
4
4
  export declare function readRegisteredToolNames(): Promise<string[]>;
5
5
  //# sourceMappingURL=registered-tools.d.ts.map
@@ -1,21 +1,9 @@
1
1
  // tools/tool-usage-report/registered-tools.ts — SPEC-574
2
- // Reads all tool names registered in license-plans.json (freeTools + proTools + alwaysAllowed).
3
- import { readFileSync } from 'node:fs';
4
- import { fileURLToPath } from 'node:url';
5
- import { dirname, join } from 'node:path';
6
- function loadLicensePlans() {
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = dirname(__filename);
9
- const configPath = join(__dirname, '../../config/license-plans.json');
10
- const raw = readFileSync(configPath, 'utf-8');
11
- return JSON.parse(raw);
12
- }
2
+ import { readCanonicalToolNames } from '../tool-registry/inventory.js';
13
3
  /**
14
- * Returns a deduplicated list of all tool names registered in license-plans.json.
4
+ * Returns the live tool inventory captured by the canonical registry.
15
5
  */
16
6
  export function readRegisteredToolNames() {
17
- const plans = loadLicensePlans();
18
- const allTools = new Set([...plans.freeTools, ...plans.proTools, ...plans.alwaysAllowed]);
19
- return Promise.resolve([...allTools].sort());
7
+ return Promise.resolve(readCanonicalToolNames().sort());
20
8
  }
21
9
  //# sourceMappingURL=registered-tools.js.map
@@ -10,6 +10,9 @@ export async function checkComplianceGate(specId, projectId, projectPath) {
10
10
  try {
11
11
  const { scoreCompliance } = await import('../../engine/verifier/compliance-scorer.js');
12
12
  const result = await scoreCompliance(specId, projectPath);
13
+ if (result.totalCriteria === 0 && result.criteriaDetails.length === 0) {
14
+ return { skipped: true, score: null, issues: [], blocked: false };
15
+ }
13
16
  const score = result.score;
14
17
  const issues = result.criteriaDetails
15
18
  .filter((detail) => detail.status === 'unverified')
@@ -54,8 +54,9 @@ import { isAbsolute, join } from 'node:path';
54
54
  import { RuntimeDatabase } from '../../storage/runtime-db.js';
55
55
  import { resolveStorageLayout } from '../../storage/storage-layout.js';
56
56
  import { projectDataDir } from '../../storage/base-store.js';
57
+ import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
57
58
  import { ValidationReceiptStore, LOCAL_VALIDATION_RECEIPT_ISSUER, createValidationReceiptAuthority, readCurrentValidationReceipt, } from '../../engine/validation/validation-receipt.js';
58
- import { beginValidationFreshnessBarrier, bindValidationFreshnessLease, captureValidationFreshnessLease, } from '../../engine/validation/validation-freshness.js';
59
+ import { beginValidationFreshnessBarrier, bindValidationFreshnessLease, captureValidationFreshnessLease, closeValidationFreshnessLease, } from '../../engine/validation/validation-freshness.js';
59
60
  import { computeDurableValidationBindings, toValidationReceiptBindings, } from '../../engine/validation/durable-validation.js';
60
61
  export function completedJobPublishesReceipt(job, receiptId) {
61
62
  if (job?.state !== 'completed' || !job.result || typeof job.result !== 'object') {
@@ -105,34 +106,46 @@ export async function verifyCurrentDoneReceipt(identity) {
105
106
  if (!receiptJobExists) {
106
107
  return { valid: false, reason: 'missing-receipt' };
107
108
  }
108
- let freshnessLease = await captureValidationFreshnessLease(identity, currentBindings);
109
- if (!freshnessLease && identity.projectPath && identity.specPath) {
110
- const projectPath = identity.projectPath;
111
- const specPath = isAbsolute(identity.specPath)
112
- ? identity.specPath
113
- : join(projectPath, identity.specPath);
114
- const lease = await beginValidationFreshnessBarrier({
115
- projectId: identity.projectId,
116
- specId: identity.specId,
117
- projectPath,
118
- handoffPath: join(projectDataDir(identity.projectId), 'handoffs', identity.specId),
119
- invalidateCurrentBindings: false,
120
- });
121
- const observed = await computeDurableValidationBindings({
122
- canonicalProjectId: identity.projectId,
123
- specId: identity.specId,
124
- projectPath,
125
- specPath,
126
- });
127
- const observedBindings = toValidationReceiptBindings(observed.bindings, observed.artifactDigests);
128
- if (JSON.stringify(observedBindings) === JSON.stringify(currentBindings) &&
129
- (await bindValidationFreshnessLease(lease, observedBindings))) {
130
- freshnessLease = lease;
109
+ let ownedLease = await captureValidationFreshnessLease(identity, currentBindings);
110
+ try {
111
+ if (!ownedLease && identity.projectPath && identity.specPath) {
112
+ const projectPath = identity.projectPath;
113
+ const specPath = isAbsolute(identity.specPath)
114
+ ? identity.specPath
115
+ : join(projectPath, identity.specPath);
116
+ ownedLease = await beginValidationFreshnessBarrier({
117
+ projectId: identity.projectId,
118
+ specId: identity.specId,
119
+ projectPath,
120
+ handoffPath: join(projectDataDir(identity.projectId), 'handoffs', identity.specId),
121
+ invalidateCurrentBindings: false,
122
+ });
123
+ const observed = await computeDurableValidationBindings({
124
+ canonicalProjectId: identity.projectId,
125
+ specId: identity.specId,
126
+ projectPath,
127
+ specPath,
128
+ });
129
+ const observedBindings = toValidationReceiptBindings(observed.bindings, observed.artifactDigests);
130
+ if (JSON.stringify(observedBindings) !== JSON.stringify(currentBindings) ||
131
+ !(await bindValidationFreshnessLease(ownedLease, observedBindings))) {
132
+ return { valid: false, reason: 'stale-bindings' };
133
+ }
134
+ }
135
+ if (!ownedLease) {
136
+ return { valid: false, reason: 'stale-bindings' };
137
+ }
138
+ const transferred = ownedLease;
139
+ ownedLease = undefined;
140
+ return { ...verification, freshnessLease: transferred };
141
+ }
142
+ finally {
143
+ if (ownedLease) {
144
+ await closeValidationFreshnessLease(ownedLease).catch((error) => {
145
+ reportClassifiedDegradation('VALIDATION_FRESHNESS_CHECK_FAILED', error);
146
+ });
131
147
  }
132
148
  }
133
- return freshnessLease
134
- ? { ...verification, freshnessLease }
135
- : { valid: false, reason: 'stale-bindings' };
136
149
  }
137
150
  catch (e_1) {
138
151
  env_1.error = e_1;
@@ -66,8 +66,25 @@ import { ValidationReceiptStore, LOCAL_VALIDATION_RECEIPT_ISSUER, createValidati
66
66
  import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
67
67
  import { captureValidationFreshnessLease } from '../../engine/validation/validation-freshness.js';
68
68
  import { computeDurableValidationBindings, toValidationReceiptBindings, } from '../../engine/validation/durable-validation.js';
69
+ import { checkReconciliationFreshness } from '../../engine/evidence-gates/reconciliation-freshness.js';
70
+ import { extractCanonicalFileOwnership } from '../../engine/handoff-packager.js';
69
71
  /** SPEC-1054: BDD/SDD lifecycle evidence gate. */
70
72
  export async function checkLifecycleEvidenceTransitionGate(args) {
73
+ const staleReconciliationEvidence = await checkReconciliationFreshness({
74
+ projectId: args.projectId,
75
+ specId: args.specId,
76
+ });
77
+ if (staleReconciliationEvidence.length > 0) {
78
+ return evidenceGateError({
79
+ specId: args.specId,
80
+ transition: args.transition,
81
+ issues: staleReconciliationEvidence.map(({ artifactId }) => ({
82
+ code: 'SUPERSEDED_RECONCILIATION_EVIDENCE',
83
+ message: artifactId,
84
+ })),
85
+ requiredContractKinds: [],
86
+ });
87
+ }
71
88
  const [criteriaResult, artifacts] = await Promise.all([
72
89
  extractLifecycleGateCriteriaAndBody(args.spec, args.projectPath),
73
90
  readEvidenceArtifacts({
@@ -108,8 +125,26 @@ export async function checkLifecycleEvidenceTransitionGate(args) {
108
125
  artifacts,
109
126
  projectPath: args.projectPath,
110
127
  });
128
+ const canonicalOwnership = body
129
+ ? extractCanonicalFileOwnership(body)
130
+ : { present: false, toCreate: [], toModify: [], toTest: [], blockers: [] };
111
131
  const groundedTechnicalPaths = body ? parseGroundedTechnicalPaths(body) : [];
112
- result.issues.push(...checkDoneDriftContract({ index, groundedTechnicalPaths }));
132
+ const approvedScopePaths = [
133
+ ...new Set([
134
+ ...canonicalOwnership.toCreate,
135
+ ...canonicalOwnership.toModify,
136
+ ...canonicalOwnership.toTest,
137
+ ...groundedTechnicalPaths,
138
+ ]),
139
+ ];
140
+ if (canonicalOwnership.blockers.length > 0) {
141
+ const safeBlockers = canonicalOwnership.blockers.map((blocker) => blocker.startsWith('CONFLICTING_FILE_OWNERSHIP:') ? blocker : 'INVALID_FILE_OWNERSHIP');
142
+ result.issues.push({
143
+ code: 'done_drift_unapproved_scope',
144
+ message: `Approved canonical ownership is invalid: ${[...new Set(safeBlockers)].join(', ')}.`,
145
+ });
146
+ }
147
+ result.issues.push(...checkDoneDriftContract({ index, approvedScopePaths }));
113
148
  }
114
149
  if (result.issues.length === 0) {
115
150
  return null;
@@ -10,7 +10,7 @@ export interface FrontmatterSyncWarning {
10
10
  specPath: string | null;
11
11
  reason: string;
12
12
  }
13
- export declare function syncSpecFiles(updatedSpec: Spec, _currentStatus: SpecStatus, newStatus: SpecStatus, projectPath?: string): Promise<{
13
+ export declare function syncSpecFiles(updatedSpec: Spec, _currentStatus: SpecStatus, newStatus: SpecStatus, projectPath?: string, qualityWarnings?: readonly string[]): Promise<{
14
14
  warning?: FrontmatterSyncWarning;
15
15
  }>;
16
16
  export declare function tryReconcile(newStatus: string, specId: string, projectId: string): Promise<string | null>;
@@ -32,5 +32,6 @@ export declare function recordTerminalTransitionEvent(args: {
32
32
  modelId?: string;
33
33
  gateResults?: Record<string, 'pass' | 'fail' | 'skip' | 'forced'>;
34
34
  meta?: Record<string, unknown>;
35
+ projectPath?: string;
35
36
  }): Promise<void>;
36
37
  //# sourceMappingURL=file-sync.d.ts.map
@@ -3,11 +3,12 @@ import { metricsStore } from '../../storage/index.js';
3
3
  import { addLesson, getLessons } from '../../storage/lessons-store.js';
4
4
  import { dispatchFeedbackEvent } from '../learn.js';
5
5
  import { autoReconcileOnDone } from '../update-status-reconcile.js';
6
- import { readFile } from 'node:fs/promises';
6
+ import { lstat, readFile, realpath } from 'node:fs/promises';
7
7
  import { parseFrontmatter } from '../../engine/frontmatter-parser.js';
8
8
  import { computeFrontmatterSha } from '../../engine/frontmatter-sha/index.js';
9
9
  import { appendTransitionEvent } from '../../storage/transition-log.js';
10
10
  import { atomicWriteFile } from '../../engine/safety/atomic-write-file.js';
11
+ import { isAbsolute, normalize, relative, resolve, sep } from 'node:path';
11
12
  import { redactFailureMessage, reportClassifiedDegradation, } from '../../errors/classified-degradation.js';
12
13
  export async function recordDoneMetrics(projectId, specId, spec, actuals, projectPath) {
13
14
  if (actuals.devHours + actuals.reviewHours === 0) {
@@ -74,6 +75,46 @@ async function autoCaptureLessonEstimation(spec, actuals, accuracy, projectId, p
74
75
  }
75
76
  const SPEC_BODY_SHRINK_ABSOLUTE_THRESHOLD = 200;
76
77
  const SPEC_BODY_SHRINK_RATIO_THRESHOLD = 0.05;
78
+ async function resolveSpecPathForTransition(spec, projectPath) {
79
+ if (!projectPath) {
80
+ return spec.specPath;
81
+ }
82
+ const normalizedPath = normalize(spec.specPath);
83
+ const segments = normalizedPath.split(sep).filter(Boolean);
84
+ const planuIndex = segments.lastIndexOf('planu');
85
+ const specDirectory = segments[planuIndex + 2];
86
+ const isPortableContract = planuIndex >= 0 &&
87
+ segments[planuIndex + 1] === 'specs' &&
88
+ segments[planuIndex + 3] === 'spec.md' &&
89
+ planuIndex + 4 === segments.length &&
90
+ specDirectory !== undefined &&
91
+ (specDirectory === spec.id || specDirectory.startsWith(`${spec.id}-`));
92
+ if (!isPortableContract) {
93
+ throw new Error('SPEC_PATH_RELOCALIZATION_FAILED: specPath is not a portable spec contract');
94
+ }
95
+ const selectedRoot = resolve(projectPath);
96
+ const candidate = resolve(selectedRoot, 'planu', 'specs', specDirectory, 'spec.md');
97
+ const relativeCandidate = relative(selectedRoot, candidate);
98
+ if (relativeCandidate.startsWith(`..${sep}`) ||
99
+ relativeCandidate === '..' ||
100
+ isAbsolute(relativeCandidate)) {
101
+ throw new Error('SPEC_PATH_RELOCALIZATION_FAILED: specPath escapes the selected root');
102
+ }
103
+ const [rootRealpath, candidateRealpath, candidateStat] = await Promise.all([
104
+ realpath(selectedRoot),
105
+ realpath(candidate),
106
+ lstat(candidate),
107
+ ]);
108
+ const realRelative = relative(rootRealpath, candidateRealpath);
109
+ if (candidateStat.isSymbolicLink() ||
110
+ !candidateStat.isFile() ||
111
+ realRelative.startsWith(`..${sep}`) ||
112
+ realRelative === '..' ||
113
+ isAbsolute(realRelative)) {
114
+ throw new Error('SPEC_PATH_RELOCALIZATION_FAILED: specPath is not a contained regular file');
115
+ }
116
+ return candidateRealpath;
117
+ }
77
118
  function bodyWithoutFrontmatter(content) {
78
119
  return parseFrontmatter(content).body;
79
120
  }
@@ -95,13 +136,23 @@ function assertSpecBodyIntegrity(args) {
95
136
  throw new Error(`SPEC_INTEGRITY_WRITE_FAILED: refusing to write ${args.specId} because update_status(${args.newStatus}) would shrink spec.md body by ${String(lost)} characters without an explicit migration marker.`);
96
137
  }
97
138
  }
98
- export async function syncSpecFiles(updatedSpec, _currentStatus, newStatus, projectPath) {
139
+ export async function syncSpecFiles(updatedSpec, _currentStatus, newStatus, projectPath, qualityWarnings = []) {
99
140
  let warning;
100
141
  if (updatedSpec.specPath) {
101
142
  try {
102
- const specContent = await readFile(updatedSpec.specPath, 'utf-8');
143
+ const transitionSpecPath = await resolveSpecPathForTransition(updatedSpec, projectPath);
144
+ const specContent = await readFile(transitionSpecPath, 'utf-8');
145
+ if (projectPath) {
146
+ const parsedId = parseFrontmatter(specContent).metadata.id;
147
+ if (parsedId !== updatedSpec.id) {
148
+ throw new Error('SPEC_PATH_RELOCALIZATION_FAILED: spec frontmatter ID does not match');
149
+ }
150
+ }
103
151
  const { updateFrontmatterField } = await import('../../engine/frontmatter-parser.js');
104
152
  let updatedContent = updateFrontmatterField(specContent, 'status', newStatus);
153
+ if (qualityWarnings.length > 0) {
154
+ updatedContent = updateFrontmatterField(updatedContent, 'qualityWarnings', JSON.stringify(qualityWarnings));
155
+ }
105
156
  if (newStatus === 'done') {
106
157
  updatedContent = markAllCriteriaDone(updatedContent);
107
158
  if (isLeanSpecContent(updatedContent)) {
@@ -114,7 +165,7 @@ export async function syncSpecFiles(updatedSpec, _currentStatus, newStatus, proj
114
165
  newStatus,
115
166
  specId: updatedSpec.id,
116
167
  });
117
- await atomicWriteFile(updatedSpec.specPath, updatedContent);
168
+ await atomicWriteFile(transitionSpecPath, updatedContent);
118
169
  // SPEC-544: Auto-stage spec.md after writing so it's included in the user's next commit
119
170
  // SPEC-575: Auto-commit staged planu/ docs (idempotent, safe-fail)
120
171
  // Commit message must reflect the actual transition — 'mark-done' is only
@@ -125,7 +176,7 @@ export async function syncSpecFiles(updatedSpec, _currentStatus, newStatus, proj
125
176
  process.env.PLANU_SUPPRESS_AUTOCOMMIT !== 'true') {
126
177
  try {
127
178
  const { git: gitCmd } = await import('../git/git-helpers.js');
128
- await gitCmd(projectPath, ['add', '--', updatedSpec.specPath]);
179
+ await gitCmd(projectPath, ['add', '--', transitionSpecPath]);
129
180
  const { planuAutoCommit } = await import('../../engine/git/planu-autocommit.js');
130
181
  void planuAutoCommit({
131
182
  projectPath,
@@ -197,7 +248,7 @@ export async function recordTerminalTransitionEvent(args) {
197
248
  let frontmatterSha;
198
249
  if (args.specPath) {
199
250
  try {
200
- const content = await readFile(args.specPath, 'utf-8');
251
+ const content = await readFile(await resolveSpecPathForTransition({ id: args.specId, specPath: args.specPath }, args.projectPath), 'utf-8');
201
252
  const { metadata } = parseFrontmatter(content);
202
253
  frontmatterSha = computeFrontmatterSha(metadata);
203
254
  }
@@ -1,5 +1,7 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { UpdateStatusInput, ToolResult } from '../../types/index.js';
3
+ /** Bind deferred lifecycle work to one normalized absolute root without persisting that path. */
4
+ export declare function computeTransitionRootBinding(projectPath: string): string;
3
5
  /** Recover durable post-commit work for every registered project after server startup. */
4
6
  export declare function recoverPendingPostCommitTasksAtStartup(): Promise<void>;
5
7
  export declare function handleUpdateStatus(params: UpdateStatusInput, server?: McpServer): Promise<ToolResult>;