@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,275 @@
1
+ /** Coverage of declared reads, not authorization or production-read readiness.
2
+ * The input is the complete composed LawGraph, never tenant source-name switches.
3
+ */
4
+ import type { LawGraph, LawReadNode, LawFieldPathRef } from "./law_graph.js";
5
+ import type { SqliteLayout, SqliteSlot, SqliteValue } from "./sqlite_layout.js";
6
+ type Nodes = ReadonlyMap<string, LawGraph["nodes"][number]>;
7
+ export interface SqliteQueryPlan {
8
+ sid: string;
9
+ name: string;
10
+ keys: { path: string[]; kind: "string" | "integer" | "boolean" }[];
11
+ index: string;
12
+ ddl: string;
13
+ sql: string;
14
+ }
15
+ const literal = (s: string) => `'${s.replaceAll("'", "''")}'`;
16
+ type Scalar = { sql: string; kind: "string" | "integer" | "boolean" };
17
+ // Expressions are made only from generated column ordinals and quoted literals.
18
+ // SQLite maintains expression indexes transactionally; no second key store.
19
+ export function scalarSlot(slot: SqliteSlot, tail: readonly string[]): Scalar {
20
+ if (slot.surfaced)
21
+ throw Error("Surfaced query keys need observed-value indexing");
22
+ const result = scalarValue(slot.value, tail);
23
+ return {
24
+ ...result,
25
+ sql: `CASE WHEN c${slot.presence}=2 THEN ${result.sql} END`,
26
+ };
27
+ }
28
+ function scalarValue(value: SqliteValue, tail: readonly string[]): Scalar {
29
+ if (value.kind === "object" && tail.length) {
30
+ const member = value.members?.find((m) => m.name === tail[0]);
31
+ if (!member) throw Error(`missing nested member ${tail[0]}`);
32
+ return scalarSlot(member, tail.slice(1));
33
+ }
34
+ if (value.kind === "union" && tail.length) {
35
+ const arms = value.variants!.flatMap((arm, i) => {
36
+ // The nominal sum encoder puts its tag in `type`; SQL stores the ordinal.
37
+ if (tail.length === 1 && tail[0] === "type")
38
+ return [{ i, sql: literal(arm.label), kind: "string" as const }];
39
+ if (!arm.value.members?.some((m) => m.name === tail[0])) {
40
+ if (
41
+ arm.value.members
42
+ ?.find((m) => m.name === "value")
43
+ ?.value.members?.some((m) => m.name === tail[0])
44
+ )
45
+ throw Error(
46
+ "named sum payload path differs from authored path; typed-path resolution required"
47
+ );
48
+ return [];
49
+ }
50
+ return [{ i, ...scalarValue(arm.value, tail) }];
51
+ });
52
+ if (!arms.length) throw Error(`no sum arm has ${tail.join(".")}`);
53
+ if (arms.some((a) => a.kind !== arms[0]!.kind))
54
+ throw Error("query path has incompatible sum-arm scalar kinds");
55
+ return {
56
+ kind: arms[0]!.kind,
57
+ sql: `CASE c${value.column} ${arms
58
+ .map((a) => `WHEN ${a.i} THEN ${a.sql}`)
59
+ .join(" ")} END`,
60
+ };
61
+ }
62
+ if (tail.length)
63
+ throw Error(`indexed traversal through ${value.kind} is not implemented`);
64
+ if (
65
+ !["string", "integer", "boolean"].includes(value.kind) ||
66
+ value.column === undefined
67
+ )
68
+ throw Error(`query key ${value.kind} requires a separate index capability`);
69
+ return { kind: value.kind as Scalar["kind"], sql: `c${value.column}` };
70
+ }
71
+ export function planSqliteQueries(
72
+ nodes: Nodes,
73
+ aggregateId: string,
74
+ layout: Pick<SqliteLayout, "table" | "wireType" | "fields">
75
+ ) {
76
+ const plans: SqliteQueryPlan[] = [],
77
+ refusals: { sid: string; reason: string }[] = [];
78
+ for (const read of [...nodes.values()].filter(
79
+ (n): n is LawReadNode =>
80
+ n.kind === "read" && n.readKind === "query" && n.of.id === aggregateId
81
+ )) {
82
+ if (read.readKind !== "query") continue;
83
+ try {
84
+ if (read.predicate) throw Error("filtered query is not implemented");
85
+ if (!/^[a-f0-9]+$/i.test(read.entity.sid))
86
+ throw Error("unsafe read identity");
87
+ if (!read.key.length) throw Error("empty query key");
88
+ if (read.key.length + 1 > 2000)
89
+ throw Error("query index exceeds 2000-column SQLite target");
90
+ const keys = read.key.map((k) => {
91
+ const path = k.authoredPath.split(".");
92
+ const field = layout.fields.find((f) => f.name === path[0]);
93
+ if (!field) throw Error(`unmapped key ${k.authoredPath}`);
94
+ return { path, ...scalarSlot(field, path.slice(1)) };
95
+ });
96
+ const type = layout.fields.find((f) => f.name === "__type")!;
97
+ const archive = layout.fields.find((f) => f.name === "__archived");
98
+ if (!archive) throw Error("archive metadata not mapped");
99
+ // COALESCE handles absent archive cells (SQL NULL is not FALSE).
100
+ const guard = `c${type.presence}=2 AND c${type.value.column}=${literal(
101
+ layout.wireType
102
+ )} AND COALESCE(c${archive.value.column},0)<>1`;
103
+ const index = `r_${read.entity.sid.toLowerCase()}`;
104
+ plans.push({
105
+ sid: read.entity.sid,
106
+ name: read.entity.label,
107
+ keys: keys.map(({ path, kind }) => ({ path, kind })),
108
+ index,
109
+ ddl: `CREATE INDEX ${index} ON ${layout.table}(${keys
110
+ .map((k) => k.sql)
111
+ .join(",")},id) WHERE ${guard};`,
112
+ sql: `SELECT id FROM ${
113
+ layout.table
114
+ } INDEXED BY ${index} WHERE ${guard} AND ${keys
115
+ .map((k, i) => `(${k.sql})=?${i + 1}`)
116
+ .join(" AND ")} AND id>?${keys.length + 1} ORDER BY id LIMIT ?${
117
+ keys.length + 2
118
+ }`,
119
+ });
120
+ } catch (error) {
121
+ refusals.push({ sid: read.entity.sid, reason: (error as Error).message });
122
+ }
123
+ }
124
+ return { plans: plans.sort((a, b) => a.sid.localeCompare(b.sid)), refusals };
125
+ }
126
+ export function readFields(read: LawReadNode): readonly LawFieldPathRef[] {
127
+ switch (read.readKind) {
128
+ case "query":
129
+ return read.key;
130
+ case "count":
131
+ case "exists":
132
+ return read.groupBy ? [read.groupBy] : [];
133
+ case "sum":
134
+ case "min":
135
+ case "max":
136
+ return [read.value, ...(read.groupBy ? [read.groupBy] : [])];
137
+ case "ordered":
138
+ return [read.orderBy];
139
+ case "spatial":
140
+ return [read.geometry];
141
+ case "combined":
142
+ return [read.via];
143
+ case "temporalEnum":
144
+ return [read.source];
145
+ case "derived":
146
+ return [];
147
+ }
148
+ }
149
+ export function inspectSqliteReads(
150
+ nodes: Nodes,
151
+ layouts: readonly SqliteLayout[]
152
+ ) {
153
+ const reads = [...nodes.values()]
154
+ .filter((n): n is LawReadNode => n.kind === "read")
155
+ .map((read) => {
156
+ const aggregate = nodes.get(read.of.id),
157
+ domain = nodes.get(read.domain.id);
158
+ if (aggregate?.kind !== "aggregate" || domain?.kind !== "domain")
159
+ throw Error("read owner missing from compiled graph");
160
+ const layout = layouts.find(
161
+ (p) => p.aggregateSid === aggregate.entity.sid
162
+ );
163
+ const fields = readFields(read).map((p) => {
164
+ const field = aggregate.fields
165
+ .map((f) => nodes.get(f.id))
166
+ .find((f) => f?.entity.label === p.authoredPath.split(".")[0]);
167
+ return {
168
+ path: p.authoredPath,
169
+ fieldId: p.field.id,
170
+ storage: field?.kind === "field" ? field.storageKind : "unknown",
171
+ drivers:
172
+ field?.kind === "field"
173
+ ? field.mergeDrivers.map((d) => d.kind)
174
+ : [],
175
+ };
176
+ });
177
+ const spatial =
178
+ read.readKind === "spatial" &&
179
+ layout?.spatialIndexes.some((s) => s.sid === read.entity.sid);
180
+ const query = layout?.queryReads.some((q) => q.sid === read.entity.sid);
181
+ const count = layout?.countReads.some((q) => q.sid === read.entity.sid);
182
+ const computed = layout?.computedReads.some(
183
+ (q) => q.sid === read.entity.sid
184
+ );
185
+ const refusal =
186
+ layout?.queryRefusals.find((q) => q.sid === read.entity.sid) ??
187
+ layout?.countRefusals.find((q) => q.sid === read.entity.sid) ??
188
+ layout?.computedRefusals.find((q) => q.sid === read.entity.sid);
189
+ return {
190
+ sid: read.entity.sid,
191
+ name: read.entity.label,
192
+ domain: domain.entity.label,
193
+ kind: read.readKind,
194
+ aggregateSid: aggregate.entity.sid,
195
+ wireType: aggregate.wireType,
196
+ public: read.public,
197
+ contract: read.contract.id,
198
+ fields,
199
+ filtered: !!read.predicate,
200
+ status:
201
+ spatial || query || count || computed
202
+ ? "component-implemented"
203
+ : "missing",
204
+ reason: !layout
205
+ ? "aggregate layout unavailable"
206
+ : spatial || query || count || computed
207
+ ? null
208
+ : refusal?.reason ?? `${read.readKind} read adapter not implemented`,
209
+ requirements: [
210
+ read.readKind,
211
+ ...(fields.length > 1 ? ["compound"] : []),
212
+ ...(fields.some((f) => f.path.includes(".")) ? ["nested-path"] : []),
213
+ ...(fields.some((f) => f.storage === "set")
214
+ ? ["set-membership"]
215
+ : []),
216
+ ...(fields.some((f) => f.drivers.includes("Surfaced"))
217
+ ? ["surfaced-observation"]
218
+ : []),
219
+ ...(read.predicate ? ["predicate"] : []),
220
+ ],
221
+ runtimeVerified: false,
222
+ };
223
+ })
224
+ .sort(
225
+ (a, b) =>
226
+ a.domain.localeCompare(b.domain) ||
227
+ a.name.localeCompare(b.name) ||
228
+ a.sid.localeCompare(b.sid)
229
+ );
230
+ const kinds = Object.fromEntries(
231
+ [...new Set(reads.map((r) => r.kind))].sort().map((kind) => {
232
+ const group = reads.filter((r) => r.kind === kind);
233
+ return [
234
+ kind,
235
+ {
236
+ total: group.length,
237
+ implemented: group.filter((r) => r.status === "component-implemented")
238
+ .length,
239
+ missing: group.filter((r) => r.status === "missing").length,
240
+ },
241
+ ];
242
+ })
243
+ );
244
+ const foreignReads = [...nodes.values()]
245
+ .filter(
246
+ (n) => n.kind === "structural" && n.structuralKind === "foreign-read"
247
+ )
248
+ .map((n) => {
249
+ if (n.kind !== "structural" || n.structuralKind !== "foreign-read")
250
+ throw Error("unreachable");
251
+ return {
252
+ id: n.entity.id,
253
+ owner: n.owner.id,
254
+ query: n.query,
255
+ sourcePolicy: n.source.id,
256
+ requirements: [
257
+ "authenticated-source-frontier",
258
+ "source-policy",
259
+ "snapshot-binding",
260
+ ],
261
+ runtimeVerified: false,
262
+ };
263
+ });
264
+ return {
265
+ scope:
266
+ "declared read component coverage; not authorization, generated-client or runtime proof",
267
+ total: reads.length,
268
+ implemented: reads.filter((r) => r.status === "component-implemented")
269
+ .length,
270
+ missing: reads.filter((r) => r.status === "missing").length,
271
+ kinds,
272
+ reads,
273
+ foreignReads,
274
+ };
275
+ }
@@ -0,0 +1,185 @@
1
+ /** Component fixtures from authored descriptors, independently of the physical
2
+ * planner. Real wire encoder, synthetic values: NOT admitted tenant records.
3
+ * Keep this opt-in diagnostic outside compiler/law outputs and public barrels.
4
+ */
5
+ import type {
6
+ Field,
7
+ ValueObjectDescriptor,
8
+ ValueObjectFieldDescriptor,
9
+ ValueObjectFieldMeta,
10
+ } from "./fields.js";
11
+ import type { DomainModule } from "./codegen_dart.js";
12
+ import { encodeNominalValueObject } from "./wire_encode.js";
13
+ import type { LawGraph } from "./law_graph.js";
14
+
15
+ function object(
16
+ d: ValueObjectDescriptor,
17
+ types: Map<string, ValueObjectDescriptor>,
18
+ n: number
19
+ ): unknown {
20
+ if (d.geometry) {
21
+ const point = [1, 2.5];
22
+ return {
23
+ type: d.geometry,
24
+ coordinates:
25
+ d.geometry === "Point"
26
+ ? point
27
+ : d.geometry === "Polygon"
28
+ ? [[point, [2, 3], [3, 1], point]]
29
+ : [point, [2, 3]],
30
+ };
31
+ }
32
+ if (d.union) {
33
+ const [label, arm] = Object.entries(d.union).sort(([a], [b]) =>
34
+ a.localeCompare(b)
35
+ )[Math.floor(n / 3) % Object.keys(d.union).length]!;
36
+ return "ref" in arm
37
+ ? { type: label, value: object(types.get(arm.ref)!, types, n) }
38
+ : { type: label, ...members(arm.fields, types, n) };
39
+ }
40
+ return members(d.fields ?? {}, types, n);
41
+ }
42
+ function members(
43
+ fields: Readonly<Record<string, ValueObjectFieldDescriptor>>,
44
+ types: Map<string, ValueObjectDescriptor>,
45
+ n: number
46
+ ) {
47
+ return Object.fromEntries(
48
+ Object.entries(fields).flatMap(([name, f]) =>
49
+ f.optional && n % 3 === 0 ? [] : [[name, member(f, types, n)]]
50
+ )
51
+ );
52
+ }
53
+ function member(
54
+ f: ValueObjectFieldDescriptor,
55
+ types: Map<string, ValueObjectDescriptor>,
56
+ n: number
57
+ ): unknown {
58
+ if (f.nullable && n % 3 === 1) return null;
59
+ switch (f.type) {
60
+ case "string":
61
+ return f.digest ? "a".repeat(64) : n % 3 === 0 ? "" : `sample-λ-${n}`;
62
+ case "enum":
63
+ return f.values[n % f.values.length];
64
+ case "literal":
65
+ return f.value;
66
+ case "number":
67
+ // This interchange is JSON; the native scalar fixture separately covers
68
+ // IEEE negative-zero bits without JSON.stringify normalising them to zero.
69
+ return f.int ? n : n % 2 === 0 ? 0 : 1.25;
70
+ case "boolean":
71
+ return n % 2 === 0;
72
+ case "array":
73
+ return n % 3 === 0
74
+ ? []
75
+ : [member(f.items, types, n), member(f.items, types, n + 1)];
76
+ case "map":
77
+ return n % 3 === 0
78
+ ? {}
79
+ : {
80
+ "": member(f.values, types, n),
81
+ "λ:2/key": member(f.values, types, n + 1),
82
+ };
83
+ case "object":
84
+ case "geometry":
85
+ return object(types.get(f.ref)!, types, n);
86
+ }
87
+ }
88
+ function nominal(meta: ValueObjectFieldMeta, n: number) {
89
+ const types = new Map(
90
+ [meta.descriptor, ...meta.dependencies].map((d) => [d.name, d])
91
+ );
92
+ return {
93
+ ValueObject: encodeNominalValueObject(
94
+ meta.descriptor,
95
+ object(meta.descriptor, types, n),
96
+ types
97
+ ),
98
+ };
99
+ }
100
+ function value(f: Field, n: number): unknown {
101
+ if (f.nullSemantic && f.nullSemantic !== "forbid" && n % 3 === 1)
102
+ return { Json: null };
103
+ const ref = (type: string) => ({
104
+ workspace: "synthetic-workspace",
105
+ type,
106
+ id: `synthetic-${n}`,
107
+ });
108
+ if (f.nomosRef) return { NomosRef: ref(f.nomosRef.targetAggregateId) };
109
+ if (f.versionedForeignRef)
110
+ return {
111
+ VersionedNomosRef: {
112
+ pinned: ref(f.versionedForeignRef.targetAggregateId),
113
+ series: ref(f.versionedForeignRef.seriesAggregateId),
114
+ },
115
+ };
116
+ if (f.valueObject) return nominal(f.valueObject, n);
117
+ if (f.kind === "map") {
118
+ const leaf = f.mapValueVo
119
+ ? nominal(f.mapValueVo, n)
120
+ : f.mapValueKind === "int"
121
+ ? { Int: n }
122
+ : f.mapValueKind === "bool"
123
+ ? { Bool: n % 2 === 0 }
124
+ : { Str: `entry-${n}` };
125
+ return { Map: n % 3 === 0 ? {} : { "": leaf, "λ:2/key": leaf } };
126
+ }
127
+ if (f.kind === "set") return { Set: n % 3 === 0 ? [] : ["alpha", "βeta"] };
128
+ if (f.kind === "int") return { Int: n };
129
+ if (f.kind === "bool") return { Bool: n % 2 === 0 };
130
+ if (["string", "enum", "ref"].includes(f.kind)) return { Str: `sample-${n}` };
131
+ throw new Error(`unsupported descriptor fixture kind ${f.kind}`);
132
+ }
133
+ export function sqliteDescriptorSamples(
134
+ modules: readonly DomainModule[],
135
+ graphs: ReadonlyMap<string, LawGraph>
136
+ ) {
137
+ const seen = new Set<string>();
138
+ return modules.flatMap((mod) =>
139
+ mod.aggregates.flatMap((a) => {
140
+ // Shared framework handles may occur in multiple modules; physical binding
141
+ // is by the compiler's wireType + stable SID, supplied by the caller.
142
+ const node = graphs
143
+ .get(mod.name)!
144
+ .nodes.find((n) => n.kind === "aggregate" && n.entity.label === a.id);
145
+ if (node?.kind !== "aggregate")
146
+ throw new Error(`missing aggregate ${mod.name}.${a.id}`);
147
+ const key = node.entity.sid;
148
+ if (seen.has(key)) return [];
149
+ seen.add(key);
150
+ let arms = 1;
151
+ for (const f of Object.values(a.fields))
152
+ for (const meta of [f.valueObject, f.mapValueVo])
153
+ if (meta)
154
+ for (const d of [meta.descriptor, ...meta.dependencies])
155
+ arms = Math.max(arms, Object.keys(d.union ?? {}).length);
156
+ const labels = new Set(
157
+ node.fields.map(
158
+ (r) =>
159
+ graphs.get(mod.name)!.nodes.find((n) => n.entity.id === r.id)!
160
+ .entity.label
161
+ )
162
+ );
163
+ const base = {
164
+ aggregate: a.id,
165
+ sid: key,
166
+ wireType: node.wireType,
167
+ scope:
168
+ "synthetic descriptor values through the production nominal wire encoder; not admitted domain data",
169
+ };
170
+ try {
171
+ const samples = Array.from({ length: Math.max(3, arms * 3) }, (_, n) =>
172
+ Object.fromEntries(
173
+ Object.entries(a.fields)
174
+ .filter(([name]) => labels.has(name))
175
+ .map(([name, f]) => [name, value(f, n)])
176
+ )
177
+ );
178
+ return [{ ...base, samples }];
179
+ } catch (error) {
180
+ // An unsupported fixture must not erase the planner's useful diagnostics.
181
+ return [{ ...base, samples: [], samplingError: String(error) }];
182
+ }
183
+ })
184
+ );
185
+ }
@@ -13,7 +13,7 @@ export interface StableIdentityAggregateInput {
13
13
  }
14
14
 
15
15
  /**
16
- * Compatibility bridge for W4.1. The existing shape-aware continuity pass proposes
16
+ * Compatibility mapping for W4.1. The existing shape-aware continuity pass proposes
17
17
  * carries; the generalized registry owns the final SIDs and durable tombstones. Later
18
18
  * W4 work replaces those proposals with typed-graph/previous-USDA evidence.
19
19
  */
@@ -2,7 +2,7 @@ import { createHash } from "node:crypto";
2
2
  import { z } from "zod";
3
3
  import type { DomainModule } from "./codegen_dart.js";
4
4
  import { canonicalJson } from "./canonical_json.js";
5
- import { encodeDriver } from "./drivers.js";
5
+ import { driversShareValueSpace, driverValueSpace, encodeDriver } from "./drivers.js";
6
6
  import type { Field } from "./fields.js";
7
7
  import {
8
8
  mintAggregateSid,
@@ -126,7 +126,16 @@ function fieldValueContractDetails(field: Field): { contract: string; shape: unk
126
126
  return { contract, shape: contractShape };
127
127
  }
128
128
 
129
- function fieldSchemaIdentity(
129
+ /**
130
+ * Stable identity of one field contract — byte-identical to the kernel's
131
+ * `field_schema_identity` (pinned by the golden in `stable_ids_for_module.test.ts` and
132
+ * `kernel/tests/field_schema_identity.rs`). The `driver` slot carries the driver's stored
133
+ * VALUE SPACE (`driverValueSpace`), not the driver: switching among single-value drivers
134
+ * (Lww, LwwCausal, LwwBy, FirstWriterWins, FirstWriterCandidates, Surfaced/Attributed of
135
+ * those) keeps the identity, because D20 stores the observation antichain and the driver is
136
+ * a projection-time reduction. The value kind and contract stay in the identity (a retype).
137
+ */
138
+ export function fieldSchemaIdentity(
130
139
  aggregateSid: string,
131
140
  fieldSid: string,
132
141
  kind: string,
@@ -141,7 +150,7 @@ function fieldSchemaIdentity(
141
150
  field: fieldSid,
142
151
  kind,
143
152
  valueContract,
144
- driver,
153
+ driver: driverValueSpace(driver),
145
154
  }),
146
155
  "utf8",
147
156
  )
@@ -214,7 +223,10 @@ function fieldEvolutionRules(
214
223
  prior?.schema !== undefined &&
215
224
  prior.schema !== targetSchema &&
216
225
  prior.shape !== undefined &&
217
- canonicalJson(prior.driver) === canonicalJson(driver) &&
226
+ // Same stored value space (a single-value driver switch is free under D20): the prior
227
+ // schema was minted under an older preimage, so its stamped observations still route.
228
+ prior.driver !== undefined &&
229
+ driversShareValueSpace(prior.driver, driver) &&
218
230
  safeAutomaticWidening(prior.shape, target.shape) &&
219
231
  !bySource.has(prior.schema)
220
232
  ) {
@@ -24,12 +24,12 @@ function callUsdaForTestIdentity(
24
24
  ? { ...aggregate, audience: { kind: "public" as const } }
25
25
  : aggregate),
26
26
  valueObjects: collectValueObjectDescriptors(candidate.aggregates),
27
- directives: candidate.directives.map((directive) => ({
28
- ...directive,
29
- ...((directive as { birthsChild?: boolean }).birthsChild === true
30
- ? { declaredQueryReads: [] }
31
- : {}),
32
- })),
27
+ // Keep object identity for every directive this fixture does not change: a business intent's
28
+ // `.directs` step holds the original directive, and the law graph treats a copy as a second declaration.
29
+ directives: candidate.directives.map((directive) =>
30
+ (directive as { birthsChild?: boolean }).birthsChild === true
31
+ ? { ...directive, declaredQueryReads: [] }
32
+ : directive),
33
33
  });
34
34
  const byName = new Map(
35
35
  [module, ...closureModules].map((candidate) => [candidate.name, normalize(candidate)]),
@@ -16,6 +16,7 @@ interface RelationshipTarget {
16
16
  readonly asset: string;
17
17
  readonly line: number;
18
18
  readonly path: string;
19
+ readonly relationship?: string;
19
20
  }
20
21
 
21
22
  const PRIM_DECLARATION = /^(\s*)(?:def|over)(?:\s+[A-Za-z_][A-Za-z0-9_:]*)?\s+"([^"]+)"\s*$/;
@@ -27,7 +28,10 @@ const RELATIONSHIP_TARGET = /<([^>]+)>/g;
27
28
  * This intentionally checks only absolute `/Nomos` targets. Asset paths, external scene references
28
29
  * and ordinary USD relationships retain normal OpenUSD semantics; Nomos law identities do not.
29
30
  */
30
- export function assertUsdaRelationshipIntegrity(assets: readonly UsdaRelationshipAsset[]): void {
31
+ export function assertUsdaRelationshipIntegrity(
32
+ assets: readonly UsdaRelationshipAsset[],
33
+ options: { readonly allowMissingRelationships?: ReadonlySet<string> } = {},
34
+ ): void {
31
35
  const prims = new Set<string>();
32
36
  const targets: RelationshipTarget[] = [];
33
37
 
@@ -48,13 +52,26 @@ export function assertUsdaRelationshipIntegrity(assets: readonly UsdaRelationshi
48
52
  for (const match of line.matchAll(RELATIONSHIP_TARGET)) {
49
53
  const path = match[1]!;
50
54
  if (path === "/Nomos" || path.startsWith("/Nomos/")) {
51
- targets.push({ asset: asset.logicalPath, line: offset + 1, path });
55
+ const relationship = /\brel\s+([A-Za-z_][A-Za-z0-9_:]*)\s*=/.exec(line)?.[1];
56
+ targets.push({
57
+ asset: asset.logicalPath,
58
+ line: offset + 1,
59
+ path,
60
+ ...(relationship === undefined ? {} : { relationship }),
61
+ });
52
62
  }
53
63
  }
54
64
  }
55
65
  }
56
66
 
57
- const missing = targets.filter((target) => !prims.has(target.path));
67
+ const missing = targets.filter(
68
+ (target) =>
69
+ !prims.has(target.path) &&
70
+ !(
71
+ target.relationship !== undefined &&
72
+ options.allowMissingRelationships?.has(target.relationship)
73
+ ),
74
+ );
58
75
  if (missing.length === 0) return;
59
76
  const examples = missing.slice(0, 8).map((target) =>
60
77
  `${target.asset}:${target.line} targets missing prim <${target.path}>`).join("\n ");
package/src/usda_text.ts CHANGED
@@ -3,7 +3,27 @@
3
3
 
4
4
  /** Escape a string for a double-quoted USDA string literal. */
5
5
  export function usdaString(value: string): string {
6
- return JSON.stringify(value);
6
+ let encoded = '"';
7
+ for (const character of value) {
8
+ switch (character) {
9
+ case '"': encoded += '\\"'; break;
10
+ case "\\": encoded += "\\\\"; break;
11
+ case "\n": encoded += "\\n"; break;
12
+ case "\r": encoded += "\\r"; break;
13
+ case "\t": encoded += "\\t"; break;
14
+ case "\b": encoded += "\\b"; break;
15
+ case "\f": encoded += "\\f"; break;
16
+ default: {
17
+ const codePoint = character.codePointAt(0)!;
18
+ if (codePoint < 0x20 || codePoint === 0x7f) {
19
+ encoded += `\\u${codePoint.toString(16).padStart(4, "0")}`;
20
+ } else {
21
+ encoded += character;
22
+ }
23
+ }
24
+ }
25
+ }
26
+ return `${encoded}"`;
7
27
  }
8
28
 
9
29
  /** Emit a USDA `string[]` literal. */