@cleocode/core 2026.10.27 → 2026.11.1-canary.3

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 (520) hide show
  1. package/README.md +2 -0
  2. package/binaries/README.md +30 -10
  3. package/dist/.source-stamp.json +4 -0
  4. package/dist/audit/reconstruct.d.ts.map +1 -1
  5. package/dist/audit/reconstruct.js +3 -13
  6. package/dist/audit/reconstruct.js.map +1 -1
  7. package/dist/build-provenance.json +2 -2
  8. package/dist/cloud/nexus-cloud.d.ts.map +1 -1
  9. package/dist/cloud/nexus-cloud.js +3 -3
  10. package/dist/cloud/nexus-cloud.js.map +1 -1
  11. package/dist/cloud/nexus-device.d.ts +1 -1
  12. package/dist/cloud/nexus-link.d.ts +18 -2
  13. package/dist/cloud/nexus-link.d.ts.map +1 -1
  14. package/dist/cloud/nexus-link.js +26 -6
  15. package/dist/cloud/nexus-link.js.map +1 -1
  16. package/dist/cloud/nexus-vault.d.ts.map +1 -1
  17. package/dist/cloud/nexus-vault.js +3 -9
  18. package/dist/cloud/nexus-vault.js.map +1 -1
  19. package/dist/decide/sites/registry.d.ts +40 -0
  20. package/dist/decide/sites/registry.d.ts.map +1 -1
  21. package/dist/decide/sites/registry.js +38 -0
  22. package/dist/decide/sites/registry.js.map +1 -1
  23. package/dist/docs/adr-allocator.d.ts +3 -3
  24. package/dist/docs/adr-allocator.d.ts.map +1 -1
  25. package/dist/docs/adr-allocator.js +8 -5
  26. package/dist/docs/adr-allocator.js.map +1 -1
  27. package/dist/docs/blob-consolidation.d.ts.map +1 -1
  28. package/dist/docs/blob-consolidation.js +3 -2
  29. package/dist/docs/blob-consolidation.js.map +1 -1
  30. package/dist/docs/derive-links.d.ts +12 -0
  31. package/dist/docs/derive-links.d.ts.map +1 -1
  32. package/dist/docs/derive-links.js +19 -0
  33. package/dist/docs/derive-links.js.map +1 -1
  34. package/dist/docs/doc-name-rule.d.ts +105 -0
  35. package/dist/docs/doc-name-rule.d.ts.map +1 -0
  36. package/dist/docs/doc-name-rule.js +212 -0
  37. package/dist/docs/doc-name-rule.js.map +1 -0
  38. package/dist/docs/docs-inconsistency-detector.d.ts.map +1 -1
  39. package/dist/docs/docs-inconsistency-detector.js +4 -3
  40. package/dist/docs/docs-inconsistency-detector.js.map +1 -1
  41. package/dist/docs/docs-ops.d.ts +27 -5
  42. package/dist/docs/docs-ops.d.ts.map +1 -1
  43. package/dist/docs/docs-ops.js +149 -17
  44. package/dist/docs/docs-ops.js.map +1 -1
  45. package/dist/docs/docs-read-model.d.ts +45 -15
  46. package/dist/docs/docs-read-model.d.ts.map +1 -1
  47. package/dist/docs/docs-read-model.js +22 -102
  48. package/dist/docs/docs-read-model.js.map +1 -1
  49. package/dist/docs/docs-update.d.ts.map +1 -1
  50. package/dist/docs/docs-update.js +8 -2
  51. package/dist/docs/docs-update.js.map +1 -1
  52. package/dist/docs/doctor.d.ts +71 -4
  53. package/dist/docs/doctor.d.ts.map +1 -1
  54. package/dist/docs/doctor.js +324 -23
  55. package/dist/docs/doctor.js.map +1 -1
  56. package/dist/docs/duplicate-check.d.ts +138 -0
  57. package/dist/docs/duplicate-check.d.ts.map +1 -0
  58. package/dist/docs/duplicate-check.js +286 -0
  59. package/dist/docs/duplicate-check.js.map +1 -0
  60. package/dist/docs/fetch-result.d.ts.map +1 -1
  61. package/dist/docs/fetch-result.js +27 -0
  62. package/dist/docs/fetch-result.js.map +1 -1
  63. package/dist/docs/import/scanner.d.ts +2 -0
  64. package/dist/docs/import/scanner.d.ts.map +1 -1
  65. package/dist/docs/import/scanner.js +3 -1
  66. package/dist/docs/import/scanner.js.map +1 -1
  67. package/dist/docs/lineage.d.ts +66 -0
  68. package/dist/docs/lineage.d.ts.map +1 -0
  69. package/dist/docs/lineage.js +190 -0
  70. package/dist/docs/lineage.js.map +1 -0
  71. package/dist/docs/modernize/apply.d.ts +139 -0
  72. package/dist/docs/modernize/apply.d.ts.map +1 -0
  73. package/dist/docs/modernize/apply.js +760 -0
  74. package/dist/docs/modernize/apply.js.map +1 -0
  75. package/dist/docs/modernize/guard.d.ts +92 -0
  76. package/dist/docs/modernize/guard.d.ts.map +1 -0
  77. package/dist/docs/modernize/guard.js +214 -0
  78. package/dist/docs/modernize/guard.js.map +1 -0
  79. package/dist/docs/modernize/index.d.ts +68 -0
  80. package/dist/docs/modernize/index.d.ts.map +1 -0
  81. package/dist/docs/modernize/index.js +97 -0
  82. package/dist/docs/modernize/index.js.map +1 -0
  83. package/dist/docs/modernize/judge.d.ts +85 -0
  84. package/dist/docs/modernize/judge.d.ts.map +1 -0
  85. package/dist/docs/modernize/judge.js +186 -0
  86. package/dist/docs/modernize/judge.js.map +1 -0
  87. package/dist/docs/modernize/plan.d.ts +77 -0
  88. package/dist/docs/modernize/plan.d.ts.map +1 -0
  89. package/dist/docs/modernize/plan.js +510 -0
  90. package/dist/docs/modernize/plan.js.map +1 -0
  91. package/dist/docs/modernize/restore.d.ts +41 -0
  92. package/dist/docs/modernize/restore.d.ts.map +1 -0
  93. package/dist/docs/modernize/restore.js +103 -0
  94. package/dist/docs/modernize/restore.js.map +1 -0
  95. package/dist/docs/modernize/rules.d.ts +197 -0
  96. package/dist/docs/modernize/rules.d.ts.map +1 -0
  97. package/dist/docs/modernize/rules.js +510 -0
  98. package/dist/docs/modernize/rules.js.map +1 -0
  99. package/dist/docs/modernize/store.d.ts +64 -0
  100. package/dist/docs/modernize/store.d.ts.map +1 -0
  101. package/dist/docs/modernize/store.js +390 -0
  102. package/dist/docs/modernize/store.js.map +1 -0
  103. package/dist/docs/publications-store.d.ts +16 -2
  104. package/dist/docs/publications-store.d.ts.map +1 -1
  105. package/dist/docs/publications-store.js +23 -2
  106. package/dist/docs/publications-store.js.map +1 -1
  107. package/dist/docs/publish-pr.d.ts.map +1 -1
  108. package/dist/docs/publish-pr.js +12 -1
  109. package/dist/docs/publish-pr.js.map +1 -1
  110. package/dist/docs/rot.d.ts +94 -0
  111. package/dist/docs/rot.d.ts.map +1 -0
  112. package/dist/docs/rot.js +298 -0
  113. package/dist/docs/rot.js.map +1 -0
  114. package/dist/docs/similarity-check.d.ts +2 -0
  115. package/dist/docs/similarity-check.d.ts.map +1 -1
  116. package/dist/docs/similarity-check.js +6 -49
  117. package/dist/docs/similarity-check.js.map +1 -1
  118. package/dist/docs/slug-rename.d.ts +84 -0
  119. package/dist/docs/slug-rename.d.ts.map +1 -0
  120. package/dist/docs/slug-rename.js +166 -0
  121. package/dist/docs/slug-rename.js.map +1 -0
  122. package/dist/docs/slug-similarity.d.ts +24 -0
  123. package/dist/docs/slug-similarity.d.ts.map +1 -0
  124. package/dist/docs/slug-similarity.js +63 -0
  125. package/dist/docs/slug-similarity.js.map +1 -0
  126. package/dist/docs/wikilinks.d.ts +20 -4
  127. package/dist/docs/wikilinks.d.ts.map +1 -1
  128. package/dist/docs/wikilinks.js +52 -7
  129. package/dist/docs/wikilinks.js.map +1 -1
  130. package/dist/docs/writer-registry.d.ts.map +1 -1
  131. package/dist/docs/writer-registry.js +33 -0
  132. package/dist/docs/writer-registry.js.map +1 -1
  133. package/dist/doctor/type-matrix-repair.d.ts +194 -0
  134. package/dist/doctor/type-matrix-repair.d.ts.map +1 -0
  135. package/dist/doctor/type-matrix-repair.js +662 -0
  136. package/dist/doctor/type-matrix-repair.js.map +1 -0
  137. package/dist/gateway-client/generated/index.d.ts +2 -2
  138. package/dist/gateway-client/generated/index.d.ts.map +1 -1
  139. package/dist/gateway-client/generated/index.js +1 -1
  140. package/dist/gateway-client/generated/index.js.map +1 -1
  141. package/dist/gateway-client/generated/namespaces.gen.d.ts +5 -0
  142. package/dist/gateway-client/generated/namespaces.gen.d.ts.map +1 -1
  143. package/dist/gateway-client/generated/namespaces.gen.js +6 -1
  144. package/dist/gateway-client/generated/namespaces.gen.js.map +1 -1
  145. package/dist/gateway-client/generated/sdk.gen.d.ts +21 -1
  146. package/dist/gateway-client/generated/sdk.gen.d.ts.map +1 -1
  147. package/dist/gateway-client/generated/sdk.gen.js +55 -0
  148. package/dist/gateway-client/generated/sdk.gen.js.map +1 -1
  149. package/dist/gateway-client/generated/types.gen.d.ts +222 -0
  150. package/dist/gateway-client/generated/types.gen.d.ts.map +1 -1
  151. package/dist/gc/gc-subsystem.d.ts +4 -0
  152. package/dist/gc/gc-subsystem.d.ts.map +1 -1
  153. package/dist/gc/gc-subsystem.js +16 -0
  154. package/dist/gc/gc-subsystem.js.map +1 -1
  155. package/dist/git/work-tree.d.ts +48 -0
  156. package/dist/git/work-tree.d.ts.map +1 -1
  157. package/dist/git/work-tree.js +63 -1
  158. package/dist/git/work-tree.js.map +1 -1
  159. package/dist/hooks/handlers/session-hooks.d.ts +5 -4
  160. package/dist/hooks/handlers/session-hooks.d.ts.map +1 -1
  161. package/dist/hooks/handlers/session-hooks.js +5 -21
  162. package/dist/hooks/handlers/session-hooks.js.map +1 -1
  163. package/dist/internal.d.ts +5 -1
  164. package/dist/internal.d.ts.map +1 -1
  165. package/dist/internal.js +5 -1
  166. package/dist/internal.js.map +1 -1
  167. package/dist/memory/brain-doctor.d.ts.map +1 -1
  168. package/dist/memory/brain-doctor.js +6 -1
  169. package/dist/memory/brain-doctor.js.map +1 -1
  170. package/dist/memory/engine-compat.d.ts.map +1 -1
  171. package/dist/memory/engine-compat.js +6 -0
  172. package/dist/memory/engine-compat.js.map +1 -1
  173. package/dist/nexus/analyze-orchestrator.d.ts +24 -0
  174. package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
  175. package/dist/nexus/analyze-orchestrator.js +43 -5
  176. package/dist/nexus/analyze-orchestrator.js.map +1 -1
  177. package/dist/nexus/user-profile.d.ts +2 -1
  178. package/dist/nexus/user-profile.d.ts.map +1 -1
  179. package/dist/nexus/user-profile.js +13 -5
  180. package/dist/nexus/user-profile.js.map +1 -1
  181. package/dist/orchestrate/admission.d.ts +8 -0
  182. package/dist/orchestrate/admission.d.ts.map +1 -1
  183. package/dist/orchestrate/admission.js +3 -1
  184. package/dist/orchestrate/admission.js.map +1 -1
  185. package/dist/orchestrate/query-ops.d.ts.map +1 -1
  186. package/dist/orchestrate/query-ops.js +15 -4
  187. package/dist/orchestrate/query-ops.js.map +1 -1
  188. package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
  189. package/dist/orchestrate/spawn-ops.js +43 -2
  190. package/dist/orchestrate/spawn-ops.js.map +1 -1
  191. package/dist/orchestration/index.d.ts +6 -0
  192. package/dist/orchestration/index.d.ts.map +1 -1
  193. package/dist/orchestration/index.js +3 -0
  194. package/dist/orchestration/index.js.map +1 -1
  195. package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
  196. package/dist/orchestration/spawn-prompt.js +3 -1
  197. package/dist/orchestration/spawn-prompt.js.map +1 -1
  198. package/dist/paths.d.ts +43 -1
  199. package/dist/paths.d.ts.map +1 -1
  200. package/dist/paths.js +51 -1
  201. package/dist/paths.js.map +1 -1
  202. package/dist/project-lifecycle.d.ts.map +1 -1
  203. package/dist/project-lifecycle.js +31 -0
  204. package/dist/project-lifecycle.js.map +1 -1
  205. package/dist/release/authorization.d.ts +156 -0
  206. package/dist/release/authorization.d.ts.map +1 -0
  207. package/dist/release/authorization.js +460 -0
  208. package/dist/release/authorization.js.map +1 -0
  209. package/dist/release/ci-evidence.d.ts +55 -4
  210. package/dist/release/ci-evidence.d.ts.map +1 -1
  211. package/dist/release/ci-evidence.js +251 -22
  212. package/dist/release/ci-evidence.js.map +1 -1
  213. package/dist/release/ci-run-evidence.d.ts +107 -0
  214. package/dist/release/ci-run-evidence.d.ts.map +1 -0
  215. package/dist/release/ci-run-evidence.js +234 -0
  216. package/dist/release/ci-run-evidence.js.map +1 -0
  217. package/dist/release/cut.d.ts +231 -0
  218. package/dist/release/cut.d.ts.map +1 -0
  219. package/dist/release/cut.js +775 -0
  220. package/dist/release/cut.js.map +1 -0
  221. package/dist/release/deploy-evidence.d.ts +173 -0
  222. package/dist/release/deploy-evidence.d.ts.map +1 -0
  223. package/dist/release/deploy-evidence.js +381 -0
  224. package/dist/release/deploy-evidence.js.map +1 -0
  225. package/dist/release/engine-ops.d.ts.map +1 -1
  226. package/dist/release/engine-ops.js +10 -4
  227. package/dist/release/engine-ops.js.map +1 -1
  228. package/dist/release/index.d.ts +3 -0
  229. package/dist/release/index.d.ts.map +1 -1
  230. package/dist/release/index.js +2 -0
  231. package/dist/release/index.js.map +1 -1
  232. package/dist/release/invariants/archive-reason-invariant.d.ts.map +1 -1
  233. package/dist/release/invariants/archive-reason-invariant.js +4 -1
  234. package/dist/release/invariants/archive-reason-invariant.js.map +1 -1
  235. package/dist/release/open.d.ts.map +1 -1
  236. package/dist/release/open.js +2 -6
  237. package/dist/release/open.js.map +1 -1
  238. package/dist/release/plan.d.ts +34 -2
  239. package/dist/release/plan.d.ts.map +1 -1
  240. package/dist/release/plan.js +30 -6
  241. package/dist/release/plan.js.map +1 -1
  242. package/dist/release/preflight-skip.d.ts +4 -19
  243. package/dist/release/preflight-skip.d.ts.map +1 -1
  244. package/dist/release/preflight-skip.js +5 -110
  245. package/dist/release/preflight-skip.js.map +1 -1
  246. package/dist/release/reconcile-latest.d.ts +29 -0
  247. package/dist/release/reconcile-latest.d.ts.map +1 -0
  248. package/dist/release/reconcile-latest.js +71 -0
  249. package/dist/release/reconcile-latest.js.map +1 -0
  250. package/dist/release/reconcile.d.ts +3 -1
  251. package/dist/release/reconcile.d.ts.map +1 -1
  252. package/dist/release/reconcile.js +18 -6
  253. package/dist/release/reconcile.js.map +1 -1
  254. package/dist/release/release-published.d.ts +27 -0
  255. package/dist/release/release-published.d.ts.map +1 -0
  256. package/dist/release/release-published.js +35 -0
  257. package/dist/release/release-published.js.map +1 -0
  258. package/dist/release/tty-confirm.d.ts +23 -0
  259. package/dist/release/tty-confirm.d.ts.map +1 -0
  260. package/dist/release/tty-confirm.js +50 -0
  261. package/dist/release/tty-confirm.js.map +1 -0
  262. package/dist/remote/index.js +1 -1
  263. package/dist/remote/index.js.map +1 -1
  264. package/dist/resources/admission-ledger.d.ts +103 -1
  265. package/dist/resources/admission-ledger.d.ts.map +1 -1
  266. package/dist/resources/admission-ledger.js +200 -17
  267. package/dist/resources/admission-ledger.js.map +1 -1
  268. package/dist/resources/agent-lease.d.ts +82 -0
  269. package/dist/resources/agent-lease.d.ts.map +1 -0
  270. package/dist/resources/agent-lease.js +167 -0
  271. package/dist/resources/agent-lease.js.map +1 -0
  272. package/dist/resources/governor.d.ts +27 -1
  273. package/dist/resources/governor.d.ts.map +1 -1
  274. package/dist/resources/governor.js +88 -4
  275. package/dist/resources/governor.js.map +1 -1
  276. package/dist/resources/hook-footprint.d.ts +13 -1
  277. package/dist/resources/hook-footprint.d.ts.map +1 -1
  278. package/dist/resources/hook-footprint.js +33 -7
  279. package/dist/resources/hook-footprint.js.map +1 -1
  280. package/dist/resources/run-governed.d.ts +25 -0
  281. package/dist/resources/run-governed.d.ts.map +1 -1
  282. package/dist/resources/run-governed.js +44 -3
  283. package/dist/resources/run-governed.js.map +1 -1
  284. package/dist/sagas/reconcile.d.ts.map +1 -1
  285. package/dist/sagas/reconcile.js +11 -0
  286. package/dist/sagas/reconcile.js.map +1 -1
  287. package/dist/scaffold/ensure-dirs.d.ts.map +1 -1
  288. package/dist/scaffold/ensure-dirs.js +8 -6
  289. package/dist/scaffold/ensure-dirs.js.map +1 -1
  290. package/dist/security/override-cap-setting.d.ts +132 -0
  291. package/dist/security/override-cap-setting.d.ts.map +1 -1
  292. package/dist/security/override-cap-setting.js +88 -10
  293. package/dist/security/override-cap-setting.js.map +1 -1
  294. package/dist/security/owner-override-authority.d.ts.map +1 -1
  295. package/dist/security/owner-override-authority.js +5 -1
  296. package/dist/security/owner-override-authority.js.map +1 -1
  297. package/dist/selfimprove/draft-pr.d.ts.map +1 -1
  298. package/dist/selfimprove/draft-pr.js +4 -1
  299. package/dist/selfimprove/draft-pr.js.map +1 -1
  300. package/dist/session/engine-ops.d.ts.map +1 -1
  301. package/dist/session/engine-ops.js +4 -16
  302. package/dist/session/engine-ops.js.map +1 -1
  303. package/dist/sessions/briefing.d.ts +6 -0
  304. package/dist/sessions/briefing.d.ts.map +1 -1
  305. package/dist/sessions/briefing.js +34 -0
  306. package/dist/sessions/briefing.js.map +1 -1
  307. package/dist/sessions/session-end-snapshot-entry.js +2 -2
  308. package/dist/sessions/session-end-snapshot-entry.js.map +1 -1
  309. package/dist/sessions/session-end-snapshot.js +4 -4
  310. package/dist/sessions/session-end-snapshot.js.map +1 -1
  311. package/dist/skills/injection/token.d.ts.map +1 -1
  312. package/dist/skills/injection/token.js +3 -6
  313. package/dist/skills/injection/token.js.map +1 -1
  314. package/dist/skills/orchestrator/spawn.d.ts.map +1 -1
  315. package/dist/skills/orchestrator/spawn.js +3 -4
  316. package/dist/skills/orchestrator/spawn.js.map +1 -1
  317. package/dist/skills/propose-patch.d.ts.map +1 -1
  318. package/dist/skills/propose-patch.js +4 -1
  319. package/dist/skills/propose-patch.js.map +1 -1
  320. package/dist/spawn/branch-integration.d.ts.map +1 -1
  321. package/dist/spawn/branch-integration.js +5 -2
  322. package/dist/spawn/branch-integration.js.map +1 -1
  323. package/dist/store/attachment-repair.d.ts.map +1 -1
  324. package/dist/store/attachment-repair.js +5 -4
  325. package/dist/store/attachment-repair.js.map +1 -1
  326. package/dist/store/attachment-store.d.ts +6 -0
  327. package/dist/store/attachment-store.d.ts.map +1 -1
  328. package/dist/store/attachment-store.js +19 -2
  329. package/dist/store/attachment-store.js.map +1 -1
  330. package/dist/store/blob-ops.d.ts +1 -1
  331. package/dist/store/blob-ops.d.ts.map +1 -1
  332. package/dist/store/blob-ops.js +7 -3
  333. package/dist/store/blob-ops.js.map +1 -1
  334. package/dist/store/conduit-doc-history.d.ts +15 -1
  335. package/dist/store/conduit-doc-history.d.ts.map +1 -1
  336. package/dist/store/conduit-doc-history.js +16 -10
  337. package/dist/store/conduit-doc-history.js.map +1 -1
  338. package/dist/store/db-helpers.d.ts +29 -0
  339. package/dist/store/db-helpers.d.ts.map +1 -1
  340. package/dist/store/db-helpers.js +89 -1
  341. package/dist/store/db-helpers.js.map +1 -1
  342. package/dist/store/decision-adr-links.d.ts.map +1 -1
  343. package/dist/store/decision-adr-links.js +5 -2
  344. package/dist/store/decision-adr-links.js.map +1 -1
  345. package/dist/store/git-checkpoint.d.ts +11 -1
  346. package/dist/store/git-checkpoint.d.ts.map +1 -1
  347. package/dist/store/git-checkpoint.js +14 -3
  348. package/dist/store/git-checkpoint.js.map +1 -1
  349. package/dist/store/llmtxt-blob-adapter.d.ts.map +1 -1
  350. package/dist/store/llmtxt-blob-adapter.js +4 -1
  351. package/dist/store/llmtxt-blob-adapter.js.map +1 -1
  352. package/dist/store/schema/attachments.d.ts +7 -5
  353. package/dist/store/schema/attachments.d.ts.map +1 -1
  354. package/dist/store/schema/attachments.js +5 -2
  355. package/dist/store/schema/attachments.js.map +1 -1
  356. package/dist/store/session-store.d.ts.map +1 -1
  357. package/dist/store/session-store.js +6 -0
  358. package/dist/store/session-store.js.map +1 -1
  359. package/dist/store/sqlite-backup.d.ts +6 -1
  360. package/dist/store/sqlite-backup.d.ts.map +1 -1
  361. package/dist/store/sqlite-backup.js +9 -5
  362. package/dist/store/sqlite-backup.js.map +1 -1
  363. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  364. package/dist/store/sqlite-data-accessor.js +63 -36
  365. package/dist/store/sqlite-data-accessor.js.map +1 -1
  366. package/dist/system/backup.d.ts +29 -0
  367. package/dist/system/backup.d.ts.map +1 -1
  368. package/dist/system/backup.js +240 -37
  369. package/dist/system/backup.js.map +1 -1
  370. package/dist/system/dependencies.d.ts +22 -0
  371. package/dist/system/dependencies.d.ts.map +1 -1
  372. package/dist/system/dependencies.js +49 -2
  373. package/dist/system/dependencies.js.map +1 -1
  374. package/dist/system/health.d.ts.map +1 -1
  375. package/dist/system/health.js +23 -1
  376. package/dist/system/health.js.map +1 -1
  377. package/dist/task-work/claims.d.ts.map +1 -1
  378. package/dist/task-work/claims.js +14 -0
  379. package/dist/task-work/claims.js.map +1 -1
  380. package/dist/task-work/index.d.ts.map +1 -1
  381. package/dist/task-work/index.js +22 -0
  382. package/dist/task-work/index.js.map +1 -1
  383. package/dist/tasks/ac-coverage-gate.d.ts +27 -0
  384. package/dist/tasks/ac-coverage-gate.d.ts.map +1 -1
  385. package/dist/tasks/ac-coverage-gate.js +63 -28
  386. package/dist/tasks/ac-coverage-gate.js.map +1 -1
  387. package/dist/tasks/affected-packages.d.ts +26 -30
  388. package/dist/tasks/affected-packages.d.ts.map +1 -1
  389. package/dist/tasks/affected-packages.js +27 -50
  390. package/dist/tasks/affected-packages.js.map +1 -1
  391. package/dist/tasks/affected-scope.d.ts +13 -3
  392. package/dist/tasks/affected-scope.d.ts.map +1 -1
  393. package/dist/tasks/affected-scope.js +29 -11
  394. package/dist/tasks/affected-scope.js.map +1 -1
  395. package/dist/tasks/change-set.d.ts.map +1 -1
  396. package/dist/tasks/change-set.js +39 -20
  397. package/dist/tasks/change-set.js.map +1 -1
  398. package/dist/tasks/command-gate-cmd.d.ts +33 -0
  399. package/dist/tasks/command-gate-cmd.d.ts.map +1 -0
  400. package/dist/tasks/command-gate-cmd.js +45 -0
  401. package/dist/tasks/command-gate-cmd.js.map +1 -0
  402. package/dist/tasks/complete-ci.d.ts +9 -0
  403. package/dist/tasks/complete-ci.d.ts.map +1 -1
  404. package/dist/tasks/complete-ci.js +21 -4
  405. package/dist/tasks/complete-ci.js.map +1 -1
  406. package/dist/tasks/complete.d.ts.map +1 -1
  407. package/dist/tasks/complete.js +14 -0
  408. package/dist/tasks/complete.js.map +1 -1
  409. package/dist/tasks/component-pr.d.ts +37 -0
  410. package/dist/tasks/component-pr.d.ts.map +1 -1
  411. package/dist/tasks/component-pr.js +106 -14
  412. package/dist/tasks/component-pr.js.map +1 -1
  413. package/dist/tasks/done-plan.d.ts +14 -1
  414. package/dist/tasks/done-plan.d.ts.map +1 -1
  415. package/dist/tasks/done-plan.js +125 -15
  416. package/dist/tasks/done-plan.js.map +1 -1
  417. package/dist/tasks/done-record.d.ts.map +1 -1
  418. package/dist/tasks/done-record.js +4 -0
  419. package/dist/tasks/done-record.js.map +1 -1
  420. package/dist/tasks/engine-converters.d.ts.map +1 -1
  421. package/dist/tasks/engine-converters.js +2 -0
  422. package/dist/tasks/engine-converters.js.map +1 -1
  423. package/dist/tasks/evidence-tree.d.ts +28 -1
  424. package/dist/tasks/evidence-tree.d.ts.map +1 -1
  425. package/dist/tasks/evidence-tree.js +66 -2
  426. package/dist/tasks/evidence-tree.js.map +1 -1
  427. package/dist/tasks/evidence.d.ts +39 -27
  428. package/dist/tasks/evidence.d.ts.map +1 -1
  429. package/dist/tasks/evidence.js +382 -188
  430. package/dist/tasks/evidence.js.map +1 -1
  431. package/dist/tasks/gate-notes.d.ts +17 -0
  432. package/dist/tasks/gate-notes.d.ts.map +1 -1
  433. package/dist/tasks/gate-notes.js.map +1 -1
  434. package/dist/tasks/gate-preview.d.ts +7 -1
  435. package/dist/tasks/gate-preview.d.ts.map +1 -1
  436. package/dist/tasks/gate-preview.js +30 -4
  437. package/dist/tasks/gate-preview.js.map +1 -1
  438. package/dist/tasks/gate-runner.d.ts +42 -0
  439. package/dist/tasks/gate-runner.d.ts.map +1 -1
  440. package/dist/tasks/gate-runner.js +234 -94
  441. package/dist/tasks/gate-runner.js.map +1 -1
  442. package/dist/tasks/manifest-scope.d.ts +115 -0
  443. package/dist/tasks/manifest-scope.d.ts.map +1 -0
  444. package/dist/tasks/manifest-scope.js +352 -0
  445. package/dist/tasks/manifest-scope.js.map +1 -0
  446. package/dist/tasks/merge-close.d.ts +376 -0
  447. package/dist/tasks/merge-close.d.ts.map +1 -0
  448. package/dist/tasks/merge-close.js +1497 -0
  449. package/dist/tasks/merge-close.js.map +1 -0
  450. package/dist/tasks/qa-run-binding.d.ts +5 -0
  451. package/dist/tasks/qa-run-binding.d.ts.map +1 -1
  452. package/dist/tasks/qa-run-binding.js +6 -1
  453. package/dist/tasks/qa-run-binding.js.map +1 -1
  454. package/dist/tasks/req.d.ts.map +1 -1
  455. package/dist/tasks/req.js +29 -1
  456. package/dist/tasks/req.js.map +1 -1
  457. package/dist/tasks/review-verdict.d.ts +159 -0
  458. package/dist/tasks/review-verdict.d.ts.map +1 -0
  459. package/dist/tasks/review-verdict.js +442 -0
  460. package/dist/tasks/review-verdict.js.map +1 -0
  461. package/dist/tasks/task-reparent.d.ts.map +1 -1
  462. package/dist/tasks/task-reparent.js +22 -3
  463. package/dist/tasks/task-reparent.js.map +1 -1
  464. package/dist/tasks/test-report-counts.d.ts +274 -0
  465. package/dist/tasks/test-report-counts.d.ts.map +1 -0
  466. package/dist/tasks/test-report-counts.js +746 -0
  467. package/dist/tasks/test-report-counts.js.map +1 -0
  468. package/dist/tasks/test-run-binding.d.ts +20 -45
  469. package/dist/tasks/test-run-binding.d.ts.map +1 -1
  470. package/dist/tasks/test-run-binding.js +34 -119
  471. package/dist/tasks/test-run-binding.js.map +1 -1
  472. package/dist/tasks/update.d.ts.map +1 -1
  473. package/dist/tasks/update.js +42 -0
  474. package/dist/tasks/update.js.map +1 -1
  475. package/dist/tasks/verification-policy.d.ts +12 -0
  476. package/dist/tasks/verification-policy.d.ts.map +1 -1
  477. package/dist/tasks/verification-policy.js +13 -0
  478. package/dist/tasks/verification-policy.js.map +1 -1
  479. package/dist/tasks/workspace-resolution.d.ts +225 -0
  480. package/dist/tasks/workspace-resolution.d.ts.map +1 -0
  481. package/dist/tasks/workspace-resolution.js +497 -0
  482. package/dist/tasks/workspace-resolution.js.map +1 -0
  483. package/dist/validation/doctor/checks.d.ts +20 -0
  484. package/dist/validation/doctor/checks.d.ts.map +1 -1
  485. package/dist/validation/doctor/checks.js +112 -0
  486. package/dist/validation/doctor/checks.js.map +1 -1
  487. package/dist/validation/engine-ops.d.ts.map +1 -1
  488. package/dist/validation/engine-ops.js +37 -3
  489. package/dist/validation/engine-ops.js.map +1 -1
  490. package/dist/validation/validate-ops.d.ts +4 -0
  491. package/dist/validation/validate-ops.d.ts.map +1 -1
  492. package/dist/validation/validate-ops.js +79 -2
  493. package/dist/validation/validate-ops.js.map +1 -1
  494. package/dist/worktree/list.d.ts +4 -21
  495. package/dist/worktree/list.d.ts.map +1 -1
  496. package/dist/worktree/list.js +14 -44
  497. package/dist/worktree/list.js.map +1 -1
  498. package/dist/worktree/merged-cleanup.d.ts +63 -0
  499. package/dist/worktree/merged-cleanup.d.ts.map +1 -0
  500. package/dist/worktree/merged-cleanup.js +571 -0
  501. package/dist/worktree/merged-cleanup.js.map +1 -0
  502. package/dist/worktree/prune.d.ts +64 -2
  503. package/dist/worktree/prune.d.ts.map +1 -1
  504. package/dist/worktree/prune.js +151 -6
  505. package/dist/worktree/prune.js.map +1 -1
  506. package/dist/worktree/sentinel-index.d.ts +14 -0
  507. package/dist/worktree/sentinel-index.d.ts.map +1 -1
  508. package/dist/worktree/sentinel-index.js +17 -0
  509. package/dist/worktree/sentinel-index.js.map +1 -1
  510. package/dist/worktree/worktree-adopt.d.ts +1 -13
  511. package/dist/worktree/worktree-adopt.d.ts.map +1 -1
  512. package/dist/worktree/worktree-adopt.js +2 -17
  513. package/dist/worktree/worktree-adopt.js.map +1 -1
  514. package/package.json +12 -12
  515. package/schemas/project-context.schema.json +33 -0
  516. package/templates/CLEO-INJECTION.md +6 -16
  517. package/templates/CLEO-REFERENCE.md +27 -4
  518. package/templates/git-hooks/legacy-hashes.json +2 -1
  519. package/templates/git-hooks/pre-commit +43 -11
  520. package/templates/workflows/release-prepare.yml.tmpl +9 -88
@@ -0,0 +1,460 @@
1
+ /**
2
+ * Standing release authorization (T14141 · owner decisions D11212, D11215).
3
+ *
4
+ * `cleo release cut --yes` tags when the person at the terminal types the
5
+ * version, or when the owner stored a standing authorization covering it (an
6
+ * agent). A grant is created only through the owner check of
7
+ * `cleo config owner set` (T13787): not a restricted agent role, a TTY, and the
8
+ * owner-auth password typed now. It is signed with the enrolled owner key
9
+ * (`ownerKey`), so an agent cannot forge or widen one without the password.
10
+ *
11
+ * ## Storage, anchored twice
12
+ *
13
+ * The grant lives in `.cleo/release-authorizations.json` (untracked) AND in
14
+ * `<cleoHome>/release-authorizations.json` under the project's key. It counts
15
+ * only when both copies are identical, the signature verifies against the
16
+ * enrolled key, and the enrollment itself judges `ok`.
17
+ *
18
+ * ## Revocation, signed and counted (fail closed)
19
+ *
20
+ * Revoking is owner-only like granting (the password signs it). It removes the
21
+ * grant from both files and appends a signed revocation entry to both, and the
22
+ * revocation count is sealed in the git-tracked `.cleo/owner-settings.json`.
23
+ * Every grant also signs the count at issue. If the two revocation lists
24
+ * differ, an entry is not signed, the list is shorter than the sealed count or
25
+ * than any grant's count at issue, or the count's seal fails, EVERY grant is
26
+ * treated as tampered. Restoring old copies of both grant files therefore does
27
+ * not revive a revoked grant: the sealed count still names the revocation, and
28
+ * rolling that back too shows in `git status`. As with the override cap, an
29
+ * agent running as the same OS user can still edit these files: tampering is
30
+ * detectable (refused, audited, shown by `cleo doctor`), not preventable.
31
+ *
32
+ * ## Scope, expiry, uses (D11215)
33
+ *
34
+ * Scope `canary`, `prerelease`, `stable` or one exact version; `cut`'s own
35
+ * version gates (CalVer, above the newest tag) still apply. Expiry is required,
36
+ * at most 30 days. `uses` is an optional cap; without it the count is only
37
+ * reported. Uses are counted from the cut audit rows and from the tags whose
38
+ * message names the grant (`Authorized-by: <id>`), whichever is higher.
39
+ *
40
+ * @task T14141
41
+ * @task T14102
42
+ */
43
+ import { execFileSync } from 'node:child_process';
44
+ import { randomBytes } from 'node:crypto';
45
+ import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
46
+ import { dirname, join } from 'node:path';
47
+ import { getCleoHome } from '../paths.js';
48
+ import { judgeOwnerState, ownerCheck, ownerKey, projectKey, provenance, readSealedOwnerSetting, writeSealedOwnerSetting, } from '../security/override-cap-setting.js';
49
+ import { atomicWriteJson } from '../store/atomic.js';
50
+ /** The longest a grant may run (D11215). */
51
+ export const RELEASE_AUTHORIZATION_MAX_DAYS = 30;
52
+ /** Grant/revoke/refusal audit log, relative to the project root. */
53
+ export const RELEASE_AUTHORIZATION_AUDIT_FILE = '.cleo/audit/release-authorizations.jsonl';
54
+ /** The tag-message trailer that names the grant a cut used. */
55
+ export const AUTHORIZED_BY_TRAILER = 'Authorized-by';
56
+ /** The owner-settings key sealing how many grants were ever revoked. */
57
+ export const REVOCATION_COUNT_SETTING = 'release.authorizationRevocations';
58
+ const PROJECT_FILE = join('.cleo', 'release-authorizations.json');
59
+ const CUT_AUDIT_FILE = '.cleo/audit/release-cut.jsonl';
60
+ function globalPath() {
61
+ return join(getCleoHome(), 'release-authorizations.json');
62
+ }
63
+ function readJson(path, fallback) {
64
+ try {
65
+ return existsSync(path) ? JSON.parse(readFileSync(path, 'utf-8')) : fallback;
66
+ }
67
+ catch {
68
+ return fallback;
69
+ }
70
+ }
71
+ function readProject(projectRoot) {
72
+ const file = readJson(join(projectRoot, PROJECT_FILE), {});
73
+ return { schemaVersion: 1, grants: file.grants ?? [], revoked: file.revoked ?? [] };
74
+ }
75
+ function readGlobalAll() {
76
+ return readJson(globalPath(), {}).projects ?? {};
77
+ }
78
+ function readGlobal(projectRoot) {
79
+ const record = readGlobalAll()[projectKey(projectRoot)];
80
+ return { grants: record?.grants ?? [], revoked: record?.revoked ?? [] };
81
+ }
82
+ async function writeGlobal(projectRoot, record) {
83
+ const all = readGlobalAll();
84
+ all[projectKey(projectRoot)] = record;
85
+ await atomicWriteJson(globalPath(), { schemaVersion: 1, projects: all });
86
+ }
87
+ /** The exact bytes a grant's signature covers. */
88
+ function grantPayload(projectRoot, g) {
89
+ return JSON.stringify({
90
+ kind: 'release-authorization',
91
+ project: projectKey(projectRoot),
92
+ id: g.id,
93
+ scope: g.scope,
94
+ reason: g.reason,
95
+ issuedAt: g.issuedAt,
96
+ expiresAt: g.expiresAt,
97
+ uses: g.uses,
98
+ decisionId: g.decisionId,
99
+ revocationsAtIssue: g.revocationsAtIssue,
100
+ ownerPubkey: g.ownerPubkey,
101
+ });
102
+ }
103
+ /** The exact bytes a revocation's signature covers. */
104
+ function revocationPayload(projectRoot, r, ownerPubkey) {
105
+ return JSON.stringify({
106
+ kind: 'release-authorization-revocation',
107
+ project: projectKey(projectRoot),
108
+ id: r.id,
109
+ revokedAt: r.revokedAt,
110
+ ownerPubkey,
111
+ });
112
+ }
113
+ /**
114
+ * Why the revocation record cannot be trusted, or null. Any answer other than
115
+ * null makes every grant tampered (fail closed).
116
+ */
117
+ async function revocationProblem(projectRoot, project, global, ownerPubkey) {
118
+ if (JSON.stringify(project.revoked) !== JSON.stringify(global.revoked))
119
+ return 'the project and global revocation lists differ';
120
+ const sealed = await readSealedOwnerSetting(projectRoot, REVOCATION_COUNT_SETTING);
121
+ if (sealed === 'tampered')
122
+ return `${REVOCATION_COUNT_SETTING} is not sealed by the enrolled owner key`;
123
+ const count = sealed ?? 0;
124
+ if (global.revoked.length !== count)
125
+ return `the revocation list holds ${global.revoked.length} entries, but the owner sealed ${count} in .cleo/owner-settings.json`;
126
+ const atIssue = Math.max(0, ...[...project.grants, ...global.grants].map((g) => g.revocationsAtIssue ?? 0));
127
+ if (atIssue > global.revoked.length)
128
+ return `a grant was issued after ${atIssue} revocations, but only ${global.revoked.length} are listed`;
129
+ const { verifyAuditLine } = await import('../identity/cleo-identity.js');
130
+ for (const r of global.revoked) {
131
+ if (!(await verifyAuditLine(revocationPayload(projectRoot, r, ownerPubkey), r.sig, ownerPubkey)))
132
+ return `revocation ${r.id} is not signed by the enrolled owner key`;
133
+ }
134
+ return null;
135
+ }
136
+ function audit(projectRoot, row) {
137
+ try {
138
+ const path = join(projectRoot, RELEASE_AUTHORIZATION_AUDIT_FILE);
139
+ mkdirSync(dirname(path), { recursive: true });
140
+ const who = provenance(process.env['CLEO_SESSION_ID'] ?? null);
141
+ appendFileSync(path, `${JSON.stringify({ at: new Date().toISOString(), ...row, tty: who.tty, parent: who.parent, pid: process.pid })}\n`, 'utf-8');
142
+ }
143
+ catch {
144
+ // non-fatal: the signed grant files are the record
145
+ }
146
+ }
147
+ /**
148
+ * Parse a scope argument.
149
+ *
150
+ * @param raw - `canary`, `prerelease`, `stable`, or a version (`2026.10.28`, `v2026.10.28-canary.1`).
151
+ * @returns The scope, or null when it is none of those.
152
+ */
153
+ export function parseReleaseAuthorizationScope(raw) {
154
+ if (raw === 'canary' || raw === 'prerelease' || raw === 'stable')
155
+ return raw;
156
+ const v = raw.startsWith('v') ? raw : `v${raw}`;
157
+ return /^v\d{4}\.\d{1,2}\.\d+(-[0-9A-Za-z.-]+)?$/.test(v) ? v : null;
158
+ }
159
+ /**
160
+ * Whether `scope` covers `version` (`v`-prefixed).
161
+ *
162
+ * @param scope - The grant scope.
163
+ * @param version - The version being cut.
164
+ * @returns True when the grant applies.
165
+ */
166
+ export function scopeCovers(scope, version) {
167
+ if (scope === 'canary')
168
+ return /-canary\.\d+$/.test(version);
169
+ if (scope === 'prerelease')
170
+ return version.includes('-');
171
+ if (scope === 'stable')
172
+ return !version.includes('-');
173
+ return scope === version;
174
+ }
175
+ /** Parse `30m`, `24h` or `7d` into milliseconds; null when malformed or over 30 days. */
176
+ function parseExpiry(raw) {
177
+ const m = /^(\d+)([mhd])$/.exec(raw.trim());
178
+ if (!m)
179
+ return null;
180
+ const ms = Number(m[1]) * { m: 60_000, h: 3_600_000, d: 86_400_000 }[m[2]];
181
+ return ms > 0 && ms <= RELEASE_AUTHORIZATION_MAX_DAYS * 86_400_000 ? ms : null;
182
+ }
183
+ /** Cuts a grant has allowed: audit rows or tags naming it, whichever is higher. */
184
+ function usesOf(projectRoot, id, gitRoot) {
185
+ let rows = 0;
186
+ try {
187
+ for (const line of readFileSync(join(projectRoot, CUT_AUDIT_FILE), 'utf-8').split('\n')) {
188
+ if (line.includes(`"allowedBy":"authorization:${id}"`) && line.includes('"outcome":"tagged"'))
189
+ rows++;
190
+ }
191
+ }
192
+ catch {
193
+ rows = 0;
194
+ }
195
+ let tags = 0;
196
+ try {
197
+ tags = execFileSync('git', ['for-each-ref', '--format=%(contents)', 'refs/tags/v*'], {
198
+ cwd: gitRoot,
199
+ encoding: 'utf-8',
200
+ stdio: ['ignore', 'pipe', 'ignore'],
201
+ })
202
+ .split('\n')
203
+ .filter((l) => l.trim() === `${AUTHORIZED_BY_TRAILER}: ${id}`).length;
204
+ }
205
+ catch {
206
+ tags = 0;
207
+ }
208
+ return Math.max(rows, tags);
209
+ }
210
+ /**
211
+ * Every grant the project knows of, with its state: active, expired, used up,
212
+ * revoked, or tampered (not identical in both files, unsigned, or the owner
213
+ * enrollment itself is not `ok`).
214
+ *
215
+ * @param projectRoot - Project root.
216
+ * @param now - Clock (tests).
217
+ * @param gitRoot - Checkout whose tags are counted (T14160: the invoking one); default `projectRoot`.
218
+ * @returns The grants, newest first.
219
+ *
220
+ * @example
221
+ * ```ts
222
+ * const active = (await listReleaseAuthorizations(root)).filter((g) => g.state === 'active');
223
+ * ```
224
+ *
225
+ * @task T14141
226
+ */
227
+ export async function listReleaseAuthorizations(projectRoot, now = new Date(), gitRoot = projectRoot) {
228
+ const projectFile = readProject(projectRoot);
229
+ const project = projectFile.grants;
230
+ const global = readGlobal(projectRoot);
231
+ const owner = await judgeOwnerState(projectRoot);
232
+ const revocationWhy = owner.kind === 'ok'
233
+ ? await revocationProblem(projectRoot, projectFile, global, owner.file.ownerPubkey)
234
+ : null;
235
+ const { verifyAuditLine } = await import('../identity/cleo-identity.js');
236
+ const ids = [...new Set([...project, ...global.grants].map((g) => g.id))];
237
+ const out = [];
238
+ for (const id of ids) {
239
+ const p = project.find((g) => g.id === id);
240
+ const g = global.grants.find((x) => x.id === id);
241
+ const grant = (g ?? p);
242
+ const used = usesOf(projectRoot, id, gitRoot);
243
+ let state = 'active';
244
+ let why;
245
+ if (global.revoked.some((r) => r.id === id)) {
246
+ state = 'revoked';
247
+ }
248
+ else if (!p || !g || JSON.stringify(p) !== JSON.stringify(g)) {
249
+ state = 'tampered';
250
+ why = 'the project and global copies differ or one is missing';
251
+ }
252
+ else if (owner.kind !== 'ok') {
253
+ state = 'tampered';
254
+ why = owner.kind === 'tampered' ? owner.why : 'no owner is enrolled';
255
+ }
256
+ else if (revocationWhy !== null) {
257
+ state = 'tampered';
258
+ why = revocationWhy;
259
+ }
260
+ else if (grant.ownerPubkey !== owner.file.ownerPubkey ||
261
+ !(await verifyAuditLine(grantPayload(projectRoot, grant), grant.sig, grant.ownerPubkey))) {
262
+ state = 'tampered';
263
+ why = 'the grant is not signed by the enrolled owner key';
264
+ }
265
+ else if (Date.parse(grant.expiresAt) <= now.getTime()) {
266
+ state = 'expired';
267
+ }
268
+ else if (grant.uses !== null && used >= grant.uses) {
269
+ state = 'used-up';
270
+ }
271
+ out.push({ ...grant, state, used, ...(why ? { why } : {}) });
272
+ }
273
+ return out.sort((a, b) => b.issuedAt.localeCompare(a.issuedAt));
274
+ }
275
+ /**
276
+ * The active grant covering `version`, or null. This is the seam
277
+ * `cleo release cut --yes` consults before asking on the terminal (D11212).
278
+ *
279
+ * @param projectRoot - Project whose authorization is read.
280
+ * @param version - Version being cut (`v`-prefixed).
281
+ * @param gitRoot - Checkout whose tags are counted (the invoking one); default `projectRoot`.
282
+ * @returns The grant's id when an active, verified grant covers the cut.
283
+ *
284
+ * @example
285
+ * ```ts
286
+ * const auth = await releaseAuthorizationFor(projectRoot, 'v2026.10.28');
287
+ * ```
288
+ *
289
+ * @task T14141
290
+ */
291
+ export async function releaseAuthorizationFor(projectRoot, version, gitRoot = projectRoot) {
292
+ const grants = await listReleaseAuthorizations(projectRoot, new Date(), gitRoot);
293
+ for (const g of grants.filter((x) => x.state === 'tampered' && scopeCovers(x.scope, version))) {
294
+ audit(projectRoot, {
295
+ action: 'tampered-ignored',
296
+ id: g.id,
297
+ version,
298
+ reason: g.why ?? 'tampered',
299
+ });
300
+ }
301
+ const hit = grants.find((g) => g.state === 'active' && scopeCovers(g.scope, version));
302
+ return hit ? { id: hit.id } : null;
303
+ }
304
+ /**
305
+ * Grant a standing release authorization. Owner-only: the T13787 owner check
306
+ * (role fence, TTY, the owner-auth password against the bound session), an
307
+ * `ok` owner enrollment, and the password deriving the enrolled key. The grant
308
+ * is recorded as an owner decision and audited.
309
+ *
310
+ * @param projectRoot - Project root.
311
+ * @param input - The owner caller, scope, expiry (`30m`/`24h`/`30d`), reason, optional use cap.
312
+ * @returns The signed grant, or the refusal.
313
+ *
314
+ * @example
315
+ * ```ts
316
+ * await grantReleaseAuthorization(root, { ...caller, scope: 'canary', expires: '7d', reason: 'canary train' });
317
+ * ```
318
+ *
319
+ * @task T14141
320
+ */
321
+ export async function grantReleaseAuthorization(projectRoot, input) {
322
+ const refuse = (code, message) => {
323
+ audit(projectRoot, { action: 'grant-refused', code, reason: message, scope: input.scope });
324
+ return { ok: false, code, message };
325
+ };
326
+ const scope = parseReleaseAuthorizationScope(input.scope);
327
+ if (scope === null)
328
+ return refuse('E_VALIDATION', // @sync-invariant none:input-shape a malformed grant request is refused before any write
329
+ `--scope must be canary, prerelease, stable or a CalVer version, not "${input.scope}"`);
330
+ const ttl = parseExpiry(input.expires);
331
+ if (ttl === null)
332
+ return refuse('E_VALIDATION', // @sync-invariant none:input-shape a malformed grant request is refused before any write
333
+ `--expires must be like 30m, 24h or 7d, at most ${RELEASE_AUTHORIZATION_MAX_DAYS}d`);
334
+ if (!input.reason.trim())
335
+ return refuse('E_VALIDATION', '--reason is required'); // @sync-invariant none:input-shape a malformed grant request is refused before any write
336
+ if (input.uses !== undefined && (!Number.isInteger(input.uses) || input.uses < 1))
337
+ return refuse('E_VALIDATION', '--uses must be a positive integer'); // @sync-invariant none:input-shape a malformed grant request is refused before any write
338
+ const check = ownerCheck(input);
339
+ if (!check.ok)
340
+ return refuse(check.code, check.message);
341
+ const state = await judgeOwnerState(projectRoot);
342
+ if (state.kind !== 'ok')
343
+ return refuse('E_OWNER_NOT_ENROLLED', // @sync-invariant none:local-only release grants are device-local owner files; refused before any write
344
+ state.kind === 'tampered'
345
+ ? `Owner settings are not usable: ${state.why}`
346
+ : 'No owner is enrolled for this project; the owner enrolls first with `cleo config owner-enroll`.');
347
+ const key = await ownerKey(input.password, state.file.salt);
348
+ if (key.pubkeyHex !== state.file.ownerPubkey)
349
+ return refuse('E_OVERRIDE_TOKEN_INVALID', // @sync-invariant none:local-only release grants are device-local owner files; refused before any write
350
+ 'The password does not match the owner key enrolled for this project.');
351
+ const id = `ra-${randomBytes(6).toString('hex')}`;
352
+ const issuedAt = new Date();
353
+ const expiresAt = new Date(issuedAt.getTime() + ttl).toISOString();
354
+ let decisionId;
355
+ try {
356
+ const { storeDecision } = await import('../memory/decisions.js');
357
+ const row = await storeDecision(projectRoot, {
358
+ type: 'process',
359
+ decision: `Standing release authorization ${id}: scope ${scope} until ${expiresAt}${input.uses ? `, at most ${input.uses} cut(s)` : ''}`,
360
+ rationale: input.reason.trim(),
361
+ confidence: 'high',
362
+ confirmationState: 'accepted',
363
+ decidedBy: 'owner',
364
+ contextTaskId: 'T14141',
365
+ });
366
+ decisionId = row.id;
367
+ }
368
+ catch (err) {
369
+ return refuse('E_DECISION_NOT_RECORDED', // @sync-invariant none:local-only the grant is refused before its files are written
370
+ `The owner decision could not be recorded: ${err instanceof Error ? err.message : String(err)}`);
371
+ }
372
+ const unsigned = {
373
+ id,
374
+ scope,
375
+ reason: input.reason.trim(),
376
+ issuedAt: issuedAt.toISOString(),
377
+ expiresAt,
378
+ uses: input.uses ?? null,
379
+ decisionId,
380
+ revocationsAtIssue: readGlobal(projectRoot).revoked.length,
381
+ ownerPubkey: state.file.ownerPubkey,
382
+ };
383
+ const { signAuditLine } = await import('../identity/cleo-identity.js');
384
+ const { sig } = await signAuditLine(key, grantPayload(projectRoot, unsigned));
385
+ const grant = { ...unsigned, sig };
386
+ const project = readProject(projectRoot);
387
+ await atomicWriteJson(join(projectRoot, PROJECT_FILE), {
388
+ ...project,
389
+ grants: [...project.grants, grant],
390
+ });
391
+ const global = readGlobal(projectRoot);
392
+ await writeGlobal(projectRoot, { ...global, grants: [...global.grants, grant] });
393
+ audit(projectRoot, {
394
+ action: 'grant',
395
+ id,
396
+ scope,
397
+ expiresAt,
398
+ uses: grant.uses,
399
+ decisionId,
400
+ sessionId: input.session?.id ?? null,
401
+ });
402
+ return { ok: true, grant };
403
+ }
404
+ /**
405
+ * Revoke a grant now. Owner-only like granting (the password signs the
406
+ * revocation): the grant leaves both files, a signed revocation entry joins
407
+ * both, and the revocation count is sealed in `.cleo/owner-settings.json`.
408
+ *
409
+ * @param projectRoot - Project root.
410
+ * @param input - The owner caller and the grant id.
411
+ * @returns The revoked grant, or the refusal.
412
+ *
413
+ * @example
414
+ * ```ts
415
+ * await revokeReleaseAuthorization(root, { ...caller, id: 'ra-1a2b3c4d5e6f' });
416
+ * ```
417
+ *
418
+ * @task T14141
419
+ */
420
+ export async function revokeReleaseAuthorization(projectRoot, input) {
421
+ const refuse = (code, message) => {
422
+ audit(projectRoot, { action: 'revoke-refused', id: input.id, code, reason: message });
423
+ return { ok: false, code, message };
424
+ };
425
+ const check = ownerCheck(input);
426
+ if (!check.ok)
427
+ return refuse(check.code, check.message);
428
+ const state = await judgeOwnerState(projectRoot);
429
+ if (state.kind !== 'ok')
430
+ return refuse('E_OWNER_NOT_ENROLLED', // @sync-invariant none:local-only release grants are device-local owner files; refused before any write
431
+ state.kind === 'tampered'
432
+ ? `Owner settings are not usable: ${state.why}`
433
+ : 'No owner is enrolled for this project.');
434
+ const key = await ownerKey(input.password, state.file.salt);
435
+ if (key.pubkeyHex !== state.file.ownerPubkey)
436
+ return refuse('E_OVERRIDE_TOKEN_INVALID', // @sync-invariant none:local-only release grants are device-local owner files; refused before any write
437
+ 'The password does not match the owner key enrolled for this project.');
438
+ const project = readProject(projectRoot);
439
+ const global = readGlobal(projectRoot);
440
+ const grant = global.grants.find((g) => g.id === input.id) ?? project.grants.find((g) => g.id === input.id);
441
+ if (!grant)
442
+ return refuse('E_NOT_FOUND', `No release authorization ${input.id}`); // @sync-invariant none:input-shape an unknown grant id is refused before any write
443
+ const unsigned = { id: input.id, revokedAt: new Date().toISOString() };
444
+ const { signAuditLine } = await import('../identity/cleo-identity.js');
445
+ const { sig } = await signAuditLine(key, revocationPayload(projectRoot, unsigned, state.file.ownerPubkey));
446
+ const revoked = [...global.revoked, { ...unsigned, sig }];
447
+ await atomicWriteJson(join(projectRoot, PROJECT_FILE), {
448
+ schemaVersion: 1,
449
+ grants: project.grants.filter((g) => g.id !== input.id),
450
+ revoked,
451
+ });
452
+ await writeGlobal(projectRoot, {
453
+ grants: global.grants.filter((g) => g.id !== input.id),
454
+ revoked,
455
+ });
456
+ await writeSealedOwnerSetting(projectRoot, REVOCATION_COUNT_SETTING, revoked.length, key);
457
+ audit(projectRoot, { action: 'revoke', id: input.id, scope: grant.scope, count: revoked.length });
458
+ return { ok: true, grant };
459
+ }
460
+ //# sourceMappingURL=authorization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization.js","sourceRoot":"","sources":["../../src/release/authorization.ts"],"names":[],"mappings":"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"}
@@ -146,6 +146,14 @@ export interface MainCommit {
146
146
  /** Number of parents; 2+ is a merge commit. */
147
147
  parents: number;
148
148
  }
149
+ /**
150
+ * What a targeted `test-run:` report must cover, worded once for the
151
+ * validator's refusal and for every hint that offers a targeted run (T14119),
152
+ * so a hint never offers a route the validator refuses.
153
+ *
154
+ * @task T14119
155
+ */
156
+ export declare const TARGETED_RUN_COVERAGE: string;
149
157
  /** Most later default-branch commits examined for a green stand-in run (T12742). */
150
158
  export declare const CI_DESCENDANT_MAX_CANDIDATES = 20;
151
159
  /** Latest committer time after the merge commit a stand-in may have (T12742): 7 days. */
@@ -220,6 +228,12 @@ export interface ResolveCiEvidenceOptions {
220
228
  * `git log --first-parent -- <paths>`.
221
229
  */
222
230
  touchingCommits?: (from: string, to: string, paths: readonly string[], cwd: string) => MainCommit[] | null;
231
+ /**
232
+ * When later commits edited the PR's files, the first hunk the PR added
233
+ * that is no longer present at `at` (T14119), or null when every one is.
234
+ * Defaults to {@link missingPrHunk}.
235
+ */
236
+ missingPrHunk?: (merge: string, at: string, paths: readonly string[], cwd: string) => string | null;
223
237
  /**
224
238
  * Plain-text log of one Actions job (a check-run id), or null when it cannot
225
239
  * be read (T13809). Defaults to `gh api repos/{owner}/{repo}/actions/jobs/<id>/logs`.
@@ -326,6 +340,19 @@ export interface CiChecksConfig {
326
340
  * @task T12634
327
341
  */
328
342
  export declare function isCiDocumentPath(path: string): boolean;
343
+ /**
344
+ * Whether a check run's name is the job a configured glob names (T14148). A
345
+ * matrix job's `name:` is a template (`Type Check${{ matrix.node … }}`), and a
346
+ * job skipped before its matrix expands reports that raw template as its check
347
+ * name; its static prefix (`Type Check`) is the job's name, so the skip counts
348
+ * as the job's, the same job its rendered variants run as.
349
+ *
350
+ * @param re - The configured job glob, anchored.
351
+ * @param name - The check run's name.
352
+ * @returns True when the run belongs to the job.
353
+ * @task T14148
354
+ */
355
+ export declare function jobNameMatches(re: RegExp, name: string): boolean;
329
356
  /**
330
357
  * Path glob to an anchored regular expression (T13175): `**` followed by `/` is
331
358
  * any number of whole directories (including none), a trailing `/` followed by
@@ -427,7 +454,9 @@ export type SupersededOnMergeResult = {
427
454
  * SUPERSEDED there (T12742): its latest merge-commit verdict is `cancelled`
428
455
  * or `skipped`, and no run of a required check or of a job in a pinned
429
456
  * workflow on the merge commit — any attempt — concluded with a failure. A
430
- * failed, timed-out, pending or missing check is never superseded. Pure.
457
+ * failed, timed-out or pending check is never superseded, nor is a missing
458
+ * one unless its pinned workflow's run on the merge commit was cancelled or
459
+ * skipped, so it never ran (T14103, T14144). Pure.
431
460
  *
432
461
  * @param required - Required check names.
433
462
  * @param checks - Every check fetched for the merge commit (and PR head).
@@ -697,6 +726,8 @@ export interface FindGreenDescendantInput {
697
726
  listDescendants: NonNullable<ResolveCiEvidenceOptions['listDescendants']>;
698
727
  /** First-parent commits in a range touching paths. */
699
728
  touchingCommits: NonNullable<ResolveCiEvidenceOptions['touchingCommits']>;
729
+ /** First PR hunk missing at a later commit (T14119). */
730
+ missingPrHunk: NonNullable<ResolveCiEvidenceOptions['missingPrHunk']>;
700
731
  /** Ancestry test. */
701
732
  isAncestor: NonNullable<ResolveCiEvidenceOptions['isAncestor']>;
702
733
  /** First parent of a commit (T13453: the inherited-failure walk); absent = never inherit. */
@@ -775,8 +806,10 @@ export type FindGreenDescendantResult = {
775
806
  * failed job of a pinned workflow) refuses, and a PENDING run refuses with
776
807
  * "wait for <sha>" — a later green run is never shopped for past one that
777
808
  * is red or may still go red. Only cancelled, skipped and missing
778
- * (never-started) runs, and a run red only for the flaky-quarantine budget
779
- * (T13809), move on to the next candidate.
809
+ * (never-started) runs, a run red only for the flaky-quarantine budget
810
+ * (T13809), and a run whose every failing job tested nothing — its runner
811
+ * was cancelled or a test worker crashed, no test failed (T14176) — move
812
+ * on to the next candidate.
780
813
  *
781
814
  * @param input - Merge-commit checks, pins, changed paths, PR head and injected I/O.
782
815
  * @returns The stand-in SHA, its checks and proven range, or the refusal reason.
@@ -836,7 +869,9 @@ export type FindGreenCurrentHeadResult = {
836
869
  *
837
870
  * Candidates are HEAD, then its first parents while they differ from HEAD only
838
871
  * in documentation ({@link isCiDocumentPath}, the T13784 rule: nothing a test
839
- * reads moved), up to {@link CI_DESCENDANT_MAX_CANDIDATES}. Each must descend
872
+ * reads moved), or while every commit stepped past had green required checks
873
+ * and its gates' jobs skipped by CI's own change filter (T14177: the filter
874
+ * judged its change untested), up to {@link CI_DESCENDANT_MAX_CANDIDATES}. Each must descend
840
875
  * from the merge commit. The first decisive verdict decides, as in
841
876
  * {@link findGreenDescendant}: every required check green on its own `push`
842
877
  * runs (and the gates' jobs run, T13846) accepts; a failed or pending one
@@ -875,6 +910,22 @@ export declare function listMainDescendants(mergeSha: string, ref: string, cwd:
875
910
  * @task T12742
876
911
  */
877
912
  export declare function listPathTouchingMainCommits(from: string, to: string, paths: readonly string[], cwd: string): MainCommit[] | null;
913
+ /**
914
+ * Default {@link ResolveCiEvidenceOptions.missingPrHunk} (T14119): the first
915
+ * hunk the PR added (`git diff -U0 <merge>^1 <merge>`) whose added lines no
916
+ * longer appear, contiguous and in order, in that file at `at`. A binary file
917
+ * counts as missing once its blob differs. Lines the PR removed are not
918
+ * checked: a later commit cannot un-test a deletion. A git error is reported
919
+ * as missing, never as present.
920
+ *
921
+ * @param merge - The PR's merge commit (its first parent is the base).
922
+ * @param at - The later commit whose run would stand in.
923
+ * @param paths - The PR's changed paths.
924
+ * @param cwd - Repository work tree.
925
+ * @returns The missing hunk, described, or null when every hunk is present.
926
+ * @task T14119
927
+ */
928
+ export declare function missingPrHunk(merge: string, at: string, paths: readonly string[], cwd: string): string | null;
878
929
  /**
879
930
  * Default branch name from `gh repo view --json defaultBranchRef`.
880
931
  *