@githolon/dsl 0.108.7 → 0.110.1

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 (308) hide show
  1. package/assets/operation-contract.wasm +0 -0
  2. package/check_package.mjs +12 -15
  3. package/compile_package.mjs +17 -18
  4. package/compile_proof.mjs +16 -1
  5. package/dart/CHANGELOG.md +80 -1
  6. package/dart/README.md +25 -2
  7. package/dart/lib/src/admission_decision.dart +41 -0
  8. package/dart/lib/src/application_framework_calls.dart +52 -2
  9. package/dart/lib/src/application_model_adoption.dart +187 -0
  10. package/dart/lib/src/application_status.dart +73 -0
  11. package/dart/lib/src/console_enrolment.dart +271 -0
  12. package/dart/lib/src/console_http_io.dart +26 -0
  13. package/dart/lib/src/console_http_stub.dart +7 -0
  14. package/dart/lib/src/dev_cloud.dart +69 -22
  15. package/dart/lib/src/generated_call.dart +83 -23
  16. package/dart/lib/src/kernel_primitives.dart +119 -0
  17. package/dart/lib/src/nms_conformance_runtime.dart +1 -1
  18. package/dart/lib/src/nms_generated_runtime.dart +32 -10
  19. package/dart/lib/src/nms_test_environment.dart +1 -1
  20. package/dart/lib/src/node_runner_transport.dart +41 -46
  21. package/dart/lib/src/observed_session_directory.dart +70 -0
  22. package/dart/lib/src/operation_receipts.dart +112 -0
  23. package/dart/lib/src/peer_application_streams.dart +103 -0
  24. package/dart/lib/src/reception/dart_reception.dart +4280 -0
  25. package/dart/lib/src/reception/event_desk.dart +214 -0
  26. package/dart/lib/src/reception/extremum_read.dart +46 -0
  27. package/dart/lib/src/reception/local_copies.dart +371 -0
  28. package/dart/lib/src/reception/peer_office_connection.dart +11 -0
  29. package/dart/lib/src/reception/progress_desk.dart +268 -0
  30. package/dart/lib/src/reception/reception_contract.dart +11 -0
  31. package/dart/lib/src/reception/reception_session.dart +284 -0
  32. package/dart/lib/src/reception/sync_diagnostics.dart +26 -0
  33. package/dart/lib/src/reception/workspace_preparation_report.dart +126 -0
  34. package/dart/lib/src/replica_readiness.dart +123 -0
  35. package/dart/lib/src/runner/node-entry.mjs +23950 -15776
  36. package/dart/lib/src/runtime_v2_gateway.dart +56 -3
  37. package/dart/lib/src/runtime_v2_transport.dart +544 -3
  38. package/dart/lib/src/session_bound.dart +200 -311
  39. package/dart/lib/src/signing_identity_kernel.dart +84 -0
  40. package/dart/lib/src/sync_status_projection.dart +550 -0
  41. package/dart/lib/src/sync_status_reducer.dart +170 -0
  42. package/dart/lib/src/test_harness.dart +809 -1153
  43. package/dart/lib/src/testing/test_custody.dart +66 -0
  44. package/dart/lib/src/testing/test_peer.dart +328 -0
  45. package/dart/lib/src/typed_watch_registry.dart +169 -0
  46. package/dart/lib/src/workspace_open_progress.dart +27 -0
  47. package/dart/pubspec.lock +24 -1
  48. package/dart/pubspec.yaml +7 -2
  49. package/dart/pubspec_overrides.yaml +2 -0
  50. package/dart/test/admission_decision_test.dart +48 -0
  51. package/dart/test/background_model_adoption_test.dart +228 -0
  52. package/dart/test/bundle_version_pairing_test.dart +4 -4
  53. package/dart/test/child_authentication_repair_test.dart +359 -0
  54. package/dart/test/cloud_bound_local_shell_test.dart +119 -0
  55. package/dart/test/console_enrolment_refusal_test.dart +52 -0
  56. package/dart/test/console_enrolment_test.dart +227 -0
  57. package/dart/test/errors_test.dart +5 -5
  58. package/dart/test/event_plane_seam_test.dart +50 -164
  59. package/dart/test/extremum_read_test.dart +58 -0
  60. package/dart/test/fixtures/wedge/wedge-entry.mjs +3 -21
  61. package/dart/test/generated_query_test.dart +32 -0
  62. package/dart/test/harness_phase_timeout_test.dart +18 -23
  63. package/dart/test/kernel_author_after_read_test.dart +242 -0
  64. package/dart/test/kernel_fence_test.dart +137 -0
  65. package/dart/test/local_copies_test.dart +222 -0
  66. package/dart/test/model_adoption_test.dart +198 -0
  67. package/dart/test/node_peer_local_custody_test.dart +153 -0
  68. package/dart/test/offer_authentication_proof_test.dart +352 -52
  69. package/dart/test/operation_compatibility_test.dart +151 -0
  70. package/dart/test/platform_credential_effect_test.dart +386 -0
  71. package/dart/test/receiving_group_open_test.dart +213 -0
  72. package/dart/test/reception/workspace_preparation_report_test.dart +103 -0
  73. package/dart/test/reception_event_desk_close_test.dart +16 -0
  74. package/dart/test/reception_span_trace_test.dart +23 -0
  75. package/dart/test/replica_readiness_test.dart +156 -0
  76. package/dart/test/runtime_projections_test.dart +92 -0
  77. package/dart/test/runtime_v2_gateway_test.dart +131 -0
  78. package/dart/test/signing_identity_kernel_test.dart +75 -0
  79. package/dart/test/sync_status_preparation_report_test.dart +29 -0
  80. package/dart/test/sync_status_reducer_test.dart +419 -0
  81. package/dart/test/test_harness_test.dart +71 -95
  82. package/dart/test/typed_query_watch_test.dart +170 -0
  83. package/dart/test/typed_watch_registry_test.dart +249 -0
  84. package/dart_lints/README.md +18 -0
  85. package/dart_lints/lib/nomos_lints.dart +70 -0
  86. package/dart_lints/pubspec.lock +580 -0
  87. package/dart_lints/pubspec.yaml +12 -0
  88. package/dart_lints/test/reference_identity_test.dart +75 -0
  89. package/dart_types/CHANGELOG.md +18 -0
  90. package/dart_types/lib/nomos_kernel_protocol.dart +21 -1
  91. package/dart_types/lib/nomos_types.dart +9 -1
  92. package/dart_types/lib/src/admission_decision.dart +37 -0
  93. package/dart_types/lib/src/aggregate_meta.dart +1 -1
  94. package/dart_types/lib/src/approved_model.dart +65 -0
  95. package/dart_types/lib/src/custody.dart +10 -18
  96. package/dart_types/lib/src/error_info.dart +4 -4
  97. package/dart_types/lib/src/errors.dart +29 -29
  98. package/dart_types/lib/src/foreign_ref.dart +62 -33
  99. package/dart_types/lib/src/local_work_rejected.dart +3 -3
  100. package/dart_types/lib/src/nomos_ref.dart +3 -1
  101. package/dart_types/lib/src/principal.dart +2 -2
  102. package/dart_types/lib/src/proto/google/protobuf/any.pb.dart +163 -0
  103. package/dart_types/lib/src/proto/google/protobuf/any.pbenum.dart +11 -0
  104. package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pb.dart +137 -0
  105. package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pbenum.dart +11 -0
  106. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +20721 -10433
  107. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pbenum.dart +555 -27
  108. package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pb.dart +387 -0
  109. package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pbenum.dart +46 -0
  110. package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pb.dart +295 -0
  111. package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pbenum.dart +139 -0
  112. package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pb.dart +269 -0
  113. package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pbenum.dart +103 -0
  114. package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pb.dart +417 -0
  115. package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pbenum.dart +62 -0
  116. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pb.dart +9968 -0
  117. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pbenum.dart +133 -0
  118. package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pb.dart +204 -0
  119. package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pbenum.dart +54 -0
  120. package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pb.dart +1550 -0
  121. package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pbenum.dart +11 -0
  122. package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pb.dart +710 -0
  123. package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pbenum.dart +11 -0
  124. package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pb.dart +845 -0
  125. package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pbenum.dart +11 -0
  126. package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pb.dart +198 -0
  127. package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pbenum.dart +11 -0
  128. package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pb.dart +369 -0
  129. package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pbenum.dart +11 -0
  130. package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pb.dart +609 -0
  131. package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pbenum.dart +65 -0
  132. package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pb.dart +358 -0
  133. package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pbenum.dart +100 -0
  134. package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pb.dart +2231 -0
  135. package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pbenum.dart +271 -0
  136. package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pb.dart +1286 -0
  137. package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pbenum.dart +11 -0
  138. package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pb.dart +636 -0
  139. package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pbenum.dart +116 -0
  140. package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pb.dart +1637 -0
  141. package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pbenum.dart +175 -0
  142. package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pb.dart +1269 -0
  143. package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pbenum.dart +129 -0
  144. package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pb.dart +2782 -0
  145. package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pbenum.dart +97 -0
  146. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pb.dart +2232 -8627
  147. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pbenum.dart +0 -358
  148. package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pb.dart +1639 -0
  149. package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pbenum.dart +46 -0
  150. package/dart_types/lib/src/runtime_outcome.dart +133 -0
  151. package/dart_types/lib/src/subscriptions.dart +116 -23
  152. package/dart_types/pubspec.yaml +1 -1
  153. package/dart_types/test/extremum_subscriptions_test.dart +40 -0
  154. package/dart_types/test/foreign_ref_resolution_test.dart +75 -0
  155. package/dart_types/test/nomos_ref_address_test.dart +25 -0
  156. package/dart_types/test/ordered_subscriptions_test.dart +34 -0
  157. package/operation_contract_check.mjs +24 -0
  158. package/package.json +11 -6
  159. package/src/aggregate.ts +70 -10
  160. package/src/application_topology.ts +18 -11
  161. package/src/attested.ts +3 -0
  162. package/src/attested_core.ts +46 -3
  163. package/src/birth_meter_ensure.ts +19 -7
  164. package/src/births.ts +29 -4
  165. package/src/build_package.ts +140 -13
  166. package/src/business_birth.ts +181 -4
  167. package/src/codegen_call_proto.ts +1276 -0
  168. package/src/codegen_call_usda.ts +49 -6
  169. package/src/codegen_dart.ts +83 -44
  170. package/src/codegen_dart_client.ts +458 -800
  171. package/src/{codegen_dart_application.ts → codegen_dart_facade.ts} +331 -582
  172. package/src/codegen_dart_framework_calls.ts +320 -37
  173. package/src/codegen_dart_indexed_variant.ts +159 -0
  174. package/src/codegen_dart_scenario.ts +42 -13
  175. package/src/codegen_proof.ts +3 -3
  176. package/src/codegen_provider_dart.ts +5 -0
  177. package/src/codegen_query_proto.ts +158 -0
  178. package/src/codegen_refusal.ts +189 -0
  179. package/src/codegen_result_proto.ts +931 -0
  180. package/src/codegen_result_usda.ts +4 -0
  181. package/src/codegen_ts.ts +464 -616
  182. package/src/codegen_workspace_access.ts +105 -0
  183. package/src/compatibility_graph.ts +759 -0
  184. package/src/compatibility_usda.ts +264 -0
  185. package/src/compile_package_main.ts +2017 -1195
  186. package/src/custody_placement.ts +156 -0
  187. package/src/custody_placement_usda.ts +91 -0
  188. package/src/decl_shapes.ts +21 -2
  189. package/src/describe_model.ts +1 -0
  190. package/src/directive.ts +59 -2
  191. package/src/drivers.ts +51 -0
  192. package/src/engine_entry.ts +52 -8
  193. package/src/evolve_preview.ts +11 -4
  194. package/src/exists.ts +2 -0
  195. package/src/fields.ts +75 -11
  196. package/src/flow_gate.ts +2 -1
  197. package/src/framework/application_home.ts +170 -18
  198. package/src/framework/attested_receipts.ts +8 -3
  199. package/src/framework/auth_provider_law.ts +169 -9
  200. package/src/framework/birth_certificate_law.ts +4 -0
  201. package/src/framework/capability.ts +34 -3
  202. package/src/framework/child_authentication.ts +346 -0
  203. package/src/framework/console_governance.ts +295 -0
  204. package/src/framework/delegated_roles.ts +301 -0
  205. package/src/framework/domain_lifecycle.ts +26 -13
  206. package/src/framework/founding_genesis.ts +193 -0
  207. package/src/framework/framework_aggregates.ts +1 -1
  208. package/src/framework/genesis.ts +6 -1
  209. package/src/framework/governance_relations.ts +19 -0
  210. package/src/framework/home.ts +5 -734
  211. package/src/framework/legacy/child_auth_provider_epoch.ts +73 -0
  212. package/src/framework/model_authority_repair.ts +116 -0
  213. package/src/framework/model_authority_seed.ts +185 -0
  214. package/src/framework/model_transition.ts +211 -0
  215. package/src/framework/owned_custody.ts +1 -1
  216. package/src/framework/principal_enrollment.ts +302 -0
  217. package/src/framework/receiving_group.ts +857 -0
  218. package/src/framework/receiving_group_recovery.ts +314 -0
  219. package/src/framework/relations.ts +4 -8
  220. package/src/framework/signing_identity.ts +242 -95
  221. package/src/framework/source_roster.ts +11 -5
  222. package/src/framework/workspace_access.ts +149 -0
  223. package/src/framework/workspace_invariant.ts +73 -52
  224. package/src/framework/workspaces.ts +407 -40
  225. package/src/framework_call_definitions.ts +32 -3
  226. package/src/generated_client_bundle_boundary.ts +97 -0
  227. package/src/generated_client_names.ts +1 -0
  228. package/src/identity_usda.ts +27 -0
  229. package/src/index.ts +183 -12
  230. package/src/indexed_variant.ts +83 -0
  231. package/src/intent.ts +173 -45
  232. package/src/law_check.ts +8 -5
  233. package/src/law_dependency_index.ts +231 -0
  234. package/src/law_graph.ts +508 -71
  235. package/src/law_graph_usda.ts +170 -24
  236. package/src/law_identity.ts +119 -81
  237. package/src/law_source_map.ts +4 -1
  238. package/src/law_units.ts +498 -0
  239. package/src/law_value_type.ts +7 -3
  240. package/src/member_authentication.ts +302 -0
  241. package/src/null_meta.ts +1 -1
  242. package/src/openusd_compiled_layer.ts +132 -0
  243. package/src/operation_contract_check.ts +31 -0
  244. package/src/ordered_read.ts +2 -1
  245. package/src/package_config.ts +33 -12
  246. package/src/package_dependencies.ts +1 -0
  247. package/src/plan_source_slice.ts +30 -1
  248. package/src/protobuf_field_number.ts +36 -0
  249. package/src/provenance_wire.ts +6 -0
  250. package/src/query.ts +2 -1
  251. package/src/read.ts +50 -0
  252. package/src/relation.ts +4 -1
  253. package/src/relation_schema.ts +15 -2
  254. package/src/report.ts +2 -2
  255. package/src/sqlite_computation_bundle.ts +78 -0
  256. package/src/sqlite_computed.ts +102 -0
  257. package/src/sqlite_counts.ts +154 -0
  258. package/src/sqlite_layout.ts +823 -0
  259. package/src/sqlite_reads.ts +275 -0
  260. package/src/sqlite_samples.ts +185 -0
  261. package/src/stable_id_identity_bridge.ts +1 -1
  262. package/src/stable_ids_for_module.ts +16 -4
  263. package/src/test_call_usda.ts +6 -6
  264. package/src/usda_relationship_integrity.ts +20 -3
  265. package/src/usda_text.ts +21 -1
  266. package/src/value_object.ts +81 -11
  267. package/src/wire.ts +22 -0
  268. package/src/wire_encode.ts +227 -20
  269. package/src/workspace_sharding.ts +15 -6
  270. package/src/workspace_sharing.ts +51 -49
  271. package/src/zod_introspection.ts +2 -0
  272. package/compat_package.mjs +0 -46
  273. package/dart/lib/src/home.dart +0 -15
  274. package/dart/lib/src/runner/offline-install.mjs +0 -15367
  275. package/dart/lib/src/source_trust.dart +0 -51
  276. package/dart/lib/src/webview_bridge.dart +0 -6540
  277. package/dart/lib/src/workspace_name.dart +0 -30
  278. package/dart/test/acquire_session_credentials_test.dart +0 -150
  279. package/dart/test/acquire_session_test.dart +0 -534
  280. package/dart/test/adv_realm_interference_test.dart +0 -600
  281. package/dart/test/cloud_bound_topology_test.dart +0 -168
  282. package/dart/test/cluster_births_test.dart +0 -202
  283. package/dart/test/cluster_device_keyed_acceptance_test.dart +0 -105
  284. package/dart/test/cluster_local_autosync_test.dart +0 -123
  285. package/dart/test/cluster_scale_test.dart +0 -122
  286. package/dart/test/compat_test.dart +0 -61
  287. package/dart/test/dlq_session_surface_test.dart +0 -222
  288. package/dart/test/first_app_gauntlet_test.dart +0 -386
  289. package/dart/test/fixtures/wedge/fake-install.mjs +0 -11
  290. package/dart/test/four_layer_nested_topology_test.dart +0 -290
  291. package/dart/test/home_parity_test.dart +0 -13
  292. package/dart/test/local_sync_inert_test.dart +0 -107
  293. package/dart/test/node_runner_transport_test.dart +0 -78
  294. package/dart/test/parent_signer_recovery_test.dart +0 -155
  295. package/dart/test/residency_refusal_test.dart +0 -49
  296. package/dart/test/sealing_client_test.dart +0 -181
  297. package/dart/test/session_bound_test.dart +0 -285
  298. package/dart/test/stale_bundle_test.dart +0 -80
  299. package/dart/test/vo_read_typing_test.dart +0 -131
  300. package/dart/test/watch_after_offer_stall_test.dart +0 -100
  301. package/dart/test/webview_bridge_test.dart +0 -1930
  302. package/dart/test/workspace_name_test.dart +0 -24
  303. package/runtime/generated-application-host.js +0 -22860
  304. package/src/codegen_query_usda.ts +0 -214
  305. package/src/compat_manifest.ts +0 -26
  306. package/src/compat_package_main.ts +0 -224
  307. package/src/shape_compat.ts +0 -352
  308. package/src/usd_state.ts +0 -505
@@ -0,0 +1,264 @@
1
+ import type { CompatibilityValueShape, DomainInterface } from "./compatibility_graph.js";
2
+ import { usdaString, usdaStringArray } from "./usda_text.js";
3
+
4
+ const numbered = (prefix: string, index: number): string =>
5
+ `${prefix}_${String(index + 1).padStart(8, "0")}`;
6
+
7
+ const fingerprintAtom = (value: string): string => `${value.length}:${value}`;
8
+
9
+ /**
10
+ * Intern structurally identical compatibility types within one domain.
11
+ *
12
+ * Law-graph identities remain authoritative in the compiled law. The compatibility
13
+ * document only needs a graph against which subtype relations can be judged, so
14
+ * emitting thousands of distinct `string`, literal and equivalent record nodes is
15
+ * redundant. Recursive back-edges retain their source identity, which deliberately
16
+ * favours a missed compaction over an unsound merge.
17
+ */
18
+ function canonicalCompatibilityTypes(
19
+ types: Readonly<Record<string, CompatibilityValueShape>>,
20
+ ): {
21
+ readonly canonicalId: ReadonlyMap<string, string>;
22
+ readonly entries: readonly (readonly [string, CompatibilityValueShape])[];
23
+ } {
24
+ const fingerprints = new Map<string, string>();
25
+ const visiting = new Set<string>();
26
+ const fingerprint = (id: string): string => {
27
+ const cached = fingerprints.get(id);
28
+ if (cached !== undefined) return cached;
29
+ if (visiting.has(id)) return `backref(${fingerprintAtom(id)})`;
30
+ const type = types[id];
31
+ if (type === undefined) throw new Error(`compatibility type '${id}' is missing`);
32
+ visiting.add(id);
33
+ const ref = (target: string): string => fingerprint(target);
34
+ let value: string;
35
+ switch (type.kind) {
36
+ case "string": case "int": case "double": case "bool": case "null": case "unknown": case "reference":
37
+ value = type.kind;
38
+ break;
39
+ case "enum":
40
+ value = `enum(${[...type.values].sort().map(fingerprintAtom).join("")})`;
41
+ break;
42
+ case "geometry":
43
+ value = `geometry(${fingerprintAtom(type.geometry)})`;
44
+ break;
45
+ case "literal":
46
+ value = type.value === null
47
+ ? "literal(null)"
48
+ : `literal(${fingerprintAtom(typeof type.value)}${fingerprintAtom(String(type.value))})`;
49
+ break;
50
+ case "list":
51
+ value = `list(${ref(type.element)})`;
52
+ break;
53
+ case "map":
54
+ value = `map(${ref(type.value)})`;
55
+ break;
56
+ case "recursive":
57
+ value = `recursive(${ref(type.body)})`;
58
+ break;
59
+ case "sum":
60
+ value = `sum(${type.variants.map(ref).sort().map(fingerprintAtom).join("")})`;
61
+ break;
62
+ case "record":
63
+ value = `record(${Object.entries(type.fields)
64
+ .sort(([left], [right]) => left.localeCompare(right))
65
+ .map(([name, field]) =>
66
+ `${fingerprintAtom(name)}${field.required ? "1" : "0"}${fingerprintAtom(ref(field.type))}`)
67
+ .join("")})`;
68
+ break;
69
+ }
70
+ visiting.delete(id);
71
+ fingerprints.set(id, value);
72
+ return value;
73
+ };
74
+
75
+ const canonicalByFingerprint = new Map<string, string>();
76
+ const canonicalId = new Map<string, string>();
77
+ for (const id of Object.keys(types).sort()) {
78
+ const shape = fingerprint(id);
79
+ const canonical = canonicalByFingerprint.get(shape) ?? id;
80
+ canonicalByFingerprint.set(shape, canonical);
81
+ canonicalId.set(id, canonical);
82
+ }
83
+ const entries = Object.entries(types)
84
+ .filter(([id]) => canonicalId.get(id) === id)
85
+ .sort(([left], [right]) => left.localeCompare(right));
86
+ return { canonicalId, entries };
87
+ }
88
+
89
+ function literalOpinions(value: string | number | boolean | null, pad: string): string[] {
90
+ if (value === null) return [`${pad}custom uniform token nomos:literalKind = "null"`];
91
+ if (typeof value === "string") return [
92
+ `${pad}custom uniform token nomos:literalKind = "string"`,
93
+ `${pad}custom uniform string nomos:stringValue = ${usdaString(value)}`,
94
+ ];
95
+ if (typeof value === "boolean") return [
96
+ `${pad}custom uniform token nomos:literalKind = "bool"`,
97
+ `${pad}custom uniform bool nomos:boolValue = ${value}`,
98
+ ];
99
+ if (!Number.isFinite(value)) throw new Error("compatibility literal must be finite");
100
+ return Number.isInteger(value)
101
+ ? [`${pad}custom uniform token nomos:literalKind = "int"`, `${pad}custom uniform int64 nomos:intValue = ${value}`]
102
+ : [`${pad}custom uniform token nomos:literalKind = "double"`, `${pad}custom uniform double nomos:doubleValue = ${value}`];
103
+ }
104
+
105
+ function emitType(lines: string[], type: CompatibilityValueShape, typeRef: (id: string) => string): void {
106
+ const pad = " ";
107
+ lines.push(`${pad}custom uniform token nomos:typeKind = ${usdaString(type.kind)}`);
108
+ switch (type.kind) {
109
+ case "string": case "int": case "double": case "bool": case "null": case "unknown": case "reference": return;
110
+ case "enum":
111
+ lines.push(`${pad}custom uniform string[] nomos:values = ${usdaStringArray(type.values)}`);
112
+ return;
113
+ case "geometry":
114
+ lines.push(`${pad}custom uniform token nomos:geometry = ${usdaString(type.geometry)}`);
115
+ lines.push(`${pad}custom uniform token nomos:encoding = "rfc7946"`);
116
+ return;
117
+ case "literal":
118
+ lines.push(...literalOpinions(type.value, pad));
119
+ return;
120
+ case "list":
121
+ lines.push(`${pad}custom rel nomos:elementType = <${typeRef(type.element)}>`);
122
+ return;
123
+ case "map":
124
+ lines.push(`${pad}custom rel nomos:valueType = <${typeRef(type.value)}>`);
125
+ return;
126
+ case "recursive":
127
+ lines.push(`${pad}custom rel nomos:body = <${typeRef(type.body)}>`);
128
+ return;
129
+ case "sum":
130
+ lines.push(' def Scope "Variants"', " {");
131
+ for (const [index, target] of type.variants.entries()) {
132
+ lines.push(
133
+ ` def NomosCompatibilityVariant "${numbered("v", index)}"`,
134
+ " {",
135
+ ` custom rel nomos:type = <${typeRef(target)}>`,
136
+ " }",
137
+ );
138
+ }
139
+ lines.push(" }");
140
+ return;
141
+ case "record":
142
+ lines.push(' def Scope "Fields"', " {");
143
+ for (const [index, [name, field]] of Object.entries(type.fields)
144
+ .sort(([left], [right]) => left.localeCompare(right)).entries()) {
145
+ lines.push(
146
+ ` def NomosCompatibilityValueField "${numbered("f", index)}"`,
147
+ " {",
148
+ ` custom uniform string nomos:name = ${usdaString(name)}`,
149
+ ` custom uniform bool nomos:required = ${field.required}`,
150
+ ` custom rel nomos:type = <${typeRef(field.type)}>`,
151
+ " }",
152
+ );
153
+ }
154
+ lines.push(" }");
155
+ }
156
+ }
157
+
158
+ /** Render the application compatibility matrix from the canonical law graph. */
159
+ export function emitApplicationCompatibilityUsda(
160
+ interfaces: Readonly<Record<string, DomainInterface>>,
161
+ ): string {
162
+ const lines = [
163
+ "#usda 1.0", "(", " customLayerData = {",
164
+ ' string "nomos:format" = "nomos.application-compatibility.v1"',
165
+ " }", ")", "", 'def Scope "Nomos"', "{", ' def Scope "ApplicationCompatibility"', " {",
166
+ " custom uniform uint nomos:formatVersion = 1", ' def Scope "Domains"', " {",
167
+ ];
168
+
169
+ for (const [domainIndex, [domainKey, domain]] of Object.entries(interfaces)
170
+ .sort(([left], [right]) => left.localeCompare(right)).entries()) {
171
+ const domainName = numbered("d", domainIndex);
172
+ const canonicalTypes = canonicalCompatibilityTypes(domain.types ?? {});
173
+ const typeEntries = canonicalTypes.entries;
174
+ const typeNames = new Map(typeEntries.map(([id], index) => [id, numbered("t", index)]));
175
+ const typeRef = (id: string): string => {
176
+ const canonical = canonicalTypes.canonicalId.get(id);
177
+ const name = canonical === undefined ? undefined : typeNames.get(canonical);
178
+ if (name === undefined) throw new Error(`compatibility type '${id}' is not present in domain '${domainKey}'`);
179
+ return `/Nomos/ApplicationCompatibility/Domains/${domainName}/Types/${name}`;
180
+ };
181
+ lines.push(
182
+ ` def NomosCompatibilityDomain "${domainName}"`, " {",
183
+ ` custom uniform string nomos:domain = ${usdaString(domainKey)}`,
184
+ ` custom uniform string nomos:domainSid = ${usdaString(domain.domainSid ?? "")}`,
185
+ ' def Scope "Types"', " {",
186
+ );
187
+ for (const [typeIndex, [typeId, type]] of typeEntries.entries()) {
188
+ lines.push(
189
+ ` def NomosCompatibilityValueType "${numbered("t", typeIndex)}"`, " {",
190
+ ` custom uniform string nomos:sid = ${usdaString(typeId)}`,
191
+ );
192
+ emitType(lines, type, typeRef);
193
+ lines.push(" }");
194
+ }
195
+ lines.push(" }", ' def Scope "Directives"', " {");
196
+ for (const [directiveIndex, [route, directive]] of Object.entries(domain.directives)
197
+ .sort(([left], [right]) => left.localeCompare(right)).entries()) {
198
+ lines.push(
199
+ ` def NomosCompatibilityDirective "${numbered("i", directiveIndex)}"`, " {",
200
+ ` custom uniform string nomos:route = ${usdaString(route)}`,
201
+ ...(directive.acceptsUnknownRefusals ? [' custom uniform bool nomos:acceptsUnknownRefusals = true'] : []),
202
+ ...(Object.keys(directive.domainRefusals ?? {}).length === 0 ? [] : [
203
+ ' def Scope "Refusals"', ' {',
204
+ ...Object.entries(directive.domainRefusals ?? {}).sort(([a], [b]) => a.localeCompare(b)).flatMap(([sid, type], index) => [
205
+ ` def NomosCompatibilityRefusal "${numbered("r", index)}"`, ' {',
206
+ ` custom uniform string nomos:sid = ${usdaString(sid)}`,
207
+ ` custom rel nomos:type = <${typeRef(type)}>`, ' }',
208
+ ]), ' }',
209
+ ]),
210
+ ' def Scope "Fields"', " {",
211
+ );
212
+ for (const [fieldIndex, [name, field]] of Object.entries(directive.fields)
213
+ .sort(([left], [right]) => left.localeCompare(right)).entries()) {
214
+ if (field.type === undefined) {
215
+ throw new Error(`compatibility directive '${domainKey}.${route}.${name}' has no typed value graph`);
216
+ }
217
+ lines.push(
218
+ ` def NomosCompatibilityField "${numbered("f", fieldIndex)}"`, " {",
219
+ ` custom uniform string nomos:name = ${usdaString(name)}`,
220
+ ...(field.wireKey === undefined ? [] : [
221
+ ` custom uniform string nomos:wireKey = ${usdaString(field.wireKey)}`,
222
+ ]),
223
+ ...(field.wireAliases === undefined || field.wireAliases.length === 0 ? [] : [
224
+ ` custom uniform string[] nomos:wireAliases = [${field.wireAliases.map(usdaString).join(", ")}]`,
225
+ ]),
226
+ ...(field.schemaIdentity === undefined ? [] : [
227
+ ` custom uniform string nomos:schemaIdentity = ${usdaString(field.schemaIdentity)}`,
228
+ ]),
229
+ ` custom uniform bool nomos:optional = ${field.optional}`,
230
+ ` custom rel nomos:type = <${typeRef(field.type)}>`,
231
+ " }",
232
+ );
233
+ }
234
+ lines.push(" }", " }");
235
+ }
236
+ lines.push(" }", ' def Scope "Aggregates"', " {");
237
+ for (const [aggregateIndex, [sid, aggregate]] of Object.entries(domain.aggregates)
238
+ .sort(([left], [right]) => left.localeCompare(right)).entries()) {
239
+ lines.push(
240
+ ` def NomosCompatibilityAggregate "${numbered("a", aggregateIndex)}"`, " {",
241
+ ` custom uniform string nomos:sid = ${usdaString(sid)}`,
242
+ ` custom uniform string nomos:label = ${usdaString(aggregate.label)}`,
243
+ ' def Scope "Fields"', " {",
244
+ );
245
+ for (const [fieldIndex, [fieldSid, field]] of Object.entries(aggregate.fields)
246
+ .sort(([left], [right]) => left.localeCompare(right)).entries()) {
247
+ if (field.type === undefined) {
248
+ throw new Error(`compatibility aggregate field '${domainKey}.${aggregate.label}.${field.label}' has no typed value graph`);
249
+ }
250
+ lines.push(
251
+ ` def NomosCompatibilityField "${numbered("f", fieldIndex)}"`, " {",
252
+ ` custom uniform string nomos:sid = ${usdaString(fieldSid)}`,
253
+ ` custom uniform string nomos:label = ${usdaString(field.label)}`,
254
+ ` custom rel nomos:type = <${typeRef(field.type)}>`,
255
+ " }",
256
+ );
257
+ }
258
+ lines.push(" }", " }");
259
+ }
260
+ lines.push(" }", " }");
261
+ }
262
+ lines.push(" }", " }", "}", "");
263
+ return lines.join("\n");
264
+ }