project-tiny-context-harness 0.8.17 → 0.11.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 (488) hide show
  1. package/README.md +93 -30
  2. package/assets/README.md +158 -44
  3. package/assets/README.zh-CN.md +88 -29
  4. package/assets/agents/AGENTS_CORE.md +2 -2
  5. package/assets/context_templates/context.toml +6 -1
  6. package/assets/runtime/windows-job-supervisor/formal_process_supervisor_native_helpers.cs +301 -0
  7. package/assets/runtime/windows-job-supervisor/formal_process_supervisor_native_run.cs +197 -0
  8. package/assets/runtime/windows-job-supervisor/formal_process_supervisor_native_types.cs +215 -0
  9. package/assets/runtime/windows-job-supervisor/windows_job_process_supervisor.ps1 +117 -0
  10. package/assets/skills/design-resource-authoring/SKILL.md +6 -3
  11. package/assets/skills/design-resource-authoring/references/authority-delta-assessment.md +52 -0
  12. package/assets/skills/design-resource-authoring/references/downstream-handoff.md +5 -1
  13. package/assets/skills/design-system-authoring/SKILL.md +23 -17
  14. package/assets/skills/design-system-authoring/references/authority-adoption.md +19 -9
  15. package/assets/skills/design-system-authoring/references/open-design-design-system-provider.md +4 -0
  16. package/assets/skills/long-task-workflow/SKILL.md +6 -6
  17. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +10 -4
  18. package/assets/skills/long-task-workflow/references/contract-authoring.md +5 -5
  19. package/assets/skills/long-task-workflow/references/evidence-design.md +14 -3
  20. package/assets/skills/long-task-workflow/references/source-authoring.md +11 -8
  21. package/assets/tools/context_rules.json +53 -0
  22. package/assets/tools/validate_context.py +302 -77
  23. package/dist/cli.js +2 -1
  24. package/dist/commands/context-create.d.ts +1 -0
  25. package/dist/commands/context-create.js +90 -0
  26. package/dist/commands/context-inspect.d.ts +1 -0
  27. package/dist/commands/context-inspect.js +98 -0
  28. package/dist/commands/context-move.d.ts +1 -0
  29. package/dist/commands/context-move.js +78 -0
  30. package/dist/commands/context-register.d.ts +1 -0
  31. package/dist/commands/context-register.js +110 -0
  32. package/dist/commands/context-transaction.d.ts +1 -0
  33. package/dist/commands/context-transaction.js +84 -0
  34. package/dist/commands/context.d.ts +1 -0
  35. package/dist/commands/context.js +36 -0
  36. package/dist/commands/design-authority-delta.d.ts +1 -0
  37. package/dist/commands/design-authority-delta.js +53 -0
  38. package/dist/commands/design-authority.d.ts +1 -0
  39. package/dist/commands/design-authority.js +104 -0
  40. package/dist/commands/design-resource.js +8 -1
  41. package/dist/commands/doctor.d.ts +1 -1
  42. package/dist/commands/doctor.js +61 -3
  43. package/dist/commands/index.js +19 -2
  44. package/dist/commands/long-task-authoring.js +20 -2
  45. package/dist/commands/long-task-workdir.d.ts +2 -0
  46. package/dist/commands/long-task-workdir.js +23 -0
  47. package/dist/commands/long-task.js +75 -6
  48. package/dist/commands/route.d.ts +15 -0
  49. package/dist/commands/route.js +142 -0
  50. package/dist/index.d.ts +3 -13
  51. package/dist/index.js +3 -12
  52. package/dist/lib/cli-exit.d.ts +14 -0
  53. package/dist/lib/cli-exit.js +19 -0
  54. package/dist/lib/context-catalog/catalog-default-footprint.d.ts +3 -0
  55. package/dist/lib/context-catalog/catalog-default-footprint.js +53 -0
  56. package/dist/lib/context-catalog/catalog-diagnostics.d.ts +9 -0
  57. package/dist/lib/context-catalog/catalog-diagnostics.js +34 -0
  58. package/dist/lib/context-catalog/catalog-discovery.d.ts +7 -0
  59. package/dist/lib/context-catalog/catalog-discovery.js +81 -0
  60. package/dist/lib/context-catalog/catalog-load.d.ts +8 -0
  61. package/dist/lib/context-catalog/catalog-load.js +187 -0
  62. package/dist/lib/context-catalog/catalog-path-validation.d.ts +7 -0
  63. package/dist/lib/context-catalog/catalog-path-validation.js +62 -0
  64. package/dist/lib/context-catalog/catalog-paths.d.ts +11 -0
  65. package/dist/lib/context-catalog/catalog-paths.js +41 -0
  66. package/dist/lib/context-catalog/catalog-portable-contract.d.ts +15 -0
  67. package/dist/lib/context-catalog/catalog-portable-contract.js +68 -0
  68. package/dist/lib/context-catalog/catalog-staged-path-safety.d.ts +1 -0
  69. package/dist/lib/context-catalog/catalog-staged-path-safety.js +36 -0
  70. package/dist/lib/context-catalog/catalog-types.d.ts +40 -0
  71. package/dist/lib/context-catalog/catalog-types.js +1 -0
  72. package/dist/lib/context-catalog/catalog-validation.d.ts +9 -0
  73. package/dist/lib/context-catalog/catalog-validation.js +148 -0
  74. package/dist/lib/context-create/context-create-path.d.ts +2 -0
  75. package/dist/lib/context-create/context-create-path.js +30 -0
  76. package/dist/lib/context-create/context-create-template.d.ts +2 -0
  77. package/dist/lib/context-create/context-create-template.js +95 -0
  78. package/dist/lib/context-create/context-create-types.d.ts +28 -0
  79. package/dist/lib/context-create/context-create-types.js +1 -0
  80. package/dist/lib/context-create/context-create-write.d.ts +1 -0
  81. package/dist/lib/context-create/context-create-write.js +85 -0
  82. package/dist/lib/context-create/context-create.d.ts +2 -0
  83. package/dist/lib/context-create/context-create.js +84 -0
  84. package/dist/lib/context-default-footprint.d.ts +2 -3
  85. package/dist/lib/context-default-footprint.js +49 -57
  86. package/dist/lib/context-doctor/context-doctor-types.d.ts +16 -0
  87. package/dist/lib/context-doctor/context-doctor-types.js +15 -0
  88. package/dist/lib/context-doctor/context-doctor.d.ts +2 -0
  89. package/dist/lib/context-doctor/context-doctor.js +130 -0
  90. package/dist/lib/context-graph-snapshot.d.ts +5 -0
  91. package/dist/lib/context-graph-snapshot.js +46 -25
  92. package/dist/lib/context-inspect/context-inspect-projection.d.ts +9 -0
  93. package/dist/lib/context-inspect/context-inspect-projection.js +49 -0
  94. package/dist/lib/context-inspect/context-inspect-render.d.ts +2 -0
  95. package/dist/lib/context-inspect/context-inspect-render.js +29 -0
  96. package/dist/lib/context-inspect/context-inspect-types.d.ts +43 -0
  97. package/dist/lib/context-inspect/context-inspect-types.js +1 -0
  98. package/dist/lib/context-inspect/context-inspect.d.ts +2 -0
  99. package/dist/lib/context-inspect/context-inspect.js +104 -0
  100. package/dist/lib/context-manifest-schema.d.ts +1 -1
  101. package/dist/lib/context-manifest-schema.js +4 -20
  102. package/dist/lib/context-markdown/context-markdown-analysis.d.ts +15 -0
  103. package/dist/lib/context-markdown/context-markdown-analysis.js +245 -0
  104. package/dist/lib/context-markdown/context-markdown-extract.d.ts +7 -0
  105. package/dist/lib/context-markdown/context-markdown-extract.js +114 -0
  106. package/dist/lib/context-markdown/context-markdown-types.d.ts +57 -0
  107. package/dist/lib/context-markdown/context-markdown-types.js +1 -0
  108. package/dist/lib/context-move/context-move-input.d.ts +8 -0
  109. package/dist/lib/context-move/context-move-input.js +17 -0
  110. package/dist/lib/context-move/context-move-literal-scan.d.ts +20 -0
  111. package/dist/lib/context-move/context-move-literal-scan.js +213 -0
  112. package/dist/lib/context-move/context-move-live-validation.d.ts +3 -0
  113. package/dist/lib/context-move/context-move-live-validation.js +56 -0
  114. package/dist/lib/context-move/context-move-markdown-plan.d.ts +22 -0
  115. package/dist/lib/context-move/context-move-markdown-plan.js +39 -0
  116. package/dist/lib/context-move/context-move-projection.d.ts +3 -0
  117. package/dist/lib/context-move/context-move-projection.js +11 -0
  118. package/dist/lib/context-move/context-move-reference-validation.d.ts +11 -0
  119. package/dist/lib/context-move/context-move-reference-validation.js +64 -0
  120. package/dist/lib/context-move/context-move-render.d.ts +2 -0
  121. package/dist/lib/context-move/context-move-render.js +24 -0
  122. package/dist/lib/context-move/context-move-support.d.ts +10 -0
  123. package/dist/lib/context-move/context-move-support.js +88 -0
  124. package/dist/lib/context-move/context-move-transaction-plan.d.ts +24 -0
  125. package/dist/lib/context-move/context-move-transaction-plan.js +108 -0
  126. package/dist/lib/context-move/context-move-types.d.ts +74 -0
  127. package/dist/lib/context-move/context-move-types.js +1 -0
  128. package/dist/lib/context-move/context-move.d.ts +8 -0
  129. package/dist/lib/context-move/context-move.js +180 -0
  130. package/dist/lib/context-mutation/manifest-lossless-patch.d.ts +28 -0
  131. package/dist/lib/context-mutation/manifest-lossless-patch.js +208 -0
  132. package/dist/lib/context-mutation/markdown-link-patch.d.ts +34 -0
  133. package/dist/lib/context-mutation/markdown-link-patch.js +143 -0
  134. package/dist/lib/context-mutation/markdown-link-spans.d.ts +10 -0
  135. package/dist/lib/context-mutation/markdown-link-spans.js +179 -0
  136. package/dist/lib/context-mutation/mutation-cas.d.ts +13 -0
  137. package/dist/lib/context-mutation/mutation-cas.js +365 -0
  138. package/dist/lib/context-mutation/mutation-command-support.d.ts +12 -0
  139. package/dist/lib/context-mutation/mutation-command-support.js +57 -0
  140. package/dist/lib/context-mutation/mutation-commit.d.ts +12 -0
  141. package/dist/lib/context-mutation/mutation-commit.js +89 -0
  142. package/dist/lib/context-mutation/mutation-directories.d.ts +5 -0
  143. package/dist/lib/context-mutation/mutation-directories.js +56 -0
  144. package/dist/lib/context-mutation/mutation-file-state.d.ts +14 -0
  145. package/dist/lib/context-mutation/mutation-file-state.js +137 -0
  146. package/dist/lib/context-mutation/mutation-journal-file-validation.d.ts +1 -0
  147. package/dist/lib/context-mutation/mutation-journal-file-validation.js +106 -0
  148. package/dist/lib/context-mutation/mutation-journal-io.d.ts +5 -0
  149. package/dist/lib/context-mutation/mutation-journal-io.js +55 -0
  150. package/dist/lib/context-mutation/mutation-journal-storage.d.ts +18 -0
  151. package/dist/lib/context-mutation/mutation-journal-storage.js +283 -0
  152. package/dist/lib/context-mutation/mutation-journal-validation-support.d.ts +16 -0
  153. package/dist/lib/context-mutation/mutation-journal-validation-support.js +140 -0
  154. package/dist/lib/context-mutation/mutation-journal-validation.d.ts +3 -0
  155. package/dist/lib/context-mutation/mutation-journal-validation.js +177 -0
  156. package/dist/lib/context-mutation/mutation-journal.d.ts +8 -0
  157. package/dist/lib/context-mutation/mutation-journal.js +111 -0
  158. package/dist/lib/context-mutation/mutation-live-validation.d.ts +3 -0
  159. package/dist/lib/context-mutation/mutation-live-validation.js +51 -0
  160. package/dist/lib/context-mutation/mutation-long-task-guard.d.ts +6 -0
  161. package/dist/lib/context-mutation/mutation-long-task-guard.js +57 -0
  162. package/dist/lib/context-mutation/mutation-recovery.d.ts +4 -0
  163. package/dist/lib/context-mutation/mutation-recovery.js +189 -0
  164. package/dist/lib/context-mutation/mutation-staged-fs.d.ts +5 -0
  165. package/dist/lib/context-mutation/mutation-staged-fs.js +56 -0
  166. package/dist/lib/context-mutation/mutation-types.d.ts +103 -0
  167. package/dist/lib/context-mutation/mutation-types.js +1 -0
  168. package/dist/lib/context-register/context-register-input.d.ts +11 -0
  169. package/dist/lib/context-register/context-register-input.js +43 -0
  170. package/dist/lib/context-register/context-register-render.d.ts +2 -0
  171. package/dist/lib/context-register/context-register-render.js +21 -0
  172. package/dist/lib/context-register/context-register-support.d.ts +6 -0
  173. package/dist/lib/context-register/context-register-support.js +46 -0
  174. package/dist/lib/context-register/context-register-types.d.ts +46 -0
  175. package/dist/lib/context-register/context-register-types.js +1 -0
  176. package/dist/lib/context-register/context-register.d.ts +8 -0
  177. package/dist/lib/context-register/context-register.js +155 -0
  178. package/dist/lib/context-router/context-route-budget.d.ts +15 -0
  179. package/dist/lib/context-router/context-route-budget.js +14 -0
  180. package/dist/lib/context-router/context-route-candidates.d.ts +15 -0
  181. package/dist/lib/context-router/context-route-candidates.js +112 -0
  182. package/dist/lib/context-router/context-route-order.d.ts +6 -0
  183. package/dist/lib/context-router/context-route-order.js +53 -0
  184. package/dist/lib/context-router/context-route-paths.d.ts +16 -0
  185. package/dist/lib/context-router/context-route-paths.js +109 -0
  186. package/dist/lib/context-router/context-route-render.d.ts +2 -0
  187. package/dist/lib/context-router/context-route-render.js +32 -0
  188. package/dist/lib/context-router/context-route-scan.d.ts +18 -0
  189. package/dist/lib/context-router/context-route-scan.js +156 -0
  190. package/dist/lib/context-router/context-route-selection.d.ts +16 -0
  191. package/dist/lib/context-router/context-route-selection.js +72 -0
  192. package/dist/lib/context-router/context-route-terms.d.ts +13 -0
  193. package/dist/lib/context-router/context-route-terms.js +202 -0
  194. package/dist/lib/context-router/context-route-types.d.ts +101 -0
  195. package/dist/lib/context-router/context-route-types.js +1 -0
  196. package/dist/lib/context-router/context-route.d.ts +2 -0
  197. package/dist/lib/context-router/context-route.js +127 -0
  198. package/dist/lib/context-units-migration.d.ts +13 -0
  199. package/dist/lib/context-units-migration.js +217 -0
  200. package/dist/lib/design-authority-binding.d.ts +7 -0
  201. package/dist/lib/design-authority-binding.js +96 -0
  202. package/dist/lib/design-authority-closure.d.ts +3 -0
  203. package/dist/lib/design-authority-closure.js +201 -0
  204. package/dist/lib/design-authority-delta-codec-primitives.d.ts +10 -0
  205. package/dist/lib/design-authority-delta-codec-primitives.js +58 -0
  206. package/dist/lib/design-authority-delta-codec.d.ts +2 -0
  207. package/dist/lib/design-authority-delta-codec.js +193 -0
  208. package/dist/lib/design-authority-delta-types.d.ts +65 -0
  209. package/dist/lib/design-authority-delta-types.js +6 -0
  210. package/dist/lib/design-authority-delta-validation.d.ts +2 -0
  211. package/dist/lib/design-authority-delta-validation.js +16 -0
  212. package/dist/lib/design-authority-digest.d.ts +8 -0
  213. package/dist/lib/design-authority-digest.js +36 -0
  214. package/dist/lib/design-authority-files.d.ts +9 -0
  215. package/dist/lib/design-authority-files.js +62 -0
  216. package/dist/lib/design-authority-format.d.ts +2 -0
  217. package/dist/lib/design-authority-format.js +93 -0
  218. package/dist/lib/design-authority-links.d.ts +10 -0
  219. package/dist/lib/design-authority-links.js +137 -0
  220. package/dist/lib/design-authority-manifest.d.ts +4 -0
  221. package/dist/lib/design-authority-manifest.js +144 -0
  222. package/dist/lib/design-authority-tokens.d.ts +9 -0
  223. package/dist/lib/design-authority-tokens.js +45 -0
  224. package/dist/lib/design-authority-types.d.ts +80 -0
  225. package/dist/lib/design-authority-types.js +23 -0
  226. package/dist/lib/design-md-tool-adapter.d.ts +9 -0
  227. package/dist/lib/design-md-tool-adapter.js +152 -0
  228. package/dist/lib/design-md-tool-normalization.d.ts +7 -0
  229. package/dist/lib/design-md-tool-normalization.js +78 -0
  230. package/dist/lib/design-md-tool-types.d.ts +99 -0
  231. package/dist/lib/design-md-tool-types.js +8 -0
  232. package/dist/lib/design-resource-handoff-input-types.d.ts +1 -1
  233. package/dist/lib/design-resource-handoff-manifest-projection.js +3 -0
  234. package/dist/lib/design-resource-handoff-shape.js +14 -2
  235. package/dist/lib/design-resource-handoff-types.d.ts +3 -0
  236. package/dist/lib/design-resource-handoff-validation.js +16 -4
  237. package/dist/lib/design-resource-implementation-feasibility-validation-support.js +1 -1
  238. package/dist/lib/design-resource-recovery-current.js +22 -0
  239. package/dist/lib/design-resource-recovery-shape.js +64 -7
  240. package/dist/lib/design-resource-recovery-types.d.ts +4 -1
  241. package/dist/lib/design-resource-symbolic-fact-shape.js +7 -1
  242. package/dist/lib/design-resource-symbolic-fact-types.d.ts +3 -0
  243. package/dist/lib/design-resource-symbolic-fact-validation.js +15 -3
  244. package/dist/lib/doctor.d.ts +2 -1
  245. package/dist/lib/doctor.js +29 -1
  246. package/dist/lib/fs.js +1 -1
  247. package/dist/lib/long-task-acceptance-reachability-claims.d.ts +2 -0
  248. package/dist/lib/long-task-acceptance-reachability-claims.js +279 -0
  249. package/dist/lib/long-task-acceptance-reachability-design.d.ts +2 -0
  250. package/dist/lib/long-task-acceptance-reachability-design.js +96 -0
  251. package/dist/lib/long-task-acceptance-reachability-external.d.ts +9 -0
  252. package/dist/lib/long-task-acceptance-reachability-external.js +123 -0
  253. package/dist/lib/long-task-acceptance-reachability-helpers.d.ts +64 -0
  254. package/dist/lib/long-task-acceptance-reachability-helpers.js +473 -0
  255. package/dist/lib/long-task-acceptance-reachability-semantic.d.ts +2 -0
  256. package/dist/lib/long-task-acceptance-reachability-semantic.js +122 -0
  257. package/dist/lib/long-task-acceptance-reachability-types.d.ts +91 -0
  258. package/dist/lib/long-task-acceptance-reachability-types.js +1 -0
  259. package/dist/lib/long-task-acceptance-reachability.d.ts +4 -0
  260. package/dist/lib/long-task-acceptance-reachability.js +115 -0
  261. package/dist/lib/long-task-activation-validation.d.ts +6 -0
  262. package/dist/lib/long-task-activation-validation.js +72 -69
  263. package/dist/lib/long-task-active-authority-lock-context.d.ts +4 -0
  264. package/dist/lib/long-task-active-authority-lock-context.js +29 -0
  265. package/dist/lib/long-task-applicability-identity.d.ts +25 -0
  266. package/dist/lib/long-task-applicability-identity.js +60 -0
  267. package/dist/lib/long-task-authoring-preflight-diagnostics.js +8 -0
  268. package/dist/lib/long-task-authoring-preflight-types.d.ts +2 -0
  269. package/dist/lib/long-task-authoring-preflight-types.js +9 -0
  270. package/dist/lib/long-task-authoring-preflight.js +18 -2
  271. package/dist/lib/long-task-authority-material-diff.js +4 -0
  272. package/dist/lib/long-task-authority-materials.js +19 -0
  273. package/dist/lib/long-task-authority-policy.d.ts +3 -0
  274. package/dist/lib/long-task-authority-policy.js +3 -0
  275. package/dist/lib/long-task-authority-revision-details.js +2 -1
  276. package/dist/lib/long-task-authority-types.d.ts +2 -0
  277. package/dist/lib/long-task-authority.js +2 -0
  278. package/dist/lib/long-task-check-shape.js +6 -1
  279. package/dist/lib/long-task-claim-definitions.js +1 -3
  280. package/dist/lib/long-task-claim-semantic-proof-floor.d.ts +3 -0
  281. package/dist/lib/long-task-claim-semantic-proof-floor.js +78 -0
  282. package/dist/lib/long-task-claims.d.ts +0 -18
  283. package/dist/lib/long-task-claims.js +15 -14
  284. package/dist/lib/long-task-command-process.js +3 -0
  285. package/dist/lib/long-task-compact-authoring.js +3 -0
  286. package/dist/lib/long-task-compact-projections.js +10 -0
  287. package/dist/lib/long-task-complete-delivery-evidence-types.d.ts +38 -0
  288. package/dist/lib/long-task-complete-delivery-evidence-types.js +1 -0
  289. package/dist/lib/long-task-completion-types.d.ts +109 -0
  290. package/dist/lib/long-task-completion-types.js +1 -0
  291. package/dist/lib/long-task-conformance-policy.d.ts +2 -1
  292. package/dist/lib/long-task-conformance-policy.js +11 -4
  293. package/dist/lib/long-task-context-authority-topology.js +6 -4
  294. package/dist/lib/long-task-contract-types.d.ts +52 -1
  295. package/dist/lib/long-task-counterfactual-sandbox.d.ts +7 -1
  296. package/dist/lib/long-task-counterfactual-sandbox.js +86 -6
  297. package/dist/lib/long-task-delivery-compiler-preflight.d.ts +24 -0
  298. package/dist/lib/long-task-delivery-compiler-preflight.js +32 -0
  299. package/dist/lib/long-task-delivery-compiler.d.ts +1 -0
  300. package/dist/lib/long-task-delivery-compiler.js +59 -44
  301. package/dist/lib/long-task-delivery-parser.d.ts +3 -0
  302. package/dist/lib/long-task-delivery-parser.js +26 -8
  303. package/dist/lib/long-task-delivery-types.d.ts +2 -0
  304. package/dist/lib/long-task-delivery-types.js +2 -0
  305. package/dist/lib/long-task-delivery-validation.d.ts +6 -1
  306. package/dist/lib/long-task-delivery-validation.js +19 -4
  307. package/dist/lib/long-task-design-feasibility-binding.d.ts +1 -0
  308. package/dist/lib/long-task-design-feasibility-binding.js +3 -3
  309. package/dist/lib/long-task-design-feasibility-source-closure.js +11 -2
  310. package/dist/lib/long-task-design-obligation.d.ts +50 -0
  311. package/dist/lib/long-task-design-obligation.js +99 -0
  312. package/dist/lib/long-task-design-resource-handoff.d.ts +3 -1
  313. package/dist/lib/long-task-design-resource-handoff.js +36 -12
  314. package/dist/lib/long-task-design-resource-method-binding.js +12 -0
  315. package/dist/lib/long-task-effective-external-takeover.d.ts +15 -0
  316. package/dist/lib/long-task-effective-external-takeover.js +109 -0
  317. package/dist/lib/long-task-effective-external-ui-takeover.d.ts +5 -0
  318. package/dist/lib/long-task-effective-external-ui-takeover.js +117 -0
  319. package/dist/lib/long-task-evidence-capability-codec.js +91 -0
  320. package/dist/lib/long-task-evidence-capability-runtime.js +62 -14
  321. package/dist/lib/long-task-evidence-capability-types.d.ts +3 -2
  322. package/dist/lib/long-task-evidence-v2.d.ts +6 -1
  323. package/dist/lib/long-task-evidence-v2.js +253 -170
  324. package/dist/lib/long-task-execution-observation.d.ts +7 -0
  325. package/dist/lib/long-task-execution-observation.js +21 -4
  326. package/dist/lib/long-task-expected-authority.d.ts +4 -0
  327. package/dist/lib/long-task-expected-authority.js +126 -0
  328. package/dist/lib/long-task-external-confirmation-artifacts.d.ts +9 -0
  329. package/dist/lib/long-task-external-confirmation-artifacts.js +138 -0
  330. package/dist/lib/long-task-external-confirmation-attestation.d.ts +20 -0
  331. package/dist/lib/long-task-external-confirmation-attestation.js +115 -0
  332. package/dist/lib/long-task-external-confirmation-challenge.d.ts +23 -0
  333. package/dist/lib/long-task-external-confirmation-challenge.js +164 -0
  334. package/dist/lib/long-task-external-confirmation-context.d.ts +14 -0
  335. package/dist/lib/long-task-external-confirmation-context.js +53 -0
  336. package/dist/lib/long-task-external-confirmation-evaluation.d.ts +11 -0
  337. package/dist/lib/long-task-external-confirmation-evaluation.js +454 -0
  338. package/dist/lib/long-task-external-confirmation-expected.d.ts +8 -0
  339. package/dist/lib/long-task-external-confirmation-expected.js +200 -0
  340. package/dist/lib/long-task-external-confirmation-identity.d.ts +10 -0
  341. package/dist/lib/long-task-external-confirmation-identity.js +77 -0
  342. package/dist/lib/long-task-external-confirmation-plan.d.ts +25 -0
  343. package/dist/lib/long-task-external-confirmation-plan.js +148 -0
  344. package/dist/lib/long-task-external-confirmation-preparation.d.ts +4 -0
  345. package/dist/lib/long-task-external-confirmation-preparation.js +100 -0
  346. package/dist/lib/long-task-external-confirmation-shape.d.ts +8 -0
  347. package/dist/lib/long-task-external-confirmation-shape.js +387 -0
  348. package/dist/lib/long-task-external-confirmation-state.d.ts +10 -0
  349. package/dist/lib/long-task-external-confirmation-state.js +109 -0
  350. package/dist/lib/long-task-external-confirmation-types.d.ts +195 -0
  351. package/dist/lib/long-task-external-confirmation-types.js +1 -0
  352. package/dist/lib/long-task-final-integrity.d.ts +2 -0
  353. package/dist/lib/long-task-final-integrity.js +21 -10
  354. package/dist/lib/long-task-final-v2.d.ts +7 -2
  355. package/dist/lib/long-task-final-v2.js +179 -55
  356. package/dist/lib/long-task-finalization-identity.d.ts +27 -0
  357. package/dist/lib/long-task-finalization-identity.js +58 -0
  358. package/dist/lib/long-task-finding-context.d.ts +1 -1
  359. package/dist/lib/long-task-finding-context.js +139 -13
  360. package/dist/lib/long-task-freshness.d.ts +27 -0
  361. package/dist/lib/long-task-freshness.js +128 -5
  362. package/dist/lib/long-task-git.js +3 -3
  363. package/dist/lib/long-task-material-input-closure.d.ts +3 -0
  364. package/dist/lib/long-task-material-input-closure.js +92 -0
  365. package/dist/lib/long-task-obligation-authority-resolution.d.ts +12 -0
  366. package/dist/lib/long-task-obligation-authority-resolution.js +57 -0
  367. package/dist/lib/long-task-obligation-semantic-identity.d.ts +16 -0
  368. package/dist/lib/long-task-obligation-semantic-identity.js +116 -0
  369. package/dist/lib/long-task-observation-authority.d.ts +11 -0
  370. package/dist/lib/long-task-observation-authority.js +137 -6
  371. package/dist/lib/long-task-process-table.d.ts +2 -5
  372. package/dist/lib/long-task-process-table.js +21 -53
  373. package/dist/lib/long-task-process-tree.d.ts +0 -1
  374. package/dist/lib/long-task-process-tree.js +24 -54
  375. package/dist/lib/long-task-proof-adequacy.d.ts +12 -0
  376. package/dist/lib/long-task-proof-adequacy.js +57 -0
  377. package/dist/lib/long-task-proof-capability-floor.d.ts +6 -0
  378. package/dist/lib/long-task-proof-capability-floor.js +137 -0
  379. package/dist/lib/long-task-repair-frontier-checks.d.ts +8 -0
  380. package/dist/lib/long-task-repair-frontier-checks.js +93 -0
  381. package/dist/lib/long-task-repair-frontier-groups.d.ts +2 -0
  382. package/dist/lib/long-task-repair-frontier-groups.js +64 -0
  383. package/dist/lib/long-task-repair-frontier-utils.d.ts +6 -0
  384. package/dist/lib/long-task-repair-frontier-utils.js +27 -0
  385. package/dist/lib/long-task-repair-frontier.d.ts +14 -0
  386. package/dist/lib/long-task-repair-frontier.js +132 -0
  387. package/dist/lib/long-task-risk.d.ts +3 -2
  388. package/dist/lib/long-task-risk.js +73 -24
  389. package/dist/lib/long-task-root-shape.js +148 -8
  390. package/dist/lib/long-task-runner-freeze.d.ts +2 -1
  391. package/dist/lib/long-task-runner-freeze.js +23 -8
  392. package/dist/lib/long-task-runtime-types.d.ts +34 -40
  393. package/dist/lib/long-task-semantic-assurance-policy.js +2 -11
  394. package/dist/lib/long-task-semantic-contract-types.d.ts +2 -1
  395. package/dist/lib/long-task-semantic-drift-migration.js +48 -2
  396. package/dist/lib/long-task-semantic-fact-binding-types.d.ts +20 -0
  397. package/dist/lib/long-task-semantic-fact-closure.d.ts +5 -1
  398. package/dist/lib/long-task-semantic-fact-closure.js +33 -5
  399. package/dist/lib/long-task-semantic-fact-contract-closure.js +176 -1
  400. package/dist/lib/long-task-semantic-fact-contract-proofs.js +18 -1
  401. package/dist/lib/long-task-semantic-fact-input-closure.d.ts +16 -2
  402. package/dist/lib/long-task-semantic-fact-input-closure.js +138 -15
  403. package/dist/lib/long-task-semantic-fact-provenance-closure.js +1 -1
  404. package/dist/lib/long-task-semantic-fact-shape.d.ts +2 -1
  405. package/dist/lib/long-task-semantic-fact-shape.js +35 -1
  406. package/dist/lib/long-task-semantic-proof-adequacy.d.ts +2 -0
  407. package/dist/lib/long-task-semantic-proof-adequacy.js +19 -0
  408. package/dist/lib/long-task-semantic-proof-profile.d.ts +5 -0
  409. package/dist/lib/long-task-semantic-proof-profile.js +187 -0
  410. package/dist/lib/long-task-shape-primitives.d.ts +1 -1
  411. package/dist/lib/long-task-shape-primitives.js +5 -0
  412. package/dist/lib/long-task-source-anchors.d.ts +10 -0
  413. package/dist/lib/long-task-source-anchors.js +102 -0
  414. package/dist/lib/long-task-source-authority-types.d.ts +46 -0
  415. package/dist/lib/long-task-source-claim-validation.js +36 -0
  416. package/dist/lib/long-task-source-conservation-facts.d.ts +8 -0
  417. package/dist/lib/long-task-source-conservation-facts.js +57 -0
  418. package/dist/lib/long-task-source-conservation-types.d.ts +34 -0
  419. package/dist/lib/long-task-source-conservation-types.js +1 -0
  420. package/dist/lib/long-task-source-conservation.d.ts +7 -0
  421. package/dist/lib/long-task-source-conservation.js +110 -0
  422. package/dist/lib/long-task-source-fragments.d.ts +6 -0
  423. package/dist/lib/long-task-source-fragments.js +219 -0
  424. package/dist/lib/long-task-source-projection-resolution.d.ts +5 -0
  425. package/dist/lib/long-task-source-projection-resolution.js +57 -0
  426. package/dist/lib/long-task-source-projection-validation.d.ts +17 -0
  427. package/dist/lib/long-task-source-projection-validation.js +154 -0
  428. package/dist/lib/long-task-source-shape.js +14 -6
  429. package/dist/lib/long-task-source-supersession.d.ts +5 -0
  430. package/dist/lib/long-task-source-supersession.js +138 -0
  431. package/dist/lib/long-task-stage-policy.d.ts +7 -2
  432. package/dist/lib/long-task-stage-policy.js +67 -23
  433. package/dist/lib/long-task-state.d.ts +18 -4
  434. package/dist/lib/long-task-state.js +319 -33
  435. package/dist/lib/long-task-static-observation-freeze.js +4 -3
  436. package/dist/lib/long-task-status-projection.d.ts +3 -1
  437. package/dist/lib/long-task-status-projection.js +44 -13
  438. package/dist/lib/long-task-status-v2.d.ts +10 -6
  439. package/dist/lib/long-task-status-v2.js +70 -58
  440. package/dist/lib/long-task-target-policy.d.ts +8 -3
  441. package/dist/lib/long-task-target-policy.js +40 -9
  442. package/dist/lib/long-task-terminal-finalization.d.ts +12 -0
  443. package/dist/lib/long-task-terminal-finalization.js +190 -0
  444. package/dist/lib/long-task-ui-design-policy.js +15 -4
  445. package/dist/lib/long-task-verifier-counterfactuals.d.ts +11 -0
  446. package/dist/lib/long-task-verifier-counterfactuals.js +96 -0
  447. package/dist/lib/long-task-verifier-execution.d.ts +9 -0
  448. package/dist/lib/long-task-verifier-execution.js +67 -0
  449. package/dist/lib/long-task-verifier-identity.js +16 -5
  450. package/dist/lib/long-task-verifier-v2.js +52 -65
  451. package/dist/lib/long-task-windows-job-supervisor-helper.d.ts +1 -0
  452. package/dist/lib/long-task-windows-job-supervisor-helper.js +104 -0
  453. package/dist/lib/long-task-windows-job-supervisor-protocol.d.ts +28 -0
  454. package/dist/lib/long-task-windows-job-supervisor-protocol.js +124 -0
  455. package/dist/lib/long-task-windows-job-supervisor-result.d.ts +11 -0
  456. package/dist/lib/long-task-windows-job-supervisor-result.js +152 -0
  457. package/dist/lib/long-task-windows-job-supervisor.d.ts +2 -0
  458. package/dist/lib/long-task-windows-job-supervisor.js +126 -0
  459. package/dist/lib/long-task-workspace-scope.d.ts +1 -0
  460. package/dist/lib/long-task-workspace-scope.js +4 -1
  461. package/dist/lib/long-task-workspace.d.ts +1 -0
  462. package/dist/lib/long-task-workspace.js +10 -0
  463. package/dist/lib/migrations.js +43 -2
  464. package/dist/lib/repository-path-safety.d.ts +1 -0
  465. package/dist/lib/repository-path-safety.js +3 -3
  466. package/dist/lib/semantic-fact-input-shape.d.ts +7 -2
  467. package/dist/lib/semantic-fact-input-shape.js +25 -1
  468. package/dist/lib/semantic-fact-inventory-types.d.ts +8 -2
  469. package/dist/lib/semantic-fact-policy-census.d.ts +1 -1
  470. package/dist/lib/semantic-fact-policy-census.js +5 -2
  471. package/dist/lib/semantic-fact-policy.d.ts +1 -1
  472. package/dist/lib/semantic-fact-policy.js +2 -2
  473. package/dist/lib/semantic-fact-proof-shape.d.ts +1 -1
  474. package/dist/lib/semantic-fact-property-shape.d.ts +1 -1
  475. package/dist/lib/validators.d.ts +3 -0
  476. package/dist/lib/validators.js +45 -157
  477. package/dist/public-api-core.d.ts +12 -0
  478. package/dist/public-api-core.js +12 -0
  479. package/dist/public-api-long-task.d.ts +10 -0
  480. package/dist/public-api-long-task.js +10 -0
  481. package/dist/public-types.d.ts +5 -1
  482. package/dist/schemas/design-authority-delta-assessment-v1.schema.json +191 -0
  483. package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +166 -2
  484. package/dist/schemas/long-task-external-confirmation-record-v1.schema.json +155 -0
  485. package/dist/schemas/long-task-external-confirmation-record-v2.schema.json +209 -0
  486. package/migrations/README.md +99 -0
  487. package/package.json +7 -5
  488. package/source-mappings.yaml +18 -0
@@ -0,0 +1,283 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { lstat, readFile, readdir } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { ensureSafeRepositoryDirectory, resolveInsideRepository, } from "../repository-path-safety.js";
5
+ import { canonicalJson, sha256Hex } from "../strict-codec.js";
6
+ import { linkJournalTemporary, syncJournalDirectory, unlinkJournalPath, writeJournalTemporary, } from "./mutation-journal-io.js";
7
+ import { validateContextMutationJournal } from "./mutation-journal-validation.js";
8
+ export const CONTEXT_MUTATION_JOURNAL_DIRECTORY = "tmp/ty-context/context-transactions";
9
+ const SNAPSHOT_PATTERN = /^journal-(\d{6})\.json$/u;
10
+ const TEMPORARY_PATTERN = /^\.journal-(\d{6})\.[0-9a-f-]{36}\.tmp$/u;
11
+ const MAX_JOURNAL_SNAPSHOTS = 1024;
12
+ const MAX_JOURNAL_BYTES = 96 * 1024 * 1024;
13
+ export async function readLatestJournalSnapshot(repository, options = {}) {
14
+ const inventory = await readJournalInventory(repository);
15
+ const snapshots = await readSnapshotChain(inventory, options);
16
+ return snapshots.at(-1) ?? null;
17
+ }
18
+ export async function publishInitialJournalSnapshot(repository, journal) {
19
+ await ensureSafeRepositoryDirectory(repository, CONTEXT_MUTATION_JOURNAL_DIRECTORY, "context_mutation_journal_parent");
20
+ const inventory = await readJournalInventory(repository);
21
+ if ((await readSnapshotChain(inventory)).length)
22
+ invalid("unfinished_transaction_exists");
23
+ await removeJournalTemporaries(inventory);
24
+ return publishSnapshot(repository, journal);
25
+ }
26
+ export async function publishNextJournalSnapshot(repository, journal, expected) {
27
+ let inventory = await readJournalInventory(repository);
28
+ let current = (await readSnapshotChain(inventory)).at(-1);
29
+ assertExpectedJournalSnapshot(current, expected);
30
+ await removeJournalTemporaries(inventory);
31
+ inventory = await readJournalInventory(repository);
32
+ current = (await readSnapshotChain(inventory)).at(-1);
33
+ assertExpectedJournalSnapshotAfterOwnedTemporaryCleanup(current, expected);
34
+ return publishSnapshot(repository, journal);
35
+ }
36
+ export async function removeJournalSnapshotChain(repository, expected) {
37
+ let inventory = await readJournalInventory(repository);
38
+ const snapshots = await readSnapshotChain(inventory);
39
+ const current = snapshots.at(-1);
40
+ assertExpectedJournalSnapshot(current, expected);
41
+ await removeJournalTemporaries(inventory);
42
+ inventory = await readJournalInventory(repository);
43
+ const confirmed = await readSnapshotChain(inventory);
44
+ assertExpectedJournalSnapshotAfterOwnedTemporaryCleanup(confirmed.at(-1), expected);
45
+ for (const snapshot of [...inventory.snapshots].reverse())
46
+ await unlinkJournalPath(snapshot.absolute);
47
+ await syncJournalDirectory(inventory.directory);
48
+ }
49
+ async function readJournalInventory(repository) {
50
+ const directory = resolveInsideRepository(repository, CONTEXT_MUTATION_JOURNAL_DIRECTORY, "context_mutation_journal_parent");
51
+ const existing = await lstat(directory).catch((error) => {
52
+ if (error.code === "ENOENT")
53
+ return null;
54
+ throw error;
55
+ });
56
+ if (!existing)
57
+ return { directory, snapshots: [], temporaries: [] };
58
+ await ensureSafeRepositoryDirectory(repository, CONTEXT_MUTATION_JOURNAL_DIRECTORY, "context_mutation_journal_parent");
59
+ const snapshots = [];
60
+ const temporaries = [];
61
+ const entries = await readdir(directory, { withFileTypes: true });
62
+ if (entries.length > MAX_JOURNAL_SNAPSHOTS + 16)
63
+ invalid("journal_entry_limit_exceeded");
64
+ for (const entry of entries) {
65
+ if (!entry.isFile())
66
+ invalid(`journal_entry_unsafe:${entry.name}`);
67
+ const snapshot = SNAPSHOT_PATTERN.exec(entry.name);
68
+ const temporary = TEMPORARY_PATTERN.exec(entry.name);
69
+ if (!snapshot && !temporary)
70
+ invalid(`journal_entry_unowned:${entry.name}`);
71
+ const absolute = path.join(directory, entry.name);
72
+ const status = await lstat(absolute, { bigint: true });
73
+ if (!status.isFile() || status.isSymbolicLink())
74
+ invalid(`journal_entry_unsafe:${entry.name}`);
75
+ if (status.ino === 0n)
76
+ invalid(`journal_identity_unavailable:${entry.name}`);
77
+ const target = snapshot ? snapshots : temporaries;
78
+ target.push({
79
+ absolute,
80
+ name: entry.name,
81
+ sequence: Number((snapshot ?? temporary)[1]),
82
+ status,
83
+ });
84
+ }
85
+ snapshots.sort((left, right) => left.sequence - right.sequence);
86
+ temporaries.sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0);
87
+ if (snapshots.length > MAX_JOURNAL_SNAPSHOTS)
88
+ invalid("journal_snapshot_limit_exceeded");
89
+ return { directory, snapshots, temporaries };
90
+ }
91
+ async function readSnapshotChain(inventory, options = {}) {
92
+ for (const snapshot of inventory.snapshots)
93
+ assertSafeJournalLink(snapshot, inventory.temporaries);
94
+ for (const temporary of inventory.temporaries)
95
+ assertSafeJournalTemporary(temporary, inventory.snapshots);
96
+ const snapshots = [];
97
+ for (const entry of inventory.snapshots) {
98
+ if (entry.status.size > BigInt(MAX_JOURNAL_BYTES))
99
+ invalid("journal_snapshot_too_large");
100
+ const bytes = await readFile(entry.absolute);
101
+ await options.after_snapshot_read?.(entry.absolute);
102
+ const afterRead = await lstat(entry.absolute, { bigint: true }).catch((error) => {
103
+ if (error.code === "ENOENT")
104
+ invalid(`journal_changed_during_read:${entry.name}`);
105
+ throw error;
106
+ });
107
+ if (!sameJournalIdentity(entry.status, afterRead))
108
+ invalid(`journal_changed_during_read:${entry.name}`);
109
+ let value;
110
+ try {
111
+ value = JSON.parse(bytes.toString("utf8"));
112
+ }
113
+ catch (error) {
114
+ invalid(`journal_unreadable:${message(error)}`);
115
+ }
116
+ const journal = validateContextMutationJournal(value);
117
+ if (journal.journal_sequence !== entry.sequence)
118
+ invalid("journal_filename_sequence_mismatch");
119
+ if (!bytes.equals(Buffer.from(canonicalJson(journal), "utf8")))
120
+ invalid("journal_noncanonical_bytes");
121
+ const previous = snapshots.at(-1);
122
+ if (previous) {
123
+ if (journal.journal_sequence !== previous.journal.journal_sequence + 1)
124
+ invalid("journal_sequence_gap");
125
+ if (journal.transaction_id !== previous.journal.transaction_id)
126
+ invalid("journal_transaction_changed");
127
+ if (journal.previous_journal_sha256 !== sha256Hex(previous.bytes))
128
+ invalid("journal_predecessor_mismatch");
129
+ }
130
+ snapshots.push({
131
+ absolute: entry.absolute,
132
+ bytes,
133
+ identity: afterRead,
134
+ journal,
135
+ relative: `${CONTEXT_MUTATION_JOURNAL_DIRECTORY}/${entry.name}`,
136
+ });
137
+ }
138
+ return snapshots;
139
+ }
140
+ async function publishSnapshot(repository, journal) {
141
+ validateContextMutationJournal(journal);
142
+ const directory = resolveInsideRepository(repository, CONTEXT_MUTATION_JOURNAL_DIRECTORY, "context_mutation_journal_parent");
143
+ const sequence = String(journal.journal_sequence).padStart(6, "0");
144
+ const finalPath = path.join(directory, `journal-${sequence}.json`);
145
+ const temporary = path.join(directory, `.journal-${sequence}.${randomUUID()}.tmp`);
146
+ await writeJournalTemporary(temporary, journal);
147
+ let published = false;
148
+ try {
149
+ await linkJournalTemporary(temporary, finalPath);
150
+ published = true;
151
+ await unlinkJournalPath(temporary);
152
+ await syncJournalDirectory(directory);
153
+ await removeSupersededSnapshots(repository, journal.journal_sequence);
154
+ await syncJournalDirectory(directory);
155
+ const publishedSnapshot = await readLatestJournalSnapshot(repository);
156
+ if (!publishedSnapshot ||
157
+ publishedSnapshot.journal.journal_sequence !== journal.journal_sequence ||
158
+ !publishedSnapshot.bytes.equals(Buffer.from(canonicalJson(journal), "utf8")))
159
+ invalid("journal_publication_readback_mismatch");
160
+ return publishedSnapshot;
161
+ }
162
+ catch (error) {
163
+ if (!published)
164
+ await unlinkJournalPath(temporary).catch(() => undefined);
165
+ if (error.code === "EEXIST")
166
+ invalid("journal_compare_and_swap_failed");
167
+ throw error;
168
+ }
169
+ }
170
+ export function assertExpectedJournalSnapshot(current, expected) {
171
+ if (!current)
172
+ invalid("journal_missing");
173
+ if (current.relative !== expected.relative ||
174
+ !current.bytes.equals(expected.bytes) ||
175
+ !sameJournalIdentity(current.identity, expected.identity))
176
+ invalid("journal_compare_and_swap_failed");
177
+ }
178
+ function assertExpectedJournalSnapshotAfterOwnedTemporaryCleanup(current, expected) {
179
+ if (!current)
180
+ invalid("journal_missing");
181
+ if (current.relative === expected.relative &&
182
+ current.bytes.equals(expected.bytes) &&
183
+ (sameJournalIdentity(current.identity, expected.identity) ||
184
+ (expected.identity.nlink === 2n &&
185
+ current.identity.nlink === 1n &&
186
+ sameStableJournalIdentity(current.identity, expected.identity))))
187
+ return;
188
+ invalid("journal_compare_and_swap_failed");
189
+ }
190
+ function assertSafeJournalLink(snapshot, temporaries) {
191
+ if (snapshot.status.nlink === 1n)
192
+ return;
193
+ const ownedLinks = temporaries.filter((entry) => entry.sequence === snapshot.sequence &&
194
+ entry.status.dev === snapshot.status.dev &&
195
+ entry.status.ino === snapshot.status.ino &&
196
+ sameJournalIdentity(entry.status, snapshot.status));
197
+ if (snapshot.status.nlink !== 2n || ownedLinks.length !== 1)
198
+ invalid(`journal_hardlink_unowned_manual_recovery_required:${snapshot.name}`);
199
+ }
200
+ function assertSafeJournalTemporary(temporary, snapshots) {
201
+ const ownedSnapshots = snapshots.filter((entry) => entry.sequence === temporary.sequence &&
202
+ entry.status.dev === temporary.status.dev &&
203
+ entry.status.ino === temporary.status.ino &&
204
+ entry.status.nlink === 2n &&
205
+ temporary.status.nlink === 2n &&
206
+ sameJournalIdentity(entry.status, temporary.status));
207
+ if (ownedSnapshots.length !== 1)
208
+ invalid(`journal_temporary_unowned_manual_recovery_required:${temporary.name}`);
209
+ }
210
+ function sameJournalIdentity(left, right) {
211
+ return (sameStableJournalIdentity(left, right) &&
212
+ left.nlink === right.nlink &&
213
+ left.ctimeNs === right.ctimeNs);
214
+ }
215
+ function sameStableJournalIdentity(left, right) {
216
+ return (left.dev === right.dev &&
217
+ left.ino === right.ino &&
218
+ left.size === right.size &&
219
+ left.mode === right.mode &&
220
+ left.mtimeNs === right.mtimeNs);
221
+ }
222
+ async function removeJournalTemporaries(inventory) {
223
+ if (inventory.temporaries.length === 0)
224
+ return;
225
+ const claimedSnapshots = new Set();
226
+ for (const temporary of inventory.temporaries) {
227
+ const candidates = inventory.snapshots.filter((snapshot) => snapshot.sequence === temporary.sequence &&
228
+ snapshot.status.dev === temporary.status.dev &&
229
+ snapshot.status.ino === temporary.status.ino);
230
+ const snapshot = candidates.length === 1 ? candidates[0] : undefined;
231
+ if (!snapshot ||
232
+ claimedSnapshots.has(snapshot.name) ||
233
+ snapshot.status.nlink !== 2n ||
234
+ temporary.status.nlink !== 2n ||
235
+ !sameJournalIdentity(snapshot.status, temporary.status))
236
+ invalid(`journal_temporary_unowned_manual_recovery_required:${temporary.name}`);
237
+ claimedSnapshots.add(snapshot.name);
238
+ const [currentSnapshot, currentTemporary] = await Promise.all([
239
+ lstatOwnedJournalEntry(snapshot),
240
+ lstatOwnedJournalEntry(temporary),
241
+ ]);
242
+ if (!sameJournalIdentity(snapshot.status, currentSnapshot) ||
243
+ !sameJournalIdentity(temporary.status, currentTemporary) ||
244
+ !sameJournalIdentity(currentSnapshot, currentTemporary))
245
+ invalid(`journal_temporary_identity_changed_manual_recovery_required:${temporary.name}`);
246
+ try {
247
+ await unlinkJournalPath(temporary.absolute);
248
+ }
249
+ catch (error) {
250
+ invalid(`journal_temporary_cleanup_failed_manual_recovery_required:${temporary.name}:${message(error)}`);
251
+ }
252
+ const afterSnapshot = await lstatOwnedJournalEntry(snapshot);
253
+ const remainingTemporary = await lstat(temporary.absolute, {
254
+ bigint: true,
255
+ }).catch((error) => {
256
+ if (error.code === "ENOENT")
257
+ return null;
258
+ throw error;
259
+ });
260
+ if (remainingTemporary ||
261
+ afterSnapshot.nlink !== 1n ||
262
+ !sameStableJournalIdentity(currentSnapshot, afterSnapshot))
263
+ invalid(`journal_temporary_cleanup_transition_invalid_manual_recovery_required:${temporary.name}`);
264
+ }
265
+ await syncJournalDirectory(inventory.directory);
266
+ }
267
+ async function lstatOwnedJournalEntry(entry) {
268
+ return lstat(entry.absolute, { bigint: true }).catch((error) => {
269
+ invalid(`journal_temporary_identity_changed_manual_recovery_required:${entry.name}:${message(error)}`);
270
+ });
271
+ }
272
+ async function removeSupersededSnapshots(repository, currentSequence) {
273
+ const inventory = await readJournalInventory(repository);
274
+ for (const snapshot of inventory.snapshots)
275
+ if (snapshot.sequence < currentSequence)
276
+ await unlinkJournalPath(snapshot.absolute);
277
+ }
278
+ function invalid(reason) {
279
+ throw new Error(`context_mutation_invalid:${reason}`);
280
+ }
281
+ function message(error) {
282
+ return error instanceof Error ? error.message : String(error);
283
+ }
@@ -0,0 +1,16 @@
1
+ export declare function validateJournalFileState(value: unknown, label: string): number;
2
+ export declare function validateJournalRecordedFileState(value: unknown, label: string): void;
3
+ export declare function sameJournalRecordedPayload(recorded: unknown, semantic: unknown): boolean;
4
+ export declare function sameJournalFileState(left: unknown, right: unknown): boolean;
5
+ export declare function isPresentJournalState(value: unknown): boolean;
6
+ export declare function isAbsentJournalState(value: unknown): boolean;
7
+ export declare function validateJournalTemporaryPath(value: unknown, file: string, transactionId: string, order: number): void;
8
+ export declare function assertJournalMutationTarget(value: string): void;
9
+ export declare function assertJournalContextMarkdownPath(value: string, label: string): void;
10
+ export declare function assertJournalRelative(value: string, label: string): void;
11
+ export declare function validateJournalDigest(value: unknown, label: string): string;
12
+ export declare function requiredJournalString(value: unknown, label: string): string;
13
+ export declare function requiredJournalInteger(value: unknown, label: string): number;
14
+ export declare function isJournalRecord(value: unknown): value is Record<string, unknown>;
15
+ export declare function invalidJournal(reason: string): never;
16
+ export declare function validateIdentity(value: unknown, label: string): void;
@@ -0,0 +1,140 @@
1
+ import path from "node:path";
2
+ import { sha256Hex } from "../strict-codec.js";
3
+ export function validateJournalFileState(value, label) {
4
+ if (!isJournalRecord(value))
5
+ invalidJournal(`${label}_object_required`);
6
+ assertExactFields(value, ["exists", "sha256", "bytes_base64", "mode", "identity"], label);
7
+ if (typeof value.exists !== "boolean")
8
+ invalidJournal(`${label}_exists_invalid`);
9
+ if (!value.exists) {
10
+ if (value.sha256 !== null ||
11
+ value.bytes_base64 !== null ||
12
+ value.mode !== null ||
13
+ value.identity !== null)
14
+ invalidJournal(`${label}_absent_shape`);
15
+ return 0;
16
+ }
17
+ const digest = validateJournalDigest(value.sha256, `${label}.sha256`);
18
+ if (typeof value.bytes_base64 !== "string")
19
+ invalidJournal(`${label}.bytes_base64_string_required`);
20
+ const bytes = Buffer.from(value.bytes_base64, "base64");
21
+ if (bytes.toString("base64") !== value.bytes_base64)
22
+ invalidJournal(`${label}_base64_invalid`);
23
+ if (sha256Hex(bytes) !== digest)
24
+ invalidJournal(`${label}_digest_mismatch`);
25
+ const mode = requiredJournalInteger(value.mode, `${label}.mode`);
26
+ if (mode > 0o777)
27
+ invalidJournal(`${label}_mode_invalid`);
28
+ if (value.identity !== null)
29
+ validateIdentity(value.identity, label);
30
+ return bytes.length;
31
+ }
32
+ export function validateJournalRecordedFileState(value, label) {
33
+ if (!isJournalRecord(value))
34
+ invalidJournal(`${label}_object_required`);
35
+ assertExactFields(value, ["exists", "sha256", "mode", "identity"], label);
36
+ if (typeof value.exists !== "boolean")
37
+ invalidJournal(`${label}_exists_invalid`);
38
+ if (!value.exists) {
39
+ if (value.sha256 !== null || value.mode !== null || value.identity !== null)
40
+ invalidJournal(`${label}_absent_shape`);
41
+ return;
42
+ }
43
+ validateJournalDigest(value.sha256, `${label}.sha256`);
44
+ const mode = requiredJournalInteger(value.mode, `${label}.mode`);
45
+ if (mode > 0o777)
46
+ invalidJournal(`${label}_mode_invalid`);
47
+ if (value.identity === null)
48
+ invalidJournal(`${label}_identity_required`);
49
+ validateIdentity(value.identity, label);
50
+ }
51
+ export function sameJournalRecordedPayload(recorded, semantic) {
52
+ if (!isJournalRecord(recorded) || !isJournalRecord(semantic))
53
+ return false;
54
+ return (recorded.exists === semantic.exists &&
55
+ recorded.sha256 === semantic.sha256 &&
56
+ recorded.mode === semantic.mode);
57
+ }
58
+ export function sameJournalFileState(left, right) {
59
+ if (!isJournalRecord(left) || !isJournalRecord(right))
60
+ return false;
61
+ return (left.exists === right.exists &&
62
+ left.sha256 === right.sha256 &&
63
+ left.mode === right.mode);
64
+ }
65
+ export function isPresentJournalState(value) {
66
+ return isJournalRecord(value) && value.exists === true;
67
+ }
68
+ export function isAbsentJournalState(value) {
69
+ return isJournalRecord(value) && value.exists === false;
70
+ }
71
+ export function validateJournalTemporaryPath(value, file, transactionId, order) {
72
+ const temporary = requiredJournalString(value, "file.temporary_path");
73
+ assertJournalRelative(temporary, "file.temporary_path");
74
+ const expected = `${path.posix.dirname(file)}/.${path.posix.basename(file)}.ty-context-mutation-${transactionId.slice(0, 16)}-${order}.tmp`;
75
+ if (temporary !== expected)
76
+ invalidJournal("temporary_path_unowned");
77
+ }
78
+ export function assertJournalMutationTarget(value) {
79
+ if (value === "project_context/context.toml")
80
+ return;
81
+ assertJournalContextMarkdownPath(value, "mutation_target");
82
+ }
83
+ export function assertJournalContextMarkdownPath(value, label) {
84
+ assertJournalRelative(value, label);
85
+ if (!value.startsWith("project_context/") || !value.endsWith(".md"))
86
+ invalidJournal(`${label}_context_markdown_required`);
87
+ }
88
+ export function assertJournalRelative(value, label) {
89
+ const normalized = value.replace(/\\/gu, "/");
90
+ const segments = normalized.split("/");
91
+ if (value !== normalized ||
92
+ !normalized ||
93
+ path.isAbsolute(value) ||
94
+ normalized.startsWith("/") ||
95
+ segments.some((segment) => !segment || segment === "." || segment === ".."))
96
+ invalidJournal(`${label}_unsafe`);
97
+ }
98
+ export function validateJournalDigest(value, label) {
99
+ const digest = requiredJournalString(value, label);
100
+ if (!/^[0-9a-f]{64}$/u.test(digest))
101
+ invalidJournal(`${label}_invalid`);
102
+ return digest;
103
+ }
104
+ export function requiredJournalString(value, label) {
105
+ if (typeof value !== "string" || value.length === 0)
106
+ invalidJournal(`${label}_string_required`);
107
+ return value;
108
+ }
109
+ export function requiredJournalInteger(value, label) {
110
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
111
+ invalidJournal(`${label}_integer_required`);
112
+ return value;
113
+ }
114
+ export function isJournalRecord(value) {
115
+ return !!value && typeof value === "object" && !Array.isArray(value);
116
+ }
117
+ export function invalidJournal(reason) {
118
+ throw new Error(`context_mutation_invalid:${reason}`);
119
+ }
120
+ export function validateIdentity(value, label) {
121
+ if (!isJournalRecord(value))
122
+ invalidJournal(`${label}_identity_invalid`);
123
+ const fields = ["dev", "ino", "nlink", "size", "mtime_ns", "ctime_ns"];
124
+ if (Object.keys(value).sort().join("\0") !== [...fields].sort().join("\0"))
125
+ invalidJournal(`${label}_identity_fields_invalid`);
126
+ for (const field of ["dev", "ino", "nlink", "size"]) {
127
+ const item = value[field];
128
+ if (typeof item !== "string" || !/^(?:0|[1-9][0-9]*)$/u.test(item))
129
+ invalidJournal(`${label}.identity.${field}_decimal_required`);
130
+ }
131
+ for (const field of ["mtime_ns", "ctime_ns"]) {
132
+ const item = value[field];
133
+ if (typeof item !== "string" || !/^(?:0|-?[1-9][0-9]*)$/u.test(item))
134
+ invalidJournal(`${label}.identity.${field}_decimal_required`);
135
+ }
136
+ }
137
+ function assertExactFields(value, fields, label) {
138
+ if (Object.keys(value).sort().join("\0") !== [...fields].sort().join("\0"))
139
+ invalidJournal(`${label}_fields_invalid`);
140
+ }
@@ -0,0 +1,3 @@
1
+ import type { ContextMutationJournal } from "./mutation-types.js";
2
+ export declare const CONTEXT_MUTATION_JOURNAL_SCHEMA: "context-mutation-journal-v3";
3
+ export declare function validateContextMutationJournal(value: unknown): ContextMutationJournal;
@@ -0,0 +1,177 @@
1
+ import { normalizeContextRole } from "../context-catalog/catalog-portable-contract.js";
2
+ import { validateJournalFiles } from "./mutation-journal-file-validation.js";
3
+ import { assertJournalContextMarkdownPath, assertJournalRelative, invalidJournal, isAbsentJournalState, isJournalRecord, isPresentJournalState, requiredJournalInteger, requiredJournalString, validateJournalDigest, } from "./mutation-journal-validation-support.js";
4
+ export const CONTEXT_MUTATION_JOURNAL_SCHEMA = "context-mutation-journal-v3";
5
+ const LEGACY_CONTEXT_MUTATION_JOURNAL_SCHEMA = "context-mutation-journal-v2";
6
+ const MAX_MUTATION_FILES = 512;
7
+ const MAX_MUTATION_DIRECTORIES = 64;
8
+ const MAX_STORED_BYTES = 64 * 1024 * 1024;
9
+ const MAX_JOURNAL_SEQUENCE = 4095;
10
+ export function validateContextMutationJournal(value) {
11
+ if (!isJournalRecord(value))
12
+ invalidJournal("journal_object_required");
13
+ if (typeof value.schema_version === "string" &&
14
+ /^context-mutation-journal-v(?:0|1)$/u.test(value.schema_version))
15
+ invalidJournal("journal_pre_v2_manual_recovery_required:use_the_ty-context_version_that_created_the_journal_or_restore_exact_files_from_version_control");
16
+ if (value.schema_version !== CONTEXT_MUTATION_JOURNAL_SCHEMA &&
17
+ value.schema_version !== LEGACY_CONTEXT_MUTATION_JOURNAL_SCHEMA)
18
+ invalidJournal("journal_schema_unsupported");
19
+ const transactionId = requiredJournalString(value.transaction_id, "transaction_id");
20
+ if (!/^[0-9a-f]{64}$/u.test(transactionId))
21
+ invalidJournal("transaction_id_invalid");
22
+ const journalSequence = requiredJournalInteger(value.journal_sequence, "journal_sequence");
23
+ if (journalSequence > MAX_JOURNAL_SEQUENCE)
24
+ invalidJournal("journal_sequence_exceeded");
25
+ if (journalSequence === 0) {
26
+ if (value.previous_journal_sha256 !== null)
27
+ invalidJournal("initial_journal_predecessor_forbidden");
28
+ }
29
+ else {
30
+ validateJournalDigest(value.previous_journal_sha256, "previous_journal_sha256");
31
+ }
32
+ const operation = value.operation;
33
+ if (operation !== "register" && operation !== "move")
34
+ invalidJournal("operation_invalid");
35
+ const state = value.state;
36
+ if (state !== "planning" &&
37
+ state !== "prepared" &&
38
+ state !== "committing" &&
39
+ state !== "validating")
40
+ invalidJournal("journal_state_invalid");
41
+ const files = validateJournalFiles(value.files, transactionId, MAX_MUTATION_FILES, MAX_STORED_BYTES, value.schema_version === CONTEXT_MUTATION_JOURNAL_SCHEMA
42
+ ? "required-v3"
43
+ : "forbidden-v2");
44
+ const directories = validateDirectories(value.directories, operation);
45
+ validateAppliedPaths(value.applied_paths, files, state);
46
+ validateJournalDigest(value.catalog_before_identity, "catalog_before_identity");
47
+ validateJournalDigest(value.catalog_after_identity, "catalog_after_identity");
48
+ if (!isJournalRecord(value.operation_data))
49
+ invalidJournal("operation_data_invalid");
50
+ if (value.operation_data.kind !== operation)
51
+ invalidJournal("operation_data_kind_mismatch");
52
+ validateOperationData(value.operation_data, operation);
53
+ if (operation === "register" &&
54
+ (files.length !== 1 || files[0].path !== "project_context/context.toml"))
55
+ invalidJournal("register_file_set_invalid");
56
+ if (operation === "move")
57
+ validateMoveFileSet(files, value.operation_data, directories);
58
+ return value;
59
+ }
60
+ function validateDirectories(value, operation) {
61
+ if (!Array.isArray(value) || value.length > MAX_MUTATION_DIRECTORIES)
62
+ invalidJournal("journal_directories_invalid");
63
+ if (operation === "register" && value.length !== 0)
64
+ invalidJournal("register_directories_forbidden");
65
+ const seen = new Set();
66
+ const directories = [];
67
+ let previousDepth = 0;
68
+ for (const entry of value) {
69
+ if (!isJournalRecord(entry))
70
+ invalidJournal("journal_directory_object_required");
71
+ const directory = requiredJournalString(entry.path, "directory.path");
72
+ assertJournalRelative(directory, "directory.path");
73
+ if (!directory.startsWith("project_context/"))
74
+ invalidJournal("journal_directory_context_required");
75
+ if (entry.before_exists !== false)
76
+ invalidJournal("journal_directory_before_state_invalid");
77
+ if (seen.has(directory))
78
+ invalidJournal("journal_directory_duplicate");
79
+ seen.add(directory);
80
+ directories.push(directory);
81
+ const depth = directory.split("/").length;
82
+ if (depth < previousDepth)
83
+ invalidJournal("journal_directory_order_invalid");
84
+ previousDepth = depth;
85
+ }
86
+ return directories;
87
+ }
88
+ function validateMoveFileSet(files, operationData, directories) {
89
+ if (files.length < 3)
90
+ invalidJournal("move_file_set_incomplete");
91
+ const ordered = [...files].sort((left, right) => left.commit_order - right.commit_order);
92
+ const from = operationData.from_path;
93
+ const to = operationData.to_path;
94
+ if (ordered[0].path !== to ||
95
+ !isAbsentJournalState(ordered[0].before) ||
96
+ !isPresentJournalState(ordered[0].after))
97
+ invalidJournal("move_target_change_invalid");
98
+ const source = ordered.at(-1);
99
+ if (source.path !== from ||
100
+ !isPresentJournalState(source.before) ||
101
+ !isAbsentJournalState(source.after))
102
+ invalidJournal("move_source_change_invalid");
103
+ const manifest = ordered.at(-2);
104
+ if (manifest.path !== "project_context/context.toml" ||
105
+ !isPresentJournalState(manifest.before) ||
106
+ !isPresentJournalState(manifest.after))
107
+ invalidJournal("move_manifest_change_invalid");
108
+ for (const reference of ordered.slice(1, -2))
109
+ if (!isPresentJournalState(reference.before) ||
110
+ !isPresentJournalState(reference.after))
111
+ invalidJournal("move_reference_change_invalid");
112
+ for (const directory of directories)
113
+ if (!to.startsWith(`${directory}/`))
114
+ invalidJournal("move_directory_not_target_ancestor");
115
+ for (let index = 1; index < directories.length; index += 1)
116
+ if (!directories[index].startsWith(`${directories[index - 1]}/`))
117
+ invalidJournal("move_directories_not_chain");
118
+ }
119
+ function validateAppliedPaths(value, files, state) {
120
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string"))
121
+ invalidJournal("journal_applied_paths_invalid");
122
+ const ordered = [...files]
123
+ .sort((left, right) => left.commit_order - right.commit_order)
124
+ .map((entry) => entry.path);
125
+ if (value.some((entry, index) => entry !== ordered[index]) ||
126
+ new Set(value).size !== value.length)
127
+ invalidJournal("journal_applied_paths_not_prefix");
128
+ if ((state === "planning" || state === "prepared") && value.length !== 0)
129
+ invalidJournal("journal_applied_paths_state_mismatch");
130
+ if (state === "validating" && value.length !== ordered.length)
131
+ invalidJournal("journal_applied_paths_state_mismatch");
132
+ for (const file of files) {
133
+ const applied = value.includes(file.path);
134
+ if (applied && file.published_after === null)
135
+ invalidJournal("journal_applied_path_endpoint_missing");
136
+ if ((state === "planning" || state === "prepared") &&
137
+ (file.published_before !== null || file.published_after !== null))
138
+ invalidJournal("journal_published_state_phase_mismatch");
139
+ }
140
+ }
141
+ function validateOperationData(value, operation) {
142
+ const paths = value.expected_default_paths;
143
+ if (!Array.isArray(paths) || paths.some((entry) => typeof entry !== "string"))
144
+ invalidJournal("operation_default_paths_invalid");
145
+ const unique = new Set();
146
+ for (const file of paths) {
147
+ assertJournalRelative(file, "default_path");
148
+ if (unique.has(file))
149
+ invalidJournal("operation_default_path_duplicate");
150
+ unique.add(file);
151
+ }
152
+ requiredJournalInteger(value.expected_default_bytes, "expected_default_bytes");
153
+ if (operation === "register") {
154
+ const contextPath = requiredJournalString(value.context_path, "context_path");
155
+ assertJournalContextMarkdownPath(contextPath, "context_path");
156
+ if (typeof value.role !== "string" || !normalizeContextRole(value.role))
157
+ invalidJournal("operation_role_invalid");
158
+ if (value.read_policy !== "default" && value.read_policy !== "on-demand")
159
+ invalidJournal("operation_read_policy_invalid");
160
+ return;
161
+ }
162
+ const from = requiredJournalString(value.from_path, "from_path");
163
+ const to = requiredJournalString(value.to_path, "to_path");
164
+ assertJournalContextMarkdownPath(from, "from_path");
165
+ assertJournalContextMarkdownPath(to, "to_path");
166
+ if (from === to)
167
+ invalidJournal("operation_move_same_path");
168
+ if (value.owner_source !== "area" && value.owner_source !== "context")
169
+ invalidJournal("operation_owner_source_invalid");
170
+ if (typeof value.role !== "string" || !normalizeContextRole(value.role))
171
+ invalidJournal("operation_role_invalid");
172
+ if (value.read_policy !== null && typeof value.read_policy !== "string")
173
+ invalidJournal("operation_read_policy_invalid");
174
+ if (!Array.isArray(value.expected_reference_issues) ||
175
+ value.expected_reference_issues.some((entry) => typeof entry !== "string"))
176
+ invalidJournal("operation_reference_issues_invalid");
177
+ }
@@ -0,0 +1,8 @@
1
+ export { CONTEXT_MUTATION_JOURNAL_DIRECTORY } from "./mutation-journal-storage.js";
2
+ import type { ContextMutationJournal, ContextMutationJournalState, ContextMutationPlan } from "./mutation-types.js";
3
+ export declare function readContextMutationJournal(repository: string): Promise<ContextMutationJournal | null>;
4
+ export declare function assertNoUnfinishedContextMutationForAuthority(repository: string): Promise<void>;
5
+ export declare function createContextMutationJournal(repository: string, plan: ContextMutationPlan): Promise<ContextMutationJournal>;
6
+ export declare function updateContextMutationJournal(repository: string, expected: ContextMutationJournal, successor: ContextMutationJournal, expectedStates: ContextMutationJournalState[]): Promise<ContextMutationJournal>;
7
+ export declare function removeContextMutationJournal(repository: string, expected: ContextMutationJournal): Promise<void>;
8
+ export declare function assertSameContextMutationJournalSnapshot(expected: ContextMutationJournal, current: ContextMutationJournal): void;