project-tiny-context-harness 0.2.85 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/README.md +164 -427
  2. package/assets/README.md +284 -455
  3. package/assets/README.zh-CN.md +200 -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 +63 -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 +467 -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
@@ -3,9 +3,9 @@ import { createHash } from "node:crypto";
3
3
  import { promises as fs } from "node:fs";
4
4
  import path from "node:path";
5
5
  import { promisify } from "node:util";
6
- import { ensureDir, listFiles, pathExists, readText, writeTextIfChanged } from "./fs.js";
6
+ import { ensureDir, listFiles, pathExists, readText, writeTextIfChanged, } from "./fs.js";
7
7
  import { harnessRoot } from "./harness-root.js";
8
- import { SAFE_EXAMPLE_FILE_NAMES, shouldExcludeRelativePath, shouldIncludeCodeFile, toPosix } from "./source-files.js";
8
+ import { SAFE_EXAMPLE_FILE_NAMES, shouldExcludeRelativePath, shouldIncludeCodeFile, toPosix, } from "./source-files.js";
9
9
  const execFileAsync = promisify(execFile);
10
10
  const EXPORT_HEADER = "Export artifact. Do not reference from project_context/context.toml.";
11
11
  const DEFAULT_EXPORT_DIR = "tmp/ty-context/context-exports";
@@ -30,8 +30,11 @@ async function runFullContextExport(projectRoot, options) {
30
30
  const outputRelativePath = repoRelative(projectRoot, outputPath);
31
31
  const warnings = [];
32
32
  const sourceFiles = await collectSourceFiles(projectRoot, warnings);
33
- const sourceRelativeFiles = sourceFiles.map((file) => repoRelative(projectRoot, file)).sort();
34
- const sourceContextCount = sourceRelativeFiles.filter((file) => file === "project_context/context.toml" || file.startsWith("project_context/")).length;
33
+ const sourceRelativeFiles = sourceFiles
34
+ .map((file) => repoRelative(projectRoot, file))
35
+ .sort();
36
+ const sourceContextCount = sourceRelativeFiles.filter((file) => file === "project_context/context.toml" ||
37
+ file.startsWith("project_context/")).length;
35
38
  const sourceSections = [];
36
39
  const contextEntrySections = [];
37
40
  for (const file of sourceFiles) {
@@ -66,7 +69,9 @@ async function runFullContextExport(projectRoot, options) {
66
69
  "- source_file_list:",
67
70
  ...sourceRelativeFiles.map((file) => ` - ${file}`),
68
71
  "- warnings:",
69
- ...(warnings.length > 0 ? warnings.map((warning) => ` - ${warning}`) : [" - none"]),
72
+ ...(warnings.length > 0
73
+ ? warnings.map((warning) => ` - ${warning}`)
74
+ : [" - none"]),
70
75
  "",
71
76
  "## Directory Tree Summary",
72
77
  "",
@@ -78,12 +83,14 @@ async function runFullContextExport(projectRoot, options) {
78
83
  "",
79
84
  "## Context Code Entry Point Index",
80
85
  "",
81
- contextEntrySections.length > 0 ? contextEntrySections.join("\n\n") : "- No Code Entry Points sections found in exported Context Markdown.",
86
+ contextEntrySections.length > 0
87
+ ? contextEntrySections.join("\n\n")
88
+ : "- No Code Entry Points sections found in exported Context Markdown.",
82
89
  "",
83
90
  "## Source Files",
84
91
  "",
85
92
  sourceSections.join("\n\n"),
86
- ""
93
+ "",
87
94
  ].join("\n");
88
95
  if (!options.check) {
89
96
  await ensureDir(path.dirname(outputPath));
@@ -96,7 +103,7 @@ async function runFullContextExport(projectRoot, options) {
96
103
  sourceFiles: sourceRelativeFiles,
97
104
  sourceContextCount,
98
105
  warnings,
99
- wrote: !options.check
106
+ wrote: !options.check,
100
107
  };
101
108
  }
102
109
  async function runCodeImplementationExport(projectRoot, options) {
@@ -121,7 +128,7 @@ async function runCodeImplementationExport(projectRoot, options) {
121
128
  characters: content.length,
122
129
  sha256: sha256(content),
123
130
  summary: summarizeCodeFile(relative, content, language),
124
- content
131
+ content,
125
132
  });
126
133
  }
127
134
  records.sort((left, right) => left.relative.localeCompare(right.relative));
@@ -146,7 +153,9 @@ async function runCodeImplementationExport(projectRoot, options) {
146
153
  `- total_lines: ${totalLines}`,
147
154
  `- total_characters: ${totalCharacters}`,
148
155
  "- warnings:",
149
- ...(warnings.length > 0 ? warnings.map((warning) => ` - ${warning}`) : [" - none"]),
156
+ ...(warnings.length > 0
157
+ ? warnings.map((warning) => ` - ${warning}`)
158
+ : [" - none"]),
150
159
  "",
151
160
  "## Implementation Guide",
152
161
  "",
@@ -159,7 +168,7 @@ async function runCodeImplementationExport(projectRoot, options) {
159
168
  "## Source Files",
160
169
  "",
161
170
  records.map(renderCodeFileSection).join("\n\n"),
162
- ""
171
+ "",
163
172
  ].join("\n");
164
173
  if (!options.check) {
165
174
  await ensureDir(path.dirname(outputPath));
@@ -175,7 +184,7 @@ async function runCodeImplementationExport(projectRoot, options) {
175
184
  totalLines,
176
185
  totalCharacters,
177
186
  warnings,
178
- wrote: !options.check
187
+ wrote: !options.check,
179
188
  };
180
189
  }
181
190
  function resolveOutputPath(projectRoot, requestedOutput, now, mode) {
@@ -190,7 +199,8 @@ function resolveOutputPath(projectRoot, requestedOutput, now, mode) {
190
199
  throw new Error("export-context --output must stay inside the workspace; use tmp/ty-context/context-exports/<name>.md");
191
200
  }
192
201
  const normalized = toPosix(relative);
193
- if (normalized === "project_context" || normalized.startsWith("project_context/")) {
202
+ if (normalized === "project_context" ||
203
+ normalized.startsWith("project_context/")) {
194
204
  throw new Error("export-context output is a temporary artifact; use tmp/ty-context/context-exports/** instead of project_context/**");
195
205
  }
196
206
  if (!normalized.startsWith(`${DEFAULT_EXPORT_DIR}/`)) {
@@ -212,7 +222,8 @@ async function collectSourceFiles(projectRoot, warnings) {
212
222
  const contextRoot = path.join(projectRoot, "project_context");
213
223
  for (const file of await listFiles(contextRoot)) {
214
224
  const relative = repoRelative(projectRoot, file);
215
- if ((relative.endsWith(".md") || relative.endsWith(".toml")) && !shouldExcludeRelativePath(relative)) {
225
+ if ((relative.endsWith(".md") || relative.endsWith(".toml")) &&
226
+ !shouldExcludeRelativePath(relative)) {
216
227
  files.add(file);
217
228
  }
218
229
  }
@@ -220,14 +231,16 @@ async function collectSourceFiles(projectRoot, warnings) {
220
231
  const skillRoot = path.join(projectRoot, root, "skills");
221
232
  for (const file of await listFiles(skillRoot)) {
222
233
  const relative = repoRelative(projectRoot, file);
223
- if (relative.endsWith("/SKILL.md") && !shouldExcludeRelativePath(relative)) {
234
+ if (relative.endsWith("/SKILL.md") &&
235
+ !shouldExcludeRelativePath(relative)) {
224
236
  files.add(file);
225
237
  }
226
238
  }
227
239
  for (const file of await listCandidateFiles(projectRoot)) {
228
240
  const relative = repoRelative(projectRoot, file);
229
241
  const base = path.basename(file);
230
- if (["README.md", "AGENTS.md", "DESIGN.md"].includes(base) && !shouldExcludeRelativePath(relative)) {
242
+ if (["README.md", "AGENTS.md", "DESIGN.md"].includes(base) &&
243
+ !shouldExcludeRelativePath(relative)) {
231
244
  files.add(file);
232
245
  }
233
246
  }
@@ -247,9 +260,17 @@ async function collectCodeSourceFiles(projectRoot) {
247
260
  }
248
261
  async function listGitCandidateFiles(projectRoot) {
249
262
  try {
250
- const result = await execFileAsync("git", ["-C", projectRoot, "ls-files", "--cached", "--others", "--exclude-standard", "-z"], {
263
+ const result = await execFileAsync("git", [
264
+ "-C",
265
+ projectRoot,
266
+ "ls-files",
267
+ "--cached",
268
+ "--others",
269
+ "--exclude-standard",
270
+ "-z",
271
+ ], {
251
272
  encoding: "utf8",
252
- maxBuffer: GIT_LS_MAX_BUFFER
273
+ maxBuffer: GIT_LS_MAX_BUFFER,
253
274
  });
254
275
  const stdout = result.stdout;
255
276
  return stdout
@@ -322,7 +343,8 @@ async function buildDirectoryTree(projectRoot, warnings) {
322
343
  }
323
344
  const visibleEntries = entries
324
345
  .filter((entry) => !shouldExcludeRelativePath(repoRelative(projectRoot, path.join(current, entry.name))))
325
- .sort((left, right) => Number(right.isDirectory()) - Number(left.isDirectory()) || left.name.localeCompare(right.name));
346
+ .sort((left, right) => Number(right.isDirectory()) - Number(left.isDirectory()) ||
347
+ left.name.localeCompare(right.name));
326
348
  for (const entry of visibleEntries) {
327
349
  if (count >= MAX_TREE_ENTRIES) {
328
350
  truncated = true;
@@ -362,7 +384,9 @@ async function buildMakefileVerificationSummary(projectRoot) {
362
384
  summary.push(` ${line.trim()}`);
363
385
  }
364
386
  }
365
- return summary.length > 0 ? summary.join("\n") : "- No obvious verification targets found in root Makefile.";
387
+ return summary.length > 0
388
+ ? summary.join("\n")
389
+ : "- No obvious verification targets found in root Makefile.";
366
390
  }
367
391
  function redactSensitiveAssignments(content) {
368
392
  let count = 0;
@@ -379,7 +403,13 @@ function redactSensitiveAssignments(content) {
379
403
  function renderSourceSection(relative, content) {
380
404
  const fence = fenceFor(content);
381
405
  const language = languageFor(relative);
382
- return [`### ${relative}`, "", `${fence}${language}`, content.trimEnd(), fence].join("\n");
406
+ return [
407
+ `### ${relative}`,
408
+ "",
409
+ `${fence}${language}`,
410
+ content.trimEnd(),
411
+ fence,
412
+ ].join("\n");
383
413
  }
384
414
  function renderCodeFileSection(record) {
385
415
  const fence = fenceFor(record.content);
@@ -396,7 +426,7 @@ function renderCodeFileSection(record) {
396
426
  "",
397
427
  `${fence}${record.language}`,
398
428
  record.content.trimEnd(),
399
- fence
429
+ fence,
400
430
  ].join("\n");
401
431
  }
402
432
  function renderCodeFileIndex(records) {
@@ -406,7 +436,7 @@ function renderCodeFileIndex(records) {
406
436
  return [
407
437
  "| Path | Type | Lines | Characters | SHA256 | Summary |",
408
438
  "|---|---:|---:|---:|---|---|",
409
- ...records.map((record) => `| ${escapeTableCell(record.relative)} | ${escapeTableCell(record.language)} | ${record.lines} | ${record.characters} | ${record.sha256.slice(0, 12)} | ${escapeTableCell(record.summary)} |`)
439
+ ...records.map((record) => `| ${escapeTableCell(record.relative)} | ${escapeTableCell(record.language)} | ${record.lines} | ${record.characters} | ${record.sha256.slice(0, 12)} | ${escapeTableCell(record.summary)} |`),
410
440
  ].join("\n");
411
441
  }
412
442
  function buildImplementationGuide(records) {
@@ -432,7 +462,7 @@ function buildImplementationGuide(records) {
432
462
  `- Main modules: ${modules || "no obvious modules identified"}.`,
433
463
  `- Key entry points: ${entrypoints.length > 0 ? entrypoints.join(", ") : "no obvious entry points identified"}.`,
434
464
  "- Each file block keeps the relative path, heuristic summary, line count, character count, SHA256 and redacted source body.",
435
- "- This file is a temporary implementation snapshot, not durable Context; durable project facts still belong in project_context/**."
465
+ "- This file is a temporary implementation snapshot, not durable Context; durable project facts still belong in project_context/**.",
436
466
  ].join("\n");
437
467
  }
438
468
  function summarizeCodeFile(relative, content, language) {
@@ -448,17 +478,25 @@ function summarizeCodeFile(relative, content, language) {
448
478
  if (base.toLowerCase() === "makefile") {
449
479
  return summarizeMakefile(content);
450
480
  }
451
- if (base.toLowerCase().startsWith("dockerfile") || lower.endsWith(".dockerfile")) {
481
+ if (base.toLowerCase().startsWith("dockerfile") ||
482
+ lower.endsWith(".dockerfile")) {
452
483
  const image = /^FROM\s+(.+)$/im.exec(content)?.[1]?.trim();
453
- return image ? `Defines a Docker image build starting from ${image}.` : "Defines a Docker image build.";
484
+ return image
485
+ ? `Defines a Docker image build starting from ${image}.`
486
+ : "Defines a Docker image build.";
454
487
  }
455
- if (lower.endsWith("docker-compose.yml") || lower.endsWith("docker-compose.yaml") || base.toLowerCase().startsWith("compose.")) {
488
+ if (lower.endsWith("docker-compose.yml") ||
489
+ lower.endsWith("docker-compose.yaml") ||
490
+ base.toLowerCase().startsWith("compose.")) {
456
491
  const services = extractYamlTopLevelMapKeys(content, "services").slice(0, 6);
457
492
  return services.length > 0
458
493
  ? `Defines Docker Compose services ${services.join(", ")}.`
459
494
  : "Defines Docker Compose services and local runtime wiring.";
460
495
  }
461
- if (language === "yaml" || language === "toml" || language === "json" || language === "jsonc") {
496
+ if (language === "yaml" ||
497
+ language === "toml" ||
498
+ language === "json" ||
499
+ language === "jsonc") {
462
500
  return symbols.length > 0
463
501
  ? `Defines project configuration around ${symbols.slice(0, 6).join(", ")}.`
464
502
  : "Defines project configuration used by the implementation or tooling.";
@@ -471,19 +509,30 @@ function summarizeCodeFile(relative, content, language) {
471
509
  function extractSymbolSummary(content, language) {
472
510
  const symbols = new Set();
473
511
  const patterns = language === "python"
474
- ? [/^(?:async\s+)?def\s+([A-Za-z_][\w]*)/gm, /^class\s+([A-Za-z_][\w]*)/gm]
512
+ ? [
513
+ /^(?:async\s+)?def\s+([A-Za-z_][\w]*)/gm,
514
+ /^class\s+([A-Za-z_][\w]*)/gm,
515
+ ]
475
516
  : language === "go"
476
- ? [/^func\s+(?:\([^)]+\)\s*)?([A-Za-z_][\w]*)/gm, /^type\s+([A-Za-z_][\w]*)/gm]
517
+ ? [
518
+ /^func\s+(?:\([^)]+\)\s*)?([A-Za-z_][\w]*)/gm,
519
+ /^type\s+([A-Za-z_][\w]*)/gm,
520
+ ]
477
521
  : language === "sql"
478
- ? [/\bCREATE\s+(?:OR\s+REPLACE\s+)?(?:TABLE|VIEW|FUNCTION|PROCEDURE|INDEX|TRIGGER)\s+([A-Za-z0-9_."]+)/gim]
479
- : language === "yaml" || language === "toml" || language === "json" || language === "jsonc"
522
+ ? [
523
+ /\bCREATE\s+(?:OR\s+REPLACE\s+)?(?:TABLE|VIEW|FUNCTION|PROCEDURE|INDEX|TRIGGER)\s+([A-Za-z0-9_."]+)/gim,
524
+ ]
525
+ : language === "yaml" ||
526
+ language === "toml" ||
527
+ language === "json" ||
528
+ language === "jsonc"
480
529
  ? [/^["']?([A-Za-z0-9_.-]+)["']?\s*[:=]/gm]
481
530
  : [
482
531
  /(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)/g,
483
532
  /(?:export\s+)?class\s+([A-Za-z_$][\w$]*)/g,
484
533
  /(?:export\s+)?interface\s+([A-Za-z_$][\w$]*)/g,
485
534
  /(?:export\s+)?type\s+([A-Za-z_$][\w$]*)/g,
486
- /(?:export\s+)?const\s+([A-Za-z_$][\w$]*)/g
535
+ /(?:export\s+)?const\s+([A-Za-z_$][\w$]*)/g,
487
536
  ];
488
537
  for (const pattern of patterns) {
489
538
  let match;
@@ -505,7 +554,7 @@ function extractRouteSummary(content) {
505
554
  const routePatterns = [
506
555
  /\.(get|post|put|patch|delete|head|options)\s*\(\s*["'`]([^"'`]+)["'`]/gi,
507
556
  /\bHandleFunc\s*\(\s*["'`]([^"'`]+)["'`]/g,
508
- /\bHandle\s*\(\s*["'`]([^"'`]+)["'`]/g
557
+ /\bHandle\s*\(\s*["'`]([^"'`]+)["'`]/g,
509
558
  ];
510
559
  for (const pattern of routePatterns) {
511
560
  let match;
@@ -521,7 +570,9 @@ function extractRouteSummary(content) {
521
570
  return [...routes];
522
571
  }
523
572
  function summarizeMakefile(content) {
524
- const targets = [...content.matchAll(/^([A-Za-z0-9_.-]+):/gm)].map((match) => match[1]).slice(0, 8);
573
+ const targets = [...content.matchAll(/^([A-Za-z0-9_.-]+):/gm)]
574
+ .map((match) => match[1])
575
+ .slice(0, 8);
525
576
  return targets.length > 0
526
577
  ? `Defines Make targets ${targets.join(", ")} for local build, validation or automation.`
527
578
  : "Defines Make targets for local build, validation or automation.";
@@ -551,10 +602,14 @@ function extractJsonString(content, key) {
551
602
  }
552
603
  function describeFilePurpose(relative, language) {
553
604
  const lower = relative.toLowerCase();
554
- if (lower.includes("/test") || lower.includes(".test.") || lower.includes(".spec.")) {
605
+ if (lower.includes("/test") ||
606
+ lower.includes(".test.") ||
607
+ lower.includes(".spec.")) {
555
608
  return `Contains ${language} tests for ${path.posix.basename(relative)}`;
556
609
  }
557
- if (lower.includes("/cli") || lower.endsWith("/cli.ts") || lower.endsWith("/cli.js")) {
610
+ if (lower.includes("/cli") ||
611
+ lower.endsWith("/cli.ts") ||
612
+ lower.endsWith("/cli.js")) {
558
613
  return `Implements ${language} CLI behavior for ${path.posix.basename(relative)}`;
559
614
  }
560
615
  if (lower.includes("/commands/")) {
@@ -563,7 +618,9 @@ function describeFilePurpose(relative, language) {
563
618
  if (lower.includes("/lib/") || lower.includes("/internal/")) {
564
619
  return `Implements ${language} library behavior for ${path.posix.basename(relative)}`;
565
620
  }
566
- if (lower.includes("/components/") || lower.includes("/pages/") || lower.includes("/app/")) {
621
+ if (lower.includes("/components/") ||
622
+ lower.includes("/pages/") ||
623
+ lower.includes("/app/")) {
567
624
  return `Implements ${language} UI or application behavior for ${path.posix.basename(relative)}`;
568
625
  }
569
626
  return `Contains ${language} implementation for ${path.posix.basename(relative)}`;
@@ -624,7 +681,9 @@ function languageFor(relative) {
624
681
  if (base === "makefile") {
625
682
  return "make";
626
683
  }
627
- if (base === "dockerfile" || base.startsWith("dockerfile.") || lower.endsWith(".dockerfile")) {
684
+ if (base === "dockerfile" ||
685
+ base.startsWith("dockerfile.") ||
686
+ lower.endsWith(".dockerfile")) {
628
687
  return "dockerfile";
629
688
  }
630
689
  if (SAFE_EXAMPLE_FILE_NAMES.has(base)) {
@@ -645,7 +704,9 @@ function languageFor(relative) {
645
704
  if (lower.endsWith(".jsx")) {
646
705
  return "jsx";
647
706
  }
648
- if (lower.endsWith(".js") || lower.endsWith(".mjs") || lower.endsWith(".cjs")) {
707
+ if (lower.endsWith(".js") ||
708
+ lower.endsWith(".mjs") ||
709
+ lower.endsWith(".cjs")) {
649
710
  return "javascript";
650
711
  }
651
712
  if (lower.endsWith(".py")) {
@@ -699,7 +760,10 @@ function extractSection(content, heading) {
699
760
  return body || undefined;
700
761
  }
701
762
  function timestampForFile(now) {
702
- return now.toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z");
763
+ return now
764
+ .toISOString()
765
+ .replace(/[-:]/g, "")
766
+ .replace(/\.\d{3}Z$/, "Z");
703
767
  }
704
768
  function repoRelative(root, file) {
705
769
  return toPosix(path.relative(root, file));
@@ -0,0 +1,18 @@
1
+ export interface ContextGraphSnapshot {
2
+ mode: "referenced" | "full";
3
+ topology_sha256: string;
4
+ files: string[];
5
+ sha256: Record<string, string>;
6
+ controlling_files: string[];
7
+ supporting_files: string[];
8
+ }
9
+ export interface CampaignContextBaseline {
10
+ graph_sha256: string;
11
+ files: Record<string, string>;
12
+ baseline_sha256: string;
13
+ }
14
+ export declare function captureContextGraphSnapshot(repositoryRoot: string, contextRefs: Iterable<string>, mode?: "referenced" | "full"): Promise<ContextGraphSnapshot>;
15
+ export declare function captureCampaignContextBaseline(repositoryRoot: string, contextRefs: Iterable<string>): Promise<CampaignContextBaseline>;
16
+ export declare function assertCampaignContextBaselineFresh(repositoryRoot: string, expected: CampaignContextBaseline, contextRefs: Iterable<string>): Promise<void>;
17
+ export declare function currentContextTopologySha256(repositoryRoot: string): Promise<string>;
18
+ export declare function listContextFiles(repositoryRoot: string): Promise<string[]>;
@@ -0,0 +1,171 @@
1
+ import { readFile, readdir } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { contextAuthorityTopologyHash } from "./long-task-context-authority-topology.js";
4
+ import { canonicalJson, sha256Hex } from "./strict-codec.js";
5
+ import { parseContextManifest, } from "./context-manifest-schema.js";
6
+ import { assertProtectedRepositoryFile } from "./long-task-protected-files.js";
7
+ const CONTEXT_MANIFEST_PATH = "project_context/context.toml";
8
+ const SUPPORTING_CONTEXT_ROLES = new Set(["implementation-index", "archive"]);
9
+ export async function captureContextGraphSnapshot(repositoryRoot, contextRefs, mode = "referenced") {
10
+ const root = path.resolve(repositoryRoot);
11
+ const manifest = await readContextManifest(root);
12
+ const allFiles = await listContextFiles(root);
13
+ const available = new Set(allFiles);
14
+ const selected = new Set();
15
+ const explicitlySelected = new Set();
16
+ if (mode === "full") {
17
+ allFiles.forEach((file) => selected.add(file));
18
+ }
19
+ else {
20
+ for (const required of [
21
+ CONTEXT_MANIFEST_PATH,
22
+ "project_context/global.md",
23
+ "project_context/architecture.md",
24
+ ]) {
25
+ if (!available.has(required)) {
26
+ throw new Error(`context_snapshot_required_file_missing:${required}`);
27
+ }
28
+ selected.add(required);
29
+ explicitlySelected.add(required);
30
+ }
31
+ for (const contextRef of contextRefs) {
32
+ const normalized = normalizeRepoPath(contextRef);
33
+ if (!available.has(normalized)) {
34
+ throw new Error(`context_ref_invalid:${contextRef}`);
35
+ }
36
+ selected.add(normalized);
37
+ explicitlySelected.add(normalized);
38
+ }
39
+ addTransitiveChildren(manifest, selected, available);
40
+ }
41
+ const files = [...selected].sort();
42
+ const authorityTopologySha256 = contextAuthorityTopologyHash(manifest, files);
43
+ const hashes = Object.fromEntries(await Promise.all(files.map(async (file) => [
44
+ file,
45
+ file === CONTEXT_MANIFEST_PATH
46
+ ? authorityTopologySha256
47
+ : await hashFile(root, path.join(root, file)),
48
+ ])));
49
+ const classification = classifyContextFiles(manifest, files, explicitlySelected, mode);
50
+ return {
51
+ mode,
52
+ topology_sha256: authorityTopologySha256,
53
+ files,
54
+ sha256: sortRecord(hashes),
55
+ controlling_files: classification.controlling,
56
+ supporting_files: classification.supporting,
57
+ };
58
+ }
59
+ export async function captureCampaignContextBaseline(repositoryRoot, contextRefs) {
60
+ const snapshot = await captureContextGraphSnapshot(repositoryRoot, contextRefs, "referenced");
61
+ const files = sortRecord(snapshot.sha256);
62
+ return {
63
+ graph_sha256: snapshot.topology_sha256,
64
+ files,
65
+ baseline_sha256: sha256Hex(canonicalJson({ graph_sha256: snapshot.topology_sha256, files })),
66
+ };
67
+ }
68
+ export async function assertCampaignContextBaselineFresh(repositoryRoot, expected, contextRefs) {
69
+ const current = await captureCampaignContextBaseline(repositoryRoot, contextRefs);
70
+ if (current.graph_sha256 !== expected.graph_sha256) {
71
+ throw new Error("campaign_context_changed:graph");
72
+ }
73
+ if (current.baseline_sha256 !== expected.baseline_sha256) {
74
+ const changed = [
75
+ ...new Set([
76
+ ...Object.keys(expected.files),
77
+ ...Object.keys(current.files),
78
+ ]),
79
+ ]
80
+ .filter((file) => expected.files[file] !== current.files[file])
81
+ .sort();
82
+ throw new Error(`campaign_context_changed:files:${changed.join(",") || "set"}`);
83
+ }
84
+ }
85
+ export async function currentContextTopologySha256(repositoryRoot) {
86
+ const root = path.resolve(repositoryRoot);
87
+ return contextAuthorityTopologyHash(await readContextManifest(root), await listContextFiles(root));
88
+ }
89
+ export async function listContextFiles(repositoryRoot) {
90
+ const root = path.resolve(repositoryRoot);
91
+ const contextRoot = path.join(root, "project_context");
92
+ const result = [];
93
+ async function visit(directory) {
94
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
95
+ const absolute = path.join(directory, entry.name);
96
+ if (entry.isSymbolicLink()) {
97
+ throw new Error(`protected_input_symlink_not_allowed:context_authority:${absolute.replace(/\\/gu, "/")}`);
98
+ }
99
+ if (entry.isDirectory()) {
100
+ await visit(absolute);
101
+ }
102
+ else if (entry.isFile()) {
103
+ await assertProtectedRepositoryFile(root, absolute, "context_authority");
104
+ result.push(repoRelative(root, absolute));
105
+ }
106
+ }
107
+ }
108
+ await visit(contextRoot);
109
+ return result.sort();
110
+ }
111
+ async function readContextManifest(root) {
112
+ const manifestFile = await assertProtectedRepositoryFile(root, path.join(root, "project_context", "context.toml"), "context_manifest");
113
+ const parsed = parseContextManifest(await readFile(manifestFile, "utf8"));
114
+ if (!parsed.manifest || parsed.errors.length > 0) {
115
+ throw new Error(`context_manifest_invalid:${parsed.errors.join("|")}`);
116
+ }
117
+ return parsed.manifest;
118
+ }
119
+ function addTransitiveChildren(manifest, selected, available) {
120
+ const children = new Map(manifest.contexts.map((entry) => [
121
+ normalizeRepoPath(entry.path),
122
+ entry.default_children.map(normalizeRepoPath),
123
+ ]));
124
+ const queue = [...selected];
125
+ while (queue.length > 0) {
126
+ const current = queue.shift();
127
+ for (const child of children.get(current) ?? []) {
128
+ if (!available.has(child)) {
129
+ throw new Error(`context_graph_child_missing:${current}:${child}`);
130
+ }
131
+ if (!selected.has(child)) {
132
+ selected.add(child);
133
+ queue.push(child);
134
+ }
135
+ }
136
+ }
137
+ }
138
+ function classifyContextFiles(manifest, files, explicitlySelected, mode) {
139
+ if (mode === "full")
140
+ return { controlling: [...files], supporting: [] };
141
+ const roles = new Map(manifest.contexts.map((entry) => [normalizeRepoPath(entry.path), entry.role]));
142
+ const controlling = [];
143
+ const supporting = [];
144
+ for (const file of files) {
145
+ const role = roles.get(file);
146
+ if (explicitlySelected.has(file) ||
147
+ role === undefined ||
148
+ !SUPPORTING_CONTEXT_ROLES.has(role))
149
+ controlling.push(file);
150
+ else
151
+ supporting.push(file);
152
+ }
153
+ return { controlling, supporting };
154
+ }
155
+ async function hashFile(root, file) {
156
+ const protectedFile = await assertProtectedRepositoryFile(root, file, "context_authority");
157
+ return sha256Hex(await readFile(protectedFile));
158
+ }
159
+ function repoRelative(root, file) {
160
+ const value = path.relative(root, file).replace(/\\/g, "/");
161
+ if (value.startsWith("../") || path.isAbsolute(value)) {
162
+ throw new Error(`Path is outside repository: ${file}`);
163
+ }
164
+ return value;
165
+ }
166
+ function normalizeRepoPath(value) {
167
+ return value.replace(/\\/g, "/").replace(/^\.\//, "");
168
+ }
169
+ function sortRecord(value) {
170
+ return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)));
171
+ }
@@ -0,0 +1,28 @@
1
+ export type ContextRole = "global" | "architecture" | "area" | "domain" | "subdomain" | "foundation" | "archive" | "contract" | "verification" | "deployment" | "implementation-index" | "decision-rationale";
2
+ export interface ContextAreaEntry {
3
+ line: number;
4
+ id: string;
5
+ root: string;
6
+ context: string;
7
+ kind?: string;
8
+ default: boolean;
9
+ forbidden_runtime_dependencies: string[];
10
+ }
11
+ export interface ContextNodeEntry {
12
+ line: number;
13
+ path: string;
14
+ role: string;
15
+ read_when?: string;
16
+ read_policy?: string;
17
+ triggers: string[];
18
+ default_children: string[];
19
+ }
20
+ export interface ContextManifest {
21
+ areas: ContextAreaEntry[];
22
+ contexts: ContextNodeEntry[];
23
+ }
24
+ export interface ContextManifestParseResult {
25
+ manifest?: ContextManifest;
26
+ errors: string[];
27
+ }
28
+ export declare function parseContextManifest(content: string, file?: string): ContextManifestParseResult;