project-tiny-context-harness 0.8.4 → 0.8.6

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 (254) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +394 -363
  3. package/assets/README.md +570 -514
  4. package/assets/README.zh-CN.md +331 -300
  5. package/assets/agents/.gitkeep +1 -1
  6. package/assets/agents/AGENTS_CORE.md +45 -25
  7. package/assets/context_templates/architecture.md +26 -25
  8. package/assets/context_templates/area.md +32 -31
  9. package/assets/context_templates/context.toml +30 -24
  10. package/assets/context_templates/deployment.md +35 -35
  11. package/assets/context_templates/global.md +57 -57
  12. package/assets/context_templates/product-surface-contract.md +70 -70
  13. package/assets/context_templates/screen-contract.md +189 -189
  14. package/assets/context_templates/verification.md +31 -30
  15. package/assets/github/.gitkeep +1 -1
  16. package/assets/github/harness.yml +39 -39
  17. package/assets/make/.gitkeep +1 -1
  18. package/assets/make/ty-context.mk +48 -48
  19. package/assets/skills/context_development_engineer/SKILL.md +155 -122
  20. package/assets/skills/context_full_project_export/SKILL.md +28 -28
  21. package/assets/skills/context_harness_upgrade/SKILL.md +60 -60
  22. package/assets/skills/context_product_plan/SKILL.md +99 -79
  23. package/assets/skills/context_surface_contract/SKILL.md +191 -191
  24. package/assets/skills/context_uiux_design/SKILL.md +171 -171
  25. package/assets/skills/design-resource-authoring/SKILL.md +86 -84
  26. package/assets/skills/design-resource-authoring/references/downstream-handoff.md +138 -123
  27. package/assets/skills/design-resource-authoring/references/open-design-provider.md +132 -127
  28. package/assets/skills/design-resource-authoring/references/resource-selection.md +181 -154
  29. package/assets/skills/design-system-authoring/SKILL.md +57 -57
  30. package/assets/skills/design-system-authoring/agents/openai.yaml +6 -6
  31. package/assets/skills/design-system-authoring/references/authority-adoption.md +48 -48
  32. package/assets/skills/design-system-authoring/references/open-design-design-system-provider.md +110 -110
  33. package/assets/skills/long-task-workflow/SKILL.md +98 -92
  34. package/assets/skills/long-task-workflow/agents/openai.yaml +3 -1
  35. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +72 -72
  36. package/assets/skills/long-task-workflow/references/contract-authoring.md +122 -101
  37. package/assets/skills/long-task-workflow/references/evidence-design.md +82 -61
  38. package/assets/skills/long-task-workflow/references/source-authoring.md +109 -90
  39. package/assets/skills/source-plan-authoring/SKILL.md +14 -14
  40. package/assets/tools/validate_context.py +442 -442
  41. package/dist/commands/long-task-authoring.js +27 -2
  42. package/dist/lib/context-default-footprint.js +2 -0
  43. package/dist/lib/context-manifest.js +6 -0
  44. package/dist/lib/context-templates.js +1 -1
  45. package/dist/lib/design-resource-fact-enums.d.ts +20 -0
  46. package/dist/lib/design-resource-fact-enums.js +170 -0
  47. package/dist/lib/design-resource-fact-locator-extractors.d.ts +8 -0
  48. package/dist/lib/design-resource-fact-locator-extractors.js +108 -0
  49. package/dist/lib/design-resource-fact-locator-resolver.d.ts +3 -0
  50. package/dist/lib/design-resource-fact-locator-resolver.js +112 -0
  51. package/dist/lib/design-resource-fact-locator-validation.d.ts +5 -0
  52. package/dist/lib/design-resource-fact-locator-validation.js +16 -0
  53. package/dist/lib/design-resource-fact-manifest-catalog.d.ts +4 -0
  54. package/dist/lib/design-resource-fact-manifest-catalog.js +249 -0
  55. package/dist/lib/design-resource-fact-manifest-model.d.ts +91 -0
  56. package/dist/lib/design-resource-fact-manifest-model.js +21 -0
  57. package/dist/lib/design-resource-fact-manifest-shape-axes.d.ts +6 -0
  58. package/dist/lib/design-resource-fact-manifest-shape-axes.js +159 -0
  59. package/dist/lib/design-resource-fact-manifest-shape-evidence.d.ts +4 -0
  60. package/dist/lib/design-resource-fact-manifest-shape-evidence.js +59 -0
  61. package/dist/lib/design-resource-fact-manifest-shape-facts.d.ts +4 -0
  62. package/dist/lib/design-resource-fact-manifest-shape-facts.js +109 -0
  63. package/dist/lib/design-resource-fact-manifest-shape-inspector.d.ts +5 -0
  64. package/dist/lib/design-resource-fact-manifest-shape-inspector.js +144 -0
  65. package/dist/lib/design-resource-fact-manifest-shape.d.ts +7 -0
  66. package/dist/lib/design-resource-fact-manifest-shape.js +75 -0
  67. package/dist/lib/design-resource-fact-manifest-types.d.ts +3 -0
  68. package/dist/lib/design-resource-fact-manifest-types.js +3 -0
  69. package/dist/lib/design-resource-fact-manifest-universe.d.ts +5 -0
  70. package/dist/lib/design-resource-fact-manifest-universe.js +50 -0
  71. package/dist/lib/design-resource-fact-manifest-validation.d.ts +3 -0
  72. package/dist/lib/design-resource-fact-manifest-validation.js +106 -0
  73. package/dist/lib/design-resource-fact-policy.d.ts +18 -0
  74. package/dist/lib/design-resource-fact-policy.js +72 -1
  75. package/dist/lib/design-resource-fact-property-methods.d.ts +3 -0
  76. package/dist/lib/design-resource-fact-property-methods.js +158 -0
  77. package/dist/lib/design-resource-fact-shape-primitives.d.ts +3 -0
  78. package/dist/lib/design-resource-fact-shape-primitives.js +18 -0
  79. package/dist/lib/design-resource-fact-types.d.ts +164 -0
  80. package/dist/lib/design-resource-fact-types.js +1 -0
  81. package/dist/lib/design-resource-fact-universe-assets.d.ts +4 -0
  82. package/dist/lib/design-resource-fact-universe-assets.js +71 -0
  83. package/dist/lib/design-resource-fact-universe-catalog.d.ts +4 -0
  84. package/dist/lib/design-resource-fact-universe-catalog.js +151 -0
  85. package/dist/lib/design-resource-fact-universe-conditions.d.ts +2 -0
  86. package/dist/lib/design-resource-fact-universe-conditions.js +92 -0
  87. package/dist/lib/design-resource-fact-universe-facts.d.ts +4 -0
  88. package/dist/lib/design-resource-fact-universe-facts.js +108 -0
  89. package/dist/lib/design-resource-fact-universe-helpers.d.ts +30 -0
  90. package/dist/lib/design-resource-fact-universe-helpers.js +167 -0
  91. package/dist/lib/design-resource-fact-universe-inspector.d.ts +7 -0
  92. package/dist/lib/design-resource-fact-universe-inspector.js +119 -0
  93. package/dist/lib/design-resource-fact-universe-proof.d.ts +4 -0
  94. package/dist/lib/design-resource-fact-universe-proof.js +113 -0
  95. package/dist/lib/design-resource-fact-universe-subjects.d.ts +5 -0
  96. package/dist/lib/design-resource-fact-universe-subjects.js +97 -0
  97. package/dist/lib/design-resource-fact-universe-variations.d.ts +2 -0
  98. package/dist/lib/design-resource-fact-universe-variations.js +75 -0
  99. package/dist/lib/design-resource-fact-value-validation.d.ts +2 -0
  100. package/dist/lib/design-resource-fact-value-validation.js +80 -0
  101. package/dist/lib/design-resource-handoff-file-primitives.js +2 -0
  102. package/dist/lib/design-resource-handoff-file-validation.js +13 -100
  103. package/dist/lib/design-resource-handoff-policy.d.ts +1 -0
  104. package/dist/lib/design-resource-handoff-policy.js +118 -11
  105. package/dist/lib/design-resource-handoff-shape-evidence.js +46 -3
  106. package/dist/lib/design-resource-handoff-shape-primitives.d.ts +5 -0
  107. package/dist/lib/design-resource-handoff-shape-primitives.js +28 -0
  108. package/dist/lib/design-resource-handoff-shape-structure.js +143 -22
  109. package/dist/lib/design-resource-handoff-shape.js +25 -0
  110. package/dist/lib/design-resource-handoff-types.d.ts +97 -21
  111. package/dist/lib/design-resource-handoff-types.js +22 -0
  112. package/dist/lib/design-resource-handoff-validation-coverage.d.ts +1 -1
  113. package/dist/lib/design-resource-handoff-validation-coverage.js +145 -118
  114. package/dist/lib/design-resource-handoff-validation-fact-cells.d.ts +2 -0
  115. package/dist/lib/design-resource-handoff-validation-fact-cells.js +60 -0
  116. package/dist/lib/design-resource-handoff-validation-fact-records.d.ts +2 -0
  117. package/dist/lib/design-resource-handoff-validation-fact-records.js +90 -0
  118. package/dist/lib/design-resource-handoff-validation-facts.js +10 -94
  119. package/dist/lib/design-resource-handoff-validation-proofs.d.ts +2 -0
  120. package/dist/lib/design-resource-handoff-validation-proofs.js +67 -0
  121. package/dist/lib/design-resource-handoff-validation-resource-closure.d.ts +3 -0
  122. package/dist/lib/design-resource-handoff-validation-resource-closure.js +88 -0
  123. package/dist/lib/design-resource-handoff-validation-structure.js +43 -14
  124. package/dist/lib/design-resource-handoff-validation.js +32 -0
  125. package/dist/lib/design-resource-handoff-web-dependency-validation.d.ts +2 -1
  126. package/dist/lib/design-resource-handoff-web-dependency-validation.js +67 -7
  127. package/dist/lib/execution-target-capabilities.d.ts +1 -1
  128. package/dist/lib/execution-target-capabilities.js +14 -0
  129. package/dist/lib/long-task-activation-validation.js +6 -2
  130. package/dist/lib/long-task-applicability-shape.js +3 -3
  131. package/dist/lib/long-task-authoring-authority-preview.js +1 -0
  132. package/dist/lib/long-task-authority-policy.d.ts +1 -0
  133. package/dist/lib/long-task-authority-policy.js +1 -0
  134. package/dist/lib/long-task-authority.js +13 -0
  135. package/dist/lib/long-task-claim-definitions.js +13 -1
  136. package/dist/lib/long-task-claims.js +23 -1
  137. package/dist/lib/long-task-contract-types.d.ts +3 -0
  138. package/dist/lib/long-task-delivery-compiler.js +1 -0
  139. package/dist/lib/long-task-delivery-parser.js +11 -1
  140. package/dist/lib/long-task-delivery-types.d.ts +1 -0
  141. package/dist/lib/long-task-delivery-types.js +1 -0
  142. package/dist/lib/long-task-delivery-validation.js +17 -0
  143. package/dist/lib/long-task-design-resource-handoff.js +62 -38
  144. package/dist/lib/long-task-design-target-capabilities.d.ts +14 -0
  145. package/dist/lib/long-task-design-target-capabilities.js +126 -0
  146. package/dist/lib/long-task-evidence-capability-codec.d.ts +94 -0
  147. package/dist/lib/long-task-evidence-capability-codec.js +395 -22
  148. package/dist/lib/long-task-evidence-capability-policy.js +18 -0
  149. package/dist/lib/long-task-evidence-capability-runtime.js +78 -0
  150. package/dist/lib/long-task-evidence-capability-types.d.ts +114 -1
  151. package/dist/lib/long-task-outcome-parser.js +4 -0
  152. package/dist/lib/long-task-playwright-capability-records.d.ts +5 -0
  153. package/dist/lib/long-task-playwright-capability-records.js +146 -0
  154. package/dist/lib/long-task-playwright-case-evidence.d.ts +3 -2
  155. package/dist/lib/long-task-playwright-case-evidence.js +10 -79
  156. package/dist/lib/long-task-playwright-case-primitives.d.ts +28 -0
  157. package/dist/lib/long-task-playwright-case-primitives.js +143 -0
  158. package/dist/lib/long-task-playwright-evidence.d.ts +1 -1
  159. package/dist/lib/long-task-playwright-evidence.js +10 -75
  160. package/dist/lib/long-task-runner-freeze.d.ts +2 -2
  161. package/dist/lib/long-task-runner-freeze.js +15 -1
  162. package/dist/lib/long-task-runtime-types.d.ts +4 -1
  163. package/dist/lib/long-task-semantic-contract-types.d.ts +1 -1
  164. package/dist/lib/long-task-semantic-drift-migration.js +2 -2
  165. package/dist/lib/long-task-semantic-fact-binding-types.d.ts +57 -0
  166. package/dist/lib/long-task-semantic-fact-binding-types.js +1 -0
  167. package/dist/lib/long-task-semantic-fact-closure-primitives.d.ts +5 -0
  168. package/dist/lib/long-task-semantic-fact-closure-primitives.js +43 -0
  169. package/dist/lib/long-task-semantic-fact-closure.d.ts +13 -0
  170. package/dist/lib/long-task-semantic-fact-closure.js +48 -0
  171. package/dist/lib/long-task-semantic-fact-contract-closure.d.ts +4 -0
  172. package/dist/lib/long-task-semantic-fact-contract-closure.js +24 -0
  173. package/dist/lib/long-task-semantic-fact-contract-facts.d.ts +4 -0
  174. package/dist/lib/long-task-semantic-fact-contract-facts.js +30 -0
  175. package/dist/lib/long-task-semantic-fact-contract-proofs.d.ts +4 -0
  176. package/dist/lib/long-task-semantic-fact-contract-proofs.js +97 -0
  177. package/dist/lib/long-task-semantic-fact-evidence.d.ts +21 -0
  178. package/dist/lib/long-task-semantic-fact-evidence.js +165 -0
  179. package/dist/lib/long-task-semantic-fact-input-closure.d.ts +4 -0
  180. package/dist/lib/long-task-semantic-fact-input-closure.js +101 -0
  181. package/dist/lib/long-task-semantic-fact-provenance-closure.d.ts +4 -0
  182. package/dist/lib/long-task-semantic-fact-provenance-closure.js +140 -0
  183. package/dist/lib/long-task-semantic-fact-shape.d.ts +3 -0
  184. package/dist/lib/long-task-semantic-fact-shape.js +89 -0
  185. package/dist/lib/long-task-semantic-fact-value-closure.d.ts +3 -0
  186. package/dist/lib/long-task-semantic-fact-value-closure.js +110 -0
  187. package/dist/lib/long-task-shape-primitives.d.ts +2 -1
  188. package/dist/lib/long-task-shape-primitives.js +7 -0
  189. package/dist/lib/long-task-source-item-parser.js +25 -6
  190. package/dist/lib/long-task-source-target-continuity.js +4 -1
  191. package/dist/lib/long-task-source-target-index.d.ts +1 -1
  192. package/dist/lib/long-task-source-target-index.js +5 -1
  193. package/dist/lib/long-task-ui-design-policy.js +8 -4
  194. package/dist/lib/long-task-ui-surface-shape.js +83 -1
  195. package/dist/lib/long-task-ui-surface-types.d.ts +29 -0
  196. package/dist/lib/modularity.js +7 -1
  197. package/dist/lib/semantic-fact-base-types.d.ts +14 -0
  198. package/dist/lib/semantic-fact-base-types.js +1 -0
  199. package/dist/lib/semantic-fact-catalog.d.ts +8 -0
  200. package/dist/lib/semantic-fact-catalog.js +191 -0
  201. package/dist/lib/semantic-fact-condition-shape.d.ts +48 -0
  202. package/dist/lib/semantic-fact-condition-shape.js +111 -0
  203. package/dist/lib/semantic-fact-input-shape.d.ts +34 -0
  204. package/dist/lib/semantic-fact-input-shape.js +111 -0
  205. package/dist/lib/semantic-fact-inventory-types.d.ts +147 -0
  206. package/dist/lib/semantic-fact-inventory-types.js +1 -0
  207. package/dist/lib/semantic-fact-manifest-shape.d.ts +4 -0
  208. package/dist/lib/semantic-fact-manifest-shape.js +135 -0
  209. package/dist/lib/semantic-fact-manifest-types.d.ts +58 -0
  210. package/dist/lib/semantic-fact-manifest-types.js +19 -0
  211. package/dist/lib/semantic-fact-policy-authority.d.ts +8 -0
  212. package/dist/lib/semantic-fact-policy-authority.js +79 -0
  213. package/dist/lib/semantic-fact-policy-census.d.ts +2 -0
  214. package/dist/lib/semantic-fact-policy-census.js +80 -0
  215. package/dist/lib/semantic-fact-policy-condition-references.d.ts +7 -0
  216. package/dist/lib/semantic-fact-policy-condition-references.js +19 -0
  217. package/dist/lib/semantic-fact-policy-conditions.d.ts +2 -0
  218. package/dist/lib/semantic-fact-policy-conditions.js +105 -0
  219. package/dist/lib/semantic-fact-policy-facts.d.ts +3 -0
  220. package/dist/lib/semantic-fact-policy-facts.js +73 -0
  221. package/dist/lib/semantic-fact-policy-primitives.d.ts +26 -0
  222. package/dist/lib/semantic-fact-policy-primitives.js +169 -0
  223. package/dist/lib/semantic-fact-policy-proofs.d.ts +2 -0
  224. package/dist/lib/semantic-fact-policy-proofs.js +75 -0
  225. package/dist/lib/semantic-fact-policy-properties.d.ts +3 -0
  226. package/dist/lib/semantic-fact-policy-properties.js +84 -0
  227. package/dist/lib/semantic-fact-policy-units.d.ts +4 -0
  228. package/dist/lib/semantic-fact-policy-units.js +103 -0
  229. package/dist/lib/semantic-fact-policy.d.ts +17 -0
  230. package/dist/lib/semantic-fact-policy.js +41 -0
  231. package/dist/lib/semantic-fact-proof-shape.d.ts +51 -0
  232. package/dist/lib/semantic-fact-proof-shape.js +121 -0
  233. package/dist/lib/semantic-fact-proof-types.d.ts +74 -0
  234. package/dist/lib/semantic-fact-proof-types.js +1 -0
  235. package/dist/lib/semantic-fact-property-shape.d.ts +29 -0
  236. package/dist/lib/semantic-fact-property-shape.js +77 -0
  237. package/dist/lib/semantic-fact-shape-constants.d.ts +3 -0
  238. package/dist/lib/semantic-fact-shape-constants.js +38 -0
  239. package/dist/lib/semantic-fact-shape-primitives.d.ts +15 -0
  240. package/dist/lib/semantic-fact-shape-primitives.js +68 -0
  241. package/dist/lib/semantic-fact-source-parser.d.ts +9 -0
  242. package/dist/lib/semantic-fact-source-parser.js +46 -0
  243. package/dist/lib/semantic-fact-support-shape.d.ts +21 -0
  244. package/dist/lib/semantic-fact-support-shape.js +59 -0
  245. package/dist/lib/semantic-fact-types.d.ts +5 -0
  246. package/dist/lib/semantic-fact-types.js +5 -0
  247. package/dist/lib/semantic-fact-unit-shape.d.ts +34 -0
  248. package/dist/lib/semantic-fact-unit-shape.js +89 -0
  249. package/dist/lib/semantic-fact-value-shape.d.ts +12 -0
  250. package/dist/lib/semantic-fact-value-shape.js +39 -0
  251. package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +1339 -131
  252. package/migrations/README.md +15 -15
  253. package/package.json +84 -84
  254. package/source-mappings.yaml +25 -25
@@ -0,0 +1,67 @@
1
+ import { designFactComparatorSupportsMethod, designFactEvidenceSupportsMethod, designFactMethodIsCompatible, designFactOracleSupportsMethod, } from "./design-resource-fact-policy.js";
2
+ import { invalidDesignResourceHandoff, requireKnownDesignResourceRef, requireUniqueDesignResourceValues, } from "./design-resource-handoff-validation-primitives.js";
3
+ export function validateDesignResourceProofObligations(handoff, resources, targets, evidence) {
4
+ const facts = new Map(handoff.facts.map((item) => [item.key, item]));
5
+ const oracles = new Map(handoff.oracles.map((item) => [item.key, item]));
6
+ const environments = new Map(handoff.environments.map((item) => [item.key, item]));
7
+ const proofByFact = new Map();
8
+ const factMethodPairs = [];
9
+ for (const proof of handoff.proof_obligations) {
10
+ validateProofReferences(proof, facts, oracles, environments);
11
+ validateProofMethod(proof, facts.get(proof.fact_ref), oracles.get(proof.oracle_ref), evidence);
12
+ validateProofResources(proof, facts.get(proof.fact_ref), environments, resources, targets);
13
+ validateProofComparison(proof);
14
+ proofByFact.set(proof.fact_ref, (proofByFact.get(proof.fact_ref) ?? 0) + 1);
15
+ factMethodPairs.push(`${proof.fact_ref}\0${proof.method}`);
16
+ }
17
+ requireUniqueDesignResourceValues(factMethodPairs, "fact_verification_method_obligation_duplicate");
18
+ for (const fact of handoff.facts)
19
+ if (!proofByFact.has(fact.key))
20
+ invalidDesignResourceHandoff("fact_verification_method_required", fact.key);
21
+ for (const environment of handoff.environments)
22
+ requireKnownDesignResourceRef(resources, environment.definition.locator.resource_ref, "environment_resource");
23
+ }
24
+ function validateProofReferences(proof, facts, oracles, environments) {
25
+ requireKnownDesignResourceRef(facts, proof.fact_ref, "proof_fact");
26
+ requireKnownDesignResourceRef(oracles, proof.oracle_ref, "proof_oracle");
27
+ requireKnownDesignResourceRef(environments, proof.environment_ref, "proof_environment");
28
+ }
29
+ function validateProofMethod(proof, fact, oracle, evidence) {
30
+ if (!designFactMethodIsCompatible(fact.dimension, proof.method))
31
+ invalidDesignResourceHandoff("proof_verification_method_incompatible", `${proof.key}:${fact.dimension}:${proof.method}`);
32
+ if (!fact.evidence_refs.some((ref) => designFactEvidenceSupportsMethod(proof.method, evidence.get(ref).kind)))
33
+ invalidDesignResourceHandoff("proof_method_evidence_missing", `${proof.key}:${proof.fact_ref}:${proof.method}`);
34
+ if (!designFactComparatorSupportsMethod(proof.method, proof.comparison.comparator))
35
+ invalidDesignResourceHandoff("proof_comparator_method_incompatible", `${proof.key}:${proof.method}:${proof.comparison.comparator}`);
36
+ if (!designFactOracleSupportsMethod(proof.method, oracle.capability_refs))
37
+ invalidDesignResourceHandoff("proof_oracle_capability_missing", `${proof.key}:${proof.oracle_ref}:${proof.method}`);
38
+ }
39
+ function validateProofResources(proof, fact, environments, resources, targets) {
40
+ const target = targets.get(fact.target_ref);
41
+ const environmentResourceRef = environments.get(proof.environment_ref)
42
+ .definition.locator.resource_ref;
43
+ if (!target.resource_refs.includes(environmentResourceRef))
44
+ invalidDesignResourceHandoff("proof_environment_outside_target", `${proof.key}:${proof.environment_ref}:${environmentResourceRef}`);
45
+ for (const located of [
46
+ proof.comparison.parameters,
47
+ proof.comparison.tolerance,
48
+ proof.comparison.mask,
49
+ ])
50
+ if (located) {
51
+ requireKnownDesignResourceRef(resources, located.locator.resource_ref, "proof_resource");
52
+ if (!target.resource_refs.includes(located.locator.resource_ref))
53
+ invalidDesignResourceHandoff("proof_resource_outside_target", `${proof.key}:${located.locator.resource_ref}`);
54
+ }
55
+ }
56
+ function validateProofComparison(proof) {
57
+ if (proof.comparison.mode === "exact" &&
58
+ (proof.comparison.tolerance !== null || proof.comparison.mask !== null))
59
+ invalidDesignResourceHandoff("proof_exact_tolerance_forbidden", proof.key);
60
+ if (proof.comparison.mode === "tolerance" &&
61
+ proof.comparison.tolerance === null)
62
+ invalidDesignResourceHandoff("proof_tolerance_required", proof.key);
63
+ if (proof.comparison.mask !== null &&
64
+ proof.comparison.comparator !== "pixel_diff" &&
65
+ !proof.comparison.comparator.startsWith("custom."))
66
+ invalidDesignResourceHandoff("proof_mask_comparator_incompatible", `${proof.key}:${proof.comparison.comparator}`);
67
+ }
@@ -0,0 +1,3 @@
1
+ import type { DesignResourceHandoffV1 } from "./design-resource-handoff-types.js";
2
+ export declare function validateDesignResourceExactTargetFacts(handoff: DesignResourceHandoffV1): void;
3
+ export declare function validateDesignResourceResourceFactClosure(handoff: DesignResourceHandoffV1, resources: Map<string, DesignResourceHandoffV1["resources"][number]>, evidence: Map<string, DesignResourceHandoffV1["evidence"][number]>): void;
@@ -0,0 +1,88 @@
1
+ import { EXACT_TARGET_FULL_TARGET_METHODS } from "./design-resource-fact-policy.js";
2
+ import { invalidDesignResourceHandoff, requireKnownDesignResourceRef, requireUniqueDesignResourceValues, } from "./design-resource-handoff-validation-primitives.js";
3
+ export function validateDesignResourceExactTargetFacts(handoff) {
4
+ const proofsByFact = new Map();
5
+ for (const proof of handoff.proof_obligations) {
6
+ const methods = proofsByFact.get(proof.fact_ref) ?? [];
7
+ methods.push(proof.method);
8
+ proofsByFact.set(proof.fact_ref, methods);
9
+ }
10
+ for (const target of handoff.targets) {
11
+ if (target.interpretation !== "exact_target")
12
+ continue;
13
+ for (const conditionRef of target.condition_refs)
14
+ for (const method of EXACT_TARGET_FULL_TARGET_METHODS)
15
+ if (!hasExactTargetFact(handoff, target.key, conditionRef, method, proofsByFact))
16
+ invalidDesignResourceHandoff("exact_target_full_target_fact_missing", `${target.key}:${conditionRef}:${method}`);
17
+ }
18
+ }
19
+ function hasExactTargetFact(handoff, targetRef, conditionRef, method, proofsByFact) {
20
+ return handoff.facts.some((fact) => fact.target_ref === targetRef &&
21
+ fact.condition_ref === conditionRef &&
22
+ fact.observation_scope === "full_target" &&
23
+ (proofsByFact.get(fact.key) ?? []).includes(method));
24
+ }
25
+ export function validateDesignResourceResourceFactClosure(handoff, resources, evidence) {
26
+ const lineageNodes = new Map(handoff.lineage_nodes.map((item) => [item.key, item]));
27
+ const proofsByFact = new Map(handoff.facts.map((fact) => [
28
+ fact.key,
29
+ handoff.proof_obligations.filter((proof) => proof.fact_ref === fact.key),
30
+ ]));
31
+ const environments = new Map(handoff.environments.map((environment) => [environment.key, environment]));
32
+ const closuresByResource = new Map();
33
+ for (const closure of handoff.resource_fact_closure) {
34
+ validateResourceClosure(closure, handoff, resources, evidence, lineageNodes, proofsByFact, environments);
35
+ if (closuresByResource.has(closure.resource_ref))
36
+ invalidDesignResourceHandoff("resource_fact_closure_duplicate", closure.resource_ref);
37
+ closuresByResource.set(closure.resource_ref, closure.key);
38
+ }
39
+ for (const resource of handoff.resources)
40
+ if (!closuresByResource.has(resource.key))
41
+ invalidDesignResourceHandoff("resource_fact_closure_missing", resource.key);
42
+ }
43
+ function validateResourceClosure(closure, handoff, resources, evidence, lineageNodes, proofsByFact, environments) {
44
+ requireKnownDesignResourceRef(resources, closure.resource_ref, "resource_fact_closure_resource");
45
+ requireUniqueDesignResourceValues(closure.fact_refs, `resource_fact_closure_fact_ref_duplicate:${closure.key}`);
46
+ const expected = handoff.facts
47
+ .filter((fact) => factUsesResource(fact, closure.resource_ref, proofsByFact.get(fact.key) ?? [], environments, lineageNodes, evidence))
48
+ .map((fact) => fact.key);
49
+ for (const factRef of closure.fact_refs)
50
+ if (!handoff.facts.some((fact) => fact.key === factRef))
51
+ invalidDesignResourceHandoff("resource_fact_closure_fact_unknown", `${closure.key}:${factRef}`);
52
+ assertSameSet(closure.fact_refs, expected, "resource_fact_closure_mismatch", closure.resource_ref);
53
+ validateClosureDisposition(closure, resources.get(closure.resource_ref));
54
+ }
55
+ function factUsesResource(fact, resourceRef, proofs, environments, lineageNodes, evidence) {
56
+ const proofResources = proofs.flatMap((proof) => [
57
+ proof.comparison.parameters.locator.resource_ref,
58
+ proof.comparison.tolerance?.locator.resource_ref,
59
+ proof.comparison.mask?.locator.resource_ref,
60
+ environments.get(proof.environment_ref)?.definition.locator.resource_ref,
61
+ ]);
62
+ const lineageResources = [
63
+ ...fact.lineage.token_chain_refs,
64
+ ...fact.lineage.override_chain_refs,
65
+ ].map((ref) => lineageNodes.get(ref)?.value.locator.resource_ref);
66
+ return (fact.value.locator.resource_ref === resourceRef ||
67
+ fact.lineage.resolved_value.locator.resource_ref === resourceRef ||
68
+ lineageResources.includes(resourceRef) ||
69
+ proofResources.includes(resourceRef) ||
70
+ fact.evidence_refs.some((evidenceRef) => evidence.get(evidenceRef)?.resource_ref === resourceRef));
71
+ }
72
+ function validateClosureDisposition(closure, resource) {
73
+ if (closure.disposition === "material_with_facts" &&
74
+ closure.fact_refs.length === 0)
75
+ invalidDesignResourceHandoff("resource_fact_closure_facts_required", closure.key);
76
+ if (closure.disposition === "supporting_only" && closure.fact_refs.length > 0)
77
+ invalidDesignResourceHandoff("supporting_only_resource_fact_forbidden", closure.key);
78
+ if (resource.role !== "supporting" &&
79
+ closure.disposition !== "material_with_facts")
80
+ invalidDesignResourceHandoff("target_resource_fact_closure_required", `${closure.key}:${resource.role}`);
81
+ }
82
+ function assertSameSet(actual, expected, code, detail) {
83
+ const left = [...new Set(actual)].sort();
84
+ const right = [...new Set(expected)].sort();
85
+ if (left.length !== right.length ||
86
+ left.some((item, index) => item !== right[index]))
87
+ invalidDesignResourceHandoff(code, `${detail}:${left.join(",")}:${right.join(",")}`);
88
+ }
@@ -1,29 +1,38 @@
1
1
  import { invalidDesignResourceHandoff, requireKnownDesignResourceRef, requireNonemptyDesignResourceValues, requireUniqueDesignResourceValues, } from "./design-resource-handoff-validation-primitives.js";
2
2
  export function validateDesignResourceScope(handoff) {
3
- const surfaceStableKeys = new Set(handoff.subjects
4
- .filter((subject) => subject.kind === "surface")
5
- .flatMap((subject) => subject.stable_keys));
3
+ const scopedSurfaceKeys = new Set(handoff.scope.surface_keys);
4
+ const surfaceSubjects = handoff.subjects.filter((subject) => subject.kind === "surface");
5
+ const surfaceStableKeys = new Set(surfaceSubjects.flatMap((subject) => subject.stable_keys));
6
6
  for (const surfaceKey of handoff.scope.surface_keys)
7
7
  if (!surfaceStableKeys.has(surfaceKey))
8
8
  invalidDesignResourceHandoff("scope_surface_subject_missing", surfaceKey);
9
+ for (const subject of surfaceSubjects)
10
+ if (!subject.stable_keys.some((key) => scopedSurfaceKeys.has(key)))
11
+ invalidDesignResourceHandoff("scope_surface_subject_outside_scope", subject.key);
9
12
  }
10
13
  export function validateDesignResourceConditions(handoff) {
14
+ const viewportProfiles = new Map();
15
+ const densityProfiles = new Map();
16
+ const safeAreaProfiles = new Map();
17
+ const textScaleProfiles = new Map();
11
18
  for (const condition of handoff.conditions) {
12
- for (const [name, values] of [
13
- ["modes", condition.modes],
14
- ["states", condition.states],
15
- ["content_cases", condition.content_cases],
16
- ["input_methods", condition.input_methods],
17
- ]) {
18
- requireNonemptyDesignResourceValues(values, `condition_${name}_required:${condition.key}`);
19
- requireUniqueDesignResourceValues(values, `condition_${name}_duplicate:${condition.key}`);
20
- if (values.length !== 1)
21
- invalidDesignResourceHandoff(`condition_${name}_must_be_atomic`, condition.key);
22
- }
19
+ requireConsistentConditionProfile(viewportProfiles, condition.viewport.key, `${condition.viewport.width}\0${condition.viewport.height}\0${condition.viewport.unit}`, "viewport", condition.key);
20
+ requireConsistentConditionProfile(densityProfiles, condition.density.key, String(condition.density.pixel_ratio), "density", condition.key);
21
+ requireConsistentConditionProfile(safeAreaProfiles, condition.safe_area.key, `${condition.safe_area.top}\0${condition.safe_area.right}\0${condition.safe_area.bottom}\0${condition.safe_area.left}\0${condition.safe_area.unit}`, "safe_area", condition.key);
22
+ requireConsistentConditionProfile(textScaleProfiles, condition.text_scale.key, String(condition.text_scale.multiplier), "text_scale", condition.key);
23
+ requireUniqueDesignResourceValues(condition.custom_axes.map((item) => item.axis_ref), `condition_custom_axis_duplicate:${condition.key}`);
24
+ requireUniqueDesignResourceValues(condition.custom_axes.map((item) => `${item.axis_ref}\0${item.value_ref}`), `condition_custom_axis_value_duplicate:${condition.key}`);
23
25
  }
24
26
  }
27
+ function requireConsistentConditionProfile(profiles, key, definition, profileKind, conditionKey) {
28
+ const existing = profiles.get(key);
29
+ if (existing !== undefined && existing !== definition)
30
+ invalidDesignResourceHandoff(`condition_${profileKind}_profile_conflict`, `${key}:${conditionKey}`);
31
+ profiles.set(key, definition);
32
+ }
25
33
  export function validateDesignResourceSubjects(handoff, targets) {
26
34
  const stableKeys = new Set();
35
+ const subjects = new Map(handoff.subjects.map((subject) => [subject.key, subject]));
27
36
  for (const subject of handoff.subjects) {
28
37
  requireNonemptyDesignResourceValues(subject.stable_keys, `subject_stable_keys_required:${subject.key}`);
29
38
  requireUniqueDesignResourceValues(subject.stable_keys, `subject_stable_key_duplicate:${subject.key}`);
@@ -36,6 +45,23 @@ export function validateDesignResourceSubjects(handoff, targets) {
36
45
  invalidDesignResourceHandoff("subject_stable_key_ambiguous", stableKey);
37
46
  stableKeys.add(stableKey);
38
47
  }
48
+ for (const ref of [
49
+ subject.parent_ref,
50
+ subject.instance_of_ref,
51
+ subject.override_of_ref,
52
+ subject.family_ref,
53
+ subject.portal_host_ref,
54
+ ])
55
+ if (ref !== null && !subjects.has(ref))
56
+ invalidDesignResourceHandoff("subject_hierarchy_ref_unknown", `${subject.key}:${ref}`);
57
+ requireUniqueDesignResourceValues(subject.census_refs, `subject_census_ref_duplicate:${subject.key}`);
58
+ requireUniqueDesignResourceValues(subject.relation_endpoints.map((item) => item.role), `subject_relation_endpoint_role_duplicate:${subject.key}`);
59
+ if (subject.presence === "always" && subject.presence_rule_ref !== null)
60
+ invalidDesignResourceHandoff("subject_always_presence_rule_forbidden", subject.key);
61
+ if (subject.presence !== "always" && subject.presence_rule_ref === null)
62
+ invalidDesignResourceHandoff("subject_dynamic_presence_rule_required", subject.key);
63
+ if (subject.presence === "virtualized" && subject.population_ref === null)
64
+ invalidDesignResourceHandoff("subject_virtualized_population_required", subject.key);
39
65
  }
40
66
  }
41
67
  export function validateDesignResourceTargets(handoff, resources, conditions) {
@@ -60,6 +86,9 @@ function validateTargetSourceProfile(target, resources) {
60
86
  requireUniqueDesignResourceValues(profile.dependency_resource_refs, `source_profile_dependency_resource_ref_duplicate:${target.key}`);
61
87
  for (const ref of profile.dependency_resource_refs)
62
88
  requireKnownDesignResourceRef(resources, ref, "source_profile_dependency_resource");
89
+ requireKnownDesignResourceRef(resources, profile.fact_manifest_resource_ref, "source_profile_fact_manifest_resource");
90
+ if (!profile.dependency_resource_refs.includes(profile.fact_manifest_resource_ref))
91
+ invalidDesignResourceHandoff("source_profile_fact_manifest_dependency_missing", target.key);
63
92
  if (profile.dependency_resource_refs.includes(profile.entry_resource_ref))
64
93
  invalidDesignResourceHandoff("source_profile_entry_repeated_as_dependency", target.key);
65
94
  const declared = [
@@ -2,6 +2,7 @@ import { readFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { parseDesignResourceHandoffMarkdown } from "./design-resource-handoff-parser.js";
4
4
  import { validateDesignResourceFiles } from "./design-resource-handoff-file-validation.js";
5
+ import { loadAndValidateDesignResourceFactManifests } from "./design-resource-fact-manifest-validation.js";
5
6
  import { validateDesignResourceFacts } from "./design-resource-handoff-validation-facts.js";
6
7
  import { validateDesignResourceBlockers, validateDesignResourceCoverage, validateDesignResourceReachability, } from "./design-resource-handoff-validation-coverage.js";
7
8
  import { indexDesignResourceItems, invalidDesignResourceHandoff, requireNonemptyDesignResourceValues, requireUniqueDesignResourceObjects, requireUniqueDesignResourceValues, } from "./design-resource-handoff-validation-primitives.js";
@@ -14,6 +15,7 @@ export async function preflightDesignResourceHandoff(repository, handoffPath) {
14
15
  validateDesignResourceHandoffSemantics(parsed);
15
16
  const resourceHashes = await validateResourceIntegrity(repository, parsed);
16
17
  await validateDesignResourceFiles(repository, parsed);
18
+ const manifests = await loadAndValidateDesignResourceFactManifests(repository, parsed);
17
19
  const handoff = parsed.handoff;
18
20
  return {
19
21
  schema_version: "design-resource-handoff-preflight-v1",
@@ -22,11 +24,21 @@ export async function preflightDesignResourceHandoff(repository, handoffPath) {
22
24
  resource_hashes: resourceHashes,
23
25
  counts: {
24
26
  resources: handoff.resources.length,
27
+ manifests: manifests.size,
28
+ axis_dispositions: handoff.axis_dispositions.length,
25
29
  conditions: handoff.conditions.length,
26
30
  subjects: handoff.subjects.length,
31
+ variations: handoff.variations.length,
32
+ properties: handoff.properties.length,
33
+ lineage_nodes: handoff.lineage_nodes.length,
27
34
  targets: handoff.targets.length,
28
35
  evidence: handoff.evidence.length,
36
+ fact_cells: handoff.fact_cells.length,
29
37
  facts: handoff.facts.length,
38
+ proof_obligations: handoff.proof_obligations.length,
39
+ oracles: handoff.oracles.length,
40
+ environments: handoff.environments.length,
41
+ asset_bindings: handoff.asset_bindings.length,
30
42
  resource_fact_closure: handoff.resource_fact_closure.length,
31
43
  coverage: handoff.coverage.length,
32
44
  acceptance_blockers: handoff.acceptance_blockers.length,
@@ -37,21 +49,41 @@ export function validateDesignResourceHandoffSemantics(parsed) {
37
49
  const { handoff } = parsed;
38
50
  requireNonemptyDesignResourceValues(handoff.scope.surface_keys, "scope_surface_keys_required");
39
51
  requireNonemptyDesignResourceValues(handoff.resources, "resources_required");
52
+ requireNonemptyDesignResourceValues(handoff.axis_dispositions, "axis_dispositions_required");
40
53
  requireNonemptyDesignResourceValues(handoff.conditions, "conditions_required");
41
54
  requireNonemptyDesignResourceValues(handoff.subjects, "subjects_required");
55
+ requireNonemptyDesignResourceValues(handoff.variation_axis_dispositions, "variation_axis_dispositions_required");
56
+ requireNonemptyDesignResourceValues(handoff.variations, "variations_required");
57
+ requireNonemptyDesignResourceValues(handoff.properties, "properties_required");
42
58
  requireNonemptyDesignResourceValues(handoff.targets, "targets_required");
43
59
  requireNonemptyDesignResourceValues(handoff.evidence, "evidence_required");
60
+ requireNonemptyDesignResourceValues(handoff.fact_cells, "fact_cells_required");
44
61
  requireNonemptyDesignResourceValues(handoff.facts, "facts_required");
62
+ requireNonemptyDesignResourceValues(handoff.proof_obligations, "proof_obligations_required");
63
+ requireNonemptyDesignResourceValues(handoff.oracles, "oracles_required");
64
+ requireNonemptyDesignResourceValues(handoff.environments, "environments_required");
45
65
  requireNonemptyDesignResourceValues(handoff.resource_fact_closure, "resource_fact_closure_required");
46
66
  requireNonemptyDesignResourceValues(handoff.coverage, "coverage_required");
47
67
  requireUniqueDesignResourceValues(handoff.scope.surface_keys, "scope_surface_key_duplicate");
48
68
  requireUniqueDesignResourceObjects(handoff.resources, "resource_key_duplicate");
49
69
  requireUniqueDesignResourceValues(handoff.resources.map((item) => item.path), "resource_path_duplicate");
70
+ requireUniqueDesignResourceObjects(handoff.axis_dispositions, "axis_disposition_key_duplicate");
71
+ requireUniqueDesignResourceObjects(handoff.condition_exclusions, "condition_exclusion_key_duplicate");
50
72
  requireUniqueDesignResourceObjects(handoff.conditions, "condition_key_duplicate");
51
73
  requireUniqueDesignResourceObjects(handoff.subjects, "subject_key_duplicate");
74
+ requireUniqueDesignResourceObjects(handoff.variation_axis_dispositions, "variation_axis_disposition_key_duplicate");
75
+ requireUniqueDesignResourceObjects(handoff.variation_exclusions, "variation_exclusion_key_duplicate");
76
+ requireUniqueDesignResourceObjects(handoff.variations, "variation_key_duplicate");
77
+ requireUniqueDesignResourceObjects(handoff.properties, "property_key_duplicate");
78
+ requireUniqueDesignResourceObjects(handoff.lineage_nodes, "lineage_node_key_duplicate");
52
79
  requireUniqueDesignResourceObjects(handoff.targets, "target_key_duplicate");
53
80
  requireUniqueDesignResourceObjects(handoff.evidence, "evidence_key_duplicate");
54
81
  requireUniqueDesignResourceObjects(handoff.facts, "fact_key_duplicate");
82
+ requireUniqueDesignResourceObjects(handoff.fact_cells, "fact_cell_key_duplicate");
83
+ requireUniqueDesignResourceObjects(handoff.proof_obligations, "proof_obligation_key_duplicate");
84
+ requireUniqueDesignResourceObjects(handoff.oracles, "oracle_key_duplicate");
85
+ requireUniqueDesignResourceObjects(handoff.environments, "environment_key_duplicate");
86
+ requireUniqueDesignResourceObjects(handoff.asset_bindings, "asset_binding_key_duplicate");
55
87
  requireUniqueDesignResourceObjects(handoff.resource_fact_closure, "resource_fact_closure_key_duplicate");
56
88
  requireUniqueDesignResourceObjects(handoff.coverage, "coverage_key_duplicate");
57
89
  requireUniqueDesignResourceObjects(handoff.acceptance_blockers, "acceptance_blocker_key_duplicate");
@@ -1,3 +1,4 @@
1
1
  import type { ParsedDesignResourceHandoffV1 } from "./design-resource-handoff-types.js";
2
2
  import { type DesignResource } from "./design-resource-handoff-file-primitives.js";
3
- export declare function validateDesignResourceWebDependencyClosure(target: ParsedDesignResourceHandoffV1["handoff"]["targets"][number], resources: Map<string, DesignResource>, contents: Map<string, Buffer>): void;
3
+ export declare function validateDesignResourceImplementationDependencyClosure(target: ParsedDesignResourceHandoffV1["handoff"]["targets"][number], resources: Map<string, DesignResource>, contents: Map<string, Buffer>): void;
4
+ export declare const validateDesignResourceWebDependencyClosure: typeof validateDesignResourceImplementationDependencyClosure;
@@ -1,7 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { htmlAttributes, isTextResource, } from "./design-resource-handoff-file-primitives.js";
3
3
  import { invalidDesignResourceHandoff } from "./design-resource-handoff-validation-primitives.js";
4
- export function validateDesignResourceWebDependencyClosure(target, resources, contents) {
4
+ export function validateDesignResourceImplementationDependencyClosure(target, resources, contents) {
5
5
  const declaredPaths = new Set(target.resource_refs.map((ref) => resources.get(ref).path));
6
6
  for (const resourceRef of target.resource_refs) {
7
7
  const resource = resources.get(resourceRef);
@@ -10,17 +10,23 @@ export function validateDesignResourceWebDependencyClosure(target, resources, co
10
10
  const content = contents.get(resourceRef).toString("utf8");
11
11
  for (const reference of localDependencyReferences(content, resource.media_type)) {
12
12
  const resolved = resolveResourceReference(resource.path, reference);
13
- if (!declaredPaths.has(resolved))
13
+ const declared = resolveDeclaredPath(declaredPaths, resolved);
14
+ if (declared === null)
14
15
  invalidDesignResourceHandoff("implementation_dependency_undeclared", `${target.key}:${resource.path}:${reference}:${resolved}`);
15
16
  }
16
17
  }
17
18
  }
18
19
  function localDependencyReferences(content, mediaType) {
19
20
  const values = new Set();
20
- if (["text/html", "application/xhtml+xml"].includes(mediaType)) {
21
+ const markupMediaTypes = [
22
+ "text/html",
23
+ "application/xhtml+xml",
24
+ "image/svg+xml",
25
+ ];
26
+ if (markupMediaTypes.includes(mediaType)) {
21
27
  for (const tag of content.matchAll(/<(script|img|source|video|audio|track|iframe|embed|input|link|object|use|image)\b([^<>]*)>/giu)) {
22
28
  const attributes = htmlAttributes(tag[2]);
23
- for (const name of ["src", "href", "poster"])
29
+ for (const name of ["src", "href", "xlink:href", "poster"])
24
30
  addLocalReference(values, attributes.get(name));
25
31
  if (tag[1].toLowerCase() === "object")
26
32
  addLocalReference(values, attributes.get("data"));
@@ -28,8 +34,7 @@ function localDependencyReferences(content, mediaType) {
28
34
  addLocalReference(values, candidate.trim().split(/\s+/u)[0]);
29
35
  }
30
36
  }
31
- if (mediaType === "text/css" ||
32
- ["text/html", "application/xhtml+xml"].includes(mediaType))
37
+ if (mediaType === "text/css" || markupMediaTypes.includes(mediaType))
33
38
  for (const match of content.matchAll(/(?:url\(\s*["']?([^"')\s]+)|@import\s+(?:url\(\s*)?["']([^"']+))/giu))
34
39
  addLocalReference(values, match[1] ?? match[2]);
35
40
  if ([
@@ -40,14 +45,24 @@ function localDependencyReferences(content, mediaType) {
40
45
  "text/ecmascript",
41
46
  "application/ecmascript",
42
47
  "text/html",
48
+ "application/xhtml+xml",
49
+ "image/svg+xml",
43
50
  ].includes(mediaType)) {
44
51
  for (const match of content.matchAll(/(?:\b(?:from|import)\s*|\bimport\s*\(|\brequire\s*\()\s*["']([^"']+)["']/gu))
45
- addLocalReference(values, match[1]);
52
+ addModuleReference(values, match[1]);
46
53
  for (const match of content.matchAll(/(?:\bfetch\s*\(|\bnew\s+(?:Shared)?Worker\s*\(|\bnew\s+URL\s*\()\s*["']([^"']+)["']/gu))
47
54
  addLocalReference(values, match[1]);
48
55
  }
49
56
  return values;
50
57
  }
58
+ function addModuleReference(values, raw) {
59
+ if (!raw)
60
+ return;
61
+ const value = raw.trim();
62
+ if (!value.startsWith(".") && !value.startsWith("/"))
63
+ return;
64
+ addLocalReference(values, value);
65
+ }
51
66
  function addLocalReference(values, raw) {
52
67
  if (!raw)
53
68
  return;
@@ -68,3 +83,48 @@ function resolveResourceReference(from, reference) {
68
83
  invalidDesignResourceHandoff("implementation_dependency_path_unsafe", `${from}:${reference}`);
69
84
  return resolved;
70
85
  }
86
+ function resolveDeclaredPath(declaredPaths, resolved) {
87
+ if (declaredPaths.has(resolved))
88
+ return resolved;
89
+ const candidates = [
90
+ ...[
91
+ ".js",
92
+ ".jsx",
93
+ ".mjs",
94
+ ".cjs",
95
+ ".ts",
96
+ ".tsx",
97
+ ".json",
98
+ ".css",
99
+ ".svg",
100
+ ".png",
101
+ ".jpg",
102
+ ".jpeg",
103
+ ".webp",
104
+ ".avif",
105
+ ".gif",
106
+ ".ico",
107
+ ".woff",
108
+ ".woff2",
109
+ ".ttf",
110
+ ".otf",
111
+ ".mp4",
112
+ ".webm",
113
+ ".mp3",
114
+ ".wav",
115
+ ".lottie",
116
+ ].map((extension) => `${resolved}${extension}`),
117
+ ...[
118
+ "index.js",
119
+ "index.jsx",
120
+ "index.mjs",
121
+ "index.ts",
122
+ "index.tsx",
123
+ "index.json",
124
+ ].map((name) => `${resolved}/${name}`),
125
+ ].filter((candidate) => declaredPaths.has(candidate));
126
+ if (candidates.length > 1)
127
+ invalidDesignResourceHandoff("implementation_dependency_resolution_ambiguous", `${resolved}:${candidates.join(",")}`);
128
+ return candidates[0] ?? null;
129
+ }
130
+ export const validateDesignResourceWebDependencyClosure = validateDesignResourceImplementationDependencyClosure;
@@ -1,2 +1,2 @@
1
- export declare const EXECUTION_TARGET_CAPABILITIES: readonly ["browser-runtime", "native-runtime", "desktop-runtime", "service-runtime", "process-runtime", "external-runtime", "cold-start", "production-root", "pointer-input", "keyboard-input", "touch-input", "viewport-control", "pixel-density-observation", "safe-area-observation", "motion-observation", "reduced-motion", "color-scheme-control", "text-scale-control", "assistive-technology", "screen-reader", "physical-device", "device-orientation", "sensor-input", "camera-input", "haptic-output", "thermal-observation", "power-mode-control", "persistent-storage", "network-boundary"];
1
+ export declare const EXECUTION_TARGET_CAPABILITIES: readonly ["browser-runtime", "native-runtime", "desktop-runtime", "service-runtime", "process-runtime", "external-runtime", "cold-start", "production-root", "pointer-input", "keyboard-input", "touch-input", "viewport-control", "pixel-density-observation", "safe-area-observation", "motion-observation", "reduced-motion", "color-scheme-control", "text-scale-control", "localization-control", "rtl-control", "assistive-technology", "screen-reader", "physical-device", "device-orientation", "sensor-input", "camera-input", "haptic-output", "audio-output", "reduced-transparency", "increased-contrast", "bold-text-control", "button-shapes-control", "system-ui-observation", "ime-control", "permission-control", "network-state-control", "lifecycle-control", "window-state-control", "fold-state-control", "thermal-observation", "power-mode-control", "persistent-storage", "network-boundary"];
2
2
  export type ExecutionTargetCapabilityV2 = (typeof EXECUTION_TARGET_CAPABILITIES)[number];
@@ -17,6 +17,8 @@ export const EXECUTION_TARGET_CAPABILITIES = [
17
17
  "reduced-motion",
18
18
  "color-scheme-control",
19
19
  "text-scale-control",
20
+ "localization-control",
21
+ "rtl-control",
20
22
  "assistive-technology",
21
23
  "screen-reader",
22
24
  "physical-device",
@@ -24,6 +26,18 @@ export const EXECUTION_TARGET_CAPABILITIES = [
24
26
  "sensor-input",
25
27
  "camera-input",
26
28
  "haptic-output",
29
+ "audio-output",
30
+ "reduced-transparency",
31
+ "increased-contrast",
32
+ "bold-text-control",
33
+ "button-shapes-control",
34
+ "system-ui-observation",
35
+ "ime-control",
36
+ "permission-control",
37
+ "network-state-control",
38
+ "lifecycle-control",
39
+ "window-state-control",
40
+ "fold-state-control",
27
41
  "thermal-observation",
28
42
  "power-mode-control",
29
43
  "persistent-storage",
@@ -7,6 +7,7 @@ import { validateSemanticConformance } from "./long-task-conformance-policy.js";
7
7
  import { deliveryContractStructureDiagnostics, validateDeliveryContractStructure, } from "./long-task-delivery-validation.js";
8
8
  import { validateRawExecutionObservationOwnership } from "./long-task-observation-ownership.js";
9
9
  import { validateLongTaskDesignResourceHandoffs } from "./long-task-design-resource-handoff.js";
10
+ import { validateLongTaskSemanticFactClosure } from "./long-task-semantic-fact-closure.js";
10
11
  import { freezeDeliveryCheck } from "./long-task-runner-freeze.js";
11
12
  import { classifyLongTaskRisk, validateRiskProof, } from "./long-task-risk.js";
12
13
  import { validateSourceContinuity } from "./long-task-source-continuity.js";
@@ -49,6 +50,9 @@ export async function validateContractForActivation(options) {
49
50
  return decision;
50
51
  });
51
52
  const context = await attempt(mode, diagnostics, () => captureContextGraphSnapshot(repository, contract.task.context_refs, contract.task.context_snapshot_mode));
53
+ const semanticFactClosure = sourceItems && context
54
+ ? await attempt(mode, diagnostics, () => validateLongTaskSemanticFactClosure(contract, repository, sourceItems, context.files))
55
+ : null;
52
56
  const workdirRelative = repoRelative(repository, workdir);
53
57
  const workspace = await attempt(mode, diagnostics, async () => {
54
58
  const manifest = await captureWorkspaceManifest(repository, workdir);
@@ -62,7 +66,7 @@ export async function validateContractForActivation(options) {
62
66
  const executionTarget = contract.task.execution_targets.find((target) => target.key === check.execution_target.target_ref);
63
67
  if (!executionTarget)
64
68
  continue;
65
- const frozen = await attempt(mode, diagnostics, () => freezeDeliveryCheck(check, null, repository, workspace, executionTarget, contract.task.execution_targets, []), null, check.key);
69
+ const frozen = await attempt(mode, diagnostics, () => freezeDeliveryCheck(check, null, repository, workspace, executionTarget, contract.task.execution_targets, [], []), null, check.key);
66
70
  if (frozen)
67
71
  globalChecks.push(frozen);
68
72
  }
@@ -73,7 +77,7 @@ export async function validateContractForActivation(options) {
73
77
  const executionTarget = contract.task.execution_targets.find((target) => target.key === check.execution_target.target_ref);
74
78
  if (!executionTarget)
75
79
  continue;
76
- const frozen = await attempt(mode, diagnostics, () => freezeDeliveryCheck(check, outcome.key, repository, workspace, executionTarget, contract.task.execution_targets, designTargetsForCheck(outcome, check.key)), outcome.key, check.key);
80
+ const frozen = await attempt(mode, diagnostics, () => freezeDeliveryCheck(check, outcome.key, repository, workspace, executionTarget, contract.task.execution_targets, designTargetsForCheck(outcome, check.key), semanticFactClosure?.expectations_by_check.get(check.key) ?? []), outcome.key, check.key);
77
81
  if (frozen)
78
82
  checks.push(frozen);
79
83
  }
@@ -1,4 +1,4 @@
1
- import { array, key, literal, object, string, strings, } from "./long-task-shape-primitives.js";
1
+ import { array, key, literal, object, semanticRef, string, strings, } from "./long-task-shape-primitives.js";
2
2
  const JOURNEY_ROLES = [
3
3
  "success",
4
4
  "degradation",
@@ -25,8 +25,8 @@ export function parseClaimApplicability(value, label) {
25
25
  const dimensionLabel = `${itemLabel}.dimensions[${dimensionIndex}]`;
26
26
  const entry = object(dimension, dimensionLabel, ["key", "value"]);
27
27
  return {
28
- key: key(entry.key, `${dimensionLabel}.key`),
29
- value: key(entry.value, `${dimensionLabel}.value`),
28
+ key: semanticRef(entry.key, `${dimensionLabel}.key`),
29
+ value: semanticRef(entry.value, `${dimensionLabel}.value`),
30
30
  };
31
31
  }),
32
32
  given_refs: parseKeyRefs(row.given_refs, `${itemLabel}.given_refs`),
@@ -31,6 +31,7 @@ export function authoringRevisionPreview(contract, sourceHashes, sourceItems, co
31
31
  const hashes = computeAuthorityHashes(contract);
32
32
  const previousDeclaredHashes = computeAuthorityHashes({
33
33
  schema_version: "long-task-delivery-v2",
34
+ semantic_fact_manifest: active.authority_snapshot.semantic_fact_manifest,
34
35
  task: active.authority_snapshot.task,
35
36
  source_claims: active.authority_snapshot.source_claims,
36
37
  stages: active.authority_snapshot.stages,
@@ -60,6 +60,7 @@ export declare const AUTHORITY_FIELD_POLICY_REGISTRIES: {
60
60
  stage: "semantic_user_review";
61
61
  depends_on: "readiness_only";
62
62
  applicability: "semantic_user_review";
63
+ semantic_fact_bindings: "semantic_user_review";
63
64
  product: "semantic_user_review";
64
65
  technical: "semantic_user_review";
65
66
  acceptance: "proof_additive";
@@ -43,6 +43,7 @@ const OUTCOME_AUTHORITY_POLICY = {
43
43
  stage: "semantic_user_review",
44
44
  depends_on: "readiness_only",
45
45
  applicability: "semantic_user_review",
46
+ semantic_fact_bindings: "semantic_user_review",
46
47
  product: "semantic_user_review",
47
48
  technical: "semantic_user_review",
48
49
  acceptance: "proof_additive",
@@ -17,6 +17,7 @@ export function computeAuthorityHashes(contract) {
17
17
  source_authority_hash: hash({
18
18
  source_paths: contract.task.source_paths,
19
19
  source_claims: contract.source_claims,
20
+ semantic_fact_manifest: contract.semantic_fact_manifest,
20
21
  }),
21
22
  product_authority_hash: hash({
22
23
  goal: contract.task.goal,
@@ -31,6 +32,14 @@ export function computeAuthorityHashes(contract) {
31
32
  key: outcome.key,
32
33
  stage: outcome.stage,
33
34
  applicability: outcome.applicability,
35
+ ...(outcome.semantic_fact_bindings
36
+ ? {
37
+ semantic_fact_bindings: {
38
+ manifest_ref: outcome.semantic_fact_bindings.manifest_ref,
39
+ facts: outcome.semantic_fact_bindings.facts,
40
+ },
41
+ }
42
+ : {}),
34
43
  product: outcome.product,
35
44
  })),
36
45
  }),
@@ -40,6 +49,9 @@ export function computeAuthorityHashes(contract) {
40
49
  global_counterfactual_controls: contract.global.acceptance.counterfactual_controls,
41
50
  outcomes: contract.outcomes.map((outcome) => ({
42
51
  key: outcome.key,
52
+ ...(outcome.semantic_fact_bindings
53
+ ? { semantic_fact_proofs: outcome.semantic_fact_bindings.proofs }
54
+ : {}),
43
55
  checks: outcome.acceptance.checks.map(acceptanceCheck),
44
56
  population: outcome.acceptance.population,
45
57
  counterfactual_controls: outcome.acceptance.counterfactual_controls,
@@ -61,6 +73,7 @@ export function outcomeAuthorityHash(outcome) {
61
73
  return hash({
62
74
  stage: outcome.stage,
63
75
  applicability: outcome.applicability,
76
+ semantic_fact_bindings: outcome.semantic_fact_bindings,
64
77
  product: outcome.product,
65
78
  acceptance: {
66
79
  checks: outcome.acceptance.checks.map(acceptanceCheck),