project-tiny-context-harness 0.8.11 → 0.8.13

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 (395) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +514 -472
  3. package/assets/README.md +803 -749
  4. package/assets/README.zh-CN.md +468 -431
  5. package/assets/agents/.gitkeep +1 -1
  6. package/assets/agents/AGENTS_CORE.md +22 -24
  7. package/assets/agents/long-task-implementation.toml +15 -0
  8. package/assets/context_templates/architecture.md +18 -18
  9. package/assets/context_templates/area.md +30 -30
  10. package/assets/context_templates/context.toml +24 -24
  11. package/assets/context_templates/deployment.md +35 -35
  12. package/assets/context_templates/global.md +56 -56
  13. package/assets/context_templates/product-surface-contract.md +70 -70
  14. package/assets/context_templates/screen-contract.md +189 -189
  15. package/assets/context_templates/verification.md +25 -25
  16. package/assets/github/.gitkeep +1 -1
  17. package/assets/github/harness.yml +39 -39
  18. package/assets/make/.gitkeep +1 -1
  19. package/assets/make/ty-context.mk +48 -48
  20. package/assets/skills/context_development_engineer/SKILL.md +72 -185
  21. package/assets/skills/context_full_project_export/SKILL.md +28 -28
  22. package/assets/skills/context_harness_upgrade/SKILL.md +60 -60
  23. package/assets/skills/context_product_plan/SKILL.md +35 -101
  24. package/assets/skills/context_surface_contract/SKILL.md +194 -191
  25. package/assets/skills/context_uiux_design/SKILL.md +49 -172
  26. package/assets/skills/design-resource-authoring/SKILL.md +54 -88
  27. package/assets/skills/design-resource-authoring/references/downstream-handoff.md +51 -163
  28. package/assets/skills/design-resource-authoring/references/formal-selected-web-app-handoff.md +96 -0
  29. package/assets/skills/design-resource-authoring/references/open-design-provider.md +140 -120
  30. package/assets/skills/design-resource-authoring/references/recovery-and-writeback.md +199 -0
  31. package/assets/skills/design-resource-authoring/references/resource-selection.md +158 -181
  32. package/assets/skills/design-system-authoring/SKILL.md +57 -57
  33. package/assets/skills/design-system-authoring/agents/openai.yaml +6 -6
  34. package/assets/skills/design-system-authoring/references/authority-adoption.md +48 -48
  35. package/assets/skills/design-system-authoring/references/open-design-design-system-provider.md +110 -110
  36. package/assets/skills/long-task-workflow/SKILL.md +71 -106
  37. package/assets/skills/long-task-workflow/agents/openai.yaml +1 -1
  38. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +71 -69
  39. package/assets/skills/long-task-workflow/references/contract-authoring.md +110 -101
  40. package/assets/skills/long-task-workflow/references/evidence-design.md +99 -78
  41. package/assets/skills/long-task-workflow/references/source-authoring.md +90 -90
  42. package/assets/tools/validate_context.py +442 -442
  43. package/dist/commands/design-resource-recovery.d.ts +1 -0
  44. package/dist/commands/design-resource-recovery.js +152 -0
  45. package/dist/commands/design-resource.js +29 -3
  46. package/dist/commands/enable.js +2 -0
  47. package/dist/commands/index.js +2 -2
  48. package/dist/commands/long-task-revision.js +8 -7
  49. package/dist/commands/sync.js +2 -0
  50. package/dist/index.d.ts +3 -3
  51. package/dist/index.js +2 -0
  52. package/dist/lib/compact-authoring-support.d.ts +22 -0
  53. package/dist/lib/compact-authoring-support.js +143 -0
  54. package/dist/lib/compact-shared-structure-authoring.d.ts +5 -0
  55. package/dist/lib/compact-shared-structure-authoring.js +9 -0
  56. package/dist/lib/compact-shared-structure-types.d.ts +61 -0
  57. package/dist/lib/compact-shared-structure-types.js +1 -0
  58. package/dist/lib/compact-shared-structure-validation.d.ts +2 -0
  59. package/dist/lib/compact-shared-structure-validation.js +159 -0
  60. package/dist/lib/compact-shared-structures.d.ts +3 -0
  61. package/dist/lib/compact-shared-structures.js +204 -0
  62. package/dist/lib/design-resource-fact-enums.d.ts +4 -0
  63. package/dist/lib/design-resource-fact-enums.js +12 -0
  64. package/dist/lib/design-resource-fact-manifest-shape-evidence.js +2 -2
  65. package/dist/lib/design-resource-fact-policy.d.ts +2 -2
  66. package/dist/lib/design-resource-fact-types.d.ts +2 -2
  67. package/dist/lib/design-resource-handoff-bundle-draft.js +4 -2
  68. package/dist/lib/design-resource-handoff-input-types.d.ts +3 -0
  69. package/dist/lib/design-resource-handoff-parser.d.ts +2 -2
  70. package/dist/lib/design-resource-handoff-parser.js +2 -2
  71. package/dist/lib/design-resource-handoff-shape.d.ts +2 -0
  72. package/dist/lib/design-resource-handoff-shape.js +10 -0
  73. package/dist/lib/design-resource-handoff-snapshot.js +4 -0
  74. package/dist/lib/design-resource-handoff-validation.d.ts +4 -1
  75. package/dist/lib/design-resource-handoff-validation.js +11 -0
  76. package/dist/lib/design-resource-handoff-web-dependency-validation.d.ts +4 -2
  77. package/dist/lib/design-resource-reconciliation-codec.d.ts +2 -0
  78. package/dist/lib/design-resource-reconciliation-codec.js +174 -0
  79. package/dist/lib/design-resource-reconciliation-types.d.ts +62 -0
  80. package/dist/lib/design-resource-reconciliation-types.js +1 -0
  81. package/dist/lib/design-resource-reconciliation.d.ts +3 -0
  82. package/dist/lib/design-resource-reconciliation.js +224 -0
  83. package/dist/lib/design-resource-recovery-authority-policy.d.ts +8 -0
  84. package/dist/lib/design-resource-recovery-authority-policy.js +123 -0
  85. package/dist/lib/design-resource-recovery-catalog-resources.d.ts +6 -0
  86. package/dist/lib/design-resource-recovery-catalog-resources.js +121 -0
  87. package/dist/lib/design-resource-recovery-catalog-shape.d.ts +3 -0
  88. package/dist/lib/design-resource-recovery-catalog-shape.js +104 -0
  89. package/dist/lib/design-resource-recovery-catalog.d.ts +9 -0
  90. package/dist/lib/design-resource-recovery-catalog.js +103 -0
  91. package/dist/lib/design-resource-recovery-cleanup.d.ts +2 -0
  92. package/dist/lib/design-resource-recovery-cleanup.js +11 -0
  93. package/dist/lib/design-resource-recovery-codec-primitives.d.ts +19 -0
  94. package/dist/lib/design-resource-recovery-codec-primitives.js +92 -0
  95. package/dist/lib/design-resource-recovery-codec.d.ts +4 -0
  96. package/dist/lib/design-resource-recovery-codec.js +93 -0
  97. package/dist/lib/design-resource-recovery-current.d.ts +9 -0
  98. package/dist/lib/design-resource-recovery-current.js +41 -0
  99. package/dist/lib/design-resource-recovery-delta-policy.d.ts +5 -0
  100. package/dist/lib/design-resource-recovery-delta-policy.js +108 -0
  101. package/dist/lib/design-resource-recovery-files.d.ts +37 -0
  102. package/dist/lib/design-resource-recovery-files.js +204 -0
  103. package/dist/lib/design-resource-recovery-final-disposition-shape.d.ts +2 -0
  104. package/dist/lib/design-resource-recovery-final-disposition-shape.js +47 -0
  105. package/dist/lib/design-resource-recovery-patch-types.d.ts +54 -0
  106. package/dist/lib/design-resource-recovery-patch-types.js +1 -0
  107. package/dist/lib/design-resource-recovery-replay.d.ts +7 -0
  108. package/dist/lib/design-resource-recovery-replay.js +112 -0
  109. package/dist/lib/design-resource-recovery-repository-bindings.d.ts +9 -0
  110. package/dist/lib/design-resource-recovery-repository-bindings.js +49 -0
  111. package/dist/lib/design-resource-recovery-schema.d.ts +5 -0
  112. package/dist/lib/design-resource-recovery-schema.js +5 -0
  113. package/dist/lib/design-resource-recovery-shape.d.ts +10 -0
  114. package/dist/lib/design-resource-recovery-shape.js +184 -0
  115. package/dist/lib/design-resource-recovery-source-authority.d.ts +5 -0
  116. package/dist/lib/design-resource-recovery-source-authority.js +219 -0
  117. package/dist/lib/design-resource-recovery-text.d.ts +17 -0
  118. package/dist/lib/design-resource-recovery-text.js +186 -0
  119. package/dist/lib/design-resource-recovery-types.d.ts +197 -0
  120. package/dist/lib/design-resource-recovery-types.js +1 -0
  121. package/dist/lib/design-resource-recovery-writeback-policy.d.ts +5 -0
  122. package/dist/lib/design-resource-recovery-writeback-policy.js +326 -0
  123. package/dist/lib/design-resource-recovery-writeback-shape.d.ts +6 -0
  124. package/dist/lib/design-resource-recovery-writeback-shape.js +155 -0
  125. package/dist/lib/design-resource-recovery.d.ts +44 -0
  126. package/dist/lib/design-resource-recovery.js +216 -0
  127. package/dist/lib/design-resource-symbolic-applicability-authority.d.ts +7 -0
  128. package/dist/lib/design-resource-symbolic-applicability-authority.js +19 -0
  129. package/dist/lib/design-resource-symbolic-applicability-policy.d.ts +12 -0
  130. package/dist/lib/design-resource-symbolic-applicability-policy.js +79 -0
  131. package/dist/lib/design-resource-symbolic-applicability-profiles.d.ts +8 -0
  132. package/dist/lib/design-resource-symbolic-applicability-profiles.js +55 -0
  133. package/dist/lib/design-resource-symbolic-applicability-shape.d.ts +2 -0
  134. package/dist/lib/design-resource-symbolic-applicability-shape.js +76 -0
  135. package/dist/lib/design-resource-symbolic-applicability-validation.d.ts +7 -0
  136. package/dist/lib/design-resource-symbolic-applicability-validation.js +128 -0
  137. package/dist/lib/design-resource-symbolic-compilation.d.ts +3 -0
  138. package/dist/lib/design-resource-symbolic-compilation.js +13 -0
  139. package/dist/lib/design-resource-symbolic-denotation.d.ts +3 -0
  140. package/dist/lib/design-resource-symbolic-denotation.js +167 -0
  141. package/dist/lib/design-resource-symbolic-disposition-validation.d.ts +4 -0
  142. package/dist/lib/design-resource-symbolic-disposition-validation.js +28 -0
  143. package/dist/lib/design-resource-symbolic-fact-policy.d.ts +12 -0
  144. package/dist/lib/design-resource-symbolic-fact-policy.js +12 -0
  145. package/dist/lib/design-resource-symbolic-fact-shape.d.ts +3 -0
  146. package/dist/lib/design-resource-symbolic-fact-shape.js +138 -0
  147. package/dist/lib/design-resource-symbolic-fact-types.d.ts +213 -0
  148. package/dist/lib/design-resource-symbolic-fact-types.js +1 -0
  149. package/dist/lib/design-resource-symbolic-fact-validation.d.ts +3 -0
  150. package/dist/lib/design-resource-symbolic-fact-validation.js +86 -0
  151. package/dist/lib/design-resource-symbolic-indexes.d.ts +23 -0
  152. package/dist/lib/design-resource-symbolic-indexes.js +54 -0
  153. package/dist/lib/design-resource-symbolic-manifest-shape.d.ts +3 -0
  154. package/dist/lib/design-resource-symbolic-manifest-shape.js +155 -0
  155. package/dist/lib/design-resource-symbolic-manifest-validation.d.ts +6 -0
  156. package/dist/lib/design-resource-symbolic-manifest-validation.js +132 -0
  157. package/dist/lib/design-resource-symbolic-noninterference-artifact.d.ts +33 -0
  158. package/dist/lib/design-resource-symbolic-noninterference-artifact.js +110 -0
  159. package/dist/lib/design-resource-symbolic-noninterference-equivalence.d.ts +3 -0
  160. package/dist/lib/design-resource-symbolic-noninterference-equivalence.js +77 -0
  161. package/dist/lib/design-resource-symbolic-noninterference-recompute.d.ts +4 -0
  162. package/dist/lib/design-resource-symbolic-noninterference-recompute.js +146 -0
  163. package/dist/lib/design-resource-symbolic-noninterference-scope.d.ts +7 -0
  164. package/dist/lib/design-resource-symbolic-noninterference-scope.js +49 -0
  165. package/dist/lib/design-resource-symbolic-noninterference-shape.d.ts +2 -0
  166. package/dist/lib/design-resource-symbolic-noninterference-shape.js +152 -0
  167. package/dist/lib/design-resource-symbolic-noninterference-types.d.ts +103 -0
  168. package/dist/lib/design-resource-symbolic-noninterference-types.js +1 -0
  169. package/dist/lib/design-resource-symbolic-noninterference-validation.d.ts +5 -0
  170. package/dist/lib/design-resource-symbolic-noninterference-validation.js +62 -0
  171. package/dist/lib/design-resource-symbolic-oracle-fingerprint.d.ts +1 -0
  172. package/dist/lib/design-resource-symbolic-oracle-fingerprint.js +47 -0
  173. package/dist/lib/design-resource-symbolic-predicate-shape.d.ts +6 -0
  174. package/dist/lib/design-resource-symbolic-predicate-shape.js +123 -0
  175. package/dist/lib/design-resource-symbolic-production-closure.d.ts +4 -0
  176. package/dist/lib/design-resource-symbolic-production-closure.js +144 -0
  177. package/dist/lib/design-resource-symbolic-proof-authority-validation.d.ts +10 -0
  178. package/dist/lib/design-resource-symbolic-proof-authority-validation.js +68 -0
  179. package/dist/lib/design-resource-symbolic-proof-validation.d.ts +10 -0
  180. package/dist/lib/design-resource-symbolic-proof-validation.js +89 -0
  181. package/dist/lib/design-resource-symbolic-region-validation.d.ts +19 -0
  182. package/dist/lib/design-resource-symbolic-region-validation.js +146 -0
  183. package/dist/lib/design-resource-symbolic-resource-validation.d.ts +5 -0
  184. package/dist/lib/design-resource-symbolic-resource-validation.js +90 -0
  185. package/dist/lib/design-resource-symbolic-rule-shape.d.ts +27 -0
  186. package/dist/lib/design-resource-symbolic-rule-shape.js +158 -0
  187. package/dist/lib/design-resource-symbolic-safety-validation.d.ts +6 -0
  188. package/dist/lib/design-resource-symbolic-safety-validation.js +29 -0
  189. package/dist/lib/design-resource-symbolic-source-ir-evaluation.d.ts +19 -0
  190. package/dist/lib/design-resource-symbolic-source-ir-evaluation.js +74 -0
  191. package/dist/lib/design-resource-symbolic-source-ir-evidence.d.ts +44 -0
  192. package/dist/lib/design-resource-symbolic-source-ir-evidence.js +88 -0
  193. package/dist/lib/design-resource-symbolic-source-ir-oracle.d.ts +13 -0
  194. package/dist/lib/design-resource-symbolic-source-ir-oracle.js +96 -0
  195. package/dist/lib/design-resource-symbolic-source-ir-proof.d.ts +14 -0
  196. package/dist/lib/design-resource-symbolic-source-ir-proof.js +98 -0
  197. package/dist/lib/design-resource-symbolic-source-ir-shape.d.ts +2 -0
  198. package/dist/lib/design-resource-symbolic-source-ir-shape.js +38 -0
  199. package/dist/lib/design-resource-symbolic-source-ir-types.d.ts +17 -0
  200. package/dist/lib/design-resource-symbolic-source-ir-types.js +2 -0
  201. package/dist/lib/design-resource-symbolic-static-dependency-validation.d.ts +2 -0
  202. package/dist/lib/design-resource-symbolic-static-dependency-validation.js +83 -0
  203. package/dist/lib/design-resource-symbolic-structural-closure-validation.d.ts +6 -0
  204. package/dist/lib/design-resource-symbolic-structural-closure-validation.js +79 -0
  205. package/dist/lib/design-resource-symbolic-validation-support.d.ts +29 -0
  206. package/dist/lib/design-resource-symbolic-validation-support.js +111 -0
  207. package/dist/lib/design-resource-v1-capacity-header.d.ts +8 -0
  208. package/dist/lib/design-resource-v1-capacity-header.js +231 -0
  209. package/dist/lib/design-resource-v1-capacity.d.ts +5 -0
  210. package/dist/lib/design-resource-v1-capacity.js +45 -0
  211. package/dist/lib/init.js +1 -0
  212. package/dist/lib/long-task-acceptance-shape.js +8 -2
  213. package/dist/lib/long-task-activation-validation.js +13 -3
  214. package/dist/lib/long-task-admitted-observation-records.d.ts +25 -0
  215. package/dist/lib/long-task-admitted-observation-records.js +40 -0
  216. package/dist/lib/long-task-admitted-observation.d.ts +93 -0
  217. package/dist/lib/long-task-admitted-observation.js +201 -0
  218. package/dist/lib/long-task-artifacts.d.ts +1 -0
  219. package/dist/lib/long-task-artifacts.js +1 -0
  220. package/dist/lib/long-task-authority-material-diff.js +1 -0
  221. package/dist/lib/long-task-authority-policy.d.ts +5 -0
  222. package/dist/lib/long-task-authority-policy.js +5 -0
  223. package/dist/lib/long-task-authority-revision-details.js +3 -1
  224. package/dist/lib/long-task-authority.js +2 -1
  225. package/dist/lib/long-task-check-execution-policy.js +5 -0
  226. package/dist/lib/long-task-check-runner.d.ts +2 -2
  227. package/dist/lib/long-task-check-runner.js +440 -23
  228. package/dist/lib/long-task-claims.d.ts +18 -0
  229. package/dist/lib/long-task-claims.js +35 -0
  230. package/dist/lib/long-task-codex-agent-profile.d.ts +42 -0
  231. package/dist/lib/long-task-codex-agent-profile.js +276 -0
  232. package/dist/lib/long-task-compact-authoring-projections.d.ts +12 -0
  233. package/dist/lib/long-task-compact-authoring-projections.js +67 -0
  234. package/dist/lib/long-task-compact-authoring.d.ts +3 -0
  235. package/dist/lib/long-task-compact-authoring.js +173 -0
  236. package/dist/lib/long-task-compact-carrier.d.ts +7 -0
  237. package/dist/lib/long-task-compact-carrier.js +132 -0
  238. package/dist/lib/long-task-compact-parser.d.ts +14 -0
  239. package/dist/lib/long-task-compact-parser.js +123 -0
  240. package/dist/lib/long-task-compact-primitives.d.ts +22 -0
  241. package/dist/lib/long-task-compact-primitives.js +132 -0
  242. package/dist/lib/long-task-compact-projections.d.ts +4 -0
  243. package/dist/lib/long-task-compact-projections.js +153 -0
  244. package/dist/lib/long-task-compact-structure-targets.d.ts +2 -0
  245. package/dist/lib/long-task-compact-structure-targets.js +91 -0
  246. package/dist/lib/long-task-conformance-policy.js +3 -1
  247. package/dist/lib/long-task-counterfactual-claim-policy.d.ts +3 -4
  248. package/dist/lib/long-task-counterfactual-claim-policy.js +11 -3
  249. package/dist/lib/long-task-counterfactual-sandbox.d.ts +1 -1
  250. package/dist/lib/long-task-counterfactual-sandbox.js +8 -5
  251. package/dist/lib/long-task-counterfactual-types.d.ts +2 -0
  252. package/dist/lib/long-task-delivery-compiler.js +2 -0
  253. package/dist/lib/long-task-delivery-parser.d.ts +1 -0
  254. package/dist/lib/long-task-delivery-parser.js +38 -6
  255. package/dist/lib/long-task-design-resource-handoff.d.ts +2 -1
  256. package/dist/lib/long-task-design-resource-handoff.js +71 -11
  257. package/dist/lib/long-task-design-resource-method-binding.d.ts +8 -1
  258. package/dist/lib/long-task-design-resource-method-binding.js +150 -0
  259. package/dist/lib/long-task-evidence-capability-codec.js +256 -34
  260. package/dist/lib/long-task-evidence-capability-policy.d.ts +3 -2
  261. package/dist/lib/long-task-evidence-capability-policy.js +142 -8
  262. package/dist/lib/long-task-evidence-capability-runtime.d.ts +5 -2
  263. package/dist/lib/long-task-evidence-capability-runtime.js +420 -68
  264. package/dist/lib/long-task-evidence-capability-types.d.ts +70 -2
  265. package/dist/lib/long-task-evidence-sensitivity-policy.d.ts +9 -0
  266. package/dist/lib/long-task-evidence-sensitivity-policy.js +31 -1
  267. package/dist/lib/long-task-evidence-v2.d.ts +4 -4
  268. package/dist/lib/long-task-evidence-v2.js +322 -44
  269. package/dist/lib/long-task-exact-comparison.d.ts +16 -0
  270. package/dist/lib/long-task-exact-comparison.js +28 -0
  271. package/dist/lib/long-task-execution-observation.d.ts +24 -0
  272. package/dist/lib/long-task-execution-observation.js +332 -0
  273. package/dist/lib/long-task-explain-acceptance-link.d.ts +4 -0
  274. package/dist/lib/long-task-explain-acceptance-link.js +4 -0
  275. package/dist/lib/long-task-explain-claim-links.d.ts +2 -0
  276. package/dist/lib/long-task-explain-claim-links.js +2 -0
  277. package/dist/lib/long-task-explain-source-links.d.ts +6 -0
  278. package/dist/lib/long-task-final-v2.js +7 -4
  279. package/dist/lib/long-task-hook-install.d.ts +19 -2
  280. package/dist/lib/long-task-hook-install.js +288 -91
  281. package/dist/lib/long-task-json-pointer-observation.d.ts +59 -0
  282. package/dist/lib/long-task-json-pointer-observation.js +184 -0
  283. package/dist/lib/long-task-observation-artifact.d.ts +8 -0
  284. package/dist/lib/long-task-observation-artifact.js +58 -0
  285. package/dist/lib/long-task-observation-authority.d.ts +17 -0
  286. package/dist/lib/long-task-observation-authority.js +348 -0
  287. package/dist/lib/long-task-paths.js +1 -1
  288. package/dist/lib/long-task-playwright-capability-records.d.ts +2 -0
  289. package/dist/lib/long-task-playwright-capability-records.js +74 -2
  290. package/dist/lib/long-task-process-observation.d.ts +6 -0
  291. package/dist/lib/long-task-process-observation.js +117 -0
  292. package/dist/lib/long-task-process-runtime-closure.d.ts +13 -0
  293. package/dist/lib/long-task-process-runtime-closure.js +175 -0
  294. package/dist/lib/long-task-progress.js +2 -0
  295. package/dist/lib/long-task-protected-files.d.ts +1 -1
  296. package/dist/lib/long-task-protected-files.js +1 -30
  297. package/dist/lib/long-task-risk.js +8 -3
  298. package/dist/lib/long-task-root-shape.js +10 -1
  299. package/dist/lib/long-task-runner-environment.d.ts +1 -1
  300. package/dist/lib/long-task-runner-environment.js +4 -4
  301. package/dist/lib/long-task-runner-freeze.d.ts +4 -2
  302. package/dist/lib/long-task-runner-freeze.js +130 -28
  303. package/dist/lib/long-task-runtime-types.d.ts +111 -0
  304. package/dist/lib/long-task-scoped-binding.d.ts +13 -0
  305. package/dist/lib/long-task-scoped-binding.js +11 -0
  306. package/dist/lib/long-task-semantic-contract-types.d.ts +2 -1
  307. package/dist/lib/long-task-semantic-fact-binding-types.d.ts +8 -0
  308. package/dist/lib/long-task-semantic-fact-closure.js +4 -1
  309. package/dist/lib/long-task-semantic-fact-contract-closure.d.ts +1 -1
  310. package/dist/lib/long-task-semantic-fact-contract-closure.js +18 -6
  311. package/dist/lib/long-task-semantic-fact-contract-facts.d.ts +1 -1
  312. package/dist/lib/long-task-semantic-fact-contract-facts.js +4 -1
  313. package/dist/lib/long-task-semantic-fact-contract-proofs.d.ts +1 -1
  314. package/dist/lib/long-task-semantic-fact-contract-proofs.js +12 -3
  315. package/dist/lib/long-task-semantic-fact-evidence.d.ts +8 -4
  316. package/dist/lib/long-task-semantic-fact-evidence.js +103 -43
  317. package/dist/lib/long-task-semantic-fact-shape.js +17 -6
  318. package/dist/lib/long-task-shape-primitives.d.ts +1 -1
  319. package/dist/lib/long-task-shape-primitives.js +1 -0
  320. package/dist/lib/long-task-source-claim-validation.js +4 -1
  321. package/dist/lib/long-task-source-item-parser.d.ts +2 -2
  322. package/dist/lib/long-task-source-item-parser.js +20 -11
  323. package/dist/lib/long-task-source-target-continuity.d.ts +2 -2
  324. package/dist/lib/long-task-source-target-continuity.js +35 -2
  325. package/dist/lib/long-task-source-target-index.d.ts +3 -0
  326. package/dist/lib/long-task-source-target-index.js +19 -0
  327. package/dist/lib/long-task-stage-policy.js +10 -4
  328. package/dist/lib/long-task-static-observation-freeze.d.ts +83 -0
  329. package/dist/lib/long-task-static-observation-freeze.js +428 -0
  330. package/dist/lib/long-task-status-projection.js +5 -1
  331. package/dist/lib/long-task-target-policy.d.ts +1 -1
  332. package/dist/lib/long-task-target-policy.js +3 -0
  333. package/dist/lib/long-task-ui-design-policy.js +64 -4
  334. package/dist/lib/long-task-ui-surface-shape.js +195 -0
  335. package/dist/lib/long-task-ui-surface-types.d.ts +53 -0
  336. package/dist/lib/long-task-verifier-dependency-closure.js +7 -3
  337. package/dist/lib/long-task-verifier-v2.js +70 -9
  338. package/dist/lib/long-task-worker-selection.d.ts +2 -0
  339. package/dist/lib/long-task-worker-selection.js +7 -0
  340. package/dist/lib/long-task-workspace-scope.js +3 -1
  341. package/dist/lib/long-task-workspace.d.ts +1 -1
  342. package/dist/lib/long-task-workspace.js +12 -13
  343. package/dist/lib/migrations.js +58 -0
  344. package/dist/lib/profiles.js +0 -1
  345. package/dist/lib/repository-path-safety.d.ts +14 -0
  346. package/dist/lib/repository-path-safety.js +126 -0
  347. package/dist/lib/semantic-fact-compact-authoring.d.ts +2 -0
  348. package/dist/lib/semantic-fact-compact-authoring.js +160 -0
  349. package/dist/lib/semantic-fact-compact-capacity.d.ts +9 -0
  350. package/dist/lib/semantic-fact-compact-capacity.js +40 -0
  351. package/dist/lib/semantic-fact-compact-carrier.d.ts +16 -0
  352. package/dist/lib/semantic-fact-compact-carrier.js +146 -0
  353. package/dist/lib/semantic-fact-compact-parser.d.ts +17 -0
  354. package/dist/lib/semantic-fact-compact-parser.js +168 -0
  355. package/dist/lib/semantic-fact-compact-revision.d.ts +11 -0
  356. package/dist/lib/semantic-fact-compact-revision.js +64 -0
  357. package/dist/lib/semantic-fact-compact-support.d.ts +23 -0
  358. package/dist/lib/semantic-fact-compact-support.js +159 -0
  359. package/dist/lib/semantic-fact-policy-census.d.ts +1 -0
  360. package/dist/lib/semantic-fact-policy-census.js +43 -0
  361. package/dist/lib/semantic-fact-proof-shape.d.ts +1 -1
  362. package/dist/lib/semantic-fact-property-shape.d.ts +1 -1
  363. package/dist/lib/semantic-fact-source-parser.d.ts +5 -0
  364. package/dist/lib/semantic-fact-source-parser.js +47 -6
  365. package/dist/lib/structural-closure-cost.d.ts +79 -0
  366. package/dist/lib/structural-closure-cost.js +91 -0
  367. package/dist/lib/symbolic-denotation-dag-builder.d.ts +25 -0
  368. package/dist/lib/symbolic-denotation-dag-builder.js +176 -0
  369. package/dist/lib/symbolic-denotation-domain-validation.d.ts +3 -0
  370. package/dist/lib/symbolic-denotation-domain-validation.js +56 -0
  371. package/dist/lib/symbolic-denotation-engine.d.ts +32 -0
  372. package/dist/lib/symbolic-denotation-engine.js +140 -0
  373. package/dist/lib/symbolic-denotation-public.d.ts +11 -0
  374. package/dist/lib/symbolic-denotation-public.js +12 -0
  375. package/dist/lib/symbolic-denotation-runtime.d.ts +20 -0
  376. package/dist/lib/symbolic-denotation-runtime.js +90 -0
  377. package/dist/lib/symbolic-denotation-support.d.ts +11 -0
  378. package/dist/lib/symbolic-denotation-support.js +49 -0
  379. package/dist/lib/symbolic-denotation-types.d.ts +133 -0
  380. package/dist/lib/symbolic-denotation-types.js +18 -0
  381. package/dist/lib/symbolic-denotation-validation.d.ts +6 -0
  382. package/dist/lib/symbolic-denotation-validation.js +126 -0
  383. package/dist/lib/sync-engine.d.ts +1 -0
  384. package/dist/lib/sync-engine.js +4 -1
  385. package/dist/lib/upgrade.js +1 -0
  386. package/dist/long-task-hook.js +40 -1
  387. package/dist/public-types.d.ts +8 -0
  388. package/dist/public-types.js +1 -0
  389. package/dist/schemas/design-resource-symbolic-noninterference-artifact-v2.schema.json +289 -0
  390. package/dist/schemas/design-resource-symbolic-source-ir-v1.schema.json +130 -0
  391. package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +435 -5
  392. package/migrations/README.md +92 -15
  393. package/package.json +2 -2
  394. package/source-mappings.yaml +28 -25
  395. package/assets/skills/source-plan-authoring/SKILL.md +0 -14
@@ -1,8 +1,21 @@
1
- import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
1
+ import { randomUUID } from "node:crypto";
2
+ import { promises as fs } from "node:fs";
2
3
  import path from "node:path";
3
4
  import { fileURLToPath } from "node:url";
4
- import { pathExists } from "./fs.js";
5
5
  const MANAGED_STATUS = "Tiny Context long-task live authority gate";
6
+ const PRE_TOOL_USE_MATCHER = "^(spawn_agent|Agent)$";
7
+ const LONG_TASK_IMPLEMENTATION_AGENT_MATCHER = "^long_task_implementation$";
8
+ const MANAGED_HOOK_EVENTS = [
9
+ "PreToolUse",
10
+ "SessionStart",
11
+ "PostCompact",
12
+ "Stop",
13
+ "SubagentStart",
14
+ ];
15
+ const MANAGED_MATCHERS = new Set([
16
+ PRE_TOOL_USE_MATCHER,
17
+ LONG_TASK_IMPLEMENTATION_AGENT_MATCHER,
18
+ ]);
6
19
  const LEGACY_MANAGED_STATUSES = new Set([
7
20
  "Tiny Context long-task live authority gate",
8
21
  "Tiny Context long-task authority gate",
@@ -17,94 +30,85 @@ const LEGACY_REPO_LOCAL_COMMANDS = new Set([
17
30
  "node .codex\\hooks\\long-task-hook.mjs",
18
31
  'node ".codex\\hooks\\long-task-hook.mjs"',
19
32
  ]);
20
- export async function installLongTaskHooks(projectRoot, report) {
33
+ export const LONG_TASK_HOOK_TRUST_REVIEW_NOTICE = "Codex Hook review required: open /hooks and trust the current Tiny Context project Hook before relying on PreToolUse, SubagentStart, SessionStart or Stop behavior. Tiny Context cannot observe or persist Codex Hook trust.";
34
+ const DEFAULT_FILE_OPERATIONS = {
35
+ lstat: (target) => fs.lstat(target),
36
+ readFile: (target, encoding) => fs.readFile(target, encoding),
37
+ mkdir: (target, options) => fs.mkdir(target, options),
38
+ writeFile: (target, content, options) => fs.writeFile(target, content, options),
39
+ rename: (source, destination) => fs.rename(source, destination),
40
+ rm: (target, options) => fs.rm(target, options),
41
+ randomId: () => randomUUID(),
42
+ };
43
+ export async function installLongTaskHooks(projectRoot, report, fileOperations = {}) {
44
+ const operations = operationsWith(fileOperations);
21
45
  const packageRoot = fileURLToPath(new URL("../../", import.meta.url));
22
46
  const entry = path.join(packageRoot, "dist", "long-task-hook.js");
23
- if (!(await pathExists(entry))) {
47
+ const entryStatus = await lstatOrNull(entry, operations);
48
+ if (!entryStatus || entryStatus.isSymbolicLink() || !entryStatus.isFile()) {
24
49
  report.blocked.push("package-owned dist/long-task-hook.js is missing");
25
50
  return;
26
51
  }
27
- const legacyScript = path.join(projectRoot, ".codex", "hooks", "long-task-hook.mjs");
28
- if (await pathExists(legacyScript)) {
29
- await rm(legacyScript, { force: true });
30
- report.changed.push(".codex/hooks/long-task-hook.mjs");
31
- }
32
- const command = packageOwnedCommand(entry);
33
52
  const config = path.join(projectRoot, ".codex", "hooks.json");
34
- let root = {};
35
- if (await pathExists(config)) {
36
- try {
37
- root = JSON.parse(await readFile(config, "utf8"));
53
+ const legacyScript = path.join(projectRoot, ".codex", "hooks", "long-task-hook.mjs");
54
+ try {
55
+ const legacy = await inspectLegacyScript(projectRoot, operations);
56
+ const loaded = await readHookConfig(projectRoot, true, operations);
57
+ const command = packageOwnedCommand(entry);
58
+ const packageHooksWereCurrent = packageHooksAreCurrent(loaded.root, command);
59
+ const next = mergeManagedHooks(loaded.root, command);
60
+ const content = `${JSON.stringify(next, null, 2)}\n`;
61
+ if (loaded.snapshot.kind === "regular" &&
62
+ loaded.snapshot.content === content) {
63
+ report.skipped.push(".codex/hooks.json");
38
64
  }
39
- catch {
40
- report.blocked.push(".codex/hooks.json: invalid JSON");
41
- return;
65
+ else {
66
+ await publishHookConfig(config, loaded.snapshot, content, operations);
67
+ report.changed.push(".codex/hooks.json");
68
+ if (!packageHooksWereCurrent)
69
+ addNotice(report);
42
70
  }
71
+ await removeLegacyScriptIfPresent(projectRoot, legacyScript, legacy, report, operations);
43
72
  }
44
- const hooks = object(root.hooks);
45
- root.hooks = hooks;
46
- for (const event of ["SessionStart", "PostCompact", "Stop"]) {
47
- const groups = Array.isArray(hooks[event]) ? hooks[event] : [];
48
- const cleaned = removeManagedHookEntries(groups, command);
49
- cleaned.groups.push({
50
- hooks: [
51
- {
52
- type: "command",
53
- command,
54
- commandWindows: command,
55
- timeout: event === "Stop" ? 3600 : 10,
56
- statusMessage: MANAGED_STATUS,
57
- },
58
- ],
59
- });
60
- hooks[event] = cleaned.groups;
73
+ catch (error) {
74
+ report.blocked.push(`.codex/hooks.json: ${message(error)}`);
61
75
  }
62
- if (await writeIfChanged(config, `${JSON.stringify(root, null, 2)}\n`))
63
- report.changed.push(".codex/hooks.json");
64
- else
65
- report.skipped.push(".codex/hooks.json");
66
76
  }
67
- export async function uninstallLongTaskHooks(projectRoot, report) {
77
+ export async function uninstallLongTaskHooks(projectRoot, report, fileOperations = {}) {
78
+ const operations = operationsWith(fileOperations);
68
79
  const packageRoot = fileURLToPath(new URL("../../", import.meta.url));
69
80
  const command = packageOwnedCommand(path.join(packageRoot, "dist", "long-task-hook.js"));
70
- const legacyScript = path.join(projectRoot, ".codex", "hooks", "long-task-hook.mjs");
71
- if (await pathExists(legacyScript)) {
72
- await rm(legacyScript, { force: true });
73
- report.changed.push(".codex/hooks/long-task-hook.mjs");
74
- }
75
81
  const config = path.join(projectRoot, ".codex", "hooks.json");
76
- if (!(await pathExists(config)))
77
- return;
78
- let root;
82
+ const legacyScript = path.join(projectRoot, ".codex", "hooks", "long-task-hook.mjs");
79
83
  try {
80
- root = JSON.parse(await readFile(config, "utf8"));
81
- }
82
- catch {
83
- report.skipped.push(".codex/hooks.json: invalid JSON");
84
- return;
84
+ const legacy = await inspectLegacyScript(projectRoot, operations);
85
+ const loaded = await readHookConfig(projectRoot, false, operations);
86
+ let removed = 0;
87
+ const hooks = hookMap(loaded.root);
88
+ for (const event of MANAGED_HOOK_EVENTS) {
89
+ if (!Array.isArray(hooks[event]))
90
+ continue;
91
+ const cleaned = removeManagedHookEntries(hooks[event], command);
92
+ removed += cleaned.removed;
93
+ if (cleaned.groups.length)
94
+ hooks[event] = cleaned.groups;
95
+ else
96
+ delete hooks[event];
97
+ }
98
+ if (removed > 0 && loaded.snapshot.kind === "regular") {
99
+ loaded.root.hooks = hooks;
100
+ if (Object.keys(hooks).length === 0 &&
101
+ Object.keys(loaded.root).length === 1)
102
+ await removeHookConfig(config, loaded.snapshot, operations);
103
+ else
104
+ await publishHookConfig(config, loaded.snapshot, `${JSON.stringify(loaded.root, null, 2)}\n`, operations);
105
+ report.changed.push(".codex/hooks.json");
106
+ }
107
+ await removeLegacyScriptIfPresent(projectRoot, legacyScript, legacy, report, operations);
85
108
  }
86
- const hooks = object(root.hooks);
87
- let changed = false;
88
- for (const event of ["SessionStart", "PostCompact", "Stop"]) {
89
- if (!Array.isArray(hooks[event]))
90
- continue;
91
- const cleaned = removeManagedHookEntries(hooks[event], command);
92
- if (cleaned.removed === 0)
93
- continue;
94
- changed = true;
95
- if (cleaned.groups.length)
96
- hooks[event] = cleaned.groups;
97
- else
98
- delete hooks[event];
109
+ catch (error) {
110
+ report.blocked.push(`.codex/hooks.json: ${message(error)}`);
99
111
  }
100
- if (!changed)
101
- return;
102
- root.hooks = hooks;
103
- if (Object.keys(hooks).length === 0 && Object.keys(root).length === 1)
104
- await rm(config, { force: true });
105
- else
106
- await writeIfChanged(config, `${JSON.stringify(root, null, 2)}\n`);
107
- report.changed.push(".codex/hooks.json");
108
112
  }
109
113
  export function packageOwnedCommand(entry) {
110
114
  return `node "${path.resolve(entry).replace(/"/gu, '\\"')}"`;
@@ -129,8 +133,13 @@ export function removeManagedHookEntries(groups, currentPackageCommand = "") {
129
133
  retained.push({ ...groupValue, hooks });
130
134
  continue;
131
135
  }
132
- if (Object.keys(groupValue).some((key) => key !== "hooks"))
133
- retained.push({ ...groupValue, hooks });
136
+ const keys = Object.keys(groupValue);
137
+ if (keys.every((key) => key === "hooks"))
138
+ continue;
139
+ if (MANAGED_MATCHERS.has(String(groupValue.matcher ?? "")) &&
140
+ keys.every((key) => key === "matcher" || key === "hooks"))
141
+ continue;
142
+ retained.push({ ...groupValue, hooks });
134
143
  }
135
144
  return { groups: retained, removed };
136
145
  }
@@ -141,8 +150,7 @@ export function isManagedHookEntry(entry, currentPackageCommand = "") {
141
150
  const commands = [row.command, row.commandWindows]
142
151
  .filter((value) => typeof value === "string")
143
152
  .map((value) => value.trim());
144
- const repoLocal = commands.some((command) => LEGACY_REPO_LOCAL_COMMANDS.has(command));
145
- if (repoLocal)
153
+ if (commands.some((command) => LEGACY_REPO_LOCAL_COMMANDS.has(command)))
146
154
  return true;
147
155
  const status = String(row.statusMessage ?? "");
148
156
  if (!LEGACY_MANAGED_STATUSES.has(status))
@@ -150,6 +158,201 @@ export function isManagedHookEntry(entry, currentPackageCommand = "") {
150
158
  return commands.some((command) => (Boolean(currentPackageCommand) && command === currentPackageCommand) ||
151
159
  isHistoricalPackageOwnedCommand(command));
152
160
  }
161
+ function mergeManagedHooks(root, command) {
162
+ const hooks = hookMap(root);
163
+ root.hooks = hooks;
164
+ for (const event of MANAGED_HOOK_EVENTS) {
165
+ const current = hooks[event];
166
+ if (current !== undefined && !Array.isArray(current))
167
+ throw new Error(`hook_event_not_array:${event}`);
168
+ const cleaned = removeManagedHookEntries(current ?? [], command);
169
+ cleaned.groups.push(managedHookGroup(event, command));
170
+ hooks[event] = cleaned.groups;
171
+ }
172
+ return root;
173
+ }
174
+ function managedHookGroup(event, command) {
175
+ return {
176
+ ...(event === "PreToolUse" ? { matcher: PRE_TOOL_USE_MATCHER } : {}),
177
+ ...(event === "SubagentStart"
178
+ ? { matcher: LONG_TASK_IMPLEMENTATION_AGENT_MATCHER }
179
+ : {}),
180
+ hooks: [
181
+ {
182
+ type: "command",
183
+ command,
184
+ commandWindows: command,
185
+ timeout: event === "Stop" ? 3600 : 10,
186
+ statusMessage: MANAGED_STATUS,
187
+ },
188
+ ],
189
+ };
190
+ }
191
+ function packageHooksAreCurrent(root, command) {
192
+ let hooks;
193
+ try {
194
+ hooks = hookMap(root);
195
+ }
196
+ catch {
197
+ return false;
198
+ }
199
+ return MANAGED_HOOK_EVENTS.every((event) => {
200
+ const groups = hooks[event];
201
+ if (!Array.isArray(groups))
202
+ return false;
203
+ const matches = [];
204
+ for (const groupValue of groups) {
205
+ if (!isObject(groupValue) || !Array.isArray(groupValue.hooks))
206
+ continue;
207
+ for (const entryValue of groupValue.hooks) {
208
+ if (!isManagedHookEntry(entryValue, command))
209
+ continue;
210
+ matches.push({ group: groupValue, entry: object(entryValue) });
211
+ }
212
+ }
213
+ if (matches.length !== 1)
214
+ return false;
215
+ const [{ group, entry }] = matches;
216
+ const expectedMatcher = event === "PreToolUse"
217
+ ? PRE_TOOL_USE_MATCHER
218
+ : event === "SubagentStart"
219
+ ? LONG_TASK_IMPLEMENTATION_AGENT_MATCHER
220
+ : undefined;
221
+ return (entry.type === "command" &&
222
+ entry.command === command &&
223
+ entry.commandWindows === command &&
224
+ entry.timeout === (event === "Stop" ? 3600 : 10) &&
225
+ entry.statusMessage === MANAGED_STATUS &&
226
+ (expectedMatcher === undefined
227
+ ? !Object.hasOwn(group, "matcher")
228
+ : group.matcher === expectedMatcher));
229
+ });
230
+ }
231
+ async function readHookConfig(projectRoot, createDirectory, operations) {
232
+ const directory = await inspectCodexDirectory(projectRoot, createDirectory, operations);
233
+ if (directory === "absent")
234
+ return { root: {}, snapshot: { kind: "absent" } };
235
+ const config = path.join(projectRoot, ".codex", "hooks.json");
236
+ const status = await lstatOrNull(config, operations);
237
+ if (!status)
238
+ return { root: {}, snapshot: { kind: "absent" } };
239
+ if (status.isSymbolicLink())
240
+ throw new Error("destination_symlink_or_junction");
241
+ if (!status.isFile())
242
+ throw new Error("destination_not_regular_file");
243
+ const content = await operations.readFile(config, "utf8");
244
+ let decoded;
245
+ try {
246
+ decoded = JSON.parse(content);
247
+ }
248
+ catch {
249
+ throw new Error("invalid JSON");
250
+ }
251
+ if (!isObject(decoded))
252
+ throw new Error("root_not_object");
253
+ hookMap(decoded);
254
+ return { root: decoded, snapshot: { kind: "regular", content } };
255
+ }
256
+ function hookMap(root) {
257
+ if (root.hooks === undefined)
258
+ return {};
259
+ if (!isObject(root.hooks))
260
+ throw new Error("hooks_not_object");
261
+ return root.hooks;
262
+ }
263
+ async function inspectCodexDirectory(projectRoot, create, operations) {
264
+ const directory = path.join(projectRoot, ".codex");
265
+ let status = await lstatOrNull(directory, operations);
266
+ if (!status && create) {
267
+ await operations.mkdir(directory, { recursive: true });
268
+ status = await lstatOrNull(directory, operations);
269
+ }
270
+ if (!status)
271
+ return "absent";
272
+ if (status.isSymbolicLink())
273
+ throw new Error("parent_symlink_or_junction:.codex");
274
+ if (!status.isDirectory())
275
+ throw new Error("parent_not_directory:.codex");
276
+ return "regular";
277
+ }
278
+ async function inspectLegacyScript(projectRoot, operations) {
279
+ if ((await inspectCodexDirectory(projectRoot, false, operations)) === "absent")
280
+ return { kind: "absent" };
281
+ const parent = path.join(projectRoot, ".codex", "hooks");
282
+ const parentStatus = await lstatOrNull(parent, operations);
283
+ if (!parentStatus)
284
+ return { kind: "absent" };
285
+ if (parentStatus.isSymbolicLink())
286
+ throw new Error("legacy_parent_symlink_or_junction");
287
+ if (!parentStatus.isDirectory())
288
+ throw new Error("legacy_parent_not_directory");
289
+ const target = path.join(parent, "long-task-hook.mjs");
290
+ const targetStatus = await lstatOrNull(target, operations);
291
+ if (!targetStatus)
292
+ return { kind: "absent" };
293
+ if (targetStatus.isSymbolicLink())
294
+ throw new Error("legacy_hook_symlink_or_junction");
295
+ if (!targetStatus.isFile())
296
+ throw new Error("legacy_hook_not_regular_file");
297
+ return { kind: "regular" };
298
+ }
299
+ async function removeLegacyScriptIfPresent(projectRoot, target, initial, report, operations) {
300
+ if (initial.kind === "absent")
301
+ return;
302
+ const current = await inspectLegacyScript(projectRoot, operations);
303
+ if (current.kind !== "regular")
304
+ throw new Error("legacy_hook_changed_before_delete");
305
+ await operations.rm(target, { force: true });
306
+ report.changed.push(".codex/hooks/long-task-hook.mjs");
307
+ }
308
+ async function publishHookConfig(target, initial, content, operations) {
309
+ const temp = `${target}.tmp-${process.pid}-${operations.randomId()}`;
310
+ let renamed = false;
311
+ try {
312
+ await operations.writeFile(temp, content, { flag: "wx" });
313
+ await assertTargetUnchanged(target, initial, operations);
314
+ await operations.rename(temp, target);
315
+ renamed = true;
316
+ }
317
+ finally {
318
+ if (!renamed)
319
+ await operations.rm(temp, { force: true }).catch(() => { });
320
+ }
321
+ }
322
+ async function removeHookConfig(target, initial, operations) {
323
+ await assertTargetUnchanged(target, initial, operations);
324
+ await operations.rm(target, { force: true });
325
+ }
326
+ async function assertTargetUnchanged(target, initial, operations) {
327
+ const projectRoot = path.dirname(path.dirname(target));
328
+ await inspectCodexDirectory(projectRoot, false, operations);
329
+ const status = await lstatOrNull(target, operations);
330
+ if (initial.kind === "absent") {
331
+ if (status)
332
+ throw new Error("concurrent change: destination appeared");
333
+ return;
334
+ }
335
+ if (!status || status.isSymbolicLink() || !status.isFile())
336
+ throw new Error("concurrent change: destination type changed");
337
+ if ((await operations.readFile(target, "utf8")) !== initial.content)
338
+ throw new Error("concurrent change: destination content changed");
339
+ }
340
+ function addNotice(report) {
341
+ (report.notices ??= []).push(LONG_TASK_HOOK_TRUST_REVIEW_NOTICE);
342
+ }
343
+ function operationsWith(overrides) {
344
+ return { ...DEFAULT_FILE_OPERATIONS, ...overrides };
345
+ }
346
+ async function lstatOrNull(target, operations) {
347
+ try {
348
+ return await operations.lstat(target);
349
+ }
350
+ catch (error) {
351
+ if (code(error) === "ENOENT")
352
+ return null;
353
+ throw error;
354
+ }
355
+ }
153
356
  function isHistoricalPackageOwnedCommand(command) {
154
357
  const match = /^node "([^"\r\n]+)"$/u.exec(command);
155
358
  if (!match)
@@ -163,22 +366,16 @@ function isHistoricalPackageOwnedCommand(command) {
163
366
  return (/\/node_modules\/project-tiny-context-harness\/dist\/long-task-hook\.js$/u.test(normalized) || /\/packages\/ty-context\/dist\/long-task-hook\.js$/u.test(normalized));
164
367
  }
165
368
  function object(value) {
166
- return value && typeof value === "object" && !Array.isArray(value)
167
- ? value
168
- : {};
369
+ return isObject(value) ? value : {};
169
370
  }
170
371
  function isObject(value) {
171
372
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
172
373
  }
173
- async function writeIfChanged(file, content) {
174
- try {
175
- if ((await readFile(file, "utf8")) === content)
176
- return false;
177
- }
178
- catch { }
179
- await mkdir(path.dirname(file), { recursive: true });
180
- const temp = `${file}.tmp-${process.pid}-${Date.now()}`;
181
- await writeFile(temp, content, { flag: "wx" });
182
- await rename(temp, file);
183
- return true;
374
+ function code(error) {
375
+ return typeof error === "object" && error !== null && "code" in error
376
+ ? String(error.code)
377
+ : "";
378
+ }
379
+ function message(error) {
380
+ return error instanceof Error ? error.message : String(error);
184
381
  }
@@ -0,0 +1,59 @@
1
+ export declare const JSON_POINTER_EXACT_CAPABILITY = "json-pointer-exact-v1";
2
+ export declare const JSON_POINTER_EXACT_ORACLE_IDENTITY = "ty-context-json-pointer-exact";
3
+ export declare const JSON_POINTER_EXACT_ORACLE_VERSION = "1.0.0";
4
+ export declare const JSON_POINTER_EXACT_METHODS: readonly ["exact_value", "content", "component_state"];
5
+ export declare const JSON_POINTER_EXACT_LIMITS: Readonly<{
6
+ max_file_bytes: 1048576;
7
+ max_depth: 64;
8
+ max_pointer_bytes: 4096;
9
+ max_pointer_segments: 128;
10
+ max_canonical_value_bytes: 262144;
11
+ max_artifacts_per_check: 256;
12
+ max_total_artifact_bytes: 16777216;
13
+ }>;
14
+ export declare const JSON_POINTER_EXACT_SPEC_SHA256: string;
15
+ export interface JsonPointerExactBudget {
16
+ readonly seen_artifact_paths: Set<string>;
17
+ total_artifact_bytes: number;
18
+ }
19
+ export interface JsonPointerExactLocator {
20
+ kind: string;
21
+ value: string;
22
+ }
23
+ export interface JsonPointerExactObservation {
24
+ capability: typeof JSON_POINTER_EXACT_CAPABILITY;
25
+ artifact_path: string;
26
+ artifact_sha256: string;
27
+ locator: {
28
+ kind: "json_pointer";
29
+ value: string;
30
+ };
31
+ value_sha256: string;
32
+ canonical_value_bytes: number;
33
+ sensitivity: "plain";
34
+ }
35
+ export declare function createJsonPointerExactBudget(): JsonPointerExactBudget;
36
+ export declare function isJsonPointerExactOracle(oracle: {
37
+ trust?: string;
38
+ identity?: string;
39
+ version?: string;
40
+ sha256?: string | null;
41
+ }): boolean;
42
+ export declare function extractJsonPointerExactObservationFromBytes(input: {
43
+ artifact_path: string;
44
+ bytes: Uint8Array;
45
+ locator: JsonPointerExactLocator;
46
+ sensitivity: string;
47
+ budget?: JsonPointerExactBudget;
48
+ }): JsonPointerExactObservation;
49
+ export declare function validateJsonPointerExactLocator(locator: JsonPointerExactLocator): {
50
+ kind: "json_pointer";
51
+ value: string;
52
+ };
53
+ export declare function normalizeObservationArtifactPath(value: string): string;
54
+ export declare function invalidObservation(code: string): Error;
55
+ export declare function observationErrorMessage(error: unknown): string;
56
+ export declare function resolveJsonPointer(root: unknown, pointer: string): unknown;
57
+ export declare function parseJsonWithoutDuplicateKeys(content: string): unknown;
58
+ export declare function decodeUtf8Json(bytes: Uint8Array): string;
59
+ export declare function assertJsonTree(value: unknown, depth: number): void;
@@ -0,0 +1,184 @@
1
+ import path from "node:path";
2
+ import { canonicalValueJson, parseStrictYaml, sha256Hex, } from "./strict-codec.js";
3
+ export const JSON_POINTER_EXACT_CAPABILITY = "json-pointer-exact-v1";
4
+ export const JSON_POINTER_EXACT_ORACLE_IDENTITY = "ty-context-json-pointer-exact";
5
+ export const JSON_POINTER_EXACT_ORACLE_VERSION = "1.0.0";
6
+ export const JSON_POINTER_EXACT_METHODS = Object.freeze([
7
+ "exact_value",
8
+ "content",
9
+ "component_state",
10
+ ]);
11
+ export const JSON_POINTER_EXACT_LIMITS = Object.freeze({
12
+ max_file_bytes: 1_048_576,
13
+ max_depth: 64,
14
+ max_pointer_bytes: 4_096,
15
+ max_pointer_segments: 128,
16
+ max_canonical_value_bytes: 262_144,
17
+ max_artifacts_per_check: 256,
18
+ max_total_artifact_bytes: 16_777_216,
19
+ });
20
+ export const JSON_POINTER_EXACT_SPEC_SHA256 = sha256Hex(canonicalValueJson({
21
+ capability: JSON_POINTER_EXACT_CAPABILITY,
22
+ oracle_identity: JSON_POINTER_EXACT_ORACLE_IDENTITY,
23
+ oracle_version: JSON_POINTER_EXACT_ORACLE_VERSION,
24
+ media_type: "application/json",
25
+ encoding: "utf-8",
26
+ locator: "rfc6901-json-pointer",
27
+ canonicalization: "canonical-json-v1",
28
+ methods: JSON_POINTER_EXACT_METHODS,
29
+ comparator: "exact_value",
30
+ mode: "exact",
31
+ sensitivity: "plain",
32
+ limits: JSON_POINTER_EXACT_LIMITS,
33
+ }));
34
+ export function createJsonPointerExactBudget() {
35
+ return { seen_artifact_paths: new Set(), total_artifact_bytes: 0 };
36
+ }
37
+ export function isJsonPointerExactOracle(oracle) {
38
+ return (oracle.trust === "named_external_tcb" &&
39
+ oracle.identity === JSON_POINTER_EXACT_ORACLE_IDENTITY &&
40
+ oracle.version === JSON_POINTER_EXACT_ORACLE_VERSION &&
41
+ oracle.sha256 === null);
42
+ }
43
+ export function extractJsonPointerExactObservationFromBytes(input) {
44
+ const artifactPath = normalizeObservationArtifactPath(input.artifact_path);
45
+ if (input.sensitivity !== "plain")
46
+ throw invalidObservation("observation_protected_requires_frozen_adapter");
47
+ if (input.bytes.byteLength > JSON_POINTER_EXACT_LIMITS.max_file_bytes)
48
+ throw invalidObservation("observation_artifact_size_limit");
49
+ accountForArtifact(input.budget, artifactPath, input.bytes.byteLength);
50
+ const locator = validateJsonPointerExactLocator(input.locator);
51
+ const parsed = parseJsonWithoutDuplicateKeys(decodeUtf8Json(input.bytes));
52
+ assertJsonTree(parsed, 0);
53
+ const canonical = canonicalValueJson(resolveJsonPointer(parsed, locator.value));
54
+ const canonicalBytes = Buffer.byteLength(canonical, "utf8");
55
+ if (canonicalBytes > JSON_POINTER_EXACT_LIMITS.max_canonical_value_bytes)
56
+ throw invalidObservation("observation_canonical_value_size_limit");
57
+ return {
58
+ capability: JSON_POINTER_EXACT_CAPABILITY,
59
+ artifact_path: artifactPath,
60
+ artifact_sha256: sha256Hex(input.bytes),
61
+ locator,
62
+ value_sha256: sha256Hex(canonical),
63
+ canonical_value_bytes: canonicalBytes,
64
+ sensitivity: "plain",
65
+ };
66
+ }
67
+ export function validateJsonPointerExactLocator(locator) {
68
+ if (locator.kind !== "json_pointer" ||
69
+ typeof locator.value !== "string" ||
70
+ locator.value.startsWith("#") ||
71
+ (locator.value !== "" && !locator.value.startsWith("/")) ||
72
+ Buffer.byteLength(locator.value, "utf8") >
73
+ JSON_POINTER_EXACT_LIMITS.max_pointer_bytes)
74
+ throw invalidObservation("observation_locator_not_admitted");
75
+ const encoded = locator.value === "" ? [] : locator.value.slice(1).split("/");
76
+ if (encoded.length > JSON_POINTER_EXACT_LIMITS.max_pointer_segments)
77
+ throw invalidObservation("observation_locator_segment_limit");
78
+ for (const token of encoded)
79
+ if (/~(?:[^01]|$)/u.test(token))
80
+ throw invalidObservation("observation_locator_not_admitted");
81
+ return { kind: "json_pointer", value: locator.value };
82
+ }
83
+ export function normalizeObservationArtifactPath(value) {
84
+ if (!value ||
85
+ value.includes("\\") ||
86
+ value.includes("\0") ||
87
+ path.posix.isAbsolute(value) ||
88
+ /^[a-z]:/iu.test(value))
89
+ throw invalidObservation("observation_artifact_path_escape");
90
+ const segments = value.split("/");
91
+ if (segments.some((segment) => !segment || segment === "." || segment === ".."))
92
+ throw invalidObservation("observation_artifact_path_escape");
93
+ return segments.join("/");
94
+ }
95
+ export function invalidObservation(code) {
96
+ return new Error(code);
97
+ }
98
+ export function observationErrorMessage(error) {
99
+ return error instanceof Error ? error.message : String(error);
100
+ }
101
+ export function resolveJsonPointer(root, pointer) {
102
+ let current = root;
103
+ if (pointer === "")
104
+ return current;
105
+ for (const encoded of pointer.slice(1).split("/")) {
106
+ const token = encoded.replace(/~1/gu, "/").replace(/~0/gu, "~");
107
+ if (Array.isArray(current)) {
108
+ if (!/^(?:0|[1-9]\d*)$/u.test(token))
109
+ throw invalidObservation("observation_locator_array_index_invalid");
110
+ const index = Number(token);
111
+ if (!Number.isSafeInteger(index) || index >= current.length)
112
+ throw invalidObservation("observation_locator_not_found");
113
+ current = current[index];
114
+ continue;
115
+ }
116
+ if (!current ||
117
+ typeof current !== "object" ||
118
+ !Object.hasOwn(current, token))
119
+ throw invalidObservation("observation_locator_not_found");
120
+ current = current[token];
121
+ }
122
+ return current;
123
+ }
124
+ export function parseJsonWithoutDuplicateKeys(content) {
125
+ let parsed;
126
+ try {
127
+ parsed = JSON.parse(content);
128
+ }
129
+ catch {
130
+ throw invalidObservation("observation_json_invalid");
131
+ }
132
+ try {
133
+ const strict = parseStrictYaml(content);
134
+ if (canonicalValueJson(strict) !== canonicalValueJson(parsed))
135
+ throw invalidObservation("observation_json_canonicalization_mismatch");
136
+ }
137
+ catch (error) {
138
+ if (observationErrorMessage(error).includes("unique"))
139
+ throw invalidObservation("observation_json_duplicate_key");
140
+ if (observationErrorMessage(error).startsWith("observation_"))
141
+ throw error;
142
+ throw invalidObservation("observation_json_invalid");
143
+ }
144
+ return parsed;
145
+ }
146
+ export function decodeUtf8Json(bytes) {
147
+ if (bytes.byteLength >= 3 &&
148
+ bytes[0] === 0xef &&
149
+ bytes[1] === 0xbb &&
150
+ bytes[2] === 0xbf)
151
+ throw invalidObservation("observation_json_utf8_invalid");
152
+ try {
153
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
154
+ }
155
+ catch {
156
+ throw invalidObservation("observation_json_utf8_invalid");
157
+ }
158
+ }
159
+ export function assertJsonTree(value, depth) {
160
+ if (depth > JSON_POINTER_EXACT_LIMITS.max_depth)
161
+ throw invalidObservation("observation_json_depth_limit");
162
+ if (typeof value === "number" && !Number.isFinite(value))
163
+ throw invalidObservation("observation_json_number_invalid");
164
+ if (Array.isArray(value)) {
165
+ for (const entry of value)
166
+ assertJsonTree(entry, depth + 1);
167
+ return;
168
+ }
169
+ if (value && typeof value === "object")
170
+ for (const entry of Object.values(value))
171
+ assertJsonTree(entry, depth + 1);
172
+ }
173
+ function accountForArtifact(budget, artifactPath, bytes) {
174
+ if (!budget || budget.seen_artifact_paths.has(artifactPath))
175
+ return;
176
+ if (budget.seen_artifact_paths.size >=
177
+ JSON_POINTER_EXACT_LIMITS.max_artifacts_per_check)
178
+ throw invalidObservation("observation_artifact_count_limit");
179
+ if (budget.total_artifact_bytes + bytes >
180
+ JSON_POINTER_EXACT_LIMITS.max_total_artifact_bytes)
181
+ throw invalidObservation("observation_artifact_total_size_limit");
182
+ budget.seen_artifact_paths.add(artifactPath);
183
+ budget.total_artifact_bytes += bytes;
184
+ }