project-tiny-context-harness 0.2.85 → 0.6.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 (361) hide show
  1. package/README.md +163 -428
  2. package/assets/README.md +283 -455
  3. package/assets/README.zh-CN.md +199 -123
  4. package/assets/agents/AGENTS_CORE.md +54 -67
  5. package/assets/context_templates/context.toml +3 -0
  6. package/assets/context_templates/global.md +6 -6
  7. package/assets/github/harness.yml +2 -2
  8. package/assets/skills/context_development_engineer/SKILL.md +91 -107
  9. package/assets/skills/context_product_plan/SKILL.md +18 -28
  10. package/assets/skills/context_surface_contract/SKILL.md +35 -38
  11. package/assets/skills/context_uiux_design/SKILL.md +31 -30
  12. package/assets/skills/long-task-workflow/SKILL.md +76 -0
  13. package/assets/skills/long-task-workflow/agents/openai.yaml +4 -0
  14. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +41 -0
  15. package/assets/skills/long-task-workflow/references/contract-authoring.md +62 -0
  16. package/assets/skills/long-task-workflow/references/evidence-design.md +45 -0
  17. package/assets/skills/normal-long-task/SKILL.md +12 -489
  18. package/assets/skills/source-plan-authoring/SKILL.md +379 -0
  19. package/assets/tools/validate_context.py +293 -127
  20. package/dist/cli.js +3 -1
  21. package/dist/commands/check-modularity.js +33 -10
  22. package/dist/commands/composite-campaign.d.ts +1 -0
  23. package/dist/commands/composite-campaign.js +8 -0
  24. package/dist/commands/composite-long-task.d.ts +1 -6
  25. package/dist/commands/composite-long-task.js +7 -163
  26. package/dist/commands/delivery-set.d.ts +1 -0
  27. package/dist/commands/delivery-set.js +8 -0
  28. package/dist/commands/disable.d.ts +1 -0
  29. package/dist/commands/disable.js +15 -0
  30. package/dist/commands/enable.d.ts +1 -0
  31. package/dist/commands/enable.js +14 -0
  32. package/dist/commands/export-context-args.js +13 -4
  33. package/dist/commands/export-context.js +18 -7
  34. package/dist/commands/index.js +42 -30
  35. package/dist/commands/init.js +12 -6
  36. package/dist/commands/long-task-authoring.d.ts +3 -0
  37. package/dist/commands/long-task-authoring.js +92 -0
  38. package/dist/commands/long-task-explain.d.ts +1 -0
  39. package/dist/commands/long-task-explain.js +52 -0
  40. package/dist/commands/long-task.d.ts +1 -0
  41. package/dist/commands/long-task.js +226 -0
  42. package/dist/commands/package-source.js +2 -2
  43. package/dist/commands/upgrade.js +10 -10
  44. package/dist/index.d.ts +11 -1
  45. package/dist/index.js +8 -0
  46. package/dist/lib/config.js +34 -8
  47. package/dist/lib/context-default-footprint.d.ts +16 -0
  48. package/dist/lib/context-default-footprint.js +107 -0
  49. package/dist/lib/context-export.js +105 -41
  50. package/dist/lib/context-graph-snapshot.d.ts +18 -0
  51. package/dist/lib/context-graph-snapshot.js +171 -0
  52. package/dist/lib/context-manifest-schema.d.ts +28 -0
  53. package/dist/lib/context-manifest-schema.js +150 -0
  54. package/dist/lib/context-manifest.js +28 -20
  55. package/dist/lib/context-templates.js +5 -5
  56. package/dist/lib/design-md.js +1 -1
  57. package/dist/lib/doctor.js +54 -1
  58. package/dist/lib/harness-root.js +25 -8
  59. package/dist/lib/init.js +6 -3
  60. package/dist/lib/legacy-managed-scan.js +23 -7
  61. package/dist/lib/legacy-sdlc-migration.js +21 -11
  62. package/dist/lib/long-task-acceptance-reference.d.ts +22 -0
  63. package/dist/lib/long-task-acceptance-reference.js +46 -0
  64. package/dist/lib/long-task-acceptance-shape.d.ts +5 -0
  65. package/dist/lib/long-task-acceptance-shape.js +131 -0
  66. package/dist/lib/long-task-activation-validation.d.ts +21 -0
  67. package/dist/lib/long-task-activation-validation.js +136 -0
  68. package/dist/lib/long-task-artifacts.d.ts +5 -0
  69. package/dist/lib/long-task-artifacts.js +34 -0
  70. package/dist/lib/long-task-assertions-v2.d.ts +22 -0
  71. package/dist/lib/long-task-assertions-v2.js +212 -0
  72. package/dist/lib/long-task-authoring-authority-preview.d.ts +5 -0
  73. package/dist/lib/long-task-authoring-authority-preview.js +85 -0
  74. package/dist/lib/long-task-authoring-preflight-diagnostics.d.ts +8 -0
  75. package/dist/lib/long-task-authoring-preflight-diagnostics.js +179 -0
  76. package/dist/lib/long-task-authoring-preflight-repair-order.d.ts +8 -0
  77. package/dist/lib/long-task-authoring-preflight-repair-order.js +95 -0
  78. package/dist/lib/long-task-authoring-preflight-types.d.ts +46 -0
  79. package/dist/lib/long-task-authoring-preflight-types.js +38 -0
  80. package/dist/lib/long-task-authoring-preflight.d.ts +3 -0
  81. package/dist/lib/long-task-authoring-preflight.js +44 -0
  82. package/dist/lib/long-task-authority-material-diff.d.ts +17 -0
  83. package/dist/lib/long-task-authority-material-diff.js +152 -0
  84. package/dist/lib/long-task-authority-materials.d.ts +7 -0
  85. package/dist/lib/long-task-authority-materials.js +83 -0
  86. package/dist/lib/long-task-authority-policy.d.ts +168 -0
  87. package/dist/lib/long-task-authority-policy.js +181 -0
  88. package/dist/lib/long-task-authority-revision-details.d.ts +19 -0
  89. package/dist/lib/long-task-authority-revision-details.js +192 -0
  90. package/dist/lib/long-task-authority-revision-enforcement.d.ts +3 -0
  91. package/dist/lib/long-task-authority-revision-enforcement.js +41 -0
  92. package/dist/lib/long-task-authority-revision-types.d.ts +50 -0
  93. package/dist/lib/long-task-authority-revision-types.js +1 -0
  94. package/dist/lib/long-task-authority-revision.d.ts +4 -0
  95. package/dist/lib/long-task-authority-revision.js +188 -0
  96. package/dist/lib/long-task-authority-transition-policy.d.ts +62 -0
  97. package/dist/lib/long-task-authority-transition-policy.js +62 -0
  98. package/dist/lib/long-task-authority-types.d.ts +96 -0
  99. package/dist/lib/long-task-authority-types.js +1 -0
  100. package/dist/lib/long-task-authority.d.ts +7 -0
  101. package/dist/lib/long-task-authority.js +142 -0
  102. package/dist/lib/long-task-boundary-check.d.ts +15 -0
  103. package/dist/lib/long-task-boundary-check.js +9 -0
  104. package/dist/lib/long-task-check-evidence-decoder.d.ts +3 -0
  105. package/dist/lib/long-task-check-evidence-decoder.js +74 -0
  106. package/dist/lib/long-task-check-execution-policy.d.ts +18 -0
  107. package/dist/lib/long-task-check-execution-policy.js +36 -0
  108. package/dist/lib/long-task-check-runner.d.ts +2 -0
  109. package/dist/lib/long-task-check-runner.js +181 -0
  110. package/dist/lib/long-task-check-shape.d.ts +2 -0
  111. package/dist/lib/long-task-check-shape.js +136 -0
  112. package/dist/lib/long-task-claim-definitions.d.ts +7 -0
  113. package/dist/lib/long-task-claim-definitions.js +78 -0
  114. package/dist/lib/long-task-claim-proof-policy.d.ts +4 -0
  115. package/dist/lib/long-task-claim-proof-policy.js +57 -0
  116. package/dist/lib/long-task-claims.d.ts +10 -0
  117. package/dist/lib/long-task-claims.js +187 -0
  118. package/dist/lib/long-task-context-authority-topology.d.ts +7 -0
  119. package/dist/lib/long-task-context-authority-topology.js +37 -0
  120. package/dist/lib/long-task-context-authority.d.ts +14 -0
  121. package/dist/lib/long-task-context-authority.js +66 -0
  122. package/dist/lib/long-task-contract-types.d.ts +203 -0
  123. package/dist/lib/long-task-contract-types.js +1 -0
  124. package/dist/lib/long-task-counterfactual-claim-policy.d.ts +10 -0
  125. package/dist/lib/long-task-counterfactual-claim-policy.js +57 -0
  126. package/dist/lib/long-task-counterfactual-sandbox.d.ts +6 -0
  127. package/dist/lib/long-task-counterfactual-sandbox.js +87 -0
  128. package/dist/lib/long-task-counterfactual-types.d.ts +24 -0
  129. package/dist/lib/long-task-counterfactual-types.js +1 -0
  130. package/dist/lib/long-task-delivery-compiler.d.ts +10 -0
  131. package/dist/lib/long-task-delivery-compiler.js +129 -0
  132. package/dist/lib/long-task-delivery-parser.d.ts +13 -0
  133. package/dist/lib/long-task-delivery-parser.js +90 -0
  134. package/dist/lib/long-task-delivery-preflight.d.ts +5 -0
  135. package/dist/lib/long-task-delivery-preflight.js +151 -0
  136. package/dist/lib/long-task-delivery-shape.d.ts +5 -0
  137. package/dist/lib/long-task-delivery-shape.js +5 -0
  138. package/dist/lib/long-task-delivery-types.d.ts +8 -0
  139. package/dist/lib/long-task-delivery-types.js +8 -0
  140. package/dist/lib/long-task-delivery-validation.d.ts +3 -0
  141. package/dist/lib/long-task-delivery-validation.js +175 -0
  142. package/dist/lib/long-task-evidence-adapter-policy.d.ts +4 -0
  143. package/dist/lib/long-task-evidence-adapter-policy.js +15 -0
  144. package/dist/lib/long-task-evidence-adapter-types.d.ts +1 -0
  145. package/dist/lib/long-task-evidence-adapter-types.js +1 -0
  146. package/dist/lib/long-task-evidence-findings.d.ts +5 -0
  147. package/dist/lib/long-task-evidence-findings.js +113 -0
  148. package/dist/lib/long-task-evidence-sensitivity-policy.d.ts +4 -0
  149. package/dist/lib/long-task-evidence-sensitivity-policy.js +98 -0
  150. package/dist/lib/long-task-evidence-v2.d.ts +5 -0
  151. package/dist/lib/long-task-evidence-v2.js +226 -0
  152. package/dist/lib/long-task-explain-acceptance-link.d.ts +46 -0
  153. package/dist/lib/long-task-explain-acceptance-link.js +96 -0
  154. package/dist/lib/long-task-explain-claim-links.d.ts +45 -0
  155. package/dist/lib/long-task-explain-claim-links.js +88 -0
  156. package/dist/lib/long-task-explain-source-links.d.ts +93 -0
  157. package/dist/lib/long-task-explain-source-links.js +51 -0
  158. package/dist/lib/long-task-final-v2.d.ts +2 -0
  159. package/dist/lib/long-task-final-v2.js +124 -0
  160. package/dist/lib/long-task-finding-context.d.ts +3 -0
  161. package/dist/lib/long-task-finding-context.js +63 -0
  162. package/dist/lib/long-task-freshness.d.ts +3 -0
  163. package/dist/lib/long-task-freshness.js +80 -0
  164. package/dist/lib/long-task-hook-install.d.ts +9 -0
  165. package/dist/lib/long-task-hook-install.js +184 -0
  166. package/dist/lib/long-task-hook-preflight.d.ts +7 -0
  167. package/dist/lib/long-task-hook-preflight.js +58 -0
  168. package/dist/lib/long-task-observation-ownership.d.ts +2 -0
  169. package/dist/lib/long-task-observation-ownership.js +22 -0
  170. package/dist/lib/long-task-outcome-parser.d.ts +4 -0
  171. package/dist/lib/long-task-outcome-parser.js +100 -0
  172. package/dist/lib/long-task-paths.d.ts +49 -0
  173. package/dist/lib/long-task-paths.js +418 -0
  174. package/dist/lib/long-task-playwright-counterfactual-policy.d.ts +7 -0
  175. package/dist/lib/long-task-playwright-counterfactual-policy.js +125 -0
  176. package/dist/lib/long-task-playwright-evidence.d.ts +6 -0
  177. package/dist/lib/long-task-playwright-evidence.js +244 -0
  178. package/dist/lib/long-task-product-shape.d.ts +6 -0
  179. package/dist/lib/long-task-product-shape.js +73 -0
  180. package/dist/lib/long-task-progress.d.ts +4 -0
  181. package/dist/lib/long-task-progress.js +114 -0
  182. package/dist/lib/long-task-protected-files.d.ts +1 -0
  183. package/dist/lib/long-task-protected-files.js +30 -0
  184. package/dist/lib/long-task-required-proof-surfaces.d.ts +2 -0
  185. package/dist/lib/long-task-required-proof-surfaces.js +13 -0
  186. package/dist/lib/long-task-requirement-shape.d.ts +2 -0
  187. package/dist/lib/long-task-requirement-shape.js +18 -0
  188. package/dist/lib/long-task-risk-surfaces.d.ts +2 -0
  189. package/dist/lib/long-task-risk-surfaces.js +60 -0
  190. package/dist/lib/long-task-risk-types.d.ts +5 -0
  191. package/dist/lib/long-task-risk-types.js +12 -0
  192. package/dist/lib/long-task-risk.d.ts +9 -0
  193. package/dist/lib/long-task-risk.js +132 -0
  194. package/dist/lib/long-task-root-shape.d.ts +4 -0
  195. package/dist/lib/long-task-root-shape.js +86 -0
  196. package/dist/lib/long-task-runner-environment.d.ts +7 -0
  197. package/dist/lib/long-task-runner-environment.js +57 -0
  198. package/dist/lib/long-task-runner-files.d.ts +3 -0
  199. package/dist/lib/long-task-runner-files.js +39 -0
  200. package/dist/lib/long-task-runner-freeze.d.ts +2 -0
  201. package/dist/lib/long-task-runner-freeze.js +168 -0
  202. package/dist/lib/long-task-runtime-types.d.ts +214 -0
  203. package/dist/lib/long-task-runtime-types.js +1 -0
  204. package/dist/lib/long-task-shape-primitives.d.ts +17 -0
  205. package/dist/lib/long-task-shape-primitives.js +81 -0
  206. package/dist/lib/long-task-source-authority-types.d.ts +13 -0
  207. package/dist/lib/long-task-source-authority-types.js +1 -0
  208. package/dist/lib/long-task-source-claim-validation.d.ts +5 -0
  209. package/dist/lib/long-task-source-claim-validation.js +96 -0
  210. package/dist/lib/long-task-source-continuity.d.ts +4 -0
  211. package/dist/lib/long-task-source-continuity.js +57 -0
  212. package/dist/lib/long-task-source-inventory.d.ts +2 -0
  213. package/dist/lib/long-task-source-inventory.js +21 -0
  214. package/dist/lib/long-task-source-item-parser.d.ts +3 -0
  215. package/dist/lib/long-task-source-item-parser.js +112 -0
  216. package/dist/lib/long-task-source-shape.d.ts +2 -0
  217. package/dist/lib/long-task-source-shape.js +56 -0
  218. package/dist/lib/long-task-source-target-continuity.d.ts +4 -0
  219. package/dist/lib/long-task-source-target-continuity.js +80 -0
  220. package/dist/lib/long-task-source-target-index.d.ts +12 -0
  221. package/dist/lib/long-task-source-target-index.js +76 -0
  222. package/dist/lib/long-task-source-validation.d.ts +3 -0
  223. package/dist/lib/long-task-source-validation.js +46 -0
  224. package/dist/lib/long-task-state.d.ts +91 -0
  225. package/dist/lib/long-task-state.js +611 -0
  226. package/dist/lib/long-task-status-projection.d.ts +21 -0
  227. package/dist/lib/long-task-status-projection.js +116 -0
  228. package/dist/lib/long-task-status-v2.d.ts +37 -0
  229. package/dist/lib/long-task-status-v2.js +306 -0
  230. package/dist/lib/long-task-technical-shape.d.ts +3 -0
  231. package/dist/lib/long-task-technical-shape.js +44 -0
  232. package/dist/lib/long-task-verifier-authority.d.ts +12 -0
  233. package/dist/lib/long-task-verifier-authority.js +47 -0
  234. package/dist/lib/long-task-verifier-identity.d.ts +2 -0
  235. package/dist/lib/long-task-verifier-identity.js +55 -0
  236. package/dist/lib/long-task-verifier-v2.d.ts +13 -0
  237. package/dist/lib/long-task-verifier-v2.js +266 -0
  238. package/dist/lib/long-task-workspace-runtime-types.d.ts +23 -0
  239. package/dist/lib/long-task-workspace-runtime-types.js +1 -0
  240. package/dist/lib/long-task-workspace.d.ts +25 -0
  241. package/dist/lib/long-task-workspace.js +366 -0
  242. package/dist/lib/managed-file.js +20 -5
  243. package/dist/lib/migrations.js +156 -32
  244. package/dist/lib/modularity.d.ts +27 -1
  245. package/dist/lib/modularity.js +499 -23
  246. package/dist/lib/package-json-config.js +14 -5
  247. package/dist/lib/package-source.js +4 -2
  248. package/dist/lib/profiles.d.ts +13 -0
  249. package/dist/lib/profiles.js +66 -0
  250. package/dist/lib/schema-guard.js +4 -2
  251. package/dist/lib/source-files.js +14 -7
  252. package/dist/lib/source-pack-classify.js +91 -19
  253. package/dist/lib/source-pack-config.js +25 -8
  254. package/dist/lib/source-pack-export.js +84 -25
  255. package/dist/lib/source-pack-manifest.js +18 -6
  256. package/dist/lib/source-pack-records.js +35 -11
  257. package/dist/lib/source-pack-render.js +47 -18
  258. package/dist/lib/stable-json.d.ts +2 -0
  259. package/dist/lib/stable-json.js +21 -0
  260. package/dist/lib/strict-codec.d.ts +4 -0
  261. package/dist/lib/strict-codec.js +65 -0
  262. package/dist/lib/sync-engine.js +76 -24
  263. package/dist/lib/types.d.ts +8 -1
  264. package/dist/lib/upgrade.js +4 -3
  265. package/dist/lib/validators.js +218 -191
  266. package/dist/long-task-hook.d.ts +2 -0
  267. package/dist/long-task-hook.js +55 -0
  268. package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +340 -0
  269. package/dist/schemas/long-task-delivery-v2/long-task-outcomes-v2.schema.json +18 -0
  270. package/migrations/README.md +8 -3
  271. package/package.json +17 -6
  272. package/source-mappings.yaml +0 -3
  273. package/assets/protected-harness-baseline.json +0 -20
  274. package/assets/skills/composite-long-task-workflow/SKILL.md +0 -245
  275. package/assets/skills/composite-long-task-workflow/assets/execution-binding.template.md +0 -62
  276. package/assets/skills/composite-long-task-workflow/assets/goal-objective.template.md +0 -17
  277. package/assets/skills/composite-long-task-workflow/references/composite-long-task-workflow-protocol.md +0 -682
  278. package/dist/commands/superpowers.d.ts +0 -1
  279. package/dist/commands/superpowers.js +0 -8
  280. package/dist/lib/composite-long-task-renderer.d.ts +0 -12
  281. package/dist/lib/composite-long-task-renderer.js +0 -109
  282. package/dist/lib/plan-acceptance-artifacts.d.ts +0 -1
  283. package/dist/lib/plan-acceptance-artifacts.js +0 -220
  284. package/dist/lib/plan-acceptance-evidence.d.ts +0 -2
  285. package/dist/lib/plan-acceptance-evidence.js +0 -108
  286. package/dist/lib/plan-acceptance-json.d.ts +0 -15
  287. package/dist/lib/plan-acceptance-json.js +0 -133
  288. package/dist/lib/plan-acceptance-validator.d.ts +0 -2
  289. package/dist/lib/plan-acceptance-validator.js +0 -209
  290. package/dist/lib/plan-contract-validator.d.ts +0 -2
  291. package/dist/lib/plan-contract-validator.js +0 -127
  292. package/dist/lib/plan-validator-common.d.ts +0 -24
  293. package/dist/lib/plan-validator-common.js +0 -196
  294. package/dist/lib/superpowers-task-ac010.d.ts +0 -6
  295. package/dist/lib/superpowers-task-ac010.js +0 -26
  296. package/dist/lib/superpowers-task-assertion-normalizers.d.ts +0 -3
  297. package/dist/lib/superpowers-task-assertion-normalizers.js +0 -74
  298. package/dist/lib/superpowers-task-assertions.d.ts +0 -20
  299. package/dist/lib/superpowers-task-assertions.js +0 -257
  300. package/dist/lib/superpowers-task-attempt.d.ts +0 -4
  301. package/dist/lib/superpowers-task-attempt.js +0 -102
  302. package/dist/lib/superpowers-task-command-run-correlation.d.ts +0 -8
  303. package/dist/lib/superpowers-task-command-run-correlation.js +0 -103
  304. package/dist/lib/superpowers-task-command-specs.d.ts +0 -3
  305. package/dist/lib/superpowers-task-command-specs.js +0 -52
  306. package/dist/lib/superpowers-task-compile-diagnostics.d.ts +0 -5
  307. package/dist/lib/superpowers-task-compile-diagnostics.js +0 -20
  308. package/dist/lib/superpowers-task-compile-guards.d.ts +0 -2
  309. package/dist/lib/superpowers-task-compile-guards.js +0 -66
  310. package/dist/lib/superpowers-task-compile.d.ts +0 -6
  311. package/dist/lib/superpowers-task-compile.js +0 -133
  312. package/dist/lib/superpowers-task-completion-output.d.ts +0 -91
  313. package/dist/lib/superpowers-task-completion-output.js +0 -374
  314. package/dist/lib/superpowers-task-conformance.d.ts +0 -2
  315. package/dist/lib/superpowers-task-conformance.js +0 -24
  316. package/dist/lib/superpowers-task-contradictions.d.ts +0 -6
  317. package/dist/lib/superpowers-task-contradictions.js +0 -126
  318. package/dist/lib/superpowers-task-current-evidence.d.ts +0 -3
  319. package/dist/lib/superpowers-task-current-evidence.js +0 -176
  320. package/dist/lib/superpowers-task-delivery.d.ts +0 -4
  321. package/dist/lib/superpowers-task-delivery.js +0 -96
  322. package/dist/lib/superpowers-task-derive.d.ts +0 -14
  323. package/dist/lib/superpowers-task-derive.js +0 -393
  324. package/dist/lib/superpowers-task-events.d.ts +0 -1
  325. package/dist/lib/superpowers-task-events.js +0 -13
  326. package/dist/lib/superpowers-task-evidence-kernel.d.ts +0 -19
  327. package/dist/lib/superpowers-task-evidence-kernel.js +0 -347
  328. package/dist/lib/superpowers-task-evidence-records.d.ts +0 -2
  329. package/dist/lib/superpowers-task-evidence-records.js +0 -55
  330. package/dist/lib/superpowers-task-evidence.d.ts +0 -10
  331. package/dist/lib/superpowers-task-evidence.js +0 -147
  332. package/dist/lib/superpowers-task-fields.d.ts +0 -22
  333. package/dist/lib/superpowers-task-fields.js +0 -276
  334. package/dist/lib/superpowers-task-final-card.d.ts +0 -3
  335. package/dist/lib/superpowers-task-final-card.js +0 -35
  336. package/dist/lib/superpowers-task-gates.d.ts +0 -12
  337. package/dist/lib/superpowers-task-gates.js +0 -267
  338. package/dist/lib/superpowers-task-harness-drift.d.ts +0 -11
  339. package/dist/lib/superpowers-task-harness-drift.js +0 -90
  340. package/dist/lib/superpowers-task-next-slices.d.ts +0 -1
  341. package/dist/lib/superpowers-task-next-slices.js +0 -12
  342. package/dist/lib/superpowers-task-protected-baseline.d.ts +0 -10
  343. package/dist/lib/superpowers-task-protected-baseline.js +0 -66
  344. package/dist/lib/superpowers-task-source-compile.d.ts +0 -5
  345. package/dist/lib/superpowers-task-source-compile.js +0 -226
  346. package/dist/lib/superpowers-task-source-parser.d.ts +0 -23
  347. package/dist/lib/superpowers-task-source-parser.js +0 -218
  348. package/dist/lib/superpowers-task-state-schema.d.ts +0 -460
  349. package/dist/lib/superpowers-task-state-schema.js +0 -66
  350. package/dist/lib/superpowers-task-state-shape.d.ts +0 -3
  351. package/dist/lib/superpowers-task-state-shape.js +0 -50
  352. package/dist/lib/superpowers-task-state.d.ts +0 -16
  353. package/dist/lib/superpowers-task-state.js +0 -246
  354. package/dist/lib/superpowers-task-status.d.ts +0 -2
  355. package/dist/lib/superpowers-task-status.js +0 -24
  356. package/dist/lib/superpowers-task-under-specified.d.ts +0 -7
  357. package/dist/lib/superpowers-task-under-specified.js +0 -61
  358. package/dist/lib/superpowers-task-unregistered-evidence.d.ts +0 -11
  359. package/dist/lib/superpowers-task-unregistered-evidence.js +0 -72
  360. package/dist/lib/superpowers-task-validator.d.ts +0 -5
  361. package/dist/lib/superpowers-task-validator.js +0 -293
@@ -0,0 +1,124 @@
1
+ import { compileDeliveryContract } from "./long-task-delivery-compiler.js";
2
+ import { activeAuthorityIdentityMatches, assertMatchingActiveBinding, loadActiveLongTaskAuthority, writeFinalReceipt, } from "./long-task-state.js";
3
+ import { assertVerifierAuthorityCurrent } from "./long-task-freshness.js";
4
+ import { allCompiledChecks, runDeliveryChecks, } from "./long-task-verifier-v2.js";
5
+ import { captureWorkspaceFingerprint, createWorkspaceSnapshot, currentGitState, repositoryRoot, } from "./long-task-workspace.js";
6
+ export async function runDeliveryFinalGate(workdirInput) {
7
+ const startedAt = new Date().toISOString();
8
+ const repository = await repositoryRoot(process.cwd());
9
+ const active = (await loadActiveLongTaskAuthority(repository, { migrate_legacy: true })).authority;
10
+ if (!active)
11
+ throw new Error("active_task_missing");
12
+ if (active.workdir !== (await resolved(workdirInput)))
13
+ throw new Error("active_task_workdir_mismatch");
14
+ await assertVerifierAuthorityCurrent(repository, active.verifier_identity);
15
+ const acceptedAuthority = {
16
+ task_id: active.task_id,
17
+ authority_revision: active.authority_revision,
18
+ compiled_identity: active.active_authority_identity,
19
+ worktree_identity: active.worktree_identity,
20
+ };
21
+ const candidate = await currentGitState(repository);
22
+ if (candidate.dirty.length)
23
+ throw new Error(`final_gate_requires_clean_candidate_commit:${candidate.dirty.join(",")}`);
24
+ const compiled = await compileDeliveryContract(active.workdir, repository, {
25
+ live_gate: true,
26
+ initial_task_base: active.initial_task_base,
27
+ authority_revision: active.authority_revision,
28
+ require_completion_gate: true,
29
+ });
30
+ await assertMatchingActiveBinding(compiled);
31
+ const before = await captureWorkspaceFingerprint(repository);
32
+ const snapshot = await createWorkspaceSnapshot(repository, active.workdir, `final-${compiled.task.id}`);
33
+ try {
34
+ const run = await runDeliveryChecks(compiled, snapshot, allCompiledChecks(compiled), true, true);
35
+ const after = await captureWorkspaceFingerprint(repository);
36
+ const gitAfter = await currentGitState(repository);
37
+ if (after.identity !== before.identity ||
38
+ gitAfter.head !== candidate.head ||
39
+ gitAfter.tree !== candidate.tree ||
40
+ gitAfter.dirty.length)
41
+ run.findings.push({
42
+ code: "workspace_changed_during_final_gate",
43
+ outcome_key: null,
44
+ check_key: null,
45
+ message: "The workspace changed while Live Final Gate was running.",
46
+ next_action: "Stop concurrent mutation and rerun the complete Live Final Gate.",
47
+ });
48
+ let activeAuthorityChanged = false;
49
+ try {
50
+ const currentActive = (await loadActiveLongTaskAuthority(repository))
51
+ .authority;
52
+ activeAuthorityChanged =
53
+ !currentActive ||
54
+ !activeAuthorityIdentityMatches(currentActive, acceptedAuthority);
55
+ }
56
+ catch {
57
+ activeAuthorityChanged = true;
58
+ }
59
+ if (activeAuthorityChanged)
60
+ run.findings.push({
61
+ code: "active_authority_changed_during_final_gate",
62
+ outcome_key: null,
63
+ check_key: null,
64
+ message: "Active Authority changed while Live Final Gate was running.",
65
+ next_action: "Review the new Authority Revision and rerun the complete Live Final Gate.",
66
+ });
67
+ const outcomeResults = projectOutcomes(compiled.outcomes.map((outcome) => outcome.key), run.check_results, run.findings);
68
+ const globalChecks = run.check_results.filter((check) => check.outcome_key === null);
69
+ const globalHardFailure = globalChecks.some((check) => check.status !== "passed" && check.status !== "blocked_external");
70
+ const globalBlocked = globalChecks.some((check) => check.status === "blocked_external");
71
+ const failed = globalHardFailure ||
72
+ Object.values(outcomeResults).includes("failed") ||
73
+ run.findings.some((finding) => finding.code !== "blocked_external");
74
+ const blocked = globalBlocked ||
75
+ Object.values(outcomeResults).includes("blocked_external") ||
76
+ run.findings.some((finding) => finding.code === "blocked_external");
77
+ const workflowStatus = failed
78
+ ? "needs_work"
79
+ : blocked
80
+ ? "blocked_external"
81
+ : compiled.global.acceptance.external_confirmations.length
82
+ ? "machine_accepted_external_pending"
83
+ : "machine_accepted";
84
+ return writeFinalReceipt(repository, active.workdir, {
85
+ schema_version: "long-task-final-receipt-v2",
86
+ authority_scope: "audit_only",
87
+ reusable_for_acceptance: false,
88
+ workflow_status: workflowStatus,
89
+ compiled_identity: compiled.compiled_identity,
90
+ contract_sha256: compiled.contract_sha256,
91
+ snapshot_sha256: snapshot.manifest.snapshot_sha256,
92
+ git_head: candidate.head,
93
+ git_tree: candidate.tree,
94
+ source_hashes: compiled.source_hashes,
95
+ context_hashes: compiled.context_snapshot.sha256,
96
+ verifier_identity: compiled.verifier_identity,
97
+ check_results: run.check_results,
98
+ outcome_results: outcomeResults,
99
+ external_confirmations: compiled.global.acceptance.external_confirmations,
100
+ findings: run.findings,
101
+ snapshot_preparation_ms: snapshot.preparation_ms,
102
+ started_at: startedAt,
103
+ completed_at: new Date().toISOString(),
104
+ });
105
+ }
106
+ finally {
107
+ await snapshot.dispose();
108
+ }
109
+ }
110
+ function projectOutcomes(outcomeKeys, checks, findings) {
111
+ return Object.fromEntries(outcomeKeys.map((outcomeKey) => {
112
+ const owned = checks.filter((check) => check.outcome_key === outcomeKey);
113
+ const ownFindings = findings.filter((finding) => finding.outcome_key === outcomeKey || finding.outcome_key === null);
114
+ const status = owned.some((check) => check.status !== "passed" && check.status !== "blocked_external") || ownFindings.some((finding) => finding.code !== "blocked_external")
115
+ ? "failed"
116
+ : owned.some((check) => check.status === "blocked_external")
117
+ ? "blocked_external"
118
+ : "passed";
119
+ return [outcomeKey, status];
120
+ }));
121
+ }
122
+ async function resolved(workdir) {
123
+ return (await import("node:path")).default.resolve(workdir);
124
+ }
@@ -0,0 +1,3 @@
1
+ import type { CheckExecutionResultV2, CompiledDeliveryContractV2, LongTaskFindingV2 } from "./long-task-delivery-types.js";
2
+ export declare function enrichCheckResultFindings(compiled: CompiledDeliveryContractV2, result: CheckExecutionResultV2): CheckExecutionResultV2;
3
+ export declare function enrichFinding(compiled: CompiledDeliveryContractV2, finding: LongTaskFindingV2): LongTaskFindingV2;
@@ -0,0 +1,63 @@
1
+ import { resolveAcceptanceAssertion } from "./long-task-acceptance-reference.js";
2
+ export function enrichCheckResultFindings(compiled, result) {
3
+ return {
4
+ ...result,
5
+ findings: result.findings.map((finding) => enrichFinding(compiled, finding)),
6
+ };
7
+ }
8
+ export function enrichFinding(compiled, finding) {
9
+ const outcome = finding.outcome_key
10
+ ? compiled.outcomes.find((item) => item.key === finding.outcome_key)
11
+ : null;
12
+ const sourceClaims = sourceClaimsForFinding(compiled, finding);
13
+ const sourceTargets = compiled.source_claims
14
+ .filter((source) => sourceClaims.includes(source.key))
15
+ .flatMap((source) => dispositionTargetRefs(source.disposition))
16
+ .filter((reference, index, all) => all.indexOf(reference) === index)
17
+ .sort();
18
+ return {
19
+ ...finding,
20
+ ...(sourceClaims.length ? { source_claim_keys: sourceClaims } : {}),
21
+ ...(sourceTargets.length ? { source_target_refs: sourceTargets } : {}),
22
+ ...(outcome && !finding.owner_paths
23
+ ? { owner_paths: outcome.product.owner.path_globs }
24
+ : {}),
25
+ };
26
+ }
27
+ function dispositionTargetRefs(disposition) {
28
+ if (disposition.type === "outcome_result")
29
+ return [disposition.ref];
30
+ if (disposition.type === "claim" ||
31
+ disposition.type === "acceptance" ||
32
+ disposition.type === "global_constraint" ||
33
+ disposition.type === "risk_fact" ||
34
+ disposition.type === "external_confirmation")
35
+ return disposition.refs;
36
+ return [];
37
+ }
38
+ function sourceClaimsForFinding(compiled, finding) {
39
+ const acceptanceRef = finding.check_key && finding.assertion_key
40
+ ? `${finding.outcome_key ?? "GLOBAL"}.${finding.check_key}.${finding.assertion_key}`
41
+ : null;
42
+ const resolvedAcceptance = acceptanceRef
43
+ ? resolveAcceptanceAssertion(compiled, acceptanceRef)
44
+ : null;
45
+ const productRefs = new Set((finding.claim_keys ?? []).map((claim) => finding.outcome_key ? `${finding.outcome_key}.${claim}` : claim));
46
+ return compiled.source_claims
47
+ .filter((source) => {
48
+ if (source.disposition.type === "acceptance" &&
49
+ resolvedAcceptance &&
50
+ source.disposition.refs.includes(resolvedAcceptance.ref))
51
+ return true;
52
+ if (source.disposition.type === "claim" &&
53
+ source.disposition.refs.some((reference) => productRefs.has(reference)))
54
+ return true;
55
+ if (source.disposition.type === "outcome_result" &&
56
+ productRefs.has(source.disposition.ref))
57
+ return true;
58
+ return (source.disposition.type === "global_constraint" &&
59
+ source.disposition.refs.some((reference) => productRefs.has(reference)));
60
+ })
61
+ .map((source) => source.key)
62
+ .sort();
63
+ }
@@ -0,0 +1,3 @@
1
+ import type { CompiledDeliveryContractV2, VerifierIdentityV2 } from "./long-task-delivery-types.js";
2
+ export declare function deliveryCompileFreshness(compiled: CompiledDeliveryContractV2): Promise<string[]>;
3
+ export declare function assertVerifierAuthorityCurrent(repositoryRoot: string, expected: VerifierIdentityV2): Promise<void>;
@@ -0,0 +1,80 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { captureContextGraphSnapshot } from "./context-graph-snapshot.js";
4
+ import { canonicalValueJson, sha256Hex } from "./strict-codec.js";
5
+ import { captureVerifierIdentity } from "./long-task-verifier-identity.js";
6
+ import { verifierAuthorityDiff } from "./long-task-verifier-authority.js";
7
+ import { parseDeliveryContractBundle } from "./long-task-delivery-parser.js";
8
+ export async function deliveryCompileFreshness(compiled) {
9
+ const findings = [];
10
+ try {
11
+ const currentContract = await parseDeliveryContractBundle(compiled.workdir);
12
+ if (sha256Hex(canonicalValueJson(currentContract.contract)) !==
13
+ compiled.contract_sha256)
14
+ findings.push(`contract_changed_after_compile:${compiled.contract_file}`);
15
+ }
16
+ catch {
17
+ findings.push(`contract_changed_after_compile:${compiled.contract_file}`);
18
+ }
19
+ for (const [file, hash] of Object.entries(compiled.contract_files))
20
+ await compareFile(path.join(compiled.repository_root, file), hash, `contract_changed_after_compile:${file}`, findings);
21
+ for (const [file, hash] of Object.entries(compiled.source_hashes))
22
+ await compareFile(path.join(compiled.repository_root, file), hash, `source_changed_after_compile:${file}`, findings);
23
+ try {
24
+ const current = await captureContextGraphSnapshot(compiled.repository_root, compiled.task.context_refs, compiled.context_snapshot.mode);
25
+ if (current.topology_sha256 !== compiled.context_snapshot.topology_sha256)
26
+ findings.push("context_changed_after_compile:topology");
27
+ if (canonicalValueJson(current.files) !==
28
+ canonicalValueJson(compiled.context_snapshot.files))
29
+ findings.push("context_changed_after_compile:file_set");
30
+ for (const [file, hash] of Object.entries(compiled.context_snapshot.sha256))
31
+ if (current.sha256[file] !== hash)
32
+ findings.push(`context_changed_after_compile:${file}`);
33
+ }
34
+ catch (error) {
35
+ findings.push(`context_changed_after_compile:${message(error)}`);
36
+ }
37
+ try {
38
+ const currentVerifier = await captureVerifierIdentity(compiled.repository_root, compiled.verifier_identity.hook_sha256 !== "not-required");
39
+ const verifierDiff = verifierAuthorityDiff(compiled.verifier_identity, currentVerifier);
40
+ if (verifierDiff.verifier_content_changed)
41
+ findings.push("verifier_changed_after_compile:bundle");
42
+ if (verifierDiff.verifier_runtime_locator_changed)
43
+ findings.push("verifier_changed_after_compile:runtime_locator");
44
+ }
45
+ catch {
46
+ findings.push("verifier_changed_after_compile:bundle");
47
+ }
48
+ const checks = [
49
+ ...compiled.global.acceptance.checks,
50
+ ...compiled.outcomes.flatMap((outcome) => outcome.acceptance.checks),
51
+ ];
52
+ for (const check of checks)
53
+ for (const [file, hash] of Object.entries(check.runner.frozen_files))
54
+ await compareFile(path.join(compiled.repository_root, file), hash, `runner_changed_after_compile:${check.internal_id}:${file}`, findings);
55
+ return [...new Set(findings)].sort();
56
+ }
57
+ export async function assertVerifierAuthorityCurrent(repositoryRoot, expected) {
58
+ let current;
59
+ try {
60
+ current = await captureVerifierIdentity(repositoryRoot, expected.hook_sha256 !== "not-required");
61
+ }
62
+ catch {
63
+ throw new Error("verifier_authority_migration_required");
64
+ }
65
+ const diff = verifierAuthorityDiff(expected, current);
66
+ if (diff.verifier_content_changed || diff.verifier_runtime_locator_changed)
67
+ throw new Error("verifier_authority_migration_required");
68
+ }
69
+ async function compareFile(file, expected, finding, findings) {
70
+ try {
71
+ if (sha256Hex(await readFile(file)) !== expected)
72
+ findings.push(finding);
73
+ }
74
+ catch {
75
+ findings.push(finding);
76
+ }
77
+ }
78
+ function message(error) {
79
+ return error instanceof Error ? error.message : String(error);
80
+ }
@@ -0,0 +1,9 @@
1
+ import type { SyncReport } from "./sync-engine.js";
2
+ export declare function installLongTaskHooks(projectRoot: string, report: SyncReport): Promise<void>;
3
+ export declare function uninstallLongTaskHooks(projectRoot: string, report: SyncReport): Promise<void>;
4
+ export declare function packageOwnedCommand(entry: string): string;
5
+ export declare function removeManagedHookEntries(groups: unknown, currentPackageCommand?: string): {
6
+ groups: unknown[];
7
+ removed: number;
8
+ };
9
+ export declare function isManagedHookEntry(entry: unknown, currentPackageCommand?: string): boolean;
@@ -0,0 +1,184 @@
1
+ import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { pathExists } from "./fs.js";
5
+ const MANAGED_STATUS = "Tiny Context long-task live authority gate";
6
+ const LEGACY_MANAGED_STATUSES = new Set([
7
+ "Tiny Context long-task live authority gate",
8
+ "Tiny Context long-task authority gate",
9
+ "Tiny Context long-task completion gate",
10
+ "Tiny Context composite completion gate",
11
+ ]);
12
+ const LEGACY_REPO_LOCAL_COMMANDS = new Set([
13
+ 'node "$(git rev-parse --show-toplevel)/.codex/hooks/long-task-hook.mjs"',
14
+ "powershell -NoProfile -Command \"$r=(git rev-parse --show-toplevel); node (Join-Path $r '.codex/hooks/long-task-hook.mjs')\"",
15
+ "node .codex/hooks/long-task-hook.mjs",
16
+ 'node ".codex/hooks/long-task-hook.mjs"',
17
+ "node .codex\\hooks\\long-task-hook.mjs",
18
+ 'node ".codex\\hooks\\long-task-hook.mjs"',
19
+ ]);
20
+ export async function installLongTaskHooks(projectRoot, report) {
21
+ const packageRoot = fileURLToPath(new URL("../../", import.meta.url));
22
+ const entry = path.join(packageRoot, "dist", "long-task-hook.js");
23
+ if (!(await pathExists(entry))) {
24
+ report.blocked.push("package-owned dist/long-task-hook.js is missing");
25
+ return;
26
+ }
27
+ const legacyScript = path.join(projectRoot, ".codex", "hooks", "long-task-hook.mjs");
28
+ if (await pathExists(legacyScript)) {
29
+ await rm(legacyScript, { force: true });
30
+ report.changed.push(".codex/hooks/long-task-hook.mjs");
31
+ }
32
+ const command = packageOwnedCommand(entry);
33
+ const config = path.join(projectRoot, ".codex", "hooks.json");
34
+ let root = {};
35
+ if (await pathExists(config)) {
36
+ try {
37
+ root = JSON.parse(await readFile(config, "utf8"));
38
+ }
39
+ catch {
40
+ report.blocked.push(".codex/hooks.json: invalid JSON");
41
+ return;
42
+ }
43
+ }
44
+ const hooks = object(root.hooks);
45
+ root.hooks = hooks;
46
+ for (const event of ["SessionStart", "PostCompact", "Stop"]) {
47
+ const groups = Array.isArray(hooks[event]) ? hooks[event] : [];
48
+ const cleaned = removeManagedHookEntries(groups, command);
49
+ cleaned.groups.push({
50
+ hooks: [
51
+ {
52
+ type: "command",
53
+ command,
54
+ commandWindows: command,
55
+ timeout: event === "Stop" ? 3600 : 10,
56
+ statusMessage: MANAGED_STATUS,
57
+ },
58
+ ],
59
+ });
60
+ hooks[event] = cleaned.groups;
61
+ }
62
+ if (await writeIfChanged(config, `${JSON.stringify(root, null, 2)}\n`))
63
+ report.changed.push(".codex/hooks.json");
64
+ else
65
+ report.skipped.push(".codex/hooks.json");
66
+ }
67
+ export async function uninstallLongTaskHooks(projectRoot, report) {
68
+ const packageRoot = fileURLToPath(new URL("../../", import.meta.url));
69
+ const command = packageOwnedCommand(path.join(packageRoot, "dist", "long-task-hook.js"));
70
+ const legacyScript = path.join(projectRoot, ".codex", "hooks", "long-task-hook.mjs");
71
+ if (await pathExists(legacyScript)) {
72
+ await rm(legacyScript, { force: true });
73
+ report.changed.push(".codex/hooks/long-task-hook.mjs");
74
+ }
75
+ const config = path.join(projectRoot, ".codex", "hooks.json");
76
+ if (!(await pathExists(config)))
77
+ return;
78
+ let root;
79
+ try {
80
+ root = JSON.parse(await readFile(config, "utf8"));
81
+ }
82
+ catch {
83
+ report.skipped.push(".codex/hooks.json: invalid JSON");
84
+ return;
85
+ }
86
+ const hooks = object(root.hooks);
87
+ let changed = false;
88
+ for (const event of ["SessionStart", "PostCompact", "Stop"]) {
89
+ if (!Array.isArray(hooks[event]))
90
+ continue;
91
+ const cleaned = removeManagedHookEntries(hooks[event], command);
92
+ if (cleaned.removed === 0)
93
+ continue;
94
+ changed = true;
95
+ if (cleaned.groups.length)
96
+ hooks[event] = cleaned.groups;
97
+ else
98
+ delete hooks[event];
99
+ }
100
+ if (!changed)
101
+ return;
102
+ root.hooks = hooks;
103
+ if (Object.keys(hooks).length === 0 && Object.keys(root).length === 1)
104
+ await rm(config, { force: true });
105
+ else
106
+ await writeIfChanged(config, `${JSON.stringify(root, null, 2)}\n`);
107
+ report.changed.push(".codex/hooks.json");
108
+ }
109
+ export function packageOwnedCommand(entry) {
110
+ return `node "${path.resolve(entry).replace(/"/gu, '\\"')}"`;
111
+ }
112
+ export function removeManagedHookEntries(groups, currentPackageCommand = "") {
113
+ if (!Array.isArray(groups))
114
+ return { groups: [], removed: 0 };
115
+ const retained = [];
116
+ let removed = 0;
117
+ for (const groupValue of groups) {
118
+ if (!isObject(groupValue) || !Array.isArray(groupValue.hooks)) {
119
+ retained.push(groupValue);
120
+ continue;
121
+ }
122
+ const hooks = groupValue.hooks.filter((entry) => {
123
+ if (!isManagedHookEntry(entry, currentPackageCommand))
124
+ return true;
125
+ removed += 1;
126
+ return false;
127
+ });
128
+ if (hooks.length > 0) {
129
+ retained.push({ ...groupValue, hooks });
130
+ continue;
131
+ }
132
+ if (Object.keys(groupValue).some((key) => key !== "hooks"))
133
+ retained.push({ ...groupValue, hooks });
134
+ }
135
+ return { groups: retained, removed };
136
+ }
137
+ export function isManagedHookEntry(entry, currentPackageCommand = "") {
138
+ const row = object(entry);
139
+ if (row.type !== "command")
140
+ return false;
141
+ const commands = [row.command, row.commandWindows]
142
+ .filter((value) => typeof value === "string")
143
+ .map((value) => value.trim());
144
+ const repoLocal = commands.some((command) => LEGACY_REPO_LOCAL_COMMANDS.has(command));
145
+ if (repoLocal)
146
+ return true;
147
+ const status = String(row.statusMessage ?? "");
148
+ if (!LEGACY_MANAGED_STATUSES.has(status))
149
+ return false;
150
+ return commands.some((command) => (Boolean(currentPackageCommand) && command === currentPackageCommand) ||
151
+ isHistoricalPackageOwnedCommand(command));
152
+ }
153
+ function isHistoricalPackageOwnedCommand(command) {
154
+ const match = /^node "([^"\r\n]+)"$/u.exec(command);
155
+ if (!match)
156
+ return false;
157
+ const absolute = match[1];
158
+ if (!path.isAbsolute(absolute) &&
159
+ !path.win32.isAbsolute(absolute) &&
160
+ !path.posix.isAbsolute(absolute))
161
+ return false;
162
+ const normalized = absolute.replace(/\\/gu, "/");
163
+ return (/\/node_modules\/project-tiny-context-harness\/dist\/long-task-hook\.js$/u.test(normalized) || /\/packages\/ty-context\/dist\/long-task-hook\.js$/u.test(normalized));
164
+ }
165
+ function object(value) {
166
+ return value && typeof value === "object" && !Array.isArray(value)
167
+ ? value
168
+ : {};
169
+ }
170
+ function isObject(value) {
171
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
172
+ }
173
+ async function writeIfChanged(file, content) {
174
+ try {
175
+ if ((await readFile(file, "utf8")) === content)
176
+ return false;
177
+ }
178
+ catch { }
179
+ await mkdir(path.dirname(file), { recursive: true });
180
+ const temp = `${file}.tmp-${process.pid}-${Date.now()}`;
181
+ await writeFile(temp, content, { flag: "wx" });
182
+ await rename(temp, file);
183
+ return true;
184
+ }
@@ -0,0 +1,7 @@
1
+ export interface CompletionGateCheck {
2
+ status: "available" | "completion_gate_unavailable";
3
+ bundle_sha256: string;
4
+ hook_sha256: string;
5
+ findings: string[];
6
+ }
7
+ export declare function checkLongTaskCompletionGate(repositoryRoot: string, packageRoot: string): Promise<CompletionGateCheck>;
@@ -0,0 +1,58 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { packageOwnedCommand } from "./long-task-hook-install.js";
4
+ import { assertProtectedRepositoryFile } from "./long-task-protected-files.js";
5
+ import { sha256Hex } from "./strict-codec.js";
6
+ export async function checkLongTaskCompletionGate(repositoryRoot, packageRoot) {
7
+ const config = path.join(path.resolve(repositoryRoot), ".codex", "hooks.json");
8
+ const entry = path.join(path.resolve(packageRoot), "dist", "long-task-hook.js");
9
+ const expectedCommand = packageOwnedCommand(entry);
10
+ const findings = [];
11
+ let configHash = "missing";
12
+ let hookHash = "missing";
13
+ try {
14
+ hookHash = sha256Hex(await readFile(await assertProtectedRepositoryFile(packageRoot, entry, "package_owned_hook")));
15
+ }
16
+ catch {
17
+ findings.push("package_owned_hook_missing");
18
+ }
19
+ try {
20
+ const content = await readFile(await assertProtectedRepositoryFile(repositoryRoot, config, "completion_hook_config"), "utf8");
21
+ configHash = sha256Hex(content);
22
+ const value = JSON.parse(content);
23
+ for (const event of ["SessionStart", "PostCompact", "Stop"]) {
24
+ const handlers = managedHandlers(value.hooks?.[event], expectedCommand);
25
+ if (handlers.length !== 1)
26
+ findings.push(`completion_hook_event_missing:${event}`);
27
+ else {
28
+ const timeout = handlers[0].timeout;
29
+ const expected = event === "Stop" ? 3600 : 10;
30
+ if (timeout !== expected)
31
+ findings.push(`completion_hook_timeout_invalid:${event}`);
32
+ }
33
+ }
34
+ }
35
+ catch {
36
+ findings.push("hooks_config_missing_or_invalid");
37
+ }
38
+ const bundle_sha256 = sha256Hex(`${configHash}:${hookHash}`);
39
+ return {
40
+ status: findings.length ? "completion_gate_unavailable" : "available",
41
+ bundle_sha256,
42
+ hook_sha256: hookHash,
43
+ findings,
44
+ };
45
+ }
46
+ function managedHandlers(value, expectedCommand) {
47
+ if (Array.isArray(value))
48
+ return value.flatMap((item) => managedHandlers(item, expectedCommand));
49
+ if (value && typeof value === "object") {
50
+ const item = value;
51
+ if (item.type === "command" &&
52
+ item.command === expectedCommand &&
53
+ item.commandWindows === expectedCommand)
54
+ return [item];
55
+ return Object.values(item).flatMap((child) => managedHandlers(child, expectedCommand));
56
+ }
57
+ return [];
58
+ }
@@ -0,0 +1,2 @@
1
+ import type { CompiledCheckV2 } from "./long-task-delivery-types.js";
2
+ export declare function validateRawExecutionObservationOwnership(checks: CompiledCheckV2[]): void;
@@ -0,0 +1,22 @@
1
+ export function validateRawExecutionObservationOwnership(checks) {
2
+ const byExecution = new Map();
3
+ for (const check of checks) {
4
+ let observations = byExecution.get(check.raw_execution_identity);
5
+ if (!observations) {
6
+ observations = new Map();
7
+ byExecution.set(check.raw_execution_identity, observations);
8
+ }
9
+ for (const assertion of [
10
+ ...check.positive_assertions,
11
+ ...check.negative_assertions,
12
+ ]) {
13
+ if (!assertion.claims.length)
14
+ continue;
15
+ const owner = `${check.outcome_key ?? "GLOBAL"}.${check.key}.${assertion.key}`;
16
+ const previous = observations.get(assertion.observation);
17
+ if (previous)
18
+ throw new Error(`raw_execution_observation_reused:${check.raw_execution_identity}:${assertion.observation}:${previous}:${owner}`);
19
+ observations.set(assertion.observation, owner);
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,4 @@
1
+ import type { DeliveryOutcomeV2 } from "./long-task-delivery-types.js";
2
+ export declare function parseOutcome(value: unknown, label: string): DeliveryOutcomeV2;
3
+ export declare function parseOutcomeFragment(raw: string, relative: string): DeliveryOutcomeV2[];
4
+ export declare function safeFragmentPath(value: string, index: number): string;