project-tiny-context-harness 0.8.4 → 0.8.5

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 (252) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +393 -371
  3. package/assets/README.md +573 -526
  4. package/assets/README.zh-CN.md +333 -311
  5. package/assets/agents/.gitkeep +1 -1
  6. package/assets/agents/AGENTS_CORE.md +44 -25
  7. package/assets/context_templates/architecture.md +28 -28
  8. package/assets/context_templates/area.md +34 -34
  9. package/assets/context_templates/context.toml +30 -30
  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 +32 -32
  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 +148 -125
  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-templates.js +1 -1
  43. package/dist/lib/design-resource-fact-enums.d.ts +20 -0
  44. package/dist/lib/design-resource-fact-enums.js +170 -0
  45. package/dist/lib/design-resource-fact-locator-extractors.d.ts +8 -0
  46. package/dist/lib/design-resource-fact-locator-extractors.js +108 -0
  47. package/dist/lib/design-resource-fact-locator-resolver.d.ts +3 -0
  48. package/dist/lib/design-resource-fact-locator-resolver.js +112 -0
  49. package/dist/lib/design-resource-fact-locator-validation.d.ts +5 -0
  50. package/dist/lib/design-resource-fact-locator-validation.js +16 -0
  51. package/dist/lib/design-resource-fact-manifest-catalog.d.ts +4 -0
  52. package/dist/lib/design-resource-fact-manifest-catalog.js +249 -0
  53. package/dist/lib/design-resource-fact-manifest-model.d.ts +91 -0
  54. package/dist/lib/design-resource-fact-manifest-model.js +21 -0
  55. package/dist/lib/design-resource-fact-manifest-shape-axes.d.ts +6 -0
  56. package/dist/lib/design-resource-fact-manifest-shape-axes.js +159 -0
  57. package/dist/lib/design-resource-fact-manifest-shape-evidence.d.ts +4 -0
  58. package/dist/lib/design-resource-fact-manifest-shape-evidence.js +59 -0
  59. package/dist/lib/design-resource-fact-manifest-shape-facts.d.ts +4 -0
  60. package/dist/lib/design-resource-fact-manifest-shape-facts.js +109 -0
  61. package/dist/lib/design-resource-fact-manifest-shape-inspector.d.ts +5 -0
  62. package/dist/lib/design-resource-fact-manifest-shape-inspector.js +144 -0
  63. package/dist/lib/design-resource-fact-manifest-shape.d.ts +7 -0
  64. package/dist/lib/design-resource-fact-manifest-shape.js +75 -0
  65. package/dist/lib/design-resource-fact-manifest-types.d.ts +3 -0
  66. package/dist/lib/design-resource-fact-manifest-types.js +3 -0
  67. package/dist/lib/design-resource-fact-manifest-universe.d.ts +5 -0
  68. package/dist/lib/design-resource-fact-manifest-universe.js +50 -0
  69. package/dist/lib/design-resource-fact-manifest-validation.d.ts +3 -0
  70. package/dist/lib/design-resource-fact-manifest-validation.js +106 -0
  71. package/dist/lib/design-resource-fact-policy.d.ts +18 -0
  72. package/dist/lib/design-resource-fact-policy.js +72 -1
  73. package/dist/lib/design-resource-fact-property-methods.d.ts +3 -0
  74. package/dist/lib/design-resource-fact-property-methods.js +158 -0
  75. package/dist/lib/design-resource-fact-shape-primitives.d.ts +3 -0
  76. package/dist/lib/design-resource-fact-shape-primitives.js +18 -0
  77. package/dist/lib/design-resource-fact-types.d.ts +164 -0
  78. package/dist/lib/design-resource-fact-types.js +1 -0
  79. package/dist/lib/design-resource-fact-universe-assets.d.ts +4 -0
  80. package/dist/lib/design-resource-fact-universe-assets.js +71 -0
  81. package/dist/lib/design-resource-fact-universe-catalog.d.ts +4 -0
  82. package/dist/lib/design-resource-fact-universe-catalog.js +151 -0
  83. package/dist/lib/design-resource-fact-universe-conditions.d.ts +2 -0
  84. package/dist/lib/design-resource-fact-universe-conditions.js +92 -0
  85. package/dist/lib/design-resource-fact-universe-facts.d.ts +4 -0
  86. package/dist/lib/design-resource-fact-universe-facts.js +108 -0
  87. package/dist/lib/design-resource-fact-universe-helpers.d.ts +30 -0
  88. package/dist/lib/design-resource-fact-universe-helpers.js +167 -0
  89. package/dist/lib/design-resource-fact-universe-inspector.d.ts +7 -0
  90. package/dist/lib/design-resource-fact-universe-inspector.js +119 -0
  91. package/dist/lib/design-resource-fact-universe-proof.d.ts +4 -0
  92. package/dist/lib/design-resource-fact-universe-proof.js +113 -0
  93. package/dist/lib/design-resource-fact-universe-subjects.d.ts +5 -0
  94. package/dist/lib/design-resource-fact-universe-subjects.js +97 -0
  95. package/dist/lib/design-resource-fact-universe-variations.d.ts +2 -0
  96. package/dist/lib/design-resource-fact-universe-variations.js +75 -0
  97. package/dist/lib/design-resource-fact-value-validation.d.ts +2 -0
  98. package/dist/lib/design-resource-fact-value-validation.js +80 -0
  99. package/dist/lib/design-resource-handoff-file-primitives.js +2 -0
  100. package/dist/lib/design-resource-handoff-file-validation.js +13 -100
  101. package/dist/lib/design-resource-handoff-policy.d.ts +1 -0
  102. package/dist/lib/design-resource-handoff-policy.js +118 -11
  103. package/dist/lib/design-resource-handoff-shape-evidence.js +46 -3
  104. package/dist/lib/design-resource-handoff-shape-primitives.d.ts +5 -0
  105. package/dist/lib/design-resource-handoff-shape-primitives.js +28 -0
  106. package/dist/lib/design-resource-handoff-shape-structure.js +143 -22
  107. package/dist/lib/design-resource-handoff-shape.js +25 -0
  108. package/dist/lib/design-resource-handoff-types.d.ts +97 -21
  109. package/dist/lib/design-resource-handoff-types.js +22 -0
  110. package/dist/lib/design-resource-handoff-validation-coverage.d.ts +1 -1
  111. package/dist/lib/design-resource-handoff-validation-coverage.js +145 -118
  112. package/dist/lib/design-resource-handoff-validation-fact-cells.d.ts +2 -0
  113. package/dist/lib/design-resource-handoff-validation-fact-cells.js +60 -0
  114. package/dist/lib/design-resource-handoff-validation-fact-records.d.ts +2 -0
  115. package/dist/lib/design-resource-handoff-validation-fact-records.js +90 -0
  116. package/dist/lib/design-resource-handoff-validation-facts.js +10 -94
  117. package/dist/lib/design-resource-handoff-validation-proofs.d.ts +2 -0
  118. package/dist/lib/design-resource-handoff-validation-proofs.js +67 -0
  119. package/dist/lib/design-resource-handoff-validation-resource-closure.d.ts +3 -0
  120. package/dist/lib/design-resource-handoff-validation-resource-closure.js +88 -0
  121. package/dist/lib/design-resource-handoff-validation-structure.js +43 -14
  122. package/dist/lib/design-resource-handoff-validation.js +32 -0
  123. package/dist/lib/design-resource-handoff-web-dependency-validation.d.ts +2 -1
  124. package/dist/lib/design-resource-handoff-web-dependency-validation.js +67 -7
  125. package/dist/lib/execution-target-capabilities.d.ts +1 -1
  126. package/dist/lib/execution-target-capabilities.js +14 -0
  127. package/dist/lib/long-task-activation-validation.js +6 -2
  128. package/dist/lib/long-task-applicability-shape.js +3 -3
  129. package/dist/lib/long-task-authoring-authority-preview.js +1 -0
  130. package/dist/lib/long-task-authority-policy.d.ts +1 -0
  131. package/dist/lib/long-task-authority-policy.js +1 -0
  132. package/dist/lib/long-task-authority.js +13 -0
  133. package/dist/lib/long-task-claim-definitions.js +13 -1
  134. package/dist/lib/long-task-claims.js +23 -1
  135. package/dist/lib/long-task-contract-types.d.ts +3 -0
  136. package/dist/lib/long-task-delivery-compiler.js +1 -0
  137. package/dist/lib/long-task-delivery-parser.js +11 -1
  138. package/dist/lib/long-task-delivery-types.d.ts +1 -0
  139. package/dist/lib/long-task-delivery-types.js +1 -0
  140. package/dist/lib/long-task-delivery-validation.js +17 -0
  141. package/dist/lib/long-task-design-resource-handoff.js +62 -38
  142. package/dist/lib/long-task-design-target-capabilities.d.ts +14 -0
  143. package/dist/lib/long-task-design-target-capabilities.js +126 -0
  144. package/dist/lib/long-task-evidence-capability-codec.d.ts +94 -0
  145. package/dist/lib/long-task-evidence-capability-codec.js +395 -22
  146. package/dist/lib/long-task-evidence-capability-policy.js +18 -0
  147. package/dist/lib/long-task-evidence-capability-runtime.js +78 -0
  148. package/dist/lib/long-task-evidence-capability-types.d.ts +114 -1
  149. package/dist/lib/long-task-outcome-parser.js +4 -0
  150. package/dist/lib/long-task-playwright-capability-records.d.ts +5 -0
  151. package/dist/lib/long-task-playwright-capability-records.js +146 -0
  152. package/dist/lib/long-task-playwright-case-evidence.d.ts +3 -2
  153. package/dist/lib/long-task-playwright-case-evidence.js +10 -79
  154. package/dist/lib/long-task-playwright-case-primitives.d.ts +28 -0
  155. package/dist/lib/long-task-playwright-case-primitives.js +143 -0
  156. package/dist/lib/long-task-playwright-evidence.d.ts +1 -1
  157. package/dist/lib/long-task-playwright-evidence.js +10 -75
  158. package/dist/lib/long-task-runner-freeze.d.ts +2 -2
  159. package/dist/lib/long-task-runner-freeze.js +15 -1
  160. package/dist/lib/long-task-runtime-types.d.ts +4 -1
  161. package/dist/lib/long-task-semantic-contract-types.d.ts +1 -1
  162. package/dist/lib/long-task-semantic-drift-migration.js +2 -2
  163. package/dist/lib/long-task-semantic-fact-binding-types.d.ts +57 -0
  164. package/dist/lib/long-task-semantic-fact-binding-types.js +1 -0
  165. package/dist/lib/long-task-semantic-fact-closure-primitives.d.ts +5 -0
  166. package/dist/lib/long-task-semantic-fact-closure-primitives.js +43 -0
  167. package/dist/lib/long-task-semantic-fact-closure.d.ts +13 -0
  168. package/dist/lib/long-task-semantic-fact-closure.js +48 -0
  169. package/dist/lib/long-task-semantic-fact-contract-closure.d.ts +4 -0
  170. package/dist/lib/long-task-semantic-fact-contract-closure.js +24 -0
  171. package/dist/lib/long-task-semantic-fact-contract-facts.d.ts +4 -0
  172. package/dist/lib/long-task-semantic-fact-contract-facts.js +30 -0
  173. package/dist/lib/long-task-semantic-fact-contract-proofs.d.ts +4 -0
  174. package/dist/lib/long-task-semantic-fact-contract-proofs.js +97 -0
  175. package/dist/lib/long-task-semantic-fact-evidence.d.ts +21 -0
  176. package/dist/lib/long-task-semantic-fact-evidence.js +165 -0
  177. package/dist/lib/long-task-semantic-fact-input-closure.d.ts +4 -0
  178. package/dist/lib/long-task-semantic-fact-input-closure.js +101 -0
  179. package/dist/lib/long-task-semantic-fact-provenance-closure.d.ts +4 -0
  180. package/dist/lib/long-task-semantic-fact-provenance-closure.js +140 -0
  181. package/dist/lib/long-task-semantic-fact-shape.d.ts +3 -0
  182. package/dist/lib/long-task-semantic-fact-shape.js +89 -0
  183. package/dist/lib/long-task-semantic-fact-value-closure.d.ts +3 -0
  184. package/dist/lib/long-task-semantic-fact-value-closure.js +110 -0
  185. package/dist/lib/long-task-shape-primitives.d.ts +2 -1
  186. package/dist/lib/long-task-shape-primitives.js +7 -0
  187. package/dist/lib/long-task-source-item-parser.js +25 -6
  188. package/dist/lib/long-task-source-target-continuity.js +4 -1
  189. package/dist/lib/long-task-source-target-index.d.ts +1 -1
  190. package/dist/lib/long-task-source-target-index.js +5 -1
  191. package/dist/lib/long-task-ui-design-policy.js +8 -4
  192. package/dist/lib/long-task-ui-surface-shape.js +83 -1
  193. package/dist/lib/long-task-ui-surface-types.d.ts +29 -0
  194. package/dist/lib/modularity.js +7 -1
  195. package/dist/lib/semantic-fact-base-types.d.ts +14 -0
  196. package/dist/lib/semantic-fact-base-types.js +1 -0
  197. package/dist/lib/semantic-fact-catalog.d.ts +8 -0
  198. package/dist/lib/semantic-fact-catalog.js +191 -0
  199. package/dist/lib/semantic-fact-condition-shape.d.ts +48 -0
  200. package/dist/lib/semantic-fact-condition-shape.js +111 -0
  201. package/dist/lib/semantic-fact-input-shape.d.ts +34 -0
  202. package/dist/lib/semantic-fact-input-shape.js +111 -0
  203. package/dist/lib/semantic-fact-inventory-types.d.ts +147 -0
  204. package/dist/lib/semantic-fact-inventory-types.js +1 -0
  205. package/dist/lib/semantic-fact-manifest-shape.d.ts +4 -0
  206. package/dist/lib/semantic-fact-manifest-shape.js +135 -0
  207. package/dist/lib/semantic-fact-manifest-types.d.ts +58 -0
  208. package/dist/lib/semantic-fact-manifest-types.js +19 -0
  209. package/dist/lib/semantic-fact-policy-authority.d.ts +8 -0
  210. package/dist/lib/semantic-fact-policy-authority.js +79 -0
  211. package/dist/lib/semantic-fact-policy-census.d.ts +2 -0
  212. package/dist/lib/semantic-fact-policy-census.js +80 -0
  213. package/dist/lib/semantic-fact-policy-condition-references.d.ts +7 -0
  214. package/dist/lib/semantic-fact-policy-condition-references.js +19 -0
  215. package/dist/lib/semantic-fact-policy-conditions.d.ts +2 -0
  216. package/dist/lib/semantic-fact-policy-conditions.js +105 -0
  217. package/dist/lib/semantic-fact-policy-facts.d.ts +3 -0
  218. package/dist/lib/semantic-fact-policy-facts.js +73 -0
  219. package/dist/lib/semantic-fact-policy-primitives.d.ts +26 -0
  220. package/dist/lib/semantic-fact-policy-primitives.js +169 -0
  221. package/dist/lib/semantic-fact-policy-proofs.d.ts +2 -0
  222. package/dist/lib/semantic-fact-policy-proofs.js +75 -0
  223. package/dist/lib/semantic-fact-policy-properties.d.ts +3 -0
  224. package/dist/lib/semantic-fact-policy-properties.js +84 -0
  225. package/dist/lib/semantic-fact-policy-units.d.ts +4 -0
  226. package/dist/lib/semantic-fact-policy-units.js +103 -0
  227. package/dist/lib/semantic-fact-policy.d.ts +17 -0
  228. package/dist/lib/semantic-fact-policy.js +41 -0
  229. package/dist/lib/semantic-fact-proof-shape.d.ts +51 -0
  230. package/dist/lib/semantic-fact-proof-shape.js +121 -0
  231. package/dist/lib/semantic-fact-proof-types.d.ts +74 -0
  232. package/dist/lib/semantic-fact-proof-types.js +1 -0
  233. package/dist/lib/semantic-fact-property-shape.d.ts +29 -0
  234. package/dist/lib/semantic-fact-property-shape.js +77 -0
  235. package/dist/lib/semantic-fact-shape-constants.d.ts +3 -0
  236. package/dist/lib/semantic-fact-shape-constants.js +38 -0
  237. package/dist/lib/semantic-fact-shape-primitives.d.ts +15 -0
  238. package/dist/lib/semantic-fact-shape-primitives.js +68 -0
  239. package/dist/lib/semantic-fact-source-parser.d.ts +9 -0
  240. package/dist/lib/semantic-fact-source-parser.js +46 -0
  241. package/dist/lib/semantic-fact-support-shape.d.ts +21 -0
  242. package/dist/lib/semantic-fact-support-shape.js +59 -0
  243. package/dist/lib/semantic-fact-types.d.ts +5 -0
  244. package/dist/lib/semantic-fact-types.js +5 -0
  245. package/dist/lib/semantic-fact-unit-shape.d.ts +34 -0
  246. package/dist/lib/semantic-fact-unit-shape.js +89 -0
  247. package/dist/lib/semantic-fact-value-shape.d.ts +12 -0
  248. package/dist/lib/semantic-fact-value-shape.js +39 -0
  249. package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +1339 -131
  250. package/migrations/README.md +15 -15
  251. package/package.json +84 -84
  252. package/source-mappings.yaml +25 -25
@@ -0,0 +1,79 @@
1
+ import { SEMANTIC_FACT_REQUIRED_INSPECTOR_CAPABILITIES } from "./semantic-fact-catalog.js";
2
+ import { assertSameSemanticFactSet, requireSemanticFactBasis, requireSemanticFactSubset, semanticFactCollections, semanticFactInvalid, uniqueNonemptySemanticFacts, uniqueSemanticFacts, } from "./semantic-fact-policy-primitives.js";
3
+ import { SEMANTIC_FACT_MANIFEST_COLLECTIONS, } from "./semantic-fact-types.js";
4
+ import { canonicalValueJson, sha256Hex } from "./strict-codec.js";
5
+ export function validateSemanticFactInspector(manifest) {
6
+ uniqueNonemptySemanticFacts(manifest.inspector.capabilities, "inspector_capabilities");
7
+ requireSemanticFactSubset([...SEMANTIC_FACT_REQUIRED_INSPECTOR_CAPABILITIES], manifest.inspector.capabilities, "inspector_capability_missing", manifest.key);
8
+ if (manifest.inspector.trust === "frozen_executable"
9
+ ? !manifest.inspector.implementation_sha256
10
+ : manifest.inspector.implementation_sha256 !== null)
11
+ semanticFactInvalid("inspector_identity_digest_mismatch", `${manifest.inspector.trust}:${manifest.inspector.implementation_sha256 ?? "missing"}`);
12
+ }
13
+ export function validateSemanticFactSourceLineage(manifest) {
14
+ const validate = (label, row) => {
15
+ uniqueNonemptySemanticFacts(row.source_item_refs, `${label}_source_items:${row.key}`);
16
+ requireSemanticFactSubset(row.source_item_refs, manifest.scope.source_item_refs, `${label}_source_item_unknown`, row.key);
17
+ };
18
+ for (const row of manifest.scope.exclusions) {
19
+ validate("scope_exclusion", row);
20
+ uniqueNonemptySemanticFacts(row.affected_refs, `scope_exclusion_affected_refs:${row.key}`);
21
+ requireSemanticFactBasis(row, `scope_exclusion:${row.key}`);
22
+ }
23
+ for (const row of manifest.family_dispositions)
24
+ validate("family", row);
25
+ for (const row of manifest.subjects)
26
+ validate("subject", row);
27
+ for (const row of manifest.relations)
28
+ validate("relation", row);
29
+ for (const row of manifest.populations)
30
+ validate("population", row);
31
+ for (const row of manifest.axis_dispositions) {
32
+ validate("axis", row);
33
+ for (const value of row.values)
34
+ validate(`axis_value:${row.key}`, value);
35
+ }
36
+ for (const row of manifest.condition_rules)
37
+ validate("condition_rule", row);
38
+ for (const row of manifest.conditions)
39
+ validate("condition", row);
40
+ for (const row of manifest.condition_exclusions)
41
+ validate("condition_exclusion", row);
42
+ for (const row of manifest.property_dispositions)
43
+ validate("property", row);
44
+ for (const row of manifest.fact_cells)
45
+ validate("fact_cell", row);
46
+ for (const row of manifest.facts)
47
+ validate("fact", row);
48
+ for (const row of manifest.blockers) {
49
+ validate("blocker", row);
50
+ uniqueNonemptySemanticFacts(row.affected_refs, `blocker_affected_refs:${row.key}`);
51
+ }
52
+ }
53
+ export function semanticFactCollectionIdentity(rows) {
54
+ return sha256Hex(canonicalValueJson(rows.map((item) => item.key).sort()));
55
+ }
56
+ export function validateSemanticFactUniqueIdentities(manifest) {
57
+ uniqueNonemptySemanticFacts(manifest.scope.outcome_refs, "scope_outcome_refs");
58
+ uniqueNonemptySemanticFacts(manifest.scope.source_item_refs, "scope_source_item_refs");
59
+ uniqueSemanticFacts(manifest.inputs.map((item) => `${item.kind}\0${item.source_ref}`), "input_resource");
60
+ for (const [name, rows] of Object.entries(semanticFactCollections(manifest)))
61
+ uniqueSemanticFacts(rows.map((item) => item.key), `${name}_key`);
62
+ uniqueSemanticFacts(manifest.inspector.census.map((item) => item.key), "inspector_census_key");
63
+ uniqueSemanticFacts(manifest.generation.collections.map((item) => item.name), "generation_collection_name");
64
+ uniqueSemanticFacts(manifest.generation.chunk_indexes, "generation_chunk_index");
65
+ const expectedChunks = Array.from({ length: manifest.generation.chunk_count }, (_unused, index) => index);
66
+ assertSameSemanticFactSet(manifest.generation.chunk_indexes, expectedChunks, "generation_chunk_indexes");
67
+ }
68
+ export function validateSemanticFactGeneration(manifest) {
69
+ assertSameSemanticFactSet(manifest.generation.collections.map((item) => item.name), [...SEMANTIC_FACT_MANIFEST_COLLECTIONS], "generation_collection_set");
70
+ const actual = semanticFactCollections(manifest);
71
+ for (const declaration of manifest.generation.collections) {
72
+ const rows = actual[declaration.name];
73
+ if (declaration.expected_count !== rows.length)
74
+ semanticFactInvalid("generation_collection_count_mismatch", `${declaration.name}:${declaration.expected_count}:${rows.length}`);
75
+ const digest = semanticFactCollectionIdentity(rows);
76
+ if (declaration.identity_sha256 !== digest)
77
+ semanticFactInvalid("generation_collection_identity_mismatch", `${declaration.name}:${declaration.identity_sha256}:${digest}`);
78
+ }
79
+ }
@@ -0,0 +1,2 @@
1
+ import type { SemanticFactManifestV1 } from "./semantic-fact-types.js";
2
+ export declare function validateSemanticFactInspectorCensus(manifest: SemanticFactManifestV1): void;
@@ -0,0 +1,80 @@
1
+ import { assertSameSemanticFactSet, requireSemanticFactBasis, semanticFactInvalid, validateSemanticFactLocator, } from "./semantic-fact-policy-primitives.js";
2
+ import { canonicalValueJson, sha256Hex } from "./strict-codec.js";
3
+ export function validateSemanticFactInspectorCensus(manifest) {
4
+ const factRefs = new Set(manifest.facts.map((item) => item.key));
5
+ const factsFor = (predicate) => manifest.facts.filter(predicate).map((item) => item.key);
6
+ const expected = expectedCensusRows(manifest, factsFor);
7
+ const actual = new Set();
8
+ for (const entry of manifest.inspector.census) {
9
+ const identity = `${entry.kind}:${entry.key}`;
10
+ actual.add(identity);
11
+ const expectedEntry = expected.get(identity);
12
+ if (!expectedEntry)
13
+ semanticFactInvalid("census_identity_unknown", identity);
14
+ if (entry.locator.material_ref !== manifest.key ||
15
+ entry.locator.kind !== "manifest_pointer" ||
16
+ entry.locator.value !== expectedEntry.pointer)
17
+ semanticFactInvalid("census_locator_mismatch", identity);
18
+ const identityDigest = sha256Hex(canonicalValueJson(expectedEntry.row));
19
+ if (entry.identity_sha256 !== identityDigest)
20
+ semanticFactInvalid("census_identity_digest_mismatch", `${identity}:${entry.identity_sha256}:${identityDigest}`);
21
+ for (const factRef of entry.fact_refs)
22
+ if (!factRefs.has(factRef))
23
+ semanticFactInvalid("census_fact_unknown", `${entry.key}:${factRef}`);
24
+ assertSameSemanticFactSet(entry.fact_refs, expectedEntry.fact_refs, `census_fact_set:${identity}`);
25
+ const expectedDisposition = expectedEntry.fact_refs.length
26
+ ? "material_with_facts"
27
+ : "supporting_only";
28
+ if (entry.disposition !== expectedDisposition)
29
+ semanticFactInvalid("census_disposition_mismatch", `${identity}:${entry.disposition}:${expectedDisposition}`);
30
+ validateSemanticFactLocator(manifest, entry.locator, `census:${entry.key}`);
31
+ requireSemanticFactBasis(entry, `census:${entry.key}`);
32
+ }
33
+ assertSameSemanticFactSet([...actual], [...expected.keys()], "inspector_census_universe");
34
+ }
35
+ function expectedCensusRows(manifest, factsFor) {
36
+ const result = new Map();
37
+ const add = (kind, key, pointer, row, factRefs) => result.set(`${kind}:${key}`, {
38
+ pointer,
39
+ row,
40
+ fact_refs: [...new Set(factRefs)].sort(),
41
+ });
42
+ manifest.inputs.forEach((row, index) => add("input", row.key, `/inputs/${index}`, row, row.fact_refs));
43
+ manifest.scope.exclusions.forEach((row, index) => add("scope_exclusion", row.key, `/scope/exclusions/${index}`, row, row.affected_refs.filter((ref) => manifest.facts.some((fact) => fact.key === ref))));
44
+ manifest.family_dispositions.forEach((row, index) => add("family", row.key, `/family_dispositions/${index}`, row, factsFor((fact) => fact.family_ref === row.key)));
45
+ manifest.subjects.forEach((row, index) => add("subject", row.key, `/subjects/${index}`, row, factsFor((fact) => fact.unit_ref === row.key)));
46
+ manifest.relations.forEach((row, index) => add("relation", row.key, `/relations/${index}`, row, factsFor((fact) => fact.unit_ref === row.key)));
47
+ manifest.populations.forEach((row, index) => add("population", row.key, `/populations/${index}`, row, factsFor((fact) => fact.unit_ref === row.key ||
48
+ fact.quantifier.population_ref === row.key)));
49
+ addAxisCensusRows(manifest, factsFor, add);
50
+ manifest.condition_rules.forEach((row, index) => add("condition_rule", row.key, `/condition_rules/${index}`, row, factsFor((fact) => row.condition_refs.includes(fact.condition_ref))));
51
+ manifest.conditions.forEach((row, index) => add("condition", row.key, `/conditions/${index}`, row, factsFor((fact) => fact.condition_ref === row.key)));
52
+ manifest.condition_exclusions.forEach((row, index) => add("condition", row.key, `/condition_exclusions/${index}`, row, []));
53
+ manifest.property_dispositions.forEach((row, index) => add("property", row.key, `/property_dispositions/${index}`, row, factsFor((fact) => fact.property_ref === row.key)));
54
+ manifest.fact_cells.forEach((row, index) => add("fact_cell", row.key, `/fact_cells/${index}`, row, row.fact_ref ? [row.fact_ref] : []));
55
+ manifest.facts.forEach((row, index) => add("fact", row.key, `/facts/${index}`, row, [row.key]));
56
+ manifest.proof_obligations.forEach((row, index) => add("proof_obligation", row.key, `/proof_obligations/${index}`, row, [
57
+ row.fact_ref,
58
+ ]));
59
+ addProofSupportCensusRows(manifest, add);
60
+ return result;
61
+ }
62
+ function addAxisCensusRows(manifest, factsFor, add) {
63
+ manifest.axis_dispositions.forEach((row, axisIndex) => {
64
+ add("axis", row.key, `/axis_dispositions/${axisIndex}`, row, factsFor((fact) => manifest.conditions
65
+ .find((condition) => condition.key === fact.condition_ref)
66
+ ?.axis_values.some((value) => value.axis_ref === row.key) ?? false));
67
+ row.values.forEach((value, valueIndex) => add("axis_value", `${row.key}:${value.key}`, `/axis_dispositions/${axisIndex}/values/${valueIndex}`, value, factsFor((fact) => manifest.conditions
68
+ .find((condition) => condition.key === fact.condition_ref)
69
+ ?.axis_values.some((entry) => entry.axis_ref === row.key && entry.value_ref === value.key) ?? false)));
70
+ });
71
+ }
72
+ function addProofSupportCensusRows(manifest, add) {
73
+ manifest.oracles.forEach((row, index) => add("oracle", row.key, `/oracles/${index}`, row, manifest.proof_obligations
74
+ .filter((proof) => proof.oracle_ref === row.key)
75
+ .map((proof) => proof.fact_ref)));
76
+ manifest.environments.forEach((row, index) => add("environment", row.key, `/environments/${index}`, row, manifest.proof_obligations
77
+ .filter((proof) => proof.environment_ref === row.key)
78
+ .map((proof) => proof.fact_ref)));
79
+ manifest.blockers.forEach((row, index) => add("blocker", row.key, `/blockers/${index}`, row, row.affected_refs.filter((ref) => manifest.facts.some((fact) => fact.key === ref))));
80
+ }
@@ -0,0 +1,7 @@
1
+ import type { SemanticFactManifestV1 } from "./semantic-fact-types.js";
2
+ type Axis = SemanticFactManifestV1["axis_dispositions"][number];
3
+ type Condition = SemanticFactManifestV1["conditions"][number];
4
+ type Exclusion = SemanticFactManifestV1["condition_exclusions"][number];
5
+ export declare function validateSemanticFactConditionRuleReferences(rule: SemanticFactManifestV1["condition_rules"][number], outcomeRef: string, conditionByRef: Map<string, Condition>, exclusionByRef: Map<string, Exclusion>): void;
6
+ export declare function validateSemanticFactAxisValueCoverage(outcomeRef: string, axes: Map<string, Axis>, rows: Array<Condition | Exclusion>): void;
7
+ export {};
@@ -0,0 +1,19 @@
1
+ import { semanticFactInvalid } from "./semantic-fact-policy-primitives.js";
2
+ export function validateSemanticFactConditionRuleReferences(rule, outcomeRef, conditionByRef, exclusionByRef) {
3
+ for (const ref of rule.condition_refs) {
4
+ const row = conditionByRef.get(ref);
5
+ if (!row || row.outcome_ref !== outcomeRef)
6
+ semanticFactInvalid("condition_rule_condition_unknown", `${rule.key}:${ref}`);
7
+ }
8
+ for (const ref of rule.exclusion_refs) {
9
+ const row = exclusionByRef.get(ref);
10
+ if (!row || row.outcome_ref !== outcomeRef)
11
+ semanticFactInvalid("condition_rule_exclusion_unknown", `${rule.key}:${ref}`);
12
+ }
13
+ }
14
+ export function validateSemanticFactAxisValueCoverage(outcomeRef, axes, rows) {
15
+ for (const axis of axes.values())
16
+ for (const value of axis.values)
17
+ if (!rows.some((item) => item.axis_values.some((entry) => entry.axis_ref === axis.key && entry.value_ref === value.key)))
18
+ semanticFactInvalid("axis_value_uncovered", `${outcomeRef}:${axis.key}:${value.key}`);
19
+ }
@@ -0,0 +1,2 @@
1
+ import type { SemanticFactManifestV1 } from "./semantic-fact-types.js";
2
+ export declare function validateSemanticFactAxisAndConditionClosure(manifest: SemanticFactManifestV1): void;
@@ -0,0 +1,105 @@
1
+ import { isAtomicSemanticFactAtom, isCustomSemanticFactName, SEMANTIC_FACT_STANDARD_CONDITION_AXES, } from "./semantic-fact-catalog.js";
2
+ import { validateSemanticFactAxisValueCoverage, validateSemanticFactConditionRuleReferences, } from "./semantic-fact-policy-condition-references.js";
3
+ import { assertSameSemanticFactSet, canonicalSemanticFactCondition, requireSemanticFactBasis, requireSemanticFactSubset, semanticFactInvalid, uniqueNonemptySemanticFacts, uniqueSemanticFacts, validateSemanticFactCrossProduct, } from "./semantic-fact-policy-primitives.js";
4
+ export function validateSemanticFactAxisAndConditionClosure(manifest) {
5
+ validateAxisCatalog(manifest);
6
+ const conditionByRef = new Map(manifest.conditions.map((item) => [item.key, item]));
7
+ const exclusionByRef = new Map(manifest.condition_exclusions.map((item) => [item.key, item]));
8
+ for (const exclusion of manifest.condition_exclusions)
9
+ if (exclusion.disposition === "decision_required" ||
10
+ exclusion.disposition === "unavailable")
11
+ semanticFactInvalid("condition_exclusion_unresolved", `${exclusion.key}:${exclusion.disposition}`);
12
+ for (const outcomeRef of manifest.scope.outcome_refs)
13
+ validateOutcomeConditions(manifest, outcomeRef, conditionByRef, exclusionByRef);
14
+ }
15
+ function validateAxisCatalog(manifest) {
16
+ const standardRows = manifest.axis_dispositions.filter((item) => item.standard);
17
+ uniqueSemanticFacts(manifest.axis_dispositions.flatMap((item) => item.outcome_refs.map((outcomeRef) => `${outcomeRef}\0${item.axis}`)), "axis_outcome_identity");
18
+ for (const axis of manifest.axis_dispositions)
19
+ validateAxis(manifest, axis);
20
+ for (const outcomeRef of manifest.scope.outcome_refs)
21
+ for (const axis of SEMANTIC_FACT_STANDARD_CONDITION_AXES) {
22
+ const rows = standardRows.filter((item) => item.axis === axis && item.outcome_refs.includes(outcomeRef));
23
+ if (rows.length !== 1)
24
+ semanticFactInvalid("standard_axis_outcome_disposition_required", `${outcomeRef}:${axis}:${rows.length}`);
25
+ }
26
+ }
27
+ function validateAxis(manifest, axis) {
28
+ const isStandard = SEMANTIC_FACT_STANDARD_CONDITION_AXES.includes(axis.axis);
29
+ if (axis.standard !== isStandard)
30
+ semanticFactInvalid("axis_standard_flag_mismatch", axis.axis);
31
+ if (!axis.standard && !isCustomSemanticFactName(axis.axis))
32
+ semanticFactInvalid("custom_axis_name_required", axis.axis);
33
+ uniqueNonemptySemanticFacts(axis.outcome_refs, `axis_outcomes:${axis.key}`);
34
+ requireSemanticFactSubset(axis.outcome_refs, manifest.scope.outcome_refs, "axis_outcome_unknown", axis.key);
35
+ uniqueSemanticFacts(axis.values.map((item) => item.key), `axis_values:${axis.key}`);
36
+ for (const value of axis.values) {
37
+ if (!isAtomicSemanticFactAtom(value.key))
38
+ semanticFactInvalid("axis_value_not_atomic", `${axis.key}:${value.key}`);
39
+ requireSemanticFactBasis(value, `axis_value:${axis.key}:${value.key}`);
40
+ }
41
+ if (axis.disposition === "applicable" && !axis.values.length)
42
+ semanticFactInvalid("applicable_axis_values_required", axis.key);
43
+ if (axis.disposition !== "applicable" && axis.values.length)
44
+ semanticFactInvalid("inapplicable_axis_values_forbidden", `${axis.key}:${axis.disposition}`);
45
+ if (axis.disposition === "decision_required" ||
46
+ axis.disposition === "unavailable")
47
+ semanticFactInvalid("axis_unresolved", `${axis.key}:${axis.disposition}`);
48
+ requireSemanticFactBasis(axis, `axis:${axis.key}`);
49
+ }
50
+ function validateOutcomeConditions(manifest, outcomeRef, conditionByRef, exclusionByRef) {
51
+ const applicableAxes = manifest.axis_dispositions.filter((item) => item.disposition === "applicable" &&
52
+ item.outcome_refs.includes(outcomeRef));
53
+ const axisByRef = new Map(applicableAxes.map((item) => [item.key, item]));
54
+ const expectedAxes = [...axisByRef.keys()].sort();
55
+ const conditions = manifest.conditions.filter((item) => item.outcome_ref === outcomeRef);
56
+ const exclusions = manifest.condition_exclusions.filter((item) => item.outcome_ref === outcomeRef);
57
+ if (!conditions.length)
58
+ semanticFactInvalid("condition_required", outcomeRef);
59
+ validateConditionRows([...conditions, ...exclusions], axisByRef, expectedAxes);
60
+ uniqueSemanticFacts([...conditions, ...exclusions].map((item) => canonicalSemanticFactCondition(item.axis_values)), `condition_combination:${outcomeRef}`);
61
+ const rules = manifest.condition_rules.filter((item) => item.outcome_ref === outcomeRef);
62
+ if (!applicableAxes.length) {
63
+ if (rules.length)
64
+ semanticFactInvalid("condition_rules_without_axes", outcomeRef);
65
+ if (conditions.length !== 1 ||
66
+ conditions[0].axis_values.length ||
67
+ exclusions.length)
68
+ semanticFactInvalid("baseline_condition_required", outcomeRef);
69
+ return;
70
+ }
71
+ if (rules.length !== 1)
72
+ semanticFactInvalid("condition_rule_complete_expansion_required", `${outcomeRef}:${rules.length}`);
73
+ validateOutcomeConditionRule(rules[0], outcomeRef, axisByRef, expectedAxes, conditions, exclusions, conditionByRef, exclusionByRef);
74
+ }
75
+ function validateConditionRows(rows, axisByRef, expectedAxes) {
76
+ for (const row of rows) {
77
+ uniqueSemanticFacts(row.axis_values.map((item) => item.axis_ref), `condition_axis:${row.key}`);
78
+ assertSameSemanticFactSet(row.axis_values.map((item) => item.axis_ref), expectedAxes, `condition_axis_set:${row.key}`);
79
+ for (const axisValue of row.axis_values) {
80
+ const axis = axisByRef.get(axisValue.axis_ref);
81
+ if (!axis)
82
+ semanticFactInvalid("condition_axis_unknown", `${row.key}:${axisValue.axis_ref}`);
83
+ if (!axis.values.some((item) => item.key === axisValue.value_ref))
84
+ semanticFactInvalid("condition_axis_value_unknown", `${row.key}:${axisValue.axis_ref}:${axisValue.value_ref}`);
85
+ }
86
+ requireSemanticFactBasis(row, `condition:${row.key}`);
87
+ }
88
+ }
89
+ function validateOutcomeConditionRule(rule, outcomeRef, axisByRef, expectedAxes, conditions, exclusions, conditionByRef, exclusionByRef) {
90
+ assertSameSemanticFactSet(rule.axis_refs, expectedAxes, `condition_rule_axis_universe:${outcomeRef}`);
91
+ uniqueNonemptySemanticFacts(rule.axis_refs, `condition_rule_axes:${rule.key}`);
92
+ uniqueSemanticFacts(rule.condition_refs, `condition_rule_conditions:${rule.key}`);
93
+ uniqueSemanticFacts(rule.exclusion_refs, `condition_rule_exclusions:${rule.key}`);
94
+ requireSemanticFactBasis(rule, `condition_rule:${rule.key}`);
95
+ validateSemanticFactConditionRuleReferences(rule, outcomeRef, conditionByRef, exclusionByRef);
96
+ if (!rule.condition_refs.length && !rule.exclusion_refs.length)
97
+ semanticFactInvalid("condition_rule_cells_required", rule.key);
98
+ validateSemanticFactCrossProduct(rule, axisByRef, conditionByRef, exclusionByRef);
99
+ assertSameSemanticFactSet(rule.condition_refs, conditions.map((item) => item.key), `condition_rule_condition_closure:${outcomeRef}`);
100
+ assertSameSemanticFactSet(rule.exclusion_refs, exclusions.map((item) => item.key), `condition_rule_exclusion_closure:${outcomeRef}`);
101
+ validateSemanticFactAxisValueCoverage(outcomeRef, axisByRef, [
102
+ ...conditions,
103
+ ...exclusions,
104
+ ]);
105
+ }
@@ -0,0 +1,3 @@
1
+ import type { SemanticFactManifestIndexV1 } from "./semantic-fact-policy.js";
2
+ import type { SemanticFactManifestV1 } from "./semantic-fact-types.js";
3
+ export declare function validateSemanticFactClosure(manifest: SemanticFactManifestV1, units: SemanticFactManifestIndexV1["unit_by_ref"]): void;
@@ -0,0 +1,73 @@
1
+ import { assertSameSemanticFactSet, requireSemanticFactBasis, requireSemanticFactSubset, semanticFactCellIdentity, semanticFactInvalid, uniqueNonemptySemanticFacts, validateSemanticFactLocatedValue, validateSemanticFactQuantifier, } from "./semantic-fact-policy-primitives.js";
2
+ export function validateSemanticFactClosure(manifest, units) {
3
+ const propertyByRef = new Map(manifest.property_dispositions.map((item) => [item.key, item]));
4
+ const conditionByRef = new Map(manifest.conditions.map((item) => [item.key, item]));
5
+ const expectedCells = [];
6
+ for (const property of manifest.property_dispositions)
7
+ for (const unitRef of property.applicable_unit_refs) {
8
+ const unit = units.get(unitRef);
9
+ for (const conditionRef of property.condition_refs)
10
+ if (conditionByRef.get(conditionRef)?.outcome_ref === unit.outcome_ref)
11
+ expectedCells.push(semanticFactCellIdentity(unitRef, conditionRef, property.key));
12
+ }
13
+ assertSameSemanticFactSet(manifest.fact_cells.map((item) => semanticFactCellIdentity(item.unit_ref, item.condition_ref, item.property_ref)), expectedCells, "fact_cell_universe");
14
+ const factByRef = new Map(manifest.facts.map((item) => [item.key, item]));
15
+ const specifiedRefs = [];
16
+ for (const cell of manifest.fact_cells)
17
+ validateFactCell(cell, units, propertyByRef, conditionByRef, factByRef, specifiedRefs);
18
+ assertSameSemanticFactSet(specifiedRefs, manifest.facts.map((item) => item.key), "specified_fact_set");
19
+ for (const fact of manifest.facts)
20
+ validateFact(manifest, fact);
21
+ }
22
+ function validateFactCell(cell, units, propertyByRef, conditionByRef, factByRef, specifiedRefs) {
23
+ const unit = units.get(cell.unit_ref);
24
+ const property = propertyByRef.get(cell.property_ref);
25
+ const condition = conditionByRef.get(cell.condition_ref);
26
+ if (!unit || !property || !condition)
27
+ semanticFactInvalid("fact_cell_reference_unknown", `${cell.key}:${cell.unit_ref}:${cell.condition_ref}:${cell.property_ref}`);
28
+ if (cell.outcome_ref !== unit.outcome_ref ||
29
+ condition.outcome_ref !== unit.outcome_ref)
30
+ semanticFactInvalid("fact_cell_outcome_mismatch", cell.key);
31
+ if (cell.disposition === "decision_required" ||
32
+ cell.disposition === "unavailable")
33
+ semanticFactInvalid("fact_cell_unresolved", `${cell.key}:${cell.disposition}`);
34
+ if (cell.disposition === "specified") {
35
+ if (!cell.fact_ref)
36
+ semanticFactInvalid("specified_fact_cell_ref_required", cell.key);
37
+ specifiedRefs.push(cell.fact_ref);
38
+ const fact = factByRef.get(cell.fact_ref);
39
+ if (!fact)
40
+ semanticFactInvalid("fact_cell_fact_unknown", `${cell.key}:${cell.fact_ref}`);
41
+ if (fact.cell_ref !== cell.key ||
42
+ fact.outcome_ref !== cell.outcome_ref ||
43
+ fact.unit_ref !== cell.unit_ref ||
44
+ fact.condition_ref !== cell.condition_ref ||
45
+ fact.property_ref !== cell.property_ref ||
46
+ fact.family_ref !== unit.family_ref ||
47
+ fact.value_kind !== property.value_kind)
48
+ semanticFactInvalid("fact_cell_fact_identity_mismatch", cell.key);
49
+ }
50
+ else if (cell.fact_ref)
51
+ semanticFactInvalid("non_specified_fact_cell_ref_forbidden", cell.key);
52
+ requireSemanticFactBasis(cell, `fact_cell:${cell.key}`);
53
+ }
54
+ function validateFact(manifest, fact) {
55
+ uniqueNonemptySemanticFacts(fact.source_item_refs, `fact_source_items:${fact.key}`);
56
+ requireSemanticFactSubset(fact.source_item_refs, manifest.scope.source_item_refs, "fact_source_item_unknown", fact.key);
57
+ if (!fact.provenance.basis_refs.length)
58
+ semanticFactInvalid("fact_provenance_basis_required", fact.key);
59
+ if (fact.provenance.kind === "logically_derived" &&
60
+ !fact.provenance.derivation)
61
+ semanticFactInvalid("fact_derivation_required", fact.key);
62
+ if (fact.provenance.kind !== "logically_derived" &&
63
+ fact.provenance.derivation)
64
+ semanticFactInvalid("fact_derivation_forbidden", fact.key);
65
+ if (fact.observation_sensitivity === "protected" &&
66
+ fact.expected.representation !== "digest_only")
67
+ semanticFactInvalid("protected_fact_digest_only_required", fact.key);
68
+ if (fact.observation_sensitivity === "plain" &&
69
+ fact.expected.representation === "digest_only")
70
+ semanticFactInvalid("plain_fact_digest_only_forbidden", fact.key);
71
+ validateSemanticFactLocatedValue(manifest, fact.expected, `fact:${fact.key}:expected`);
72
+ validateSemanticFactQuantifier(manifest, fact);
73
+ }
@@ -0,0 +1,26 @@
1
+ import type { SemanticFactManifestCollectionName, SemanticFactManifestV1 } from "./semantic-fact-types.js";
2
+ export declare function validateSemanticFactLocatedValue(manifest: SemanticFactManifestV1, located: SemanticFactManifestV1["facts"][number]["expected"], label: string): void;
3
+ export declare function validateSemanticFactLocator(manifest: SemanticFactManifestV1, locator: {
4
+ material_ref: string;
5
+ kind: string;
6
+ value: string;
7
+ }, label: string): void;
8
+ export declare function validateSemanticFactQuantifier(manifest: SemanticFactManifestV1, fact: SemanticFactManifestV1["facts"][number]): void;
9
+ export declare function validateSemanticFactCrossProduct(rule: SemanticFactManifestV1["condition_rules"][number], axes: Map<string, SemanticFactManifestV1["axis_dispositions"][number]>, conditions: Map<string, SemanticFactManifestV1["conditions"][number]>, exclusions: Map<string, SemanticFactManifestV1["condition_exclusions"][number]>): void;
10
+ export declare function semanticFactCollections(manifest: SemanticFactManifestV1): Record<SemanticFactManifestCollectionName, Array<{
11
+ key: string;
12
+ }>>;
13
+ export declare function semanticFactCellIdentity(unitRef: string, conditionRef: string, propertyRef: string): string;
14
+ export declare function canonicalSemanticFactCondition(values: Array<{
15
+ axis_ref: string;
16
+ value_ref: string;
17
+ }>): string;
18
+ export declare function assertNoSemanticFactParentCycle(key: string, subjects: SemanticFactManifestV1["subjects"]): void;
19
+ export declare function requireSemanticFactBasis(value: {
20
+ basis_refs: string[];
21
+ }, label: string): void;
22
+ export declare function requireSemanticFactSubset(actual: string[], allowed: string[], code: string, label: string): void;
23
+ export declare function uniqueNonemptySemanticFacts(values: Array<string | number>, label: string): void;
24
+ export declare function uniqueSemanticFacts(values: Array<string | number>, label: string): void;
25
+ export declare function assertSameSemanticFactSet(actual: Array<string | number>, expected: Array<string | number>, label: string): void;
26
+ export declare function semanticFactInvalid(code: string, detail: string): never;
@@ -0,0 +1,169 @@
1
+ import { canonicalValueJson, sha256Hex } from "./strict-codec.js";
2
+ export function validateSemanticFactLocatedValue(manifest, located, label) {
3
+ validateSemanticFactLocator(manifest, located.locator, label);
4
+ if (located.representation === "inline") {
5
+ const digest = sha256Hex(canonicalValueJson(located.value));
6
+ if (digest !== located.sha256)
7
+ semanticFactInvalid("inline_value_digest_mismatch", `${label}:${located.sha256}:${digest}`);
8
+ }
9
+ }
10
+ export function validateSemanticFactLocator(manifest, locator, label) {
11
+ const inputRefs = new Set(manifest.inputs.map((item) => item.key));
12
+ if (locator.kind === "manifest_pointer"
13
+ ? locator.material_ref !== manifest.key
14
+ : !inputRefs.has(locator.material_ref))
15
+ semanticFactInvalid("locator_material_unknown", `${label}:${locator.material_ref}`);
16
+ }
17
+ export function validateSemanticFactQuantifier(manifest, fact) {
18
+ const quantifier = fact.quantifier;
19
+ const population = quantifier.population_ref
20
+ ? (manifest.populations.find((item) => item.key === quantifier.population_ref) ?? null)
21
+ : null;
22
+ validateSemanticFactQuantifierPopulation(fact, population);
23
+ validateSemanticFactQuantifierNonnegativeBounds(fact);
24
+ validateSemanticFactQuantifierKindBounds(fact);
25
+ }
26
+ function validateSemanticFactQuantifierPopulation(fact, population) {
27
+ const quantifier = fact.quantifier;
28
+ if (quantifier.population_ref && !population)
29
+ semanticFactInvalid("quantifier_population_unknown", `${fact.key}:${quantifier.population_ref}`);
30
+ const populationKinds = new Set([
31
+ "all",
32
+ "any",
33
+ "none",
34
+ "exactly",
35
+ "at_least",
36
+ "at_most",
37
+ "range",
38
+ ]);
39
+ if (populationKinds.has(quantifier.kind) && !quantifier.population_ref)
40
+ semanticFactInvalid("quantifier_population_required", fact.key);
41
+ if (population && population.outcome_ref !== fact.outcome_ref)
42
+ semanticFactInvalid("quantifier_population_outcome_mismatch", `${fact.key}:${population.key}`);
43
+ if (quantifier.kind === "one" && quantifier.population_ref)
44
+ semanticFactInvalid("quantifier_population_forbidden", fact.key);
45
+ }
46
+ function validateSemanticFactQuantifierNonnegativeBounds(fact) {
47
+ for (const [label, value] of [
48
+ ["minimum", fact.quantifier.minimum],
49
+ ["maximum", fact.quantifier.maximum],
50
+ ])
51
+ if (value !== null && (!Number.isInteger(value) || value < 0))
52
+ semanticFactInvalid(`quantifier_${label}_invalid`, fact.key);
53
+ }
54
+ function validateSemanticFactQuantifierKindBounds(fact) {
55
+ const quantifier = fact.quantifier;
56
+ if (quantifier.kind === "exactly" &&
57
+ (quantifier.minimum === null ||
58
+ quantifier.maximum === null ||
59
+ quantifier.minimum !== quantifier.maximum))
60
+ semanticFactInvalid("quantifier_exactly_bounds_invalid", fact.key);
61
+ if (quantifier.kind === "at_least" && quantifier.minimum === null)
62
+ semanticFactInvalid("quantifier_minimum_required", fact.key);
63
+ if (quantifier.kind === "at_most" && quantifier.maximum === null)
64
+ semanticFactInvalid("quantifier_maximum_required", fact.key);
65
+ if (quantifier.kind === "range" &&
66
+ (quantifier.minimum === null ||
67
+ quantifier.maximum === null ||
68
+ quantifier.minimum > quantifier.maximum))
69
+ semanticFactInvalid("quantifier_range_invalid", fact.key);
70
+ if (["one", "all", "any", "none"].includes(quantifier.kind) &&
71
+ (quantifier.minimum !== null || quantifier.maximum !== null))
72
+ semanticFactInvalid("quantifier_bounds_forbidden", fact.key);
73
+ if (quantifier.kind === "at_least" && quantifier.maximum !== null)
74
+ semanticFactInvalid("quantifier_maximum_forbidden", fact.key);
75
+ if (quantifier.kind === "at_most" && quantifier.minimum !== null)
76
+ semanticFactInvalid("quantifier_minimum_forbidden", fact.key);
77
+ }
78
+ export function validateSemanticFactCrossProduct(rule, axes, conditions, exclusions) {
79
+ const values = rule.axis_refs.map((axisRef) => {
80
+ const axis = axes.get(axisRef);
81
+ if (!axis)
82
+ semanticFactInvalid("condition_rule_axis_unknown", `${rule.key}:${axisRef}`);
83
+ return axis.values.map((item) => `${axisRef}=${item.key}`);
84
+ });
85
+ const expected = semanticFactCartesian(values).map((row) => row.sort().join("|"));
86
+ const actual = [...rule.condition_refs, ...rule.exclusion_refs].map((ref) => {
87
+ const row = conditions.get(ref) ?? exclusions.get(ref);
88
+ if (!row)
89
+ semanticFactInvalid("condition_rule_cell_unknown", `${rule.key}:${ref}`);
90
+ return row.axis_values
91
+ .filter((item) => rule.axis_refs.includes(item.axis_ref))
92
+ .map((item) => `${item.axis_ref}=${item.value_ref}`)
93
+ .sort()
94
+ .join("|");
95
+ });
96
+ assertSameSemanticFactSet(actual, expected, `condition_rule_cross_product:${rule.key}`);
97
+ }
98
+ export function semanticFactCollections(manifest) {
99
+ return {
100
+ inputs: manifest.inputs,
101
+ inspector_census: manifest.inspector.census,
102
+ family_dispositions: manifest.family_dispositions,
103
+ subjects: manifest.subjects,
104
+ relations: manifest.relations,
105
+ populations: manifest.populations,
106
+ axis_dispositions: manifest.axis_dispositions,
107
+ condition_rules: manifest.condition_rules,
108
+ conditions: manifest.conditions,
109
+ condition_exclusions: manifest.condition_exclusions,
110
+ property_dispositions: manifest.property_dispositions,
111
+ fact_cells: manifest.fact_cells,
112
+ facts: manifest.facts,
113
+ proof_obligations: manifest.proof_obligations,
114
+ oracles: manifest.oracles,
115
+ environments: manifest.environments,
116
+ blockers: manifest.blockers,
117
+ };
118
+ }
119
+ export function semanticFactCellIdentity(unitRef, conditionRef, propertyRef) {
120
+ return `${unitRef}\0${conditionRef}\0${propertyRef}`;
121
+ }
122
+ export function canonicalSemanticFactCondition(values) {
123
+ return values
124
+ .map((item) => `${item.axis_ref}=${item.value_ref}`)
125
+ .sort()
126
+ .join("|");
127
+ }
128
+ function semanticFactCartesian(values) {
129
+ return values.reduce((rows, current) => rows.flatMap((row) => current.map((value) => [...row, value])), [[]]);
130
+ }
131
+ export function assertNoSemanticFactParentCycle(key, subjects) {
132
+ const byKey = new Map(subjects.map((item) => [item.key, item]));
133
+ const seen = new Set();
134
+ let current = key;
135
+ while (current) {
136
+ if (seen.has(current))
137
+ semanticFactInvalid("subject_parent_cycle", key);
138
+ seen.add(current);
139
+ current = byKey.get(current)?.parent_ref ?? null;
140
+ }
141
+ }
142
+ export function requireSemanticFactBasis(value, label) {
143
+ uniqueNonemptySemanticFacts(value.basis_refs, `${label}:basis_refs`);
144
+ }
145
+ export function requireSemanticFactSubset(actual, allowed, code, label) {
146
+ const unknown = actual.filter((item) => !allowed.includes(item));
147
+ if (unknown.length)
148
+ semanticFactInvalid(code, `${label}:${unknown.join(",")}`);
149
+ }
150
+ export function uniqueNonemptySemanticFacts(values, label) {
151
+ if (!values.length)
152
+ semanticFactInvalid(`${label}_required`, "");
153
+ uniqueSemanticFacts(values, label);
154
+ }
155
+ export function uniqueSemanticFacts(values, label) {
156
+ if (new Set(values).size !== values.length)
157
+ semanticFactInvalid(`${label}_duplicate`, values.join(","));
158
+ }
159
+ export function assertSameSemanticFactSet(actual, expected, label) {
160
+ if (actual.length !== expected.length ||
161
+ new Set(actual).size !== actual.length ||
162
+ actual.some((item) => !expected.includes(item)))
163
+ semanticFactInvalid(`${label}_mismatch`, `expected=${[...expected].sort().join(",")};actual=${[...actual]
164
+ .sort()
165
+ .join(",")}`);
166
+ }
167
+ export function semanticFactInvalid(code, detail) {
168
+ throw new Error(`semantic_fact_manifest_invalid:${code}${detail ? `:${detail}` : ""}`);
169
+ }
@@ -0,0 +1,2 @@
1
+ import type { SemanticFactManifestV1 } from "./semantic-fact-types.js";
2
+ export declare function validateSemanticFactProofClosure(manifest: SemanticFactManifestV1): void;