project-tiny-context-harness 0.8.10 → 0.8.12

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 (279) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +490 -472
  3. package/assets/README.md +762 -749
  4. package/assets/README.zh-CN.md +446 -431
  5. package/assets/agents/.gitkeep +1 -1
  6. package/assets/agents/AGENTS_CORE.md +17 -23
  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 +64 -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 +52 -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 +119 -119
  30. package/assets/skills/design-resource-authoring/references/resource-selection.md +158 -181
  31. package/assets/skills/design-system-authoring/SKILL.md +57 -57
  32. package/assets/skills/design-system-authoring/agents/openai.yaml +6 -6
  33. package/assets/skills/design-system-authoring/references/authority-adoption.md +48 -48
  34. package/assets/skills/design-system-authoring/references/open-design-design-system-provider.md +110 -110
  35. package/assets/skills/long-task-workflow/SKILL.md +71 -106
  36. package/assets/skills/long-task-workflow/agents/openai.yaml +1 -1
  37. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +71 -69
  38. package/assets/skills/long-task-workflow/references/contract-authoring.md +98 -94
  39. package/assets/skills/long-task-workflow/references/evidence-design.md +67 -63
  40. package/assets/skills/long-task-workflow/references/source-authoring.md +90 -90
  41. package/assets/tools/validate_context.py +442 -442
  42. package/dist/commands/design-resource.js +9 -2
  43. package/dist/commands/enable.js +2 -0
  44. package/dist/commands/index.js +1 -1
  45. package/dist/commands/long-task-revision.js +8 -7
  46. package/dist/commands/sync.js +2 -0
  47. package/dist/index.d.ts +3 -4
  48. package/dist/index.js +2 -1
  49. package/dist/lib/compact-authoring-support.d.ts +22 -0
  50. package/dist/lib/compact-authoring-support.js +143 -0
  51. package/dist/lib/compact-shared-structure-authoring.d.ts +5 -0
  52. package/dist/lib/compact-shared-structure-authoring.js +9 -0
  53. package/dist/lib/compact-shared-structure-types.d.ts +61 -0
  54. package/dist/lib/compact-shared-structure-types.js +1 -0
  55. package/dist/lib/compact-shared-structure-validation.d.ts +2 -0
  56. package/dist/lib/compact-shared-structure-validation.js +159 -0
  57. package/dist/lib/compact-shared-structures.d.ts +3 -0
  58. package/dist/lib/compact-shared-structures.js +204 -0
  59. package/dist/lib/design-resource-fact-enums.d.ts +4 -0
  60. package/dist/lib/design-resource-fact-enums.js +12 -0
  61. package/dist/lib/design-resource-fact-manifest-shape-evidence.js +2 -2
  62. package/dist/lib/design-resource-fact-manifest-validation.d.ts +2 -1
  63. package/dist/lib/design-resource-fact-policy.d.ts +2 -2
  64. package/dist/lib/design-resource-fact-types.d.ts +2 -2
  65. package/dist/lib/design-resource-handoff-bundle-draft.d.ts +11 -0
  66. package/dist/lib/design-resource-handoff-bundle-draft.js +40 -0
  67. package/dist/lib/design-resource-handoff-bundle.js +4 -28
  68. package/dist/lib/design-resource-handoff-input-types.d.ts +14 -0
  69. package/dist/lib/design-resource-handoff-input-types.js +1 -0
  70. package/dist/lib/design-resource-handoff-manifest-projection.d.ts +2 -1
  71. package/dist/lib/design-resource-handoff-parser.d.ts +2 -2
  72. package/dist/lib/design-resource-handoff-parser.js +2 -2
  73. package/dist/lib/design-resource-handoff-shape.d.ts +4 -1
  74. package/dist/lib/design-resource-handoff-shape.js +10 -0
  75. package/dist/lib/design-resource-handoff-snapshot.d.ts +1 -1
  76. package/dist/lib/design-resource-handoff-snapshot.js +4 -0
  77. package/dist/lib/design-resource-handoff-types.d.ts +0 -10
  78. package/dist/lib/design-resource-handoff-validation.d.ts +6 -2
  79. package/dist/lib/design-resource-handoff-validation.js +11 -0
  80. package/dist/lib/design-resource-handoff-web-dependency-validation.d.ts +4 -2
  81. package/dist/lib/design-resource-symbolic-applicability-authority.d.ts +7 -0
  82. package/dist/lib/design-resource-symbolic-applicability-authority.js +19 -0
  83. package/dist/lib/design-resource-symbolic-applicability-policy.d.ts +12 -0
  84. package/dist/lib/design-resource-symbolic-applicability-policy.js +79 -0
  85. package/dist/lib/design-resource-symbolic-applicability-profiles.d.ts +8 -0
  86. package/dist/lib/design-resource-symbolic-applicability-profiles.js +55 -0
  87. package/dist/lib/design-resource-symbolic-applicability-shape.d.ts +2 -0
  88. package/dist/lib/design-resource-symbolic-applicability-shape.js +76 -0
  89. package/dist/lib/design-resource-symbolic-applicability-validation.d.ts +7 -0
  90. package/dist/lib/design-resource-symbolic-applicability-validation.js +128 -0
  91. package/dist/lib/design-resource-symbolic-compilation.d.ts +3 -0
  92. package/dist/lib/design-resource-symbolic-compilation.js +13 -0
  93. package/dist/lib/design-resource-symbolic-denotation.d.ts +3 -0
  94. package/dist/lib/design-resource-symbolic-denotation.js +167 -0
  95. package/dist/lib/design-resource-symbolic-disposition-validation.d.ts +4 -0
  96. package/dist/lib/design-resource-symbolic-disposition-validation.js +28 -0
  97. package/dist/lib/design-resource-symbolic-fact-policy.d.ts +12 -0
  98. package/dist/lib/design-resource-symbolic-fact-policy.js +12 -0
  99. package/dist/lib/design-resource-symbolic-fact-shape.d.ts +3 -0
  100. package/dist/lib/design-resource-symbolic-fact-shape.js +138 -0
  101. package/dist/lib/design-resource-symbolic-fact-types.d.ts +213 -0
  102. package/dist/lib/design-resource-symbolic-fact-types.js +1 -0
  103. package/dist/lib/design-resource-symbolic-fact-validation.d.ts +3 -0
  104. package/dist/lib/design-resource-symbolic-fact-validation.js +86 -0
  105. package/dist/lib/design-resource-symbolic-indexes.d.ts +23 -0
  106. package/dist/lib/design-resource-symbolic-indexes.js +54 -0
  107. package/dist/lib/design-resource-symbolic-manifest-shape.d.ts +3 -0
  108. package/dist/lib/design-resource-symbolic-manifest-shape.js +155 -0
  109. package/dist/lib/design-resource-symbolic-manifest-validation.d.ts +6 -0
  110. package/dist/lib/design-resource-symbolic-manifest-validation.js +132 -0
  111. package/dist/lib/design-resource-symbolic-noninterference-artifact.d.ts +33 -0
  112. package/dist/lib/design-resource-symbolic-noninterference-artifact.js +110 -0
  113. package/dist/lib/design-resource-symbolic-noninterference-equivalence.d.ts +3 -0
  114. package/dist/lib/design-resource-symbolic-noninterference-equivalence.js +77 -0
  115. package/dist/lib/design-resource-symbolic-noninterference-recompute.d.ts +4 -0
  116. package/dist/lib/design-resource-symbolic-noninterference-recompute.js +146 -0
  117. package/dist/lib/design-resource-symbolic-noninterference-scope.d.ts +7 -0
  118. package/dist/lib/design-resource-symbolic-noninterference-scope.js +49 -0
  119. package/dist/lib/design-resource-symbolic-noninterference-shape.d.ts +2 -0
  120. package/dist/lib/design-resource-symbolic-noninterference-shape.js +152 -0
  121. package/dist/lib/design-resource-symbolic-noninterference-types.d.ts +103 -0
  122. package/dist/lib/design-resource-symbolic-noninterference-types.js +1 -0
  123. package/dist/lib/design-resource-symbolic-noninterference-validation.d.ts +5 -0
  124. package/dist/lib/design-resource-symbolic-noninterference-validation.js +62 -0
  125. package/dist/lib/design-resource-symbolic-oracle-fingerprint.d.ts +1 -0
  126. package/dist/lib/design-resource-symbolic-oracle-fingerprint.js +47 -0
  127. package/dist/lib/design-resource-symbolic-predicate-shape.d.ts +6 -0
  128. package/dist/lib/design-resource-symbolic-predicate-shape.js +123 -0
  129. package/dist/lib/design-resource-symbolic-production-closure.d.ts +4 -0
  130. package/dist/lib/design-resource-symbolic-production-closure.js +144 -0
  131. package/dist/lib/design-resource-symbolic-proof-authority-validation.d.ts +10 -0
  132. package/dist/lib/design-resource-symbolic-proof-authority-validation.js +68 -0
  133. package/dist/lib/design-resource-symbolic-proof-validation.d.ts +10 -0
  134. package/dist/lib/design-resource-symbolic-proof-validation.js +89 -0
  135. package/dist/lib/design-resource-symbolic-region-validation.d.ts +19 -0
  136. package/dist/lib/design-resource-symbolic-region-validation.js +146 -0
  137. package/dist/lib/design-resource-symbolic-resource-validation.d.ts +5 -0
  138. package/dist/lib/design-resource-symbolic-resource-validation.js +90 -0
  139. package/dist/lib/design-resource-symbolic-rule-shape.d.ts +27 -0
  140. package/dist/lib/design-resource-symbolic-rule-shape.js +158 -0
  141. package/dist/lib/design-resource-symbolic-safety-validation.d.ts +6 -0
  142. package/dist/lib/design-resource-symbolic-safety-validation.js +29 -0
  143. package/dist/lib/design-resource-symbolic-source-ir-evaluation.d.ts +19 -0
  144. package/dist/lib/design-resource-symbolic-source-ir-evaluation.js +74 -0
  145. package/dist/lib/design-resource-symbolic-source-ir-evidence.d.ts +44 -0
  146. package/dist/lib/design-resource-symbolic-source-ir-evidence.js +88 -0
  147. package/dist/lib/design-resource-symbolic-source-ir-oracle.d.ts +13 -0
  148. package/dist/lib/design-resource-symbolic-source-ir-oracle.js +96 -0
  149. package/dist/lib/design-resource-symbolic-source-ir-proof.d.ts +14 -0
  150. package/dist/lib/design-resource-symbolic-source-ir-proof.js +98 -0
  151. package/dist/lib/design-resource-symbolic-source-ir-shape.d.ts +2 -0
  152. package/dist/lib/design-resource-symbolic-source-ir-shape.js +38 -0
  153. package/dist/lib/design-resource-symbolic-source-ir-types.d.ts +17 -0
  154. package/dist/lib/design-resource-symbolic-source-ir-types.js +2 -0
  155. package/dist/lib/design-resource-symbolic-static-dependency-validation.d.ts +2 -0
  156. package/dist/lib/design-resource-symbolic-static-dependency-validation.js +83 -0
  157. package/dist/lib/design-resource-symbolic-structural-closure-validation.d.ts +6 -0
  158. package/dist/lib/design-resource-symbolic-structural-closure-validation.js +79 -0
  159. package/dist/lib/design-resource-symbolic-validation-support.d.ts +29 -0
  160. package/dist/lib/design-resource-symbolic-validation-support.js +111 -0
  161. package/dist/lib/design-resource-v1-capacity-header.d.ts +8 -0
  162. package/dist/lib/design-resource-v1-capacity-header.js +231 -0
  163. package/dist/lib/design-resource-v1-capacity.d.ts +5 -0
  164. package/dist/lib/design-resource-v1-capacity.js +45 -0
  165. package/dist/lib/init.js +1 -0
  166. package/dist/lib/long-task-activation-validation.js +2 -2
  167. package/dist/lib/long-task-authority-policy.d.ts +3 -0
  168. package/dist/lib/long-task-authority-policy.js +3 -0
  169. package/dist/lib/long-task-codex-agent-profile.d.ts +42 -0
  170. package/dist/lib/long-task-codex-agent-profile.js +276 -0
  171. package/dist/lib/long-task-compact-authoring-projections.d.ts +12 -0
  172. package/dist/lib/long-task-compact-authoring-projections.js +67 -0
  173. package/dist/lib/long-task-compact-authoring.d.ts +3 -0
  174. package/dist/lib/long-task-compact-authoring.js +173 -0
  175. package/dist/lib/long-task-compact-carrier.d.ts +7 -0
  176. package/dist/lib/long-task-compact-carrier.js +132 -0
  177. package/dist/lib/long-task-compact-parser.d.ts +14 -0
  178. package/dist/lib/long-task-compact-parser.js +123 -0
  179. package/dist/lib/long-task-compact-primitives.d.ts +22 -0
  180. package/dist/lib/long-task-compact-primitives.js +132 -0
  181. package/dist/lib/long-task-compact-projections.d.ts +4 -0
  182. package/dist/lib/long-task-compact-projections.js +153 -0
  183. package/dist/lib/long-task-compact-structure-targets.d.ts +2 -0
  184. package/dist/lib/long-task-compact-structure-targets.js +90 -0
  185. package/dist/lib/long-task-counterfactual-sandbox.d.ts +1 -1
  186. package/dist/lib/long-task-counterfactual-sandbox.js +7 -5
  187. package/dist/lib/long-task-delivery-parser.d.ts +1 -0
  188. package/dist/lib/long-task-delivery-parser.js +38 -6
  189. package/dist/lib/long-task-design-resource-handoff.d.ts +2 -1
  190. package/dist/lib/long-task-design-resource-handoff.js +71 -11
  191. package/dist/lib/long-task-design-resource-method-binding.d.ts +8 -1
  192. package/dist/lib/long-task-design-resource-method-binding.js +150 -0
  193. package/dist/lib/long-task-evidence-capability-codec.js +256 -34
  194. package/dist/lib/long-task-evidence-capability-policy.js +28 -0
  195. package/dist/lib/long-task-evidence-capability-runtime.js +271 -63
  196. package/dist/lib/long-task-evidence-capability-types.d.ts +70 -2
  197. package/dist/lib/long-task-evidence-v2.d.ts +1 -1
  198. package/dist/lib/long-task-evidence-v2.js +5 -5
  199. package/dist/lib/long-task-hook-install.d.ts +19 -2
  200. package/dist/lib/long-task-hook-install.js +288 -91
  201. package/dist/lib/long-task-playwright-capability-records.d.ts +2 -0
  202. package/dist/lib/long-task-playwright-capability-records.js +74 -2
  203. package/dist/lib/long-task-runner-freeze.d.ts +1 -1
  204. package/dist/lib/long-task-runner-freeze.js +4 -2
  205. package/dist/lib/long-task-semantic-contract-types.d.ts +1 -1
  206. package/dist/lib/long-task-semantic-fact-binding-types.d.ts +8 -0
  207. package/dist/lib/long-task-semantic-fact-closure.js +4 -1
  208. package/dist/lib/long-task-semantic-fact-contract-closure.d.ts +1 -1
  209. package/dist/lib/long-task-semantic-fact-contract-closure.js +15 -3
  210. package/dist/lib/long-task-semantic-fact-contract-facts.d.ts +1 -1
  211. package/dist/lib/long-task-semantic-fact-contract-facts.js +4 -1
  212. package/dist/lib/long-task-semantic-fact-contract-proofs.d.ts +1 -1
  213. package/dist/lib/long-task-semantic-fact-contract-proofs.js +12 -3
  214. package/dist/lib/long-task-semantic-fact-evidence.d.ts +5 -1
  215. package/dist/lib/long-task-semantic-fact-evidence.js +47 -4
  216. package/dist/lib/long-task-semantic-fact-shape.js +17 -6
  217. package/dist/lib/long-task-shape-primitives.d.ts +1 -1
  218. package/dist/lib/long-task-shape-primitives.js +1 -0
  219. package/dist/lib/long-task-source-item-parser.d.ts +2 -2
  220. package/dist/lib/long-task-source-item-parser.js +20 -11
  221. package/dist/lib/long-task-ui-design-policy.js +64 -4
  222. package/dist/lib/long-task-ui-surface-shape.js +195 -0
  223. package/dist/lib/long-task-ui-surface-types.d.ts +53 -0
  224. package/dist/lib/long-task-verifier-v2.js +1 -1
  225. package/dist/lib/long-task-worker-selection.d.ts +2 -0
  226. package/dist/lib/long-task-worker-selection.js +7 -0
  227. package/dist/lib/long-task-workspace-scope.js +3 -1
  228. package/dist/lib/long-task-workspace.js +11 -1
  229. package/dist/lib/migrations.js +58 -0
  230. package/dist/lib/profiles.js +0 -1
  231. package/dist/lib/semantic-fact-compact-authoring.d.ts +2 -0
  232. package/dist/lib/semantic-fact-compact-authoring.js +160 -0
  233. package/dist/lib/semantic-fact-compact-capacity.d.ts +9 -0
  234. package/dist/lib/semantic-fact-compact-capacity.js +40 -0
  235. package/dist/lib/semantic-fact-compact-carrier.d.ts +16 -0
  236. package/dist/lib/semantic-fact-compact-carrier.js +146 -0
  237. package/dist/lib/semantic-fact-compact-parser.d.ts +17 -0
  238. package/dist/lib/semantic-fact-compact-parser.js +168 -0
  239. package/dist/lib/semantic-fact-compact-revision.d.ts +11 -0
  240. package/dist/lib/semantic-fact-compact-revision.js +64 -0
  241. package/dist/lib/semantic-fact-compact-support.d.ts +23 -0
  242. package/dist/lib/semantic-fact-compact-support.js +159 -0
  243. package/dist/lib/semantic-fact-policy-census.d.ts +1 -0
  244. package/dist/lib/semantic-fact-policy-census.js +43 -0
  245. package/dist/lib/semantic-fact-proof-shape.d.ts +1 -1
  246. package/dist/lib/semantic-fact-property-shape.d.ts +1 -1
  247. package/dist/lib/semantic-fact-source-parser.d.ts +5 -0
  248. package/dist/lib/semantic-fact-source-parser.js +47 -6
  249. package/dist/lib/structural-closure-cost.d.ts +79 -0
  250. package/dist/lib/structural-closure-cost.js +91 -0
  251. package/dist/lib/symbolic-denotation-dag-builder.d.ts +25 -0
  252. package/dist/lib/symbolic-denotation-dag-builder.js +176 -0
  253. package/dist/lib/symbolic-denotation-domain-validation.d.ts +3 -0
  254. package/dist/lib/symbolic-denotation-domain-validation.js +56 -0
  255. package/dist/lib/symbolic-denotation-engine.d.ts +32 -0
  256. package/dist/lib/symbolic-denotation-engine.js +140 -0
  257. package/dist/lib/symbolic-denotation-public.d.ts +11 -0
  258. package/dist/lib/symbolic-denotation-public.js +12 -0
  259. package/dist/lib/symbolic-denotation-runtime.d.ts +20 -0
  260. package/dist/lib/symbolic-denotation-runtime.js +90 -0
  261. package/dist/lib/symbolic-denotation-support.d.ts +11 -0
  262. package/dist/lib/symbolic-denotation-support.js +49 -0
  263. package/dist/lib/symbolic-denotation-types.d.ts +133 -0
  264. package/dist/lib/symbolic-denotation-types.js +18 -0
  265. package/dist/lib/symbolic-denotation-validation.d.ts +6 -0
  266. package/dist/lib/symbolic-denotation-validation.js +126 -0
  267. package/dist/lib/sync-engine.d.ts +1 -0
  268. package/dist/lib/sync-engine.js +4 -1
  269. package/dist/lib/upgrade.js +1 -0
  270. package/dist/long-task-hook.js +40 -1
  271. package/dist/public-types.d.ts +8 -0
  272. package/dist/public-types.js +1 -0
  273. package/dist/schemas/design-resource-symbolic-noninterference-artifact-v2.schema.json +289 -0
  274. package/dist/schemas/design-resource-symbolic-source-ir-v1.schema.json +130 -0
  275. package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +390 -5
  276. package/migrations/README.md +15 -15
  277. package/package.json +2 -2
  278. package/source-mappings.yaml +28 -25
  279. 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
  }
@@ -3,3 +3,5 @@ import type { PlaywrightCase } from "./long-task-playwright-case-evidence.js";
3
3
  export declare function evidenceRecordsForPlaywrightCases(check: CompiledCheckV2, cases: PlaywrightCase[]): EvidenceCapabilityRecordV2[];
4
4
  export declare function semanticFactAttachmentName(proofRef: string): string;
5
5
  export declare function designMethodAttachmentName(target: string, method: string, condition: string, kind: "record" | "observation"): string;
6
+ export declare function symbolicDesignMethodAttachmentName(target: string, method: string): string;
7
+ export declare function symbolicDesignCertificateAttachmentName(target: string): string;
@@ -8,7 +8,7 @@ export function evidenceRecordsForPlaywrightCases(check, cases) {
8
8
  ].find((candidate) => candidate.key === item.id);
9
9
  if (!assertion)
10
10
  continue;
11
- records.push(...baseEvidenceRecords(check, item, assertion), ...designConformanceRecords(check, item, assertion), ...designMethodRecords(check, item, assertion), ...semanticFactRecords(check, item, assertion));
11
+ records.push(...baseEvidenceRecords(check, item, assertion), ...designConformanceRecords(check, item, assertion), ...designMethodRecords(check, item, assertion), ...symbolicDesignEvidenceRecords(check, item, assertion), ...semanticFactRecords(check, item, assertion));
12
12
  }
13
13
  return records;
14
14
  }
@@ -41,7 +41,8 @@ function designConformanceRecords(check, item, assertion) {
41
41
  return [];
42
42
  return (check.design_conformance_targets ?? [])
43
43
  .filter((candidate) => candidate.conformance_assertion_ref === assertion.key ||
44
- candidate.verification_method_bindings.some((binding) => binding.assertion_ref === assertion.key))
44
+ candidate.verification_method_bindings.some((binding) => binding.assertion_ref === assertion.key) ||
45
+ (candidate.symbolic_method_bindings ?? []).some((binding) => binding.assertion_ref === assertion.key))
45
46
  .map((target) => ({
46
47
  assertion_key: assertion.key,
47
48
  capability: "design_conformance",
@@ -58,6 +59,8 @@ function designMethodRecords(check, item, assertion) {
58
59
  return [];
59
60
  const records = [];
60
61
  for (const target of check.design_conformance_targets ?? []) {
62
+ if (target.fact_model === "symbolic_rules_v2")
63
+ continue;
61
64
  const binding = target.verification_method_bindings.find((candidate) => candidate.assertion_ref === assertion.key);
62
65
  if (!binding)
63
66
  continue;
@@ -93,6 +96,69 @@ function designMethodRecords(check, item, assertion) {
93
96
  }
94
97
  return records;
95
98
  }
99
+ function symbolicDesignEvidenceRecords(check, item, assertion) {
100
+ if (!item.executed)
101
+ return [];
102
+ const records = [];
103
+ for (const target of check.design_conformance_targets ?? []) {
104
+ if (target.fact_model !== "symbolic_rules_v2")
105
+ continue;
106
+ records.push(...symbolicMethodEvidenceRecords(target, item, assertion));
107
+ const certificate = symbolicCertificateEvidenceRecord(target, item, assertion);
108
+ if (certificate)
109
+ records.push(certificate);
110
+ }
111
+ return records;
112
+ }
113
+ function symbolicMethodEvidenceRecords(target, item, assertion) {
114
+ if (!assertion.evidence_capabilities.includes("design_method"))
115
+ return [];
116
+ const records = [];
117
+ for (const binding of target.symbolic_method_bindings ?? []) {
118
+ if (binding.assertion_ref !== assertion.key)
119
+ continue;
120
+ const attachmentName = symbolicDesignMethodAttachmentName(target.key, binding.method);
121
+ if (!item.attachment_names.includes(attachmentName))
122
+ continue;
123
+ const record = typedEvidenceAttachment(item.attachment_payloads[attachmentName], "design_method");
124
+ if (record?.capability === "design_method" &&
125
+ "fact_model" in record &&
126
+ record.assertion_key === assertion.key &&
127
+ record.design_target_ref === target.key &&
128
+ record.method === binding.method)
129
+ records.push(record);
130
+ }
131
+ return records;
132
+ }
133
+ function symbolicCertificateEvidenceRecord(target, item, assertion) {
134
+ const binding = target.symbolic_certificate_binding;
135
+ if (binding?.assertion_ref !== assertion.key ||
136
+ !assertion.evidence_capabilities.includes("design_symbolic_certificate"))
137
+ return null;
138
+ const attachmentName = symbolicDesignCertificateAttachmentName(target.key);
139
+ if (!item.attachment_names.includes(attachmentName))
140
+ return null;
141
+ const record = typedEvidenceAttachment(item.attachment_payloads[attachmentName], "design_symbolic_certificate");
142
+ return record?.capability === "design_symbolic_certificate" &&
143
+ record.assertion_key === assertion.key &&
144
+ record.design_target_ref === target.key
145
+ ? record
146
+ : null;
147
+ }
148
+ function typedEvidenceAttachment(payload, capability) {
149
+ if (!payload)
150
+ return null;
151
+ try {
152
+ const records = decodeEvidenceCapabilityRecords([JSON.parse(payload)]);
153
+ const record = records[0];
154
+ return records.length === 1 && record.capability === capability
155
+ ? record
156
+ : null;
157
+ }
158
+ catch {
159
+ return null;
160
+ }
161
+ }
96
162
  function semanticFactRecords(check, item, assertion) {
97
163
  if (!item.executed ||
98
164
  !assertion.evidence_capabilities.includes("semantic_fact"))
@@ -144,3 +210,9 @@ function designFactResultAttachment(content, label) {
144
210
  export function designMethodAttachmentName(target, method, condition, kind) {
145
211
  return `ty-context-design-method:${target}:${method}:${condition}:${kind}`;
146
212
  }
213
+ export function symbolicDesignMethodAttachmentName(target, method) {
214
+ return `ty-context-design-symbolic-method:${target}:${method}:record`;
215
+ }
216
+ export function symbolicDesignCertificateAttachmentName(target) {
217
+ return `ty-context-design-symbolic-certificate:${target}:record`;
218
+ }
@@ -1,2 +1,2 @@
1
1
  import type { CompiledCheckV2, CompiledDesignTargetV2, DeliveryCheckV2, ExecutionTargetV2, SemanticFactExpectationV2, WorkspaceManifestV2 } from "./long-task-delivery-types.js";
2
- export declare function freezeDeliveryCheck(check: DeliveryCheckV2, outcomeKey: string | null, repository: string, baseline: WorkspaceManifestV2, executionTarget: ExecutionTargetV2, knownExecutionTargets: ExecutionTargetV2[], designConformanceTargets: CompiledDesignTargetV2[], semanticFactExpectations: SemanticFactExpectationV2[]): Promise<CompiledCheckV2>;
2
+ export declare function freezeDeliveryCheck(check: DeliveryCheckV2, outcomeKey: string | null, repository: string, baseline: WorkspaceManifestV2, executionTarget: ExecutionTargetV2, knownExecutionTargets: ExecutionTargetV2[], designConformanceTargets: CompiledDesignTargetV2[], semanticFactExpectations: SemanticFactExpectationV2[], protectedAuthorityPaths?: readonly string[]): Promise<CompiledCheckV2>;
@@ -1,19 +1,21 @@
1
1
  import { readFile, stat } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { computeRawExecutionIdentity } from "./long-task-check-execution-policy.js";
4
- import { assertRepositoryPattern, classifyRepositoryPatternOverlap, matchesRepoPattern, } from "./long-task-paths.js";
4
+ import { assertRepositoryPattern, classifyRepositoryPatternOverlap, matchesRepoPattern, normalizeRepositoryFile, } from "./long-task-paths.js";
5
5
  import { assertProtectedRepositoryFile } from "./long-task-protected-files.js";
6
6
  import { nearestRunnerFile, npmCliPath, npxCliPath, } from "./long-task-runner-files.js";
7
7
  import { canonicalValueJson, sha256Hex } from "./strict-codec.js";
8
8
  import { repoRelative, resolveInsideRepository, } from "./long-task-workspace.js";
9
9
  import { evidenceAdapterForRunner } from "./long-task-evidence-adapter-policy.js";
10
10
  import { freezeLocalVerifierDependencyClosure, packageScriptVerifierRoots, } from "./long-task-verifier-dependency-closure.js";
11
- export async function freezeDeliveryCheck(check, outcomeKey, repository, baseline, executionTarget, knownExecutionTargets, designConformanceTargets, semanticFactExpectations) {
11
+ export async function freezeDeliveryCheck(check, outcomeKey, repository, baseline, executionTarget, knownExecutionTargets, designConformanceTargets, semanticFactExpectations, protectedAuthorityPaths = []) {
12
12
  const prefix = outcomeKey ? `CHECK.${outcomeKey}` : "CHECK.GLOBAL";
13
13
  const expectedOutputs = check.expected_output_paths.map((pattern, index) => assertRepositoryPattern(repository, pattern, `${check.key}.expected_output_paths[${index}]`));
14
+ const protectedAuthorityFiles = protectedAuthorityPaths.map((file, index) => normalizeRepositoryFile(file, `${check.key}.protected_authority_paths[${index}]`));
14
15
  for (const [index, pattern] of check.input_paths.entries()) {
15
16
  const normalized = assertRepositoryPattern(repository, pattern, `${check.key}.input_paths[${index}]`);
16
17
  if (!baseline.files.some((file) => matchesRepoPattern(file.path, normalized)) &&
18
+ !protectedAuthorityFiles.some((file) => matchesRepoPattern(file, normalized)) &&
17
19
  !expectedOutputs.some((output) => classifyRepositoryPatternOverlap(output, normalized).status ===
18
20
  "proven_overlap"))
19
21
  throw new Error(`input_path_not_found:${check.key}:${pattern}`);
@@ -42,7 +42,7 @@ export interface ClaimApplicabilityV2 {
42
42
  given_refs: string[];
43
43
  when_refs: string[];
44
44
  }
45
- export type EvidenceCapabilityV2 = "presence" | "interaction_trace" | "state_delta" | "cross_surface_consistency" | "durable_readback" | "boundary_invocation" | "external_side_effect" | "failure_injection" | "visual_render" | "design_conformance" | "design_method" | "semantic_fact" | "target_runtime" | "input_variation";
45
+ export type EvidenceCapabilityV2 = "presence" | "interaction_trace" | "state_delta" | "cross_surface_consistency" | "durable_readback" | "boundary_invocation" | "external_side_effect" | "failure_injection" | "visual_render" | "design_conformance" | "design_method" | "design_symbolic_certificate" | "semantic_fact" | "target_runtime" | "input_variation";
46
46
  export interface CheckExecutionTargetV2 {
47
47
  target_ref: string;
48
48
  entrypoint: "root" | "internal";
@@ -8,11 +8,13 @@ export interface SemanticFactManifestRefV2 {
8
8
  }
9
9
  export interface SemanticFactBindingV2 {
10
10
  fact_ref: string;
11
+ fact_revision_digest?: string;
11
12
  claim_ref: string;
12
13
  applicability_ref: string;
13
14
  }
14
15
  export type SemanticFactProofBindingV2 = {
15
16
  proof_ref: string;
17
+ obligation_revision_digest?: string;
16
18
  fact_ref: string;
17
19
  method: string;
18
20
  proof_surface: ProofSurface;
@@ -22,6 +24,7 @@ export type SemanticFactProofBindingV2 = {
22
24
  assertion_ref: string;
23
25
  } | {
24
26
  proof_ref: string;
27
+ obligation_revision_digest?: string;
25
28
  fact_ref: string;
26
29
  method: string;
27
30
  proof_surface: ProofSurface;
@@ -37,6 +40,11 @@ export interface SemanticFactOutcomeBindingsV2 {
37
40
  export interface SemanticFactExpectationV2 {
38
41
  manifest_ref: string;
39
42
  manifest_sha256: string;
43
+ fact_key: string;
44
+ fact_revision_digest: string;
45
+ obligation_key: string;
46
+ obligation_revision_digest: string;
47
+ revision_identity_required: boolean;
40
48
  fact_ref: string;
41
49
  proof_ref: string;
42
50
  method: string;
@@ -14,7 +14,10 @@ export async function validateLongTaskSemanticFactClosure(contract, repository,
14
14
  await validateSemanticFactInputInventory(repository, sourceItems, contextFiles, manifest, designOwnedSourceItems);
15
15
  validateSemanticFactBasisClosure(manifest, sourceItems);
16
16
  await validateSemanticFactLocatedValues(repository, manifest, sourceItems);
17
- const expectations = validateSemanticFactContractProjection(contract, manifest, index);
17
+ const expectations = validateSemanticFactContractProjection(contract, manifest, index, new Map(parsed.fact_revisions.map((item) => [item.key, item.revision_digest])), new Map(parsed.obligation_revisions.map((item) => [
18
+ item.key,
19
+ item.revision_digest,
20
+ ])), parsed.carrier === "compact_v1");
18
21
  return {
19
22
  manifest,
20
23
  manifest_sha256: parsed.sha256,
@@ -1,4 +1,4 @@
1
1
  import type { DeliveryContractV2 } from "./long-task-delivery-types.js";
2
2
  import type { SemanticFactManifestIndexV1 } from "./semantic-fact-policy.js";
3
3
  import type { SemanticFactExpectationV2, SemanticFactManifestV1 } from "./semantic-fact-types.js";
4
- export declare function validateSemanticFactContractProjection(contract: DeliveryContractV2, manifest: SemanticFactManifestV1, index: SemanticFactManifestIndexV1): Map<string, SemanticFactExpectationV2[]>;
4
+ export declare function validateSemanticFactContractProjection(contract: DeliveryContractV2, manifest: SemanticFactManifestV1, index: SemanticFactManifestIndexV1, factRevisions: Map<string, string>, obligationRevisions: Map<string, string>, sourceRequiresRevisions: boolean): Map<string, SemanticFactExpectationV2[]>;