@githolon/dsl 0.108.7 → 0.110.0

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 (307) 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 +76 -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 +211 -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 +267 -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 +23905 -15774
  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 +548 -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_span_trace_test.dart +23 -0
  74. package/dart/test/replica_readiness_test.dart +156 -0
  75. package/dart/test/runtime_projections_test.dart +92 -0
  76. package/dart/test/runtime_v2_gateway_test.dart +131 -0
  77. package/dart/test/signing_identity_kernel_test.dart +75 -0
  78. package/dart/test/sync_status_preparation_report_test.dart +29 -0
  79. package/dart/test/sync_status_reducer_test.dart +419 -0
  80. package/dart/test/test_harness_test.dart +71 -95
  81. package/dart/test/typed_query_watch_test.dart +170 -0
  82. package/dart/test/typed_watch_registry_test.dart +249 -0
  83. package/dart_lints/README.md +18 -0
  84. package/dart_lints/lib/nomos_lints.dart +70 -0
  85. package/dart_lints/pubspec.lock +580 -0
  86. package/dart_lints/pubspec.yaml +12 -0
  87. package/dart_lints/test/reference_identity_test.dart +75 -0
  88. package/dart_types/CHANGELOG.md +18 -0
  89. package/dart_types/lib/nomos_kernel_protocol.dart +21 -1
  90. package/dart_types/lib/nomos_types.dart +9 -1
  91. package/dart_types/lib/src/admission_decision.dart +37 -0
  92. package/dart_types/lib/src/aggregate_meta.dart +1 -1
  93. package/dart_types/lib/src/approved_model.dart +65 -0
  94. package/dart_types/lib/src/custody.dart +10 -18
  95. package/dart_types/lib/src/error_info.dart +4 -4
  96. package/dart_types/lib/src/errors.dart +29 -29
  97. package/dart_types/lib/src/foreign_ref.dart +62 -33
  98. package/dart_types/lib/src/local_work_rejected.dart +3 -3
  99. package/dart_types/lib/src/nomos_ref.dart +3 -1
  100. package/dart_types/lib/src/principal.dart +2 -2
  101. package/dart_types/lib/src/proto/google/protobuf/any.pb.dart +163 -0
  102. package/dart_types/lib/src/proto/google/protobuf/any.pbenum.dart +11 -0
  103. package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pb.dart +137 -0
  104. package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pbenum.dart +11 -0
  105. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +20721 -10433
  106. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pbenum.dart +555 -27
  107. package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pb.dart +387 -0
  108. package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pbenum.dart +46 -0
  109. package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pb.dart +295 -0
  110. package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pbenum.dart +139 -0
  111. package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pb.dart +269 -0
  112. package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pbenum.dart +103 -0
  113. package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pb.dart +417 -0
  114. package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pbenum.dart +62 -0
  115. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pb.dart +9968 -0
  116. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pbenum.dart +133 -0
  117. package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pb.dart +204 -0
  118. package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pbenum.dart +54 -0
  119. package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pb.dart +1550 -0
  120. package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pbenum.dart +11 -0
  121. package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pb.dart +710 -0
  122. package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pbenum.dart +11 -0
  123. package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pb.dart +845 -0
  124. package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pbenum.dart +11 -0
  125. package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pb.dart +198 -0
  126. package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pbenum.dart +11 -0
  127. package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pb.dart +369 -0
  128. package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pbenum.dart +11 -0
  129. package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pb.dart +609 -0
  130. package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pbenum.dart +65 -0
  131. package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pb.dart +358 -0
  132. package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pbenum.dart +100 -0
  133. package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pb.dart +2231 -0
  134. package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pbenum.dart +271 -0
  135. package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pb.dart +1286 -0
  136. package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pbenum.dart +11 -0
  137. package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pb.dart +636 -0
  138. package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pbenum.dart +116 -0
  139. package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pb.dart +1637 -0
  140. package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pbenum.dart +175 -0
  141. package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pb.dart +1269 -0
  142. package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pbenum.dart +129 -0
  143. package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pb.dart +2782 -0
  144. package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pbenum.dart +97 -0
  145. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pb.dart +2232 -8627
  146. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pbenum.dart +0 -358
  147. package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pb.dart +1639 -0
  148. package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pbenum.dart +46 -0
  149. package/dart_types/lib/src/runtime_outcome.dart +133 -0
  150. package/dart_types/lib/src/subscriptions.dart +116 -23
  151. package/dart_types/pubspec.yaml +1 -1
  152. package/dart_types/test/extremum_subscriptions_test.dart +40 -0
  153. package/dart_types/test/foreign_ref_resolution_test.dart +75 -0
  154. package/dart_types/test/nomos_ref_address_test.dart +25 -0
  155. package/dart_types/test/ordered_subscriptions_test.dart +34 -0
  156. package/operation_contract_check.mjs +24 -0
  157. package/package.json +11 -6
  158. package/src/aggregate.ts +70 -10
  159. package/src/application_topology.ts +18 -11
  160. package/src/attested.ts +3 -0
  161. package/src/attested_core.ts +46 -3
  162. package/src/birth_meter_ensure.ts +19 -7
  163. package/src/births.ts +29 -4
  164. package/src/build_package.ts +140 -13
  165. package/src/business_birth.ts +181 -4
  166. package/src/codegen_call_proto.ts +1274 -0
  167. package/src/codegen_call_usda.ts +49 -6
  168. package/src/codegen_dart.ts +79 -44
  169. package/src/codegen_dart_client.ts +458 -800
  170. package/src/{codegen_dart_application.ts → codegen_dart_facade.ts} +331 -582
  171. package/src/codegen_dart_framework_calls.ts +320 -37
  172. package/src/codegen_dart_indexed_variant.ts +159 -0
  173. package/src/codegen_dart_scenario.ts +42 -13
  174. package/src/codegen_proof.ts +3 -3
  175. package/src/codegen_provider_dart.ts +5 -0
  176. package/src/codegen_query_proto.ts +158 -0
  177. package/src/codegen_refusal.ts +189 -0
  178. package/src/codegen_result_proto.ts +931 -0
  179. package/src/codegen_result_usda.ts +4 -0
  180. package/src/codegen_ts.ts +464 -616
  181. package/src/codegen_workspace_access.ts +105 -0
  182. package/src/compatibility_graph.ts +759 -0
  183. package/src/compatibility_usda.ts +264 -0
  184. package/src/compile_package_main.ts +1994 -1189
  185. package/src/custody_placement.ts +156 -0
  186. package/src/custody_placement_usda.ts +91 -0
  187. package/src/decl_shapes.ts +21 -2
  188. package/src/describe_model.ts +1 -0
  189. package/src/directive.ts +59 -2
  190. package/src/drivers.ts +51 -0
  191. package/src/engine_entry.ts +52 -8
  192. package/src/evolve_preview.ts +11 -4
  193. package/src/exists.ts +2 -0
  194. package/src/fields.ts +75 -11
  195. package/src/flow_gate.ts +2 -1
  196. package/src/framework/application_home.ts +170 -18
  197. package/src/framework/attested_receipts.ts +8 -3
  198. package/src/framework/auth_provider_law.ts +169 -9
  199. package/src/framework/birth_certificate_law.ts +4 -0
  200. package/src/framework/capability.ts +34 -3
  201. package/src/framework/child_authentication.ts +346 -0
  202. package/src/framework/console_governance.ts +295 -0
  203. package/src/framework/delegated_roles.ts +301 -0
  204. package/src/framework/domain_lifecycle.ts +26 -13
  205. package/src/framework/founding_genesis.ts +193 -0
  206. package/src/framework/framework_aggregates.ts +1 -1
  207. package/src/framework/genesis.ts +6 -1
  208. package/src/framework/governance_relations.ts +19 -0
  209. package/src/framework/home.ts +5 -734
  210. package/src/framework/legacy/child_auth_provider_epoch.ts +73 -0
  211. package/src/framework/model_authority_repair.ts +116 -0
  212. package/src/framework/model_authority_seed.ts +185 -0
  213. package/src/framework/model_transition.ts +211 -0
  214. package/src/framework/owned_custody.ts +1 -1
  215. package/src/framework/principal_enrollment.ts +302 -0
  216. package/src/framework/receiving_group.ts +857 -0
  217. package/src/framework/receiving_group_recovery.ts +314 -0
  218. package/src/framework/relations.ts +4 -8
  219. package/src/framework/signing_identity.ts +242 -95
  220. package/src/framework/source_roster.ts +11 -5
  221. package/src/framework/workspace_access.ts +149 -0
  222. package/src/framework/workspace_invariant.ts +73 -52
  223. package/src/framework/workspaces.ts +407 -40
  224. package/src/framework_call_definitions.ts +32 -3
  225. package/src/generated_client_bundle_boundary.ts +97 -0
  226. package/src/generated_client_names.ts +1 -0
  227. package/src/identity_usda.ts +27 -0
  228. package/src/index.ts +183 -12
  229. package/src/indexed_variant.ts +83 -0
  230. package/src/intent.ts +173 -45
  231. package/src/law_check.ts +8 -5
  232. package/src/law_dependency_index.ts +231 -0
  233. package/src/law_graph.ts +508 -71
  234. package/src/law_graph_usda.ts +170 -24
  235. package/src/law_identity.ts +119 -81
  236. package/src/law_source_map.ts +4 -1
  237. package/src/law_units.ts +498 -0
  238. package/src/law_value_type.ts +7 -3
  239. package/src/member_authentication.ts +302 -0
  240. package/src/null_meta.ts +1 -1
  241. package/src/openusd_compiled_layer.ts +132 -0
  242. package/src/operation_contract_check.ts +31 -0
  243. package/src/ordered_read.ts +2 -1
  244. package/src/package_config.ts +33 -12
  245. package/src/package_dependencies.ts +1 -0
  246. package/src/plan_source_slice.ts +30 -1
  247. package/src/protobuf_field_number.ts +36 -0
  248. package/src/provenance_wire.ts +6 -0
  249. package/src/query.ts +2 -1
  250. package/src/read.ts +50 -0
  251. package/src/relation.ts +4 -1
  252. package/src/relation_schema.ts +15 -2
  253. package/src/report.ts +2 -2
  254. package/src/sqlite_computation_bundle.ts +78 -0
  255. package/src/sqlite_computed.ts +102 -0
  256. package/src/sqlite_counts.ts +154 -0
  257. package/src/sqlite_layout.ts +823 -0
  258. package/src/sqlite_reads.ts +275 -0
  259. package/src/sqlite_samples.ts +185 -0
  260. package/src/stable_id_identity_bridge.ts +1 -1
  261. package/src/stable_ids_for_module.ts +16 -4
  262. package/src/test_call_usda.ts +6 -6
  263. package/src/usda_relationship_integrity.ts +20 -3
  264. package/src/usda_text.ts +21 -1
  265. package/src/value_object.ts +81 -11
  266. package/src/wire.ts +22 -0
  267. package/src/wire_encode.ts +227 -20
  268. package/src/workspace_sharding.ts +15 -6
  269. package/src/workspace_sharing.ts +51 -49
  270. package/src/zod_introspection.ts +2 -0
  271. package/compat_package.mjs +0 -46
  272. package/dart/lib/src/home.dart +0 -15
  273. package/dart/lib/src/runner/offline-install.mjs +0 -15367
  274. package/dart/lib/src/source_trust.dart +0 -51
  275. package/dart/lib/src/webview_bridge.dart +0 -6540
  276. package/dart/lib/src/workspace_name.dart +0 -30
  277. package/dart/test/acquire_session_credentials_test.dart +0 -150
  278. package/dart/test/acquire_session_test.dart +0 -534
  279. package/dart/test/adv_realm_interference_test.dart +0 -600
  280. package/dart/test/cloud_bound_topology_test.dart +0 -168
  281. package/dart/test/cluster_births_test.dart +0 -202
  282. package/dart/test/cluster_device_keyed_acceptance_test.dart +0 -105
  283. package/dart/test/cluster_local_autosync_test.dart +0 -123
  284. package/dart/test/cluster_scale_test.dart +0 -122
  285. package/dart/test/compat_test.dart +0 -61
  286. package/dart/test/dlq_session_surface_test.dart +0 -222
  287. package/dart/test/first_app_gauntlet_test.dart +0 -386
  288. package/dart/test/fixtures/wedge/fake-install.mjs +0 -11
  289. package/dart/test/four_layer_nested_topology_test.dart +0 -290
  290. package/dart/test/home_parity_test.dart +0 -13
  291. package/dart/test/local_sync_inert_test.dart +0 -107
  292. package/dart/test/node_runner_transport_test.dart +0 -78
  293. package/dart/test/parent_signer_recovery_test.dart +0 -155
  294. package/dart/test/residency_refusal_test.dart +0 -49
  295. package/dart/test/sealing_client_test.dart +0 -181
  296. package/dart/test/session_bound_test.dart +0 -285
  297. package/dart/test/stale_bundle_test.dart +0 -80
  298. package/dart/test/vo_read_typing_test.dart +0 -131
  299. package/dart/test/watch_after_offer_stall_test.dart +0 -100
  300. package/dart/test/webview_bridge_test.dart +0 -1930
  301. package/dart/test/workspace_name_test.dart +0 -24
  302. package/runtime/generated-application-host.js +0 -22860
  303. package/src/codegen_query_usda.ts +0 -214
  304. package/src/compat_manifest.ts +0 -26
  305. package/src/compat_package_main.ts +0 -224
  306. package/src/shape_compat.ts +0 -352
  307. 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
+ }