@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
@@ -1,3 +1,4 @@
1
+ import { dartRefusalDecoders } from "./codegen_refusal.js";
1
2
  // NOMOS — Nomos Sovereign: participants act · verify · remember LOCALLY; hosted
2
3
  // remotes are replaceable custody/transport, not truth. ⇒ ONE Nomos GitHolon
3
4
  // wasm32-wasip1 artifact {kernel · projection · embedded QuickJS engine}.
@@ -8,25 +9,26 @@
8
9
  *
9
10
  * `codegen_dart.ts` emits the per-domain TYPES: read-model classes (`…ReadModel.fromProjected`),
10
11
  * typed action inputs (`…Input` publicly; private directives retain `…Payload`), typed ids and enums. Until this file a Flutter app
11
- * still hand-typed directive ids + query ids against the raw `NomosBridge` (string + Map). This closes
12
+ * still hand-typed directive ids + query ids against a raw runtime surface (string + Map). This closes
12
13
  * that: ONE generated `<name>.client.dart` per domain, emitted by `nomos-compile` AFTER the package is
13
14
  * hashed (the deployed law's content hash baked in), carrying a `<Domain>Client` over a connected
14
- * [NomosBridge] (the WebView runner) with:
15
+ * a connected [NomosSession] with:
15
16
  *
16
17
  * * a typed OFFER method per directive — takes the generated input/implementation DTO, serialises via its
17
18
  * canonical USDA, auto-stamps omitted `…At` timestamps (the same caller-clock sugar the TS
18
19
  * client applies), returns the new local head;
19
20
  * * a typed declared-QUERY accessor per `query(...)` — one-shot `Future<List<…ReadModel>>` + a
20
- * reactive `watch…` `Stream<List<…ReadModel>>`, parsed off the bridge's `{type,id,data}` rows;
21
+ * reactive `watch…` `Stream<List<…ReadModel>>`, parsed off the session's `{type,id,data}` rows;
21
22
  * * by-id read/watch + a type-index `list…` per aggregate;
22
23
  * * typed O(1) count/sum accessors.
23
24
  *
24
25
  * It IMPORTS the sibling `<name>.dart` (for the read-model + input classes) and either the vendored
25
- * `nomos_client.dart` barrel or the package `nomos_client` barrel (for `NomosBridge`). NO manifest/hash impact —
26
+ * `nomos_client.dart` barrel or the package `nomos_client` barrel (for `NomosSession`). NO manifest/hash impact —
26
27
  * pure frontend codegen, exactly like `codegen_dart.ts`. NO FALLBACK: an unsupported shape throws at compile
27
28
  * time.
28
29
  */
29
30
  import type { z } from "zod";
31
+ import { MemberAuthenticationKind } from "./member_authentication.js";
30
32
 
31
33
  import {
32
34
  BUSINESS_BIRTH_SEED_PAYLOAD_FIELD,
@@ -65,18 +67,23 @@ import {
65
67
  type AggFieldSpec,
66
68
  type PayloadFieldSpec,
67
69
  } from "./codegen_dart.js";
68
- import type { LawGraph } from "./law_graph.js";
70
+ import type { LawGraph, LawRowReadNode } from "./law_graph.js";
69
71
  import {
70
- DART_CALL_USDA_PRELUDE,
71
- emitDartCallUsdaEncoder,
72
- type DartCallUsdaFieldAccess,
73
- } from "./codegen_call_usda.js";
72
+ DART_CALL_PROTO_PRELUDE,
73
+ emitDartCallProtoEncoder,
74
+ publishingIntentOf,
75
+ type DartCallProtoFieldAccess,
76
+ } from "./codegen_call_proto.js";
77
+ import { DART_CALL_USDA_PRELUDE } from "./codegen_call_usda.js";
74
78
  import {
75
- emitDartQueryUsdaEncoder,
79
+ emitDartQueryProtoEncoder,
76
80
  type QueryScalarKind,
77
- } from "./codegen_query_usda.js";
81
+ } from "./codegen_query_proto.js";
82
+ import { emitDartQueryResultProtoDecoder } from "./codegen_result_proto.js";
78
83
  import { finishCount } from "./count.js";
79
84
  import { finishSum } from "./sum.js";
85
+ import { finishExtremum } from "./extremum.js";
86
+ import { finishExists } from "./exists.js";
80
87
  import {
81
88
  autoStampFields,
82
89
  domainEncryptionMap,
@@ -87,13 +94,12 @@ import {
87
94
  isNamespacedAggregate,
88
95
  qualifyReadProjectionType,
89
96
  } from "./read_projection_namespace.js";
90
- import {
91
- childAuthenticationRecoveryAggregateId,
92
- isBusinessIntent,
93
- } from "./intent.js";
94
- import { publicClientInterface, type DomainInterface } from "./shape_compat.js";
97
+ import { isBusinessIntent } from "./intent.js";
98
+ import { publicClientInterface, type DomainInterface } from "./compatibility_graph.js";
99
+ import { emitApplicationCompatibilityUsda } from "./compatibility_usda.js";
95
100
  import { BUSINESS_CORRECTION_DIRECTIVE } from "./framework/business_corrections.js";
96
101
  import { deriveDirectiveRecordTarget } from "./workspace_routing.js";
102
+ import { voMetaOf } from "./value_object.js";
97
103
  import {
98
104
  buildNomosDescribeModel,
99
105
  type NomosDescribeModel,
@@ -113,16 +119,74 @@ const camel = (s: string) =>
113
119
  const lcFirst = (s: string) =>
114
120
  s.length ? s[0]!.toLowerCase() + s.slice(1) : s;
115
121
 
116
- export const dartInternalWorkspaceSharingReceiptMethod = (
117
- directiveId: string
118
- ): string => `nmsInternal${cap(camel(directiveId))}`;
122
+ type AnyDirective = Directive<unknown>;
119
123
 
120
- export const dartInternalChildAuthenticationRecoveryMethod = (
121
- aggregateId: string,
122
- ): string => `nmsInternalRepair${cap(camel(aggregateId))}Authentication`;
124
+ interface DartClientOperationSelection {
125
+ readonly publicDirectives: readonly AnyDirective[];
126
+ readonly sourceTrustViaIds: ReadonlySet<string>;
127
+ readonly sourceTrustDirectives: readonly AnyDirective[];
128
+ readonly encoderDirectives: readonly AnyDirective[];
129
+ }
123
130
 
124
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
125
- type AnyDirective = Directive<any>;
131
+ /**
132
+ * The exact operation surface for which the generated Dart session emits
133
+ * Protobuf encoders. Keeping this selection beside the encoder prevents the
134
+ * package compiler from independently guessing that every internal law
135
+ * directive is a client call.
136
+ */
137
+ function dartClientOperationSelection(
138
+ mod: DomainModule,
139
+ graph: LawGraph,
140
+ ): DartClientOperationSelection {
141
+ const authoredDirectives = mod.directives as AnyDirective[];
142
+ const publicDirectives = (mod.applicationIntents ?? mod.directives).filter(
143
+ (directive): directive is AnyDirective =>
144
+ directive !== undefined &&
145
+ typeof directive.id === "string" &&
146
+ typeof (directive as { payloadSchema?: unknown }).payloadSchema === "object" &&
147
+ (directive as { businessBirthInternal?: unknown }).businessBirthInternal !== true &&
148
+ // A directive the law offers only THROUGH a business intent is not a second client call.
149
+ publishingIntentOf(graph, mod.domain ?? mod.name, directive.id) === undefined,
150
+ );
151
+ const sourceTrustViaIds = new Set(
152
+ publicDirectives.flatMap((directive) =>
153
+ directive.businessSourceTrust === undefined
154
+ ? []
155
+ : [directive.businessSourceTrust.viaDirectiveId],
156
+ ),
157
+ );
158
+ const sourceTrustDirectives = authoredDirectives.filter((directive) =>
159
+ sourceTrustViaIds.has(directive.id),
160
+ );
161
+ for (const viaDirectiveId of sourceTrustViaIds) {
162
+ if (!sourceTrustDirectives.some((directive) => directive.id === viaDirectiveId)) {
163
+ throw new Error(
164
+ `Dart source-trust codegen: '${mod.domain ?? mod.name}' has no hidden directive '${viaDirectiveId}'`,
165
+ );
166
+ }
167
+ }
168
+ return {
169
+ publicDirectives,
170
+ sourceTrustViaIds,
171
+ sourceTrustDirectives,
172
+ encoderDirectives: [
173
+ ...new Map(
174
+ [...publicDirectives, ...sourceTrustDirectives]
175
+ .map((directive) => [directive.id, directive] as const),
176
+ ).values(),
177
+ ],
178
+ };
179
+ }
180
+
181
+ /** Exact private/public directive ids consumed by Dart operation codegen. */
182
+ export function dartBridgeClientOperationDirectiveIds(
183
+ mod: DomainModule,
184
+ graph: LawGraph,
185
+ ): readonly string[] {
186
+ return dartClientOperationSelection(mod, graph).encoderDirectives.map(
187
+ (directive) => directive.id,
188
+ );
189
+ }
126
190
 
127
191
  /** Dart reserved words that can't be method names — suffixed `_` if one slips through. */
128
192
  const DART_RESERVED = new Set([
@@ -175,13 +239,9 @@ export const dartInternalSourceTrustMethod = (directiveId: string): string =>
175
239
  export const dartHashConstName = (fileBase: string): string =>
176
240
  `${lcFirst(camel(fileBase))}DomainHash`;
177
241
 
178
- /** `todo-nomos` → `todoNomosInterfaceJson` — the baked structural-interface JSON const (#72). */
242
+ /** `todo-nomos` → `todoNomosInterface` — the generated structural contract (#72). */
179
243
  export const interfaceConstNameDart = (fileBase: string): string =>
180
- `${lcFirst(camel(fileBase))}InterfaceJson`;
181
-
182
- /** `todo-nomos` → `todoNomosCompatJson` — the baked client/law compat manifest JSON const (§5). */
183
- export const compatConstNameDart = (fileBase: string): string =>
184
- `${lcFirst(camel(fileBase))}CompatJson`;
244
+ `${lcFirst(camel(fileBase))}Interface`;
185
245
 
186
246
  /** Emit a Dart RAW triple-quoted string literal of an object's JSON (the interface is JSON-only
187
247
  * data — no `'`/`$`/backslash escaping concerns under `r'''…'''`; JSON never contains `'''`). */
@@ -189,9 +249,48 @@ function dartRawJson(value: unknown): string {
189
249
  return `r'''${JSON.stringify(value)}'''`;
190
250
  }
191
251
 
252
+ function dartRawText(value: string): string {
253
+ if (value.includes("'''")) {
254
+ throw new Error("generated Dart raw text contains its triple-quote delimiter");
255
+ }
256
+ return `r'''${value}'''`;
257
+ }
258
+
192
259
  const dartStr = (s: string) =>
193
260
  `'${s.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
194
261
 
262
+ const dartInterfaceSet = (
263
+ domainKey: string,
264
+ value: DomainInterface,
265
+ ): string => {
266
+ const directives = Object.entries(value.directives ?? {})
267
+ .sort(([left], [right]) => left.localeCompare(right))
268
+ .map(([id, directive]) => {
269
+ const fields = Object.entries(directive.fields ?? {})
270
+ .sort(([left], [right]) => left.localeCompare(right))
271
+ .map(([name, field]) =>
272
+ `InterfacePayloadField(name: ${dartStr(name)}, kind: ${dartStr(field.kind)}, optional: ${field.optional === true})`
273
+ );
274
+ return `InterfaceDirective(id: ${dartStr(id)}, fields: [${fields.join(", ")}])`;
275
+ });
276
+ const aggregates = Object.entries(value.aggregates ?? {})
277
+ .sort(([left], [right]) => left.localeCompare(right))
278
+ .map(([sid, aggregate]) => {
279
+ const fields = Object.entries(aggregate.fields ?? {})
280
+ .sort(([left], [right]) => left.localeCompare(right))
281
+ .map(([fieldSid, field]) =>
282
+ `InterfaceAggregateField(sid: ${dartStr(fieldSid)}, kind: ${dartStr(field.kind)}, label: ${dartStr(field.label ?? fieldSid)})`
283
+ );
284
+ return `InterfaceAggregate(sid: ${dartStr(aggregate.sid ?? sid)}, label: ${dartStr(aggregate.label ?? sid)}, fields: [${fields.join(", ")}])`;
285
+ });
286
+ const foreignReads = Object.entries(value.foreignReads ?? {})
287
+ .sort(([left], [right]) => left.localeCompare(right))
288
+ .flatMap(([directive, reads]) => reads.map((read) =>
289
+ `InterfaceForeignRead(directive: ${dartStr(directive)}, queryId: ${dartStr(read.queryId)}${read.from === undefined ? "" : `, source: ${dartStr(read.from)}`}${read.policy === undefined ? "" : `, policy: ${dartStr(read.policy)}`}${read.fromPayload === undefined ? "" : `, sourcePayloadField: ${dartStr(read.fromPayload)}`})`
290
+ ));
291
+ return `InterfaceSet(domains: [DomainInterface(formatVersion: ${value.v ?? 0}, domain: ${dartStr(value.domain ?? domainKey)}${value.domainSid === undefined ? "" : `, domainSid: ${dartStr(value.domainSid)}`}, directives: [${directives.join(", ")}], aggregates: [${aggregates.join(", ")}], foreignReads: [${foreignReads.join(", ")}])])`;
292
+ };
293
+
195
294
  const dartSealedValueName = (field: string): string =>
196
295
  `nmsInternalSealed${cap(camel(field))}`;
197
296
 
@@ -201,11 +300,11 @@ const dartSealKeyName = (field: string): string =>
201
300
  /** A schema-specific Dart expression for one public payload field. The USDA
202
301
  * encoder consumes typed values directly; any legacy arbitrary-data shape is a
203
302
  * compiler refusal, never a route back through JSON. */
204
- function dartCallUsdaFieldAccess(
303
+ function dartCallProtoFieldAccess(
205
304
  domain: string,
206
305
  directive: string,
207
306
  spec: PayloadFieldSpec
208
- ): DartCallUsdaFieldAccess {
307
+ ): DartCallProtoFieldAccess {
209
308
  const member = `payload.${dartMemberName(spec.name)}`;
210
309
  if (spec.nullAdmits === true) {
211
310
  return { value: member, slot: true };
@@ -358,7 +457,7 @@ function dartKeyParam(key: string): string {
358
457
  return safeMethod(safe);
359
458
  }
360
459
 
361
- /** Parse ONE bridge row (`{type,id,data}`) into a typed read model, composing the canonical `.ref` from the
460
+ /** Parse ONE session row (`{type,id,data}`) into a typed read model, composing the canonical `.ref` from the
362
461
  * session workspace (`_ws`, a getter on the client) + the row's type/id. Works for a `Map` (one-shot
363
462
  * `query`/`queryById` rows) or a `dynamic` (`watch` stream rows) — indexing resolves on both. */
364
463
  function rowToModel(model: string, rowVar: string, workspace = "_ws"): string {
@@ -402,7 +501,10 @@ function dartUsdaBasePresentValue(
402
501
  `Dart result USDA codegen: foreign reference '${spec.wireName}' has no workspace-field decoder`
403
502
  );
404
503
  }
405
- return `NmsInternalForeignRefs.create<${spec.foreignRefTarget}>(id: ${value}, workspace: ${foreignWorkspaceExpression}, type: '${spec.foreignRefAggregateType}', fromJson: ${spec.foreignRefTarget}.fromJson)`;
504
+ // A foreign reference is a typed, workspace-qualified locator. Decoding
505
+ // belongs to the generated application that owns the target domain; a
506
+ // source client must not capture another domain's private codec.
507
+ return `NmsInternalForeignRefs.create<${spec.foreignRefTarget}>(id: ${value}, workspace: ${foreignWorkspaceExpression}, type: '${spec.foreignRefAggregateType}')`;
406
508
  }
407
509
  if (spec.refIdClass !== undefined) {
408
510
  return `NmsInternalNomosRefs.create<${spec.refIdClass}>(workspace: ${workspace}, type: '${spec.refAggregateType}', id: ${value})`;
@@ -575,6 +677,10 @@ function dartUsdaProjectionValue(
575
677
  schema: z.ZodTypeAny,
576
678
  expression: string
577
679
  ): string {
680
+ const valueObject = voMetaOf(schema);
681
+ if (valueObject !== undefined) {
682
+ return `${valueObject.name}.fromProjected((${expression}.jsonValue() as Map).cast<String, Object?>())`;
683
+ }
578
684
  let inner = schema;
579
685
  while (
580
686
  zodKind(inner) === "optional" ||
@@ -615,6 +721,7 @@ interface DartUsdaResultDecoder {
615
721
  readonly spec: AggFieldSpec;
616
722
  readonly required: boolean;
617
723
  readonly foreignWorkspacePath?: string;
724
+ readonly foreignWorkspaceName?: string;
618
725
  }[];
619
726
  readonly computedFields: readonly {
620
727
  readonly name: string;
@@ -665,7 +772,7 @@ function emitDartUsdaResultDecoder(
665
772
  const selected = `row.field(${JSON.stringify(field.path)})`;
666
773
  return ` if (${selected} != null) ${JSON.stringify(
667
774
  name
668
- )}: FieldProvenance(author: ${selected}!.property('nomos:author') is String ? ${selected}.property('nomos:author') as String : null, wasContested: ${selected}.property('nomos:wasContested') == true),`;
775
+ )}: FieldProvenance(author: ${selected}!.property('nomos:author') is String ? ${selected}!.property('nomos:author') as String : null, wasContested: ${selected}!.property('nomos:wasContested') == true),`;
669
776
  });
670
777
  return [
671
778
  `List<${decoder.model}> ${functionName}(Uint8List bytes, String workspace) {`,
@@ -678,7 +785,7 @@ function emitDartUsdaResultDecoder(
678
785
  ` }`,
679
786
  ` final id = row.property('nomos:id');`,
680
787
  ` if (id is! String) throw const FormatException('USDA row has no string identity');`,
681
- ` return ${decoder.model}(`,
788
+ ` return NmsInternalRecordOrigins.remember(${decoder.model}(`,
682
789
  ` ref: NmsInternalNomosRefs.create<${
683
790
  decoder.refType
684
791
  }>(workspace: workspace, type: ${JSON.stringify(
@@ -689,32 +796,33 @@ function emitDartUsdaResultDecoder(
689
796
  : []),
690
797
  ...constructorFields,
691
798
  ...computedFields,
692
- ` );`,
799
+ ` ), workspace: workspace, type: ${JSON.stringify(decoder.runtimeType)}, id: id);`,
693
800
  ` }).toList(growable: false);`,
694
801
  `}`,
695
802
  `NomosPage<${decoder.model}> _nmsDecode${decoder.model}Page(Uint8List bytes, String workspace) {`,
696
803
  ` final result = NmsUsdaResult.parse(bytes);`,
697
804
  ` return NomosPage(rows: ${functionName}(bytes, workspace), cursor: result.cursor, done: result.done);`,
698
805
  `}`,
806
+ `/// Framework-internal nominal decoder used by a typed ForeignRef.`,
807
+ `${decoder.model}? nmsInternalDecode${decoder.model}ById(Uint8List bytes, String workspace, String id) {`,
808
+ ` for (final row in ${functionName}(bytes, workspace)) {`,
809
+ ` if (row.ref.id == id) return row;`,
810
+ ` }`,
811
+ ` return null;`,
812
+ `}`,
699
813
  ``,
700
814
  ];
701
815
  }
702
816
 
703
- export interface DartBridgeClientOptions {
817
+ export interface DartClientOptions {
704
818
  /** Content identity of the built typed USDA closure (`.law.usdz`). */
705
819
  readonly domainHash: string;
706
820
  /** Flutter asset key for the compiler-authored USDZ transport. Generated
707
821
  * child openers use it to inherit an accepted parent model through the
708
822
  * child's ordinary author gate. Omit for pure-Dart/vendored clients. */
709
- readonly lawAssetKey?: string;
710
- /** This domain's STRUCTURAL INTERFACE (#72) — directives (payload shapes) + aggregates
711
- * (read shapes, sid-keyed). Baked in as JSON so the app can negotiate shape-compatibility
712
- * against the workspace's installed offer, NOT by law hash. */
823
+ /** Compiler graph used to generate the one USDA compatibility matrix. */
713
824
  readonly interface?: unknown;
714
- /** The CLIENT/LAW COMPAT MANIFEST (§5) — the law hash + interface hash + generator provenance
715
- * this client was generated against. Baked in as JSON (DIAGNOSIS only, never a gate). */
716
- readonly compat?: unknown;
717
- /** Where the bridge/runtime support types are imported from. */
825
+ /** Where the session/runtime support types are imported from. */
718
826
  readonly supportImport?: "vendored" | "package";
719
827
  /**
720
828
  * Relative import of the shared `nomos_framework.dart` (framework-shared aggregate types, emitted
@@ -777,10 +885,10 @@ export interface DartBridgeClientOptions {
777
885
  };
778
886
  }
779
887
 
780
- /** Generate the `<name>.client.dart` async bridge client for one domain module. */
781
- export function generateDartBridgeClient(
888
+ /** Generate the `<name>.client.dart` async session client for one domain module. */
889
+ export function generateDartDomainClient(
782
890
  mod: DomainModule,
783
- opts: DartBridgeClientOptions
891
+ opts: DartClientOptions
784
892
  ): string {
785
893
  const callUsda = opts.callUsda;
786
894
  if (callUsda === undefined) {
@@ -791,25 +899,21 @@ export function generateDartBridgeClient(
791
899
  "application calls and results may not fall back to generic maps"
792
900
  );
793
901
  }
902
+ const operationSelection = dartClientOperationSelection(mod, callUsda.graph);
794
903
  const authoredDirectives = mod.directives as AnyDirective[];
795
904
  const workspaceSharingPolicies: readonly WorkspaceSharingPolicy[] =
796
905
  mod.applicationWorkspaceSharing ?? [];
797
- const workspaceSharingReceipts = [
798
- ...new Map(
799
- workspaceSharingPolicies
800
- .flatMap((policy) => [...policy.delivered, ...policy.refused])
801
- .map((receipt) => [receipt.records.id, receipt.records] as const)
802
- ).values(),
803
- ] as AnyDirective[];
804
- const workspaceSharingReceiptIds = new Set(
805
- workspaceSharingReceipts.map((directive) => directive.id)
906
+ const workspaceSharingQueryIds = new Set(
907
+ workspaceSharingPolicies.map(
908
+ (policy) => policy.invitationLaw.pendingByRecipient.id
909
+ )
806
910
  );
807
911
  const publicAggregates = mod.aggregates.filter(
808
912
  (a) =>
809
913
  (a as { businessBirthInternal?: unknown }).businessBirthInternal !== true
810
914
  );
811
915
  const publicAggregateIds = new Set(publicAggregates.map((a) => a.id));
812
- const publicDirectives = mod.applicationIntents ?? mod.directives;
916
+ const publicDirectives = operationSelection.publicDirectives;
813
917
  mod = {
814
918
  ...mod,
815
919
  aggregates: publicAggregates,
@@ -824,7 +928,8 @@ export function generateDartBridgeClient(
824
928
  queries: mod.queries.filter(
825
929
  (q) =>
826
930
  (q as { businessBirthInternal?: unknown })
827
- .businessBirthInternal !== true
931
+ .businessBirthInternal !== true ||
932
+ workspaceSharingQueryIds.has(q.id)
828
933
  ),
829
934
  }),
830
935
  ...(mod.readModelAggregates === undefined
@@ -884,6 +989,7 @@ export function generateDartBridgeClient(
884
989
  : qualifyReadProjectionType(ownerDomain, aggregateType);
885
990
  };
886
991
  const resultDecoderSources: string[] = [];
992
+ const resultProtoDecoderSources: string[] = [];
887
993
  const resultDecoderByAggregate = new Map<string, DartUsdaResultDecoder>();
888
994
  {
889
995
  for (const aggregate of mod.aggregates) {
@@ -959,7 +1065,10 @@ export function generateDartBridgeClient(
959
1065
  required: field.isFromBirth === true,
960
1066
  ...(foreignWorkspacePath === undefined
961
1067
  ? {}
962
- : { foreignWorkspacePath }),
1068
+ : {
1069
+ foreignWorkspacePath,
1070
+ foreignWorkspaceName: spec.foreignRefWorkspaceField,
1071
+ }),
963
1072
  };
964
1073
  });
965
1074
  const computedFields = [
@@ -1094,17 +1203,6 @@ export function generateDartBridgeClient(
1094
1203
  }
1095
1204
  return needsReadPrincipal(typeId) ? ", null, _client.actor" : "";
1096
1205
  };
1097
- // The DISTINCT encryption scopes this domain defines (across encrypted reads + sealing directives) — the
1098
- // set the owner ceremony rotates. Empty ⇒ no `encryption` getter is emitted for this domain.
1099
- const domScopes: string[] = (() => {
1100
- if (encMap === null) return [];
1101
- const s = new Set<string>();
1102
- for (const r of Object.values(encMap.reads))
1103
- for (const f of Object.values(r)) if (f.owned !== true) s.add(f.scope);
1104
- for (const dir of Object.values(encMap.directives))
1105
- for (const f of Object.values(dir)) if (f.owned !== true) s.add(f.scope);
1106
- return [...s].sort();
1107
- })();
1108
1206
  const ownedScopes: string[] = (() => {
1109
1207
  if (encMap === null) return [];
1110
1208
  const scopes = new Set<string>();
@@ -1135,7 +1233,7 @@ export function generateDartBridgeClient(
1135
1233
  ` /// publication. The kernel reads one compiled current pointer; it does not resolve history.`,
1136
1234
  ` Future<ReferenceVersionStatus<TVersion>> referenceVersionStatus<TVersion, TSeries>(`,
1137
1235
  ` VersionedNomosRef<TVersion, TSeries> reference) =>`,
1138
- ` bridge.checkReferenceVersion(reference);`,
1236
+ ` session.checkReferenceVersion(reference);`,
1139
1237
  ``
1140
1238
  );
1141
1239
  }
@@ -1176,10 +1274,6 @@ export function generateDartBridgeClient(
1176
1274
  // THE STATIC INTERFACE DESCRIPTOR (`XClient.interface`, session_bound_clients.md asks 5/9) —
1177
1275
  // what this client EXPECTS of a workspace: the domain key, the law hash it compiled under, and
1178
1276
  // the structural interface (#72). `bind(session)` / `session.assertCompatible(...)` consume it.
1179
- const compatInterfaceHash = (
1180
- opts.compat as { interfaceHash?: string } | undefined
1181
- )?.interfaceHash;
1182
-
1183
1277
  // ── directives → typed offer ──
1184
1278
  // A `.births()` directive is still authored on its bound parent workspace. It therefore uses the
1185
1279
  // same typed USDA/Protobuf offer door as every other directive; only the law's effect crosses custody.
@@ -1188,7 +1282,8 @@ export function generateDartBridgeClient(
1188
1282
  d &&
1189
1283
  typeof d.id === "string" &&
1190
1284
  typeof (d as { payloadSchema?: unknown }).payloadSchema === "object" &&
1191
- (d as { businessBirthInternal?: unknown }).businessBirthInternal !== true
1285
+ (d as { businessBirthInternal?: unknown }).businessBirthInternal !== true &&
1286
+ publishingIntentOf(callUsda.graph, mod.domain ?? mod.name, d.id) === undefined
1192
1287
  );
1193
1288
  const birthDirs = allDirs.filter(
1194
1289
  (d) => (d as { birthsChild?: boolean }).birthsChild === true
@@ -1196,119 +1291,10 @@ export function generateDartBridgeClient(
1196
1291
  const dirs = allDirs.filter(
1197
1292
  (d) => (d as { birthsChild?: boolean }).birthsChild !== true
1198
1293
  );
1199
- // Only a no-argument enrolled-device intent can be the client's automatic stale-token
1200
- // recovery hook. Enrolled-device intents with typed inputs are explicit business operations
1201
- // (for example all-device-loss recovery bound to a named principal) and remain ordinary
1202
- // generated APIs; their proof posture does not make them automatic lifecycle hooks.
1203
- const authenticationRecoveryDirs = dirs.filter(
1204
- (directive) =>
1205
- isBusinessIntent(directive) &&
1206
- directive.offerAuthenticationProof === "enrolledDevice" &&
1207
- introspectPayload(directive.payloadSchema as z.ZodTypeAny, enumDartTypes)
1208
- .length === 0
1209
- );
1210
- if (authenticationRecoveryDirs.length > 1) {
1211
- throw new Error(
1212
- `Dart client codegen: '${domain}' declares more than one enrolled-device authentication recovery intent; ` +
1213
- "the framework cannot choose a unique law-authored recovery operation"
1214
- );
1215
- }
1216
- const authenticationRecovery = authenticationRecoveryDirs[0];
1217
- const childAuthenticationRecoveries = dirs.flatMap((directive) => {
1218
- if (!isBusinessIntent(directive)) return [];
1219
- const aggregateId = childAuthenticationRecoveryAggregateId(directive);
1220
- if (aggregateId === undefined) return [];
1221
- const fields = introspectPayload(
1222
- directive.payloadSchema as z.ZodTypeAny,
1223
- enumDartTypes,
1224
- );
1225
- if (
1226
- fields.length !== 2 ||
1227
- fields.some(
1228
- (field) =>
1229
- !["workspace", "user"].includes(field.name) ||
1230
- field.optional ||
1231
- field.dartType !== "String",
1232
- )
1233
- ) {
1234
- throw new Error(
1235
- `Dart child-authentication recovery '${domain}/${directive.id}' must accept exactly required string fields { workspace, user }`,
1236
- );
1237
- }
1238
- return [{ aggregateId, directive }];
1239
- });
1240
- for (const recovery of childAuthenticationRecoveries) {
1241
- if (
1242
- childAuthenticationRecoveries.some(
1243
- (candidate) =>
1244
- candidate !== recovery &&
1245
- candidate.aggregateId === recovery.aggregateId,
1246
- )
1247
- ) {
1248
- throw new Error(
1249
- `Dart client codegen: '${domain}' declares more than one authentication repair action for '${recovery.aggregateId}'`,
1250
- );
1251
- }
1252
- const method = safeMethod(recovery.directive.id);
1253
- const input = dartActionInputClassName(recovery.directive);
1254
- methods.push(
1255
- ` /// Generated child-open recovery: inspect the child's kernel posture, then ask this`,
1256
- ` /// authenticated parent law to send its committed signer/provider state to that exact child.`,
1257
- ` Future<void> ${dartInternalChildAuthenticationRecoveryMethod(
1258
- recovery.aggregateId,
1259
- )}(String workspace) async {`,
1260
- ` final expectedPrincipal = actor ?? bridge.principal ?? '';`,
1261
- ` if (expectedPrincipal.isEmpty) {`,
1262
- ` throw StateError('Child authentication recovery requires the signed-in principal.');`,
1263
- ` }`,
1264
- ` final child = await bridge.acquireSession(workspace);`,
1265
- ` final posture = await child.nmsAuthenticationPosture(principal: expectedPrincipal);`,
1266
- ` if (posture.isReadyFor(expectedPrincipal)) return;`,
1267
- ` await ${method}(${input}(`,
1268
- ` workspace: workspace, user: expectedPrincipal,`,
1269
- ` ));`,
1270
- ` final parentSync = await bridge.sync(admit: true);`,
1271
- ` if (parentSync.offline || parentSync.pushFailed) {`,
1272
- ` throw StateError('Parent authentication recovery could not reach custody: ' +`,
1273
- ` (parentSync.hasPushError() ? parentSync.pushError.message : 'workspace is offline'));`,
1274
- ` }`,
1275
- ` await child.nmsAwaitProviderTokenReady(principal: expectedPrincipal);`,
1276
- ` await child.nmsAwaitAuthenticationReady(principal: expectedPrincipal);`,
1277
- ` }`,
1278
- ``,
1279
- );
1280
- }
1294
+ const sourceTrustViaIds = operationSelection.sourceTrustViaIds;
1295
+ const sourceTrustDirectives = operationSelection.sourceTrustDirectives;
1281
1296
  const localOfferDirs = [...dirs, ...birthDirs];
1282
- const sourceTrustViaIds = new Set(
1283
- dirs.flatMap((directive) =>
1284
- directive.businessSourceTrust === undefined
1285
- ? []
1286
- : [directive.businessSourceTrust.viaDirectiveId]
1287
- )
1288
- );
1289
- const sourceTrustDirectives = authoredDirectives.filter((directive) =>
1290
- sourceTrustViaIds.has(directive.id)
1291
- );
1292
- for (const viaDirectiveId of sourceTrustViaIds) {
1293
- if (
1294
- !sourceTrustDirectives.some(
1295
- (directive) => directive.id === viaDirectiveId
1296
- )
1297
- ) {
1298
- throw new Error(
1299
- `Dart source-trust codegen: '${domain}' has no hidden directive '${viaDirectiveId}'`
1300
- );
1301
- }
1302
- }
1303
- const encoderDirs = [
1304
- ...new Map(
1305
- [
1306
- ...localOfferDirs,
1307
- ...sourceTrustDirectives,
1308
- ...workspaceSharingReceipts,
1309
- ].map((directive) => [directive.id, directive] as const)
1310
- ).values(),
1311
- ];
1297
+ const encoderDirs = operationSelection.encoderDirectives;
1312
1298
  const callEncoderSources: string[] = [];
1313
1299
  const callEncoderByDirective = new Map<
1314
1300
  string,
@@ -1316,9 +1302,7 @@ export function generateDartBridgeClient(
1316
1302
  >();
1317
1303
  const internalRecordTypes = new Map<string, string>();
1318
1304
  for (const directive of encoderDirs) {
1319
- const compilerInternal =
1320
- sourceTrustViaIds.has(directive.id) ||
1321
- workspaceSharingReceiptIds.has(directive.id);
1305
+ const compilerInternal = sourceTrustViaIds.has(directive.id);
1322
1306
  const businessBirth = (
1323
1307
  directive as unknown as {
1324
1308
  businessBirth?: { publicPayloadSchema: z.ZodTypeAny };
@@ -1341,11 +1325,11 @@ export function generateDartBridgeClient(
1341
1325
  : dartActionInputClassName(directive);
1342
1326
  if (compilerInternal) internalRecordTypes.set(directive.id, payloadClass);
1343
1327
  const specsByName = new Map(specs.map((spec) => [spec.name, spec]));
1344
- const access = new Map<string, DartCallUsdaFieldAccess>();
1328
+ const access = new Map<string, DartCallProtoFieldAccess>();
1345
1329
  for (const spec of specs) {
1346
1330
  access.set(
1347
1331
  spec.name,
1348
- dartCallUsdaFieldAccess(domain, directive.id, spec)
1332
+ dartCallProtoFieldAccess(domain, directive.id, spec)
1349
1333
  );
1350
1334
  }
1351
1335
  const extraParameters: string[] = [];
@@ -1508,7 +1492,7 @@ export function generateDartBridgeClient(
1508
1492
  });
1509
1493
  }
1510
1494
  }
1511
- const encoder = emitDartCallUsdaEncoder(
1495
+ const encoder = emitDartCallProtoEncoder(
1512
1496
  callUsda.graph,
1513
1497
  callUsda.paths,
1514
1498
  domain,
@@ -1544,29 +1528,6 @@ export function generateDartBridgeClient(
1544
1528
  ``
1545
1529
  );
1546
1530
  }
1547
- for (const directive of workspaceSharingReceipts) {
1548
- const encoder = callEncoderByDirective.get(directive.id);
1549
- const payloadType = internalRecordTypes.get(directive.id);
1550
- if (
1551
- encoder === undefined ||
1552
- payloadType === undefined ||
1553
- encoder.arguments.some((argument) => argument !== "now")
1554
- ) {
1555
- throw new Error(
1556
- `Dart workspace-sharing codegen: hidden receipt '${domain}/${directive.id}' is not a closed typed record`
1557
- );
1558
- }
1559
- const method = dartInternalWorkspaceSharingReceiptMethod(directive.id);
1560
- const implementation =
1561
- encoder.arguments.length === 0
1562
- ? `=>\n _offer(${encoder.functionName}(payload));`
1563
- : `{\n final now = DateTime.now().toUtc().toIso8601String();\n return _offer(${encoder.functionName}(payload, now));\n }`;
1564
- methods.push(
1565
- ` /// @internal Compiler-generated workspace-sharing receipt. Not tenant application vocabulary.`,
1566
- ` Future<NomosOfferOutcome> ${method}(${payloadType} payload) ${implementation}`,
1567
- ``
1568
- );
1569
- }
1570
1531
  const ownedActionCallEncoders = new Map<
1571
1532
  string,
1572
1533
  {
@@ -1579,8 +1540,8 @@ export function generateDartBridgeClient(
1579
1540
  if (ownedScope !== undefined && Object.keys(ownedActions).length > 0) {
1580
1541
  const ownedAccess = (
1581
1542
  fields: readonly string[]
1582
- ): Map<string, DartCallUsdaFieldAccess> => {
1583
- const access = new Map<string, DartCallUsdaFieldAccess>();
1543
+ ): Map<string, DartCallProtoFieldAccess> => {
1544
+ const access = new Map<string, DartCallProtoFieldAccess>();
1584
1545
  for (const field of fields) {
1585
1546
  access.set(field, { value: `payload.${dartMemberName(field)}` });
1586
1547
  }
@@ -1618,7 +1579,7 @@ export function generateDartBridgeClient(
1618
1579
  for (const actions of Object.values(ownedActions)) {
1619
1580
  for (const action of ["share", "unshare", "transfer"] as const) {
1620
1581
  const directiveId = actions[action];
1621
- const encoder = emitDartCallUsdaEncoder(
1582
+ const encoder = emitDartCallProtoEncoder(
1622
1583
  callUsda.graph,
1623
1584
  callUsda.paths,
1624
1585
  domain,
@@ -1634,13 +1595,13 @@ export function generateDartBridgeClient(
1634
1595
  });
1635
1596
  }
1636
1597
  }
1637
- const approvalEncoder = emitDartCallUsdaEncoder(
1598
+ const approvalEncoder = emitDartCallProtoEncoder(
1638
1599
  callUsda.graph,
1639
1600
  callUsda.paths,
1640
1601
  domain,
1641
1602
  OWNED_DEVICE_APPROVAL_DIRECTIVE,
1642
1603
  "NomosOwnedDeviceApprovalPreparation",
1643
- new Map<string, DartCallUsdaFieldAccess>([
1604
+ new Map<string, DartCallProtoFieldAccess>([
1644
1605
  ["newKeySubject", { value: "payload.newKeySubject" }],
1645
1606
  ["ownedCustody", { value: "payload.ownedCustody" }],
1646
1607
  ["verifiedVia", { value: "payload.verifiedVia" }],
@@ -1675,48 +1636,10 @@ export function generateDartBridgeClient(
1675
1636
  const correctionActions = dirs.filter(
1676
1637
  (d) => (d as { businessBirth?: unknown }).businessBirth === undefined
1677
1638
  );
1678
- if (correctionActions.length > 0) {
1679
- const correctionsClass = `${className}Corrections`;
1680
- const outcomeClass = `${className}CorrectionOutcome`;
1681
- methods.push(
1682
- ` /// Correct this principal's latest business change. The framework owns target selection and replay.`,
1683
- ` ${correctionsClass} get corrections => ${correctionsClass}(this);`,
1684
- ``
1685
- );
1686
- pastDeclarations.push(
1687
- `/// Result of a reasoned business correction. Framework intent and testimony ids remain private.`,
1688
- `class ${outcomeClass} {`,
1689
- ` final bool ok;`,
1690
- ` final String kind;`,
1691
- ` final String? reason;`,
1692
- ` final String? message;`,
1693
- ` final String? head;`,
1694
- ` const ${outcomeClass}({required this.ok, required this.kind, this.reason, this.message, this.head});`,
1695
- ` factory ${outcomeClass}.fromJson(Map<String, Object?> json) => ${outcomeClass}(`,
1696
- ` ok: json['ok'] == true, kind: (json['kind'] ?? '') as String,`,
1697
- ` reason: json['reason'] as String?, message: json['message'] as String?, head: json['head'] as String?);`,
1698
- `}`,
1699
- ``,
1700
- `/// One business correction lane. Application code provides only its reason.`,
1701
- `class ${correctionsClass} {`,
1702
- ` final ${className} _client;`,
1703
- ` const ${correctionsClass}(this._client);`,
1704
- ` Future<${outcomeClass}> undo(String reason) => _apply('undo', reason);`,
1705
- ` Future<${outcomeClass}> redo(String reason) => _apply('redo', reason);`,
1706
- ` Future<${outcomeClass}> _apply(String kind, String reason) async {`,
1707
- ` if (reason.trim().isEmpty) throw ArgumentError('corrections.\$kind() needs a reason');`,
1708
- ` final result = await _client.bridge.correctMostRecent(`,
1709
- ` kind: kind, domain: ${dartStr(domain)},`,
1710
- ` actions: const [${correctionActions
1711
- .map((d) => dartStr(d.id))
1712
- .join(", ")}],`,
1713
- ` reason: reason, domainHash: _client.domainHash, actor: _client.actor);`,
1714
- ` return ${outcomeClass}.fromJson(result);`,
1715
- ` }`,
1716
- `}`,
1717
- ``
1718
- );
1719
- }
1639
+ // Corrections remain framework law, but no Dart API is emitted until the
1640
+ // peer runtime owns a nominal Runtime v2 correction command. The removed
1641
+ // surface called a JavaScript-only control method and decoded an anonymous
1642
+ // map, so it was neither portable nor end-to-end typed.
1720
1643
  for (const d of dirs) {
1721
1644
  const payloadClass = dartActionInputClassName(d);
1722
1645
  // targetBinding is declared on AnyDirective (directive.ts) — honour it for EVERY
@@ -1740,7 +1663,7 @@ export function generateDartBridgeClient(
1740
1663
  // THE AUTHORITY GATE (codegen-time): a directive carrying `.requires(relation)` is GATED — its method
1741
1664
  // throws MissingOfferAuthority when `actor` is null/empty, BEFORE any submit, so an actorless gated
1742
1665
  // offer is impossible to GENERATE (the war: the gate is structural, not just kernel-side). Secrets never
1743
- // appear — only the actor identity (the bridge owns signing).
1666
+ // appear — only the actor identity (the session owns signing).
1744
1667
  const gate = (d as { requiresRelationGate?: { relation: string } })
1745
1668
  .requiresRelationGate;
1746
1669
  const gateGuard =
@@ -1759,7 +1682,7 @@ export function generateDartBridgeClient(
1759
1682
  // bound [keyStore] before dispatch (a missing key throws [EncryptionKeyUnavailable] — never a plaintext
1760
1683
  // write). One async block covers creates + mutate + gated + stamps; `seal: false` is the escape hatch.
1761
1684
  // THE ONE WRITE OUTCOME (architecture/nomos_ref.md): EVERY directive method returns Future<NomosOfferOutcome>
1762
- // via the ONE lane `bridge.offerOutcome` — `outcome.created` carries every minted aggregate (each with its
1685
+ // via the ONE lane `session.offerOutcome` — `outcome.created` carries every minted aggregate (each with its
1763
1686
  // typed `.ref`), `outcome.head` the new local head. The breaking cut: creates AND non-creates alike.
1764
1687
  const createsDoc =
1765
1688
  (d as { marker?: string }).marker === "creates"
@@ -1772,7 +1695,7 @@ export function generateDartBridgeClient(
1772
1695
  principalField === undefined
1773
1696
  ? []
1774
1697
  : [
1775
- ` final nmsInternalPrincipal = actor ?? bridge.principal;`,
1698
+ ` final nmsInternalPrincipal = actor;`,
1776
1699
  ` if (nmsInternalPrincipal == null || nmsInternalPrincipal.trim().isEmpty) {`,
1777
1700
  ` throw MissingOfferAuthority(domain: ${dartStr(
1778
1701
  domain
@@ -1787,12 +1710,13 @@ export function generateDartBridgeClient(
1787
1710
  `Dart call USDA codegen: '${domain}/${d.id}' has no generated encoder`
1788
1711
  );
1789
1712
  }
1790
- const callUsda = `${callEncoder.functionName}(${[
1713
+ const generatedCall = `${callEncoder.functionName}(${[
1791
1714
  "payload",
1792
1715
  ...callEncoder.arguments,
1793
1716
  ].join(", ")})`;
1794
- const offerCall = `_offer(${callUsda}${
1795
- isBusinessIntent(d) && d.offerAuthenticationProof === "enrolledDevice"
1717
+ const offerCall = `_offer(${generatedCall}${
1718
+ isBusinessIntent(d) &&
1719
+ d.authentication?.kind === MemberAuthenticationKind.EnrolledDevice
1796
1720
  ? ", authenticationProof: NomosOfferAuthenticationProof.enrolledDevice"
1797
1721
  : ""
1798
1722
  })`;
@@ -1837,14 +1761,14 @@ export function generateDartBridgeClient(
1837
1761
  : recordTarget.kind === "premint"
1838
1762
  ? [
1839
1763
  ` final ownedRecordType = ${dartStr(runtimeType)};`,
1840
- ` final ownedRecordId = await bridge.mintId(ownedRecordType);`,
1764
+ ` final ownedRecordId = await session.mintId(ownedRecordType);`,
1841
1765
  ` const ownedRecordPreMinted = true;`,
1842
1766
  ]
1843
1767
  : recordTarget.kind === "payload"
1844
1768
  ? [
1845
1769
  ` final ownedRecordType = ${dartStr(runtimeType)};`,
1846
1770
  ` final ownedRecordId = ${
1847
- dartCallUsdaFieldAccess(
1771
+ dartCallProtoFieldAccess(
1848
1772
  domain,
1849
1773
  d.id,
1850
1774
  encryptedSpecs.get(recordTarget.field) ??
@@ -1865,7 +1789,7 @@ export function generateDartBridgeClient(
1865
1789
  const ownedKeyPrelude = ownedSeal
1866
1790
  ? [
1867
1791
  ...recordPrelude,
1868
- ` final nmsInternalOwnedKey = await bridge.nomosOwnedScopeKey(`,
1792
+ ` final nmsInternalOwnedKey = await session.nomosOwnedScopeKey(`,
1869
1793
  ` ${dartStr(Object.values(directiveEncryption)[0]!.scope)},`,
1870
1794
  ` recordType: ownedRecordType, recordId: ownedRecordId);`,
1871
1795
  ` final nmsInternalOwnedKeySubject = nmsInternalOwnedKey.ownedKeySubject;`,
@@ -1912,7 +1836,7 @@ export function generateDartBridgeClient(
1912
1836
  ` if (${key} == null) throw EncryptionKeyUnavailable(${dartStr(
1913
1837
  descriptor.scope
1914
1838
  )}, ${dartStr(field)});`,
1915
- ` ${sealed} = await bridge.cryptoSealField(`,
1839
+ ` ${sealed} = await session.cryptoSealField(`,
1916
1840
  ` scopeKey: ${key}.key, scope: ${
1917
1841
  descriptor.owned === true
1918
1842
  ? `${key}.scope`
@@ -2013,7 +1937,7 @@ export function generateDartBridgeClient(
2013
1937
  }
2014
1938
  }
2015
1939
 
2016
- // ── `.births()` directives → typed CROSS-WORKSPACE birth (bridge.createWorkspace) ──
1940
+ // ── `.births()` directives → typed CROSS-WORKSPACE birth (session.createWorkspace) ──
2017
1941
  // Each births a CHILD WORKSPACE under `parent` via a signed governance offer routed by the PARENT'S
2018
1942
  // law (POST /v2/workspaces/<parent>/<directiveId>) — never a same-workspace write. The declaring
2019
1943
  // domain's key + directiveId + baked domainHash are all bound at codegen time, so a frontend dev
@@ -2090,7 +2014,7 @@ export function generateDartBridgeClient(
2090
2014
  ownedBirthDescriptor === undefined
2091
2015
  ? []
2092
2016
  : [
2093
- ` final nmsInternalOwnedKey = await bridge.nomosOwnedBirthScopeKey(`,
2017
+ ` final nmsInternalOwnedKey = await session.nomosOwnedBirthScopeKey(`,
2094
2018
  ` ${dartStr(ownedBirthDescriptor.scope)}, ${dartStr(
2095
2019
  businessBirth.namespace
2096
2020
  )}, payload.${dartMemberName(businessBirth.keyField)}, ${dartStr(
@@ -2132,7 +2056,7 @@ export function generateDartBridgeClient(
2132
2056
  ` if (${key} == null) throw EncryptionKeyUnavailable(${dartStr(
2133
2057
  descriptor.scope
2134
2058
  )}, ${dartStr(field)});`,
2135
- ` ${sealed} = await bridge.cryptoSealField(`,
2059
+ ` ${sealed} = await session.cryptoSealField(`,
2136
2060
  ` scopeKey: ${key}.key, scope: ${
2137
2061
  descriptor.owned === true
2138
2062
  ? `${key}.scope`
@@ -2196,7 +2120,7 @@ export function generateDartBridgeClient(
2196
2120
  ` Future<NomosRef<${concreteClassName(
2197
2121
  businessBirth.aggregateId
2198
2122
  )}>> ${publicMethod}(${payloadClass} payload) async {`,
2199
- ` final principal = actor ?? bridge.principal;`,
2123
+ ` final principal = actor;`,
2200
2124
  ` if (principal == null || principal.trim().isEmpty) {`,
2201
2125
  ` throw MissingOfferAuthority(domain: ${dartStr(
2202
2126
  domain
@@ -2204,21 +2128,19 @@ export function generateDartBridgeClient(
2204
2128
  d.id
2205
2129
  )}, requires: 'a signed-in Nomos session');`,
2206
2130
  ` }`,
2207
- ` await _preflightOnce();`,
2208
- ` await _prepareCommand(${dartStr(d.id)});`,
2209
2131
  ...(businessBirth.domain === domain
2210
2132
  ? []
2211
2133
  : [
2212
2134
  ` // This parent offer synchronously runs the child genesis plan. Name that exact`,
2213
2135
  ` // authenticated slice now so birth never composes an unrelated or cold domain.`,
2214
- ` await bridge.prepareDomain(domain: ${dartStr(
2136
+ ` await session.prepareDomain(domain: ${dartStr(
2215
2137
  businessBirth.domain
2216
2138
  )}, directiveId: ${dartStr(
2217
2139
  seedDirectiveId
2218
2140
  )}, packageHash: ${hashConst});`,
2219
2141
  ...genesisDirectiveIds.map(
2220
2142
  (directiveId) =>
2221
- ` await bridge.prepareDomain(domain: ${dartStr(
2143
+ ` await session.prepareDomain(domain: ${dartStr(
2222
2144
  businessBirth.domain
2223
2145
  )}, directiveId: ${dartStr(
2224
2146
  directiveId
@@ -2298,7 +2220,9 @@ export function generateDartBridgeClient(
2298
2220
  }
2299
2221
 
2300
2222
  // ── declared queries → one-shot + reactive ──
2301
- for (const q of (mod.queries ?? []) as QueryDecl[]) {
2223
+ for (const read of [...(mod.queries ?? []), ...(mod.orderedReads ?? [])]) {
2224
+ const ordered = "orderKey" in read ? read : undefined;
2225
+ const q = "orderKey" in read ? { id: read.id, returns: read.of, key: [] as string[] } : read;
2302
2226
  const model = readModelClassName(q.returns);
2303
2227
  const agg = aggById.get(q.returns);
2304
2228
  const params = q.key
@@ -2307,7 +2231,7 @@ export function generateDartBridgeClient(
2307
2231
  `required ${dartKeyType(agg, k, enumDartTypes)} ${dartKeyParam(k)}`
2308
2232
  )
2309
2233
  .join(", ");
2310
- const queryEncoder = emitDartQueryUsdaEncoder(
2234
+ const queryEncoder = emitDartQueryProtoEncoder(
2311
2235
  callUsda.graph,
2312
2236
  callUsda.paths,
2313
2237
  domain,
@@ -2327,29 +2251,82 @@ export function generateDartBridgeClient(
2327
2251
  );
2328
2252
  callEncoderSources.push(...queryEncoder.source);
2329
2253
  const queryCall = queryEncoder.call;
2254
+ const queryNode = callUsda.graph.nodes.find(
2255
+ (node): node is LawRowReadNode =>
2256
+ node.kind === "read" &&
2257
+ (node.readKind === "query" || node.readKind === "ordered") &&
2258
+ node.entity.label === q.id
2259
+ );
2260
+ if (queryNode === undefined) {
2261
+ throw new Error(
2262
+ `Dart result Protobuf codegen: composed law has no '${domain}.${q.id}' query`
2263
+ );
2264
+ }
2265
+ const aggregateDecoder = resultDecoderByAggregate.get(q.returns);
2266
+ if (aggregateDecoder === undefined) {
2267
+ throw new Error(
2268
+ `Dart result Protobuf codegen: '${domain}.${q.id}' has no '${q.returns}' result model`
2269
+ );
2270
+ }
2271
+ const resultProtoDecoder = emitDartQueryResultProtoDecoder(
2272
+ callUsda.graph,
2273
+ callUsda.paths,
2274
+ queryNode,
2275
+ aggregateDecoder
2276
+ );
2277
+ resultProtoDecoderSources.push(...resultProtoDecoder.source);
2278
+ const decodeRows = resultProtoDecoder.rowsFunction;
2279
+ const decodePage = resultProtoDecoder.pageFunction;
2330
2280
  const m = safeMethod(lcFirst(camel(q.id)));
2331
2281
  const qScopes = readScopesFor(q.returns);
2332
2282
  const qOwned = qScopes.some((scope) => scope.owned === true);
2333
2283
  const qPrivate = needsReadPrincipal(q.returns);
2334
2284
  const qScopesExpr = scopesExpr(qScopes);
2335
2285
  const nominalWatch = qOwned
2336
- ? `bridge.nmsWatchUsda(${queryCall}${
2286
+ ? `session.nmsWatch(${queryCall}${
2337
2287
  qPrivate ? ", principal: actor" : ""
2338
- }).asyncMap((_) => _readWithOwnedKeys(${qScopesExpr}, (keys) async => _nmsDecode${model}Rows(await bridge.nmsQueryUsda(${queryCall}, keys${
2288
+ }).asyncMap((result) async => _readWithOwnedKeys(${qScopesExpr}, (keys) async => ${decodeRows}(await session.nmsQuery(${queryCall}, keys${
2339
2289
  qPrivate ? ", actor" : ""
2340
- }), _ws), (row) => row.ref))`
2290
+ }), _ws), (row) => row.ref, initial: await ${decodeRows}(result, _ws)))`
2341
2291
  : qScopes.length
2342
- ? `Stream.fromFuture(_readKeys(${qScopesExpr})).asyncExpand((keys) => bridge.nmsWatchUsda(${queryCall}, keys: keys${
2292
+ ? `Stream.fromFuture(_readKeys(${qScopesExpr})).asyncExpand((keys) => session.nmsWatch(${queryCall}, keys: keys${
2343
2293
  qPrivate ? ", principal: actor" : ""
2344
- }).map((usda) => _nmsDecode${model}Rows(usda, _ws)))`
2345
- : `bridge.nmsWatchUsda(${queryCall}${
2294
+ }).asyncMap((result) => ${decodeRows}(result, _ws)))`
2295
+ : `session.nmsWatch(${queryCall}${
2346
2296
  qPrivate ? ", principal: actor" : ""
2347
- }).map((usda) => _nmsDecode${model}Rows(usda, _ws))`;
2297
+ }).asyncMap((result) => ${decodeRows}(result, _ws))`;
2298
+ if (ordered !== undefined) {
2299
+ const resultType = ordered.limit === 1 ? `${model}?` : `List<${model}>`;
2300
+ const select = ordered.limit === 1 ? "rows.isEmpty ? null : rows.single" : "rows";
2301
+ const live = qOwned
2302
+ ? `_readWithOwnedKeys(${qScopesExpr}, (keys) async => ${decodeRows}(await session.nmsQuery(${queryCall}, keys${qPrivate ? ", actor" : ""}), _ws), (row) => row.ref)`
2303
+ : `${decodeRows}(await session.nmsQuery(${queryCall}${keysArg(q.returns)}), _ws)`;
2304
+ const past = qOwned
2305
+ ? `_client._readWithOwnedKeys(${qScopesExpr}, (keys) async => ${decodeRows}(await _client.session.nmsQueryAt(moment, ${queryCall}, keys${qPrivate ? ", _client.actor" : ""}), _client._ws), (row) => row.ref)`
2306
+ : `${decodeRows}(await _client.session.nmsQueryAt(moment, ${queryCall}${pastKeysArg(q.returns)}), _client._ws)`;
2307
+ methods.push(
2308
+ ` /// Ordered by installed law, limited to ${ordered.limit} visible records.`,
2309
+ ` Future<${resultType}> ${m}() async {`,
2310
+ ` final rows = await ${live};`,
2311
+ ` return ${select};`,
2312
+ ` }`,
2313
+ ` Stream<${resultType}> watch${cap(camel(q.id))}() => (${nominalWatch}).map((rows) => ${select});`,
2314
+ ``,
2315
+ );
2316
+ pastMethods.push(
2317
+ ` Future<${resultType}> ${m}() async {`,
2318
+ ` final rows = await ${past};`,
2319
+ ` return ${select};`,
2320
+ ` }`,
2321
+ ``,
2322
+ );
2323
+ continue;
2324
+ }
2348
2325
  const pageRead = qOwned
2349
- ? `_readPageWithOwnedKeys(${qScopesExpr}, (keys) async => _nmsDecode${model}Page(await bridge.nmsQueryPageUsda(${queryCall}, pageSize: pageSize, cursor: cursor, keys: keys${
2326
+ ? `_readPageWithOwnedKeys(${qScopesExpr}, (keys) async => ${decodePage}(await session.nmsQueryPage(${queryCall}, pageSize: pageSize, cursor: cursor, keys: keys${
2350
2327
  qPrivate ? ", principal: actor" : ""
2351
2328
  }), _ws), (row) => row.ref)`
2352
- : `_nmsDecode${model}Page(await bridge.nmsQueryPageUsda(${queryCall}, pageSize: pageSize, cursor: cursor${
2329
+ : `${decodePage}(await session.nmsQueryPage(${queryCall}, pageSize: pageSize, cursor: cursor${
2353
2330
  qScopes.length ? `, keys: await _readKeys(${qScopesExpr})` : ""
2354
2331
  }${qPrivate ? ", principal: actor" : ""}), _ws)`;
2355
2332
  methods.push(
@@ -2361,10 +2338,10 @@ export function generateDartBridgeClient(
2361
2338
  ` @Deprecated('Whole-result reads scale with result size; use ${m}Page().')`,
2362
2339
  ` Future<List<${model}>> ${m}({${params}}) async =>`,
2363
2340
  qOwned
2364
- ? ` _readWithOwnedKeys(${qScopesExpr}, (keys) async => _nmsDecode${model}Rows(await bridge.nmsQueryUsda(${queryCall}, keys${
2341
+ ? ` _readWithOwnedKeys(${qScopesExpr}, (keys) async => ${decodeRows}(await session.nmsQuery(${queryCall}, keys${
2365
2342
  qPrivate ? ", actor" : ""
2366
2343
  }), _ws), (row) => row.ref);`
2367
- : ` _nmsDecode${model}Rows(await bridge.nmsQueryUsda(${queryCall}${keysArg(
2344
+ : ` ${decodeRows}(await session.nmsQuery(${queryCall}${keysArg(
2368
2345
  q.returns
2369
2346
  )}), _ws);`,
2370
2347
  ``,
@@ -2385,10 +2362,10 @@ export function generateDartBridgeClient(
2385
2362
  ` /// Declared query \`${q.id}\` in the verified world at [moment].`,
2386
2363
  ` Future<List<${model}>> ${m}({${params}}) async =>`,
2387
2364
  qOwned
2388
- ? ` _client._readWithOwnedKeys(${qScopesExpr}, (keys) async => _nmsDecode${model}Rows(await _client.bridge.nmsQueryAtUsda(moment, ${queryCall}, keys${
2365
+ ? ` _client._readWithOwnedKeys(${qScopesExpr}, (keys) async => ${decodeRows}(await _client.session.nmsQueryAt(moment, ${queryCall}, keys${
2389
2366
  qPrivate ? ", _client.actor" : ""
2390
2367
  }), _client._ws), (row) => row.ref);`
2391
- : ` _nmsDecode${model}Rows(await _client.bridge.nmsQueryAtUsda(moment, ${queryCall}${pastKeysArg(
2368
+ : ` ${decodeRows}(await _client.session.nmsQueryAt(moment, ${queryCall}${pastKeysArg(
2392
2369
  q.returns
2393
2370
  )}), _client._ws);`,
2394
2371
  ``
@@ -2407,7 +2384,7 @@ export function generateDartBridgeClient(
2407
2384
  ` /// Declared spatial index \`${sp.id}\` — rows of \`${sp.of}\` whose \`${sp.on}\` geometry`,
2408
2385
  ` /// intersects [bbox] (an R*Tree probe on the local projection, never a scan).`,
2409
2386
  ` Future<List<${model}>> ${m}({required NomosBbox bbox}) async =>`,
2410
- ` _nmsDecode${model}Rows(await bridge.nmsSpatialWithinUsda(${dartStr(
2387
+ ` _nmsDecode${model}Rows(await session.nmsSpatialWithinUsda(${dartStr(
2411
2388
  sp.id
2412
2389
  )}, bbox), _ws);`,
2413
2390
  ``,
@@ -2415,7 +2392,7 @@ export function generateDartBridgeClient(
2415
2392
  ` Stream<List<${model}>> watch${cap(
2416
2393
  camel(sp.id)
2417
2394
  )}({required NomosBbox bbox}) =>`,
2418
- ` bridge.nmsWatchSpatialUsda(${dartStr(
2395
+ ` session.nmsWatchSpatialUsda(${dartStr(
2419
2396
  sp.id
2420
2397
  )}, bbox).map((usda) => _nmsDecode${model}Rows(usda, _ws));`,
2421
2398
  ``
@@ -2435,10 +2412,10 @@ export function generateDartBridgeClient(
2435
2412
  c.by
2436
2413
  }\`.\n Future<int> ${m}(${groupType} ${dartKeyParam(
2437
2414
  c.by
2438
- )}) => bridge.nmsCount(${dartStr(c.id)}, ${groupValue});`
2415
+ )}) => session.nmsCount(${dartStr(c.id)}, ${groupValue});`
2439
2416
  : ` /// Declared count \`${
2440
2417
  c.id
2441
- }\` — the maintained O(1) grand total.\n Future<int> ${m}() => bridge.nmsCount(${dartStr(
2418
+ }\` — the maintained O(1) grand total.\n Future<int> ${m}() => session.nmsCount(${dartStr(
2442
2419
  c.id
2443
2420
  )});`,
2444
2421
  ``
@@ -2449,16 +2426,31 @@ export function generateDartBridgeClient(
2449
2426
  c.id
2450
2427
  }\` at [moment].\n Future<int> ${m}(${groupType} ${dartKeyParam(
2451
2428
  c.by
2452
- )}) => _client.bridge.nmsCountAt(moment, ${dartStr(
2429
+ )}) => _client.session.nmsCountAt(moment, ${dartStr(
2453
2430
  c.id
2454
2431
  )}, ${groupValue});`
2455
2432
  : ` /// Declared count \`${
2456
2433
  c.id
2457
- }\` at [moment].\n Future<int> ${m}() => _client.bridge.nmsCountAt(moment, ${dartStr(
2434
+ }\` at [moment].\n Future<int> ${m}() => _client.session.nmsCountAt(moment, ${dartStr(
2458
2435
  c.id
2459
2436
  )});`,
2460
2437
  ``
2461
2438
  );
2439
+ methods.push(
2440
+ ` /// Observe the maintained tally; unchanged counts emit no new value.`,
2441
+ ` Stream<int> watch${cap(camel(c.id))}(${c.by == null ? "" : `${groupType} ${dartKeyParam(c.by)}`}) => session.nmsWatchCount(${dartStr(c.id)}${c.by == null ? "" : `, ${groupValue}`});`,
2442
+ ``,
2443
+ );
2444
+ }
2445
+ for (const membership of (mod.exists_ ?? []).map(finishExists)) {
2446
+ const method = safeMethod(lcFirst(camel(membership.id)));
2447
+ const aggregate = aggById.get(membership.of);
2448
+ const parameter = membership.by == null ? ""
2449
+ : `${dartKeyType(aggregate, membership.by, enumDartTypes)} ${dartKeyParam(membership.by)}`;
2450
+ const args = `${dartStr(membership.id)}${membership.by == null ? "" : `, ${dartKeyExpr(aggregate, membership.by)}`}`;
2451
+ methods.push(` /// Declared membership over the maintained count, never a row scan.`,
2452
+ ` Future<bool> ${method}(${parameter}) async => (await session.nmsCount(${args})) > 0;`, ``);
2453
+ pastMethods.push(` Future<bool> ${method}(${parameter}) async => (await _client.session.nmsCountAt(moment, ${args})) > 0;`, ``);
2462
2454
  }
2463
2455
  for (const s of (mod.sums ?? []).map((raw) => finishSum(raw))) {
2464
2456
  const m = safeMethod(lcFirst(camel(s.id)));
@@ -2472,10 +2464,10 @@ export function generateDartBridgeClient(
2472
2464
  s.by
2473
2465
  }\`.\n Future<int> ${m}(${groupType} ${dartKeyParam(
2474
2466
  s.by
2475
- )}) => bridge.nmsSum(${dartStr(s.id)}, ${groupValue});`
2467
+ )}) => session.nmsSum(${dartStr(s.id)}, ${groupValue});`
2476
2468
  : ` /// Declared sum \`${
2477
2469
  s.id
2478
- }\` — the maintained O(1) grand total.\n Future<int> ${m}() => bridge.nmsSum(${dartStr(
2470
+ }\` — the maintained O(1) grand total.\n Future<int> ${m}() => session.nmsSum(${dartStr(
2479
2471
  s.id
2480
2472
  )});`,
2481
2473
  ``
@@ -2486,18 +2478,36 @@ export function generateDartBridgeClient(
2486
2478
  s.id
2487
2479
  }\` at [moment].\n Future<int> ${m}(${groupType} ${dartKeyParam(
2488
2480
  s.by
2489
- )}) => _client.bridge.nmsSumAt(moment, ${dartStr(
2481
+ )}) => _client.session.nmsSumAt(moment, ${dartStr(
2490
2482
  s.id
2491
2483
  )}, ${groupValue});`
2492
2484
  : ` /// Declared sum \`${
2493
2485
  s.id
2494
- }\` at [moment].\n Future<int> ${m}() => _client.bridge.nmsSumAt(moment, ${dartStr(
2486
+ }\` at [moment].\n Future<int> ${m}() => _client.session.nmsSumAt(moment, ${dartStr(
2495
2487
  s.id
2496
2488
  )});`,
2497
2489
  ``
2498
2490
  );
2499
2491
  }
2500
2492
 
2493
+ for (const extremum of [...(mod.mins ?? []), ...(mod.maxes ?? [])].map(finishExtremum)) {
2494
+ const method = safeMethod(lcFirst(camel(extremum.id)));
2495
+ const aggregate = aggById.get(extremum.of);
2496
+ const parameter = extremum.by == null ? ""
2497
+ : `${dartKeyType(aggregate, extremum.by, enumDartTypes)} ${dartKeyParam(extremum.by)}`;
2498
+ const args = `${dartStr(extremum.id)}, ${dartStr(extremum.kind)}${extremum.by == null ? "" : `, ${dartKeyExpr(aggregate, extremum.by)}`}`;
2499
+ methods.push(
2500
+ ` /// Declared ${extremum.kind}. Null means no contributing member; zero is a value.`,
2501
+ ` Future<int?> ${method}(${parameter}) => session.nmsExtremum(${args});`,
2502
+ ``,
2503
+ );
2504
+ pastMethods.push(
2505
+ ` /// Declared ${extremum.kind} at [moment].`,
2506
+ ` Future<int?> ${method}(${parameter}) => _client.session.nmsExtremumAt(moment, ${args});`,
2507
+ ``,
2508
+ );
2509
+ }
2510
+
2501
2511
  // ── BUSINESS MERGE CONFLICT DX: keep the heterogeneous Nomos index behind an aggregate-specific,
2502
2512
  // chained API. A pending conflict is a typed reference to its own `merge(...)` capability; callers
2503
2513
  // inspect all versions and produce a merge result rather than choosing a winner.
@@ -2531,7 +2541,7 @@ export function generateDartBridgeClient(
2531
2541
  ``,
2532
2542
  ` /// Nomos-internal aggregate-filtered index used only by generated conflict references.`,
2533
2543
  ` Future<List<${rowClass}>> _pendingConflictRows(String aggregateType) async =>`,
2534
- ` NmsUsdaConflictResult.parse(await bridge.nmsPendingConflictsUsda(aggregateType))`,
2544
+ ` NmsUsdaConflictResult.parse(await session.nmsPendingConflictsUsda(aggregateType))`,
2535
2545
  ` .rows.map(${rowClass}.fromUsda).toList(growable: false);`,
2536
2546
  ``
2537
2547
  );
@@ -2750,7 +2760,7 @@ export function generateDartBridgeClient(
2750
2760
  ``,
2751
2761
  ` Future<${summaryClass}> summary() async {`,
2752
2762
  ` final summary = NmsUsdaConflictSummaryResult.parse(`,
2753
- ` await _client.bridge.nmsPendingConflictSummaryUsda());`,
2763
+ ` await _client.session.nmsPendingConflictSummaryUsda());`,
2754
2764
  ` int count(String aggregatePath) {`,
2755
2765
  ` for (final entry in summary.byAggregate) {`,
2756
2766
  ` if (entry.aggregatePath == aggregatePath) return entry.count;`,
@@ -3014,27 +3024,27 @@ export function generateDartBridgeClient(
3014
3024
  const nominalByIdWatch = aScopes.length
3015
3025
  ? `Stream.fromFuture(_readKeys(${aScopesExpr}${
3016
3026
  aOwned ? `, [(type: ${dartStr(runtimeType)}, id: id)]` : ""
3017
- })).asyncExpand((keys) => bridge.nmsWatchByIdUsda(${dartStr(
3027
+ })).asyncExpand((keys) => session.nmsWatchByIdUsda(${dartStr(
3018
3028
  runtimeType
3019
3029
  )}, id, keys: keys${
3020
3030
  aPrivate ? ", principal: actor" : ""
3021
3031
  }).map((usda) => _nmsDecode${model}Rows(usda, _ws)))`
3022
- : `bridge.nmsWatchByIdUsda(${dartStr(runtimeType)}, id${
3032
+ : `session.nmsWatchByIdUsda(${dartStr(runtimeType)}, id${
3023
3033
  aPrivate ? ", principal: actor" : ""
3024
3034
  }).map((usda) => _nmsDecode${model}Rows(usda, _ws))`;
3025
3035
  const nominalByTypeWatch = aOwned
3026
- ? `bridge.nmsWatchByTypeUsda(${dartStr(runtimeType)}${
3036
+ ? `session.nmsWatchByTypeUsda(${dartStr(runtimeType)}${
3027
3037
  aPrivate ? ", principal: actor" : ""
3028
- }).asyncMap((_) => _readWithOwnedKeys(${aScopesExpr}, (keys) async => _nmsDecode${model}Rows(await bridge.nmsQueryByTypeUsda(${dartStr(
3038
+ }).asyncMap((usda) => _readWithOwnedKeys(${aScopesExpr}, (keys) async => _nmsDecode${model}Rows(await session.nmsQueryByTypeUsda(${dartStr(
3029
3039
  runtimeType
3030
- )}, keys${aPrivate ? ", actor" : ""}), _ws), (row) => row.ref))`
3040
+ )}, keys${aPrivate ? ", actor" : ""}), _ws), (row) => row.ref, initial: _nmsDecode${model}Rows(usda, _ws)))`
3031
3041
  : aScopes.length
3032
- ? `Stream.fromFuture(_readKeys(${aScopesExpr})).asyncExpand((keys) => bridge.nmsWatchByTypeUsda(${dartStr(
3042
+ ? `Stream.fromFuture(_readKeys(${aScopesExpr})).asyncExpand((keys) => session.nmsWatchByTypeUsda(${dartStr(
3033
3043
  runtimeType
3034
3044
  )}, keys: keys${
3035
3045
  aPrivate ? ", principal: actor" : ""
3036
3046
  }).map((usda) => _nmsDecode${model}Rows(usda, _ws)))`
3037
- : `bridge.nmsWatchByTypeUsda(${dartStr(runtimeType)}${
3047
+ : `session.nmsWatchByTypeUsda(${dartStr(runtimeType)}${
3038
3048
  aPrivate ? ", principal: actor" : ""
3039
3049
  }).map((usda) => _nmsDecode${model}Rows(usda, _ws))`;
3040
3050
  methods.push(
@@ -3044,7 +3054,7 @@ export function generateDartBridgeClient(
3044
3054
  : ""
3045
3055
  }`,
3046
3056
  ` Future<List<${model}>> ${safeMethod(`${lc}ById`)}(String id) async =>`,
3047
- ` _nmsDecode${model}Rows(await bridge.nmsQueryByIdUsda(${dartStr(
3057
+ ` _nmsDecode${model}Rows(await session.nmsQueryByIdUsda(${dartStr(
3048
3058
  runtimeType
3049
3059
  )}, id${byIdKeys}), _ws);`,
3050
3060
  ``,
@@ -3055,10 +3065,10 @@ export function generateDartBridgeClient(
3055
3065
  ` /// Every ${agg.id} (the type-index probe — O(result), not a scan).`,
3056
3066
  ` Future<List<${model}>> ${safeMethod(`list${Cap}s`)}() async =>`,
3057
3067
  aOwned
3058
- ? ` _readWithOwnedKeys(${aScopesExpr}, (keys) async => _nmsDecode${model}Rows(await bridge.nmsQueryByTypeUsda(${dartStr(
3068
+ ? ` _readWithOwnedKeys(${aScopesExpr}, (keys) async => _nmsDecode${model}Rows(await session.nmsQueryByTypeUsda(${dartStr(
3059
3069
  runtimeType
3060
3070
  )}, keys${aPrivate ? ", actor" : ""}), _ws), (row) => row.ref);`
3061
- : ` _nmsDecode${model}Rows(await bridge.nmsQueryByTypeUsda(${dartStr(
3071
+ : ` _nmsDecode${model}Rows(await session.nmsQueryByTypeUsda(${dartStr(
3062
3072
  runtimeType
3063
3073
  )}${keysArg(agg.id)}), _ws);`,
3064
3074
  ``,
@@ -3070,184 +3080,25 @@ export function generateDartBridgeClient(
3070
3080
  pastMethods.push(
3071
3081
  ` /// Read one ${agg.id} by aggregate id in the verified world at [moment].`,
3072
3082
  ` Future<List<${model}>> ${safeMethod(`${lc}ById`)}(String id) async =>`,
3073
- ` _nmsDecode${model}Rows(await _client.bridge.nmsQueryByIdAtUsda(moment, ${dartStr(
3083
+ ` _nmsDecode${model}Rows(await _client.session.nmsQueryByIdAtUsda(moment, ${dartStr(
3074
3084
  runtimeType
3075
3085
  )}, id${pastByIdKeys}), _client._ws);`,
3076
3086
  ``,
3077
3087
  ` /// Every ${agg.id} in the verified world at [moment].`,
3078
3088
  ` Future<List<${model}>> ${safeMethod(`list${Cap}s`)}() async =>`,
3079
3089
  aOwned
3080
- ? ` _client._readWithOwnedKeys(${aScopesExpr}, (keys) async => _nmsDecode${model}Rows(await _client.bridge.nmsQueryByTypeAtUsda(moment, ${dartStr(
3090
+ ? ` _client._readWithOwnedKeys(${aScopesExpr}, (keys) async => _nmsDecode${model}Rows(await _client.session.nmsQueryByTypeAtUsda(moment, ${dartStr(
3081
3091
  runtimeType
3082
3092
  )}, keys${
3083
3093
  aPrivate ? ", _client.actor" : ""
3084
3094
  }), _client._ws), (row) => row.ref);`
3085
- : ` _nmsDecode${model}Rows(await _client.bridge.nmsQueryByTypeAtUsda(moment, ${dartStr(
3095
+ : ` _nmsDecode${model}Rows(await _client.session.nmsQueryByTypeAtUsda(moment, ${dartStr(
3086
3096
  runtimeType
3087
3097
  )}${pastKeysArg(agg.id)}), _client._ws);`,
3088
3098
  ``
3089
3099
  );
3090
3100
  }
3091
3101
 
3092
- if (opts.emitActivity === true)
3093
- methods.push(
3094
- ` /// Adopt THIS generated model. Nomos proves it against current history; a deliberate`,
3095
- ` /// difference returns a decision whose accept(reason) re-proves and records the reason.`,
3096
- ` NomosModel get model => NomosModel(_adoptGeneratedModel, _restorePreviousGeneratedModel);`,
3097
- ``,
3098
- ` NomosModelReview _nomosModelReview(ModelLifecycleResponse result) {`,
3099
- ` final report = result.hasReview() ? result.review : null;`,
3100
- ` return NomosModelReview(`,
3101
- ` checkedActions: report?.checkedActions.toInt() ?? 0,`,
3102
- ` candidateActions: report?.candidateActions.toInt() ?? 0,`,
3103
- ` sameOutcome: report?.hasSameOutcome() == true ? report!.sameOutcome : null,`,
3104
- ` differences: [`,
3105
- ` for (final difference in report?.differences ?? const [])`,
3106
- ` NomosModelDifference(`,
3107
- ` kind: switch (difference.kind) {`,
3108
- ` ModelDifferenceKind.MODEL_DIFFERENCE_KIND_RULES => NomosModelDifferenceKind.rules,`,
3109
- ` ModelDifferenceKind.MODEL_DIFFERENCE_KIND_OUTCOME => NomosModelDifferenceKind.outcome,`,
3110
- ` ModelDifferenceKind.MODEL_DIFFERENCE_KIND_EVIDENCE => NomosModelDifferenceKind.evidence,`,
3111
- ` _ => NomosModelDifferenceKind.rules,`,
3112
- ` },`,
3113
- ` area: difference.hasArea() ? difference.area : null,`,
3114
- ` action: difference.hasAction() ? difference.action : null,`,
3115
- ` summary: difference.summary,`,
3116
- ` ),`,
3117
- ` ],`,
3118
- ` );`,
3119
- ` }`,
3120
- ``,
3121
- ...(authenticationRecovery === undefined
3122
- ? [` Future<NomosModelAdoption> _adoptGeneratedModel([String? because]) async {`]
3123
- : [
3124
- ` Future<NomosModelAdoption> _adoptGeneratedModel([String? because]) =>`,
3125
- ` _adoptGeneratedModelAttempt(because, false);`,
3126
- ` Future<NomosModelAdoption> _adoptGeneratedModelAttempt(`,
3127
- ` String? because, bool recoveredProviderEpoch) async {`,
3128
- ]),
3129
- ` final result = await bridge.nomosFrameworkAdoptGeneratedModel(`,
3130
- ` domain: ${dartStr(
3131
- domain
3132
- )}, candidateHash: domainHash, because: because);`,
3133
- ` final review = _nomosModelReview(result);`,
3134
- ` final stage = result.stage;`,
3135
- ...(authenticationRecovery === undefined
3136
- ? []
3137
- : [
3138
- ` if (!result.accepted && !recoveredProviderEpoch) {`,
3139
- ` final posture = await bridge.nmsAuthenticationPosture(principal: actor);`,
3140
- ` if (posture.providerToken == NomosProviderTokenVerification.noMatchingKey) {`,
3141
- ` print('[nomos-model-recovery] local ${domain} posture=' + posture.providerToken.name);`,
3142
- ` await ${safeMethod(
3143
- authenticationRecovery.id
3144
- )}(const ${dartActionInputClassName(authenticationRecovery)}());`,
3145
- ` await bridge.nmsAwaitAuthenticationReady(principal: actor);`,
3146
- ` return _adoptGeneratedModelAttempt(because, true);`,
3147
- ` }`,
3148
- ` }`,
3149
- ]),
3150
- ` if ((stage == ModelLifecycleStage.MODEL_LIFECYCLE_STAGE_PROMOTED ||`,
3151
- ` stage == ModelLifecycleStage.MODEL_LIFECYCLE_STAGE_ALREADY_CURRENT) && result.accepted) {`,
3152
- ` return NomosModelAdoption.adopted(`,
3153
- ` summary: stage == ModelLifecycleStage.MODEL_LIFECYCLE_STAGE_PROMOTED`,
3154
- ` ? 'Nomos proved this model against current history and made it active.'`,
3155
- ` : 'This workspace already runs this model or a server-side successor.',`,
3156
- ` review: review);`,
3157
- ` }`,
3158
- ...(opts.lawAssetKey === undefined
3159
- ? []
3160
- : [
3161
- ` if (stage == ModelLifecycleStage.MODEL_LIFECYCLE_STAGE_STAGING_REQUIRED) {`,
3162
- ` return NomosModelAdoption.needsStaging(`,
3163
- ` summary: 'This workspace is running an older model. Stage this generated USDA candidate through the signed workspace gate before reviewing it.',`,
3164
- ` review: review,`,
3165
- ` stage: () async {`,
3166
- ` await _stageGeneratedModel();`,
3167
- ` return _adoptGeneratedModel();`,
3168
- ` },`,
3169
- ` );`,
3170
- ` }`,
3171
- ]),
3172
- ` if (stage == ModelLifecycleStage.MODEL_LIFECYCLE_STAGE_ACCEPTANCE_REQUIRED) {`,
3173
- ` return NomosModelAdoption.needsDecision(`,
3174
- ` summary: 'This model would change prior business outcomes. Review the differences and record why that is intended.',`,
3175
- ` review: review, accept: (reason) => _adoptGeneratedModel(reason));`,
3176
- ` }`,
3177
- ` final rawError = result.hasMessage() ? result.message.trim() : '';`,
3178
- ` final summary = rawError.isNotEmpty`,
3179
- ` ? rawError`,
3180
- ` : stage == ModelLifecycleStage.MODEL_LIFECYCLE_STAGE_IDENTITY_REQUIRED`,
3181
- ` ? 'Sign in before adopting this model so the decision is accountable.'`,
3182
- ` : 'The workspace changed or refused this adoption. Nothing changed; ask Nomos to try again.';`,
3183
- ` return NomosModelAdoption.blocked(summary: summary, review: review);`,
3184
- ` }`,
3185
- ``,
3186
- ...(opts.lawAssetKey === undefined
3187
- ? []
3188
- : [
3189
- ` Future<void> _stageGeneratedModel() async {`,
3190
- ` final archive = await rootBundle.load(${dartStr(
3191
- opts.lawAssetKey
3192
- )});`,
3193
- ` Future<void> attempt() => bridge.nomosInternalStageGeneratedModel(`,
3194
- ` domain: ${dartStr(domain)},`,
3195
- ` candidateHash: domainHash,`,
3196
- ` lawUsdz: archive.buffer.asUint8List(`,
3197
- ` archive.offsetInBytes, archive.lengthInBytes),`,
3198
- ` );`,
3199
- ...(authenticationRecovery === undefined
3200
- ? [` await attempt();`]
3201
- : [
3202
- ` try {`,
3203
- ` await attempt();`,
3204
- ` } on NomosModelStageFailure {`,
3205
- ` final posture = await bridge.nmsAuthenticationPosture(principal: actor);`,
3206
- ` print('[nomos-model-recovery] local ${domain} posture=' + posture.providerToken.name);`,
3207
- ` if (posture.providerToken != NomosProviderTokenVerification.noMatchingKey) rethrow;`,
3208
- ` await ${safeMethod(
3209
- authenticationRecovery.id
3210
- )}(const ${dartActionInputClassName(
3211
- authenticationRecovery
3212
- )}());`,
3213
- ` await bridge.nmsAwaitAuthenticationReady(principal: actor);`,
3214
- ` await attempt();`,
3215
- ` }`,
3216
- ]),
3217
- ` }`,
3218
- ``,
3219
- ]),
3220
- ` Future<NomosModelRestoration> _restorePreviousGeneratedModel([String? because]) async {`,
3221
- ` final result = await bridge.nomosFrameworkRestorePreviousGeneratedModel(`,
3222
- ` domain: ${dartStr(
3223
- domain
3224
- )}, currentHash: domainHash, because: because);`,
3225
- ` final review = _nomosModelReview(result);`,
3226
- ` final stage = result.stage;`,
3227
- ` if (stage == ModelLifecycleStage.MODEL_LIFECYCLE_STAGE_RESTORED && result.accepted) {`,
3228
- ` return NomosModelRestoration.restored(`,
3229
- ` summary: 'Nomos re-proved current history and restored the previous model.', review: review);`,
3230
- ` }`,
3231
- ` if (stage == ModelLifecycleStage.MODEL_LIFECYCLE_STAGE_ACCEPTANCE_REQUIRED) {`,
3232
- ` return NomosModelRestoration.needsDecision(`,
3233
- ` summary: 'Restoring the previous model changes which rules govern future work. Review the effects and record why restoration is intended.',`,
3234
- ` review: review, accept: (reason) => _restorePreviousGeneratedModel(reason));`,
3235
- ` }`,
3236
- ` final error = result.hasMessage() ? result.message : '';`,
3237
- ` final summary = stage == ModelLifecycleStage.MODEL_LIFECYCLE_STAGE_IDENTITY_REQUIRED`,
3238
- ` ? 'Sign in before restoring a model so the decision is accountable.'`,
3239
- ` : error.contains('restore-no-previous')`,
3240
- ` ? 'This is the first model for this business; there is no previous model to restore.'`,
3241
- ` : error.contains('restore-current-changed')`,
3242
- ` ? 'The current model changed before restoration could finish. Nothing changed; ask Nomos to review again.'`,
3243
- ` : error.isNotEmpty`,
3244
- ` ? error`,
3245
- ` : 'The workspace refused restoration. Nothing changed and the current model remains active.';`,
3246
- ` return NomosModelRestoration.blocked(summary: summary, review: review);`,
3247
- ` }`,
3248
- ``
3249
- );
3250
-
3251
3102
  const pastClass = `${className}Past`;
3252
3103
  const atClass = `${className}At`;
3253
3104
  methods.push(
@@ -3262,7 +3113,7 @@ export function generateDartBridgeClient(
3262
3113
  ` const ${pastClass}(this._client);`,
3263
3114
  ``,
3264
3115
  ` Future<List<NomosMoment>> moments({int limit = 100}) async {`,
3265
- ` final moments = await _client.bridge.moments(limit: limit);`,
3116
+ ` final moments = await _client.session.moments(limit: limit);`,
3266
3117
  ` const actions = <String>{${[
3267
3118
  ...allDirs.map((directive) => directive.id),
3268
3119
  ...(correctionActions.length > 0 ? [BUSINESS_CORRECTION_DIRECTIVE] : []),
@@ -3295,7 +3146,7 @@ export function generateDartBridgeClient(
3295
3146
  // ── REF-TRAVERSAL ACCESSORS (dart_codegen_parity.md P2 + §2a follow-on — ref ergonomics) ──
3296
3147
  // For every reference field on a read model, emit a companion extension method that resolves the
3297
3148
  // stored locator to the actual target row, composed ONLY from surface that already exists (no new
3298
- // read path, no new bridge op). THREE kinds, one grammar (`<Model>Refs on <Model>`):
3149
+ // read path, no new session op). THREE kinds, one grammar (`<Model>Refs on <Model>`):
3299
3150
  // 1. SAME-DOMAIN `t.ref(Target)` (target in THIS module) — resolver takes THIS client, dispatches
3300
3151
  // to its own `<target>ById` accessor. (The #72 original.)
3301
3152
  // 2. CROSS-DOMAIN same-workspace `t.ref(Target)` (target in ANOTHER domain of the package) — the
@@ -3436,46 +3287,9 @@ export function generateDartBridgeClient(
3436
3287
  ``
3437
3288
  );
3438
3289
  }
3439
- for (const [fieldName, f] of foreignRefs) {
3440
- const fr = f.foreignRef!;
3441
- const targetType = fr.targetAggregateId;
3442
- // The resolver returns the target's CONCRETE class. We can
3443
- // only reference it when it is reachable from this file: SAME-domain (already in the imported types),
3444
- // or a CROSS-DOMAIN concrete target in the package (import its sibling `<name>.dart` `show`-limited).
3445
- // A contract target (its DTO lives in the shared contracts file) or an unmapped target is left as the
3446
- // raw `ForeignRef<T>` field — no resolver, no dangling type reference.
3447
- if (fr.targetIsContract === true) continue;
3448
- const owner = pkgDomains[targetType];
3449
- const targetInThisDomain =
3450
- aggById.has(targetType) || owner?.name === thisDomainName;
3451
- if (!targetInThisDomain) {
3452
- if (owner === undefined) continue; // target not in this package — unreachable, skip the resolver
3453
- // LAYERED-packages mode: the sibling domain's TYPES file lives in the TYPES package, not
3454
- // beside this client file — a relative `<name>.dart` import points at a nonexistent path in
3455
- // the client package (the co2 0.75.0 regression). The types-barrel import above already
3456
- // re-exports every generated concrete class, so the extra import is only needed FLAT.
3457
- if (opts.typesImportUri === undefined)
3458
- addImport(`${owner.name}.dart`, concreteClassName(targetType));
3459
- }
3460
- const targetConcrete = concreteClassName(targetType);
3461
- const member = dartMemberName(fieldName);
3462
- const memberValue = admitsNull(f) ? `${member}.valueOrNull` : member;
3463
- // The stored locator member is a typed `ForeignRef<Target>?` getter, so the resolver takes a
3464
- // `remote…` name to avoid colliding with it (and to read as "the far side of the reference").
3465
- const method = safeMethod(`remote${cap(camel(member))}`);
3466
- lines.push(
3467
- ` /// Resolve \`${fieldName}\` (${agg.id}.${fieldName} -> ${targetType} @ another workspace, a`,
3468
- ` /// \`t.foreignRef\` locator) over the session-bound multi-workspace plane. The generated`,
3469
- ` /// implementation opens the foreign workspace on demand; tenant code sees only this business method.`,
3470
- ` /// Null locator (absent / empty id or workspace) ⇒ null.`,
3471
- ` Future<${targetConcrete}?> ${method}(NomosEngine engine, {String? cloud}) {`,
3472
- ` final ref = ${memberValue};`,
3473
- ` if (ref == null) return Future<${targetConcrete}?>.value(null);`,
3474
- ` return NmsInternalForeignRefs.resolve(ref, engine.foreignReader(cloud: cloud));`,
3475
- ` }`,
3476
- ``
3477
- );
3478
- }
3290
+ // Cross-workspace resolution belongs to the stateless application facade,
3291
+ // which receives Peer Office's binding. Read-model values never accept a
3292
+ // runtime/reception object or open custody themselves.
3479
3293
  lines.push(`}`);
3480
3294
  refExtensions.push(lines.join("\n"));
3481
3295
  }
@@ -3488,18 +3302,32 @@ export function generateDartBridgeClient(
3488
3302
  ` /// committed intent; a directive`,
3489
3303
  ` /// outside this generated business package is dropped. Cancel the subscription to stop.`,
3490
3304
  ` /// A bounded recent activity feed. [limit] is required and kernel-capped.`,
3491
- ` Stream<List<ActivityEvent>> watchRecentActivity({required int limit}) =>`,
3492
- ` bridge.watchActivity(limit: limit).map((rows) => rows`,
3493
- ` .map((r) => renderActivity((r as Map).cast<String, dynamic>()))`,
3494
- ` .whereType<ActivityEvent>()`,
3495
- ` .toList());`,
3305
+ ` Stream<List<ActivityEvent>> watchRecentActivity({required int limit}) async* {`,
3306
+ ` yield await recentActivity(limit: limit);`,
3307
+ ` await for (final _ in session.syncEvents) {`,
3308
+ ` yield await recentActivity(limit: limit);`,
3309
+ ` }`,
3310
+ ` }`,
3496
3311
  ``,
3497
3312
  ` /// A bounded one-shot recent activity feed. [limit] is required and kernel-capped.`,
3498
- ` Future<List<ActivityEvent>> recentActivity({String? base, required int limit}) async =>`,
3499
- ` (await bridge.activityLog(base: base, limit: limit))`,
3500
- ` .map((r) => renderActivity(r.cast<String, dynamic>()))`,
3501
- ` .whereType<ActivityEvent>()`,
3502
- ` .toList();`,
3313
+ ` Future<List<ActivityEvent>> recentActivity({String? base, required int limit}) async {`,
3314
+ ` if (base != null) {`,
3315
+ ` throw UnsupportedError('Historic activity cursors need a nominal Runtime v2 contract.');`,
3316
+ ` }`,
3317
+ ` return (await session.moments(limit: limit)).map((moment) {`,
3318
+ ` final action = moment.action ?? 'recordedChange';`,
3319
+ ` final eventDomain = moment.domain ?? ${dartStr(domain)};`,
3320
+ ` final kind = '\$eventDomain.\$action';`,
3321
+ ` return ActivityEvent(`,
3322
+ ` eventId: moment.id, kind: kind, performedBy: moment.performedBy ?? '',`,
3323
+ ` occurredAt: moment.occurredAt?.toUtc().toIso8601String() ?? '',`,
3324
+ ` title: action, message: 'Recorded \$action in \$eventDomain',`,
3325
+ ` titleKey: 'activity.\$kind.title', messageKey: 'activity.\$kind.message',`,
3326
+ ` params: const <String, String>{}, refs: const <String, ActivityRef>{},`,
3327
+ ` severity: ActivitySeverity.info, domain: eventDomain, directiveId: action,`,
3328
+ ` );`,
3329
+ ` }).toList(growable: false);`,
3330
+ ` }`,
3503
3331
  ``,
3504
3332
  ` @Deprecated('Reconstructs ledger history. Use recentActivity with an explicit bounded limit, or a DSL managed count for quantities.')`,
3505
3333
  ` Future<List<ActivityEvent>> activityLog({String? base, int? limit}) =>`,
@@ -3515,20 +3343,21 @@ export function generateDartBridgeClient(
3515
3343
  ` NomosDescribeSection section = NomosDescribeSection.root,`,
3516
3344
  ` String? since, String? performedBy, String? category, int? limit,`,
3517
3345
  ` }) async {`,
3518
- ` final raw = await bridge.activityLog(limit: limit);`,
3519
- ` var events = raw`,
3520
- ` .map((r) => renderActivity(r.cast<String, dynamic>()))`,
3521
- ` .whereType<ActivityEvent>()`,
3522
- ` .toList();`,
3346
+ ` var events = await recentActivity(limit: limit ?? 50);`,
3523
3347
  ` if (performedBy != null) events = events.where((e) => e.performedBy == performedBy).toList();`,
3524
3348
  ` if (category != null) events = events.where((e) => e.category == category).toList();`,
3525
3349
  ` if (since != null) events = events.where((e) => e.occurredAt.compareTo(since) >= 0).toList();`,
3526
3350
  ` final narrative = activityNarrative(events);`,
3527
3351
  ` var organisation = const NomosOrganisationDescription(complete: false, children: []);`,
3528
3352
  ` try {`,
3529
- ` final children = (await bridge.nomosFrameworkChildWorkspaces()).map((child) {`,
3530
- ` final workspace = child['workspace']?.toString() ?? '';`,
3531
- ` final status = child['status']?.toString() ?? 'unknown';`,
3353
+ ` final children = (await session.nomosFrameworkChildWorkspaces()).map((child) {`,
3354
+ ` final workspace = child.workspace;`,
3355
+ ` final status = switch (child.status) {`,
3356
+ ` ChildWorkspaceStatus.CHILD_WORKSPACE_STATUS_ACTIVE => 'active',`,
3357
+ ` ChildWorkspaceStatus.CHILD_WORKSPACE_STATUS_RETIRED => 'retired',`,
3358
+ ` ChildWorkspaceStatus.CHILD_WORKSPACE_STATUS_RECLAIMED => 'reclaimed',`,
3359
+ ` _ => 'unknown',`,
3360
+ ` };`,
3532
3361
  ` final summary = status == 'active'`,
3533
3362
  ` ? 'This part of the organisation is active. Follow its generated description to continue.'`,
3534
3363
  ` : status == 'retired'`,
@@ -3537,7 +3366,7 @@ export function generateDartBridgeClient(
3537
3366
  ` ? "This part of the organisation was reclaimed. Its birth remains part of this workspace's history."`,
3538
3367
  ` : 'This part of the organisation has a newer lifecycle this client does not understand. Its link remains visible.';`,
3539
3368
  ` return NomosDescribeChild(`,
3540
- ` workspace: workspace, status: status, bornAt: child['bornAt']?.toString(), label: workspace,`,
3369
+ ` workspace: workspace, status: status, bornAt: child.hasBornAt() ? child.bornAt : null, label: workspace,`,
3541
3370
  ` question: 'What does this part of the organisation do, and what has happened there?', summary: summary);`,
3542
3371
  ` }).where((child) => child.workspace.isNotEmpty).toList();`,
3543
3372
  ` organisation = NomosOrganisationDescription(complete: children.every((child) => child.status != 'unknown'), children: children);`,
@@ -3594,23 +3423,11 @@ export function generateDartBridgeClient(
3594
3423
  ` for (final rawAggregate in ((model['aggregateTypes'] as List?) ?? const [])) {`,
3595
3424
  ` final aggregate = (rawAggregate as Map).cast<String, dynamic>();`,
3596
3425
  ` final type = aggregate['type'] as String;`,
3597
- ` final queryType = aggregate['queryType'] as String;`,
3598
3426
  ` final label = aggregate['label'] as String;`,
3599
- ` try {`,
3600
- ` final rows = await bridge.query('aggregatesByType', {'__type': queryType});`,
3601
- ` final refs = rows.map((row) => NmsInternalNomosRefs.create<Object?>(`,
3602
- ` workspace: _ws, type: (row['type'] ?? type).toString(), id: (row['id'] ?? '').toString())).toList();`,
3603
- ` final exact = aggregate['audience'] == 'public' || rows.isNotEmpty;`,
3604
- ` items.add(NomosDescribeItem(`,
3605
- ` kind: 'current', id: '\${aggregate['domain']}.\$type', label: label,`,
3606
- ` summary: exact ? '\${rows.length} \$label record\${rows.length == 1 ? '' : 's'} visible now.' : 'No \$label records are visible to this session.',`,
3607
- ` details: {'domain': aggregate['domain'], 'type': type, 'audience': aggregate['audience'], if (exact) 'count': rows.length else 'status': 'none-visible'}, refs: refs));`,
3608
- ` } catch (_) {`,
3609
- ` items.add(NomosDescribeItem(`,
3610
- ` kind: 'current', id: '\${aggregate['domain']}.\$type', label: label,`,
3611
- ` summary: '\$label exists in the model, but this session cannot read its current records.',`,
3612
- ` details: {'domain': aggregate['domain'], 'type': type, 'audience': aggregate['audience'], 'status': 'unavailable'}));`,
3613
- ` }`,
3427
+ ` items.add(NomosDescribeItem(`,
3428
+ ` kind: 'current', id: '\${aggregate['domain']}.\$type', label: label,`,
3429
+ ` summary: '\$label records are read through the generated typed application API.',`,
3430
+ ` details: {'domain': aggregate['domain'], 'type': type, 'audience': aggregate['audience'], 'status': 'typed-read'}));`,
3614
3431
  ` }`,
3615
3432
  ` } else if (section == NomosDescribeSection.history) {`,
3616
3433
  ` title = 'Verified business history';`,
@@ -3657,7 +3474,7 @@ export function generateDartBridgeClient(
3657
3474
  ` return null;`,
3658
3475
  ` }`,
3659
3476
  ` final pendingConflicts = NmsUsdaConflictResult.parse(`,
3660
- ` await bridge.nmsPendingConflictsUsda(null));`,
3477
+ ` await session.nmsPendingConflictsUsda(null));`,
3661
3478
  ` for (final conflict in pendingConflicts.rows) {`,
3662
3479
  ` final aggregatePath = conflict.relationship('nomos:type');`,
3663
3480
  ` final fieldPath = conflict.relationship('nomos:field');`,
@@ -3693,7 +3510,7 @@ export function generateDartBridgeClient(
3693
3510
  ` }`,
3694
3511
  ` final modelPageItems = ((((model['pages'] as Map)['model'] as Map)['items'] as List?) ?? const [])`,
3695
3512
  ` .map((raw) => (raw as Map).cast<String, dynamic>()).where((item) => item['kind'] == 'verb').toList();`,
3696
- ` for (final entry in await bridge.deadLetters()) {`,
3513
+ ` for (final entry in await session.deadLetters()) {`,
3697
3514
  ` if (!entry.hasDomain() || !entry.hasDirective()) continue;`,
3698
3515
  ` final domain = entry.domain; final directive = entry.directive;`,
3699
3516
  ` Map<String, dynamic>? action;`,
@@ -3714,7 +3531,7 @@ export function generateDartBridgeClient(
3714
3531
  ` items = [`,
3715
3532
  ` NomosDescribeItem(kind: 'evidence', id: 'workspace', label: 'Workspace', summary: _ws, details: {'workspace': _ws}),`,
3716
3533
  ` NomosDescribeItem(kind: 'evidence', id: 'law', label: 'Generated law', summary: domainHash, details: {'domainHash': domainHash}),`,
3717
- ` NomosDescribeItem(kind: 'evidence', id: 'reader', label: 'Verified reader', summary: this.actor ?? bridge.principal ?? 'anonymous', details: {'actor': this.actor ?? bridge.principal}),`,
3534
+ ` NomosDescribeItem(kind: 'evidence', id: 'reader', label: 'Verified reader', summary: this.actor ?? 'anonymous', details: {'actor': this.actor}),`,
3718
3535
  ` if (latest != null) NomosDescribeItem(kind: 'evidence', id: latest.eventId, label: 'Latest verified moment', summary: latest.eventId,`,
3719
3536
  ` details: {'occurredAt': latest.occurredAt, 'performedBy': latest.performedBy, 'domain': latest.domain, 'kind': latest.kind}),`,
3720
3537
  ` ];`,
@@ -3727,10 +3544,7 @@ export function generateDartBridgeClient(
3727
3544
  ` /// NARRATIVE for ONE thing: the story of the aggregate [aggregateId] — events whose declared refs`,
3728
3545
  ` /// point at it (only directives declaring a ref to the aggregate appear in its story) + a transcript.`,
3729
3546
  ` Future<ActivityNarrative> describeHistory(String aggregateId, {int? limit}) async {`,
3730
- ` final raw = await bridge.activityLog(limit: limit);`,
3731
- ` final events = raw`,
3732
- ` .map((r) => renderActivity(r.cast<String, dynamic>()))`,
3733
- ` .whereType<ActivityEvent>()`,
3547
+ ` final events = (await recentActivity(limit: limit ?? 50))`,
3734
3548
  ` .where((e) => e.refs.values.any((ref) => ref.id == aggregateId))`,
3735
3549
  ` .toList();`,
3736
3550
  ` return activityNarrative(events);`,
@@ -3742,30 +3556,38 @@ export function generateDartBridgeClient(
3742
3556
  return [
3743
3557
  `// AUTO-GENERATED by nomos-compile — private runtime implementation for domain "${domain}".`,
3744
3558
  `// Regenerated every compile; do not edit or teach this file as an application entry point.`,
3745
- // GENERATED-CODE lints: the bridge read/watch surface returns dynamic (JSON rows), so typed accessors
3559
+ // GENERATED-CODE lints: the session read/watch surface returns dynamic (JSON rows), so typed accessors
3746
3560
  // do dynamic member access + casts by construction. Silence the lints that only make sense for
3747
3561
  // hand-written code, so this file never adds noise to a tenant's analyzer output (co2 feedback).
3748
3562
  // (deprecated_member_use*: the compatibility shims intentionally delegate to the deprecated
3749
3563
  // engine-level lanes for one minor version.)
3750
- `// ignore_for_file: avoid_dynamic_calls, unnecessary_this, unnecessary_cast, prefer_const_constructors, unused_import, unused_local_variable, type_annotate_public_apis, always_specify_types, deprecated_member_use, deprecated_member_use_from_same_package, invalid_use_of_internal_member`,
3564
+ `// ignore_for_file: avoid_dynamic_calls, unnecessary_this, unnecessary_cast, prefer_const_constructors, unused_import, unused_local_variable, type_annotate_public_apis, always_specify_types, deprecated_member_use, deprecated_member_use_from_same_package, invalid_use_of_internal_member, unnecessary_non_null_assertion, unnecessary_null_comparison`,
3565
+ ``,
3566
+ `import 'dart:async' show unawaited;`,
3751
3567
  ``,
3752
3568
  // `dart:convert` is needed ONLY for the interface block's `jsonDecode` — the offer lane no longer encodes
3753
- // any envelope (it routes through `bridge.offerDirective` → THE ONE ENCODER). Omit it when no interface.
3569
+ // any envelope (it routes through `session.offerDirective` → THE ONE ENCODER). Omit it when no interface.
3754
3570
  ...(clientInterface !== undefined ||
3755
3571
  opts.emitActivity === true ||
3756
3572
  localOfferDirs.length > 0 ||
3757
3573
  callEncoderSources.length > 0
3758
3574
  ? [`import 'dart:convert';`, ``]
3759
3575
  : []),
3760
- ...(localOfferDirs.length > 0 ||
3576
+ ...(clientInterface !== undefined ||
3577
+ localOfferDirs.length > 0 ||
3761
3578
  resultDecoderSources.length > 0 ||
3579
+ resultProtoDecoderSources.length > 0 ||
3762
3580
  callEncoderSources.length > 0
3763
3581
  ? [`import 'dart:typed_data';`, ``]
3764
3582
  : []),
3765
- `import '${supportImport}';`,
3766
- ...(opts.lawAssetKey !== undefined
3767
- ? [`import 'package:flutter/services.dart' show rootBundle;`]
3583
+ ...(callEncoderSources.length > 0 || resultProtoDecoderSources.length > 0
3584
+ ? [
3585
+ `import 'package:fixnum/fixnum.dart' show Int64;`,
3586
+ `import 'operation_payloads.pb.dart' as _nmsop;`,
3587
+ ``,
3588
+ ]
3768
3589
  : []),
3590
+ `import '${supportImport}'${opts.typesImportUri === undefined ? ' hide OwnedCustody, OwnedDeviceRequest' : ''};`,
3769
3591
  // Layered-packages mode: the sibling types live in their OWN package — one barrel import
3770
3592
  // replaces both the relative types import and the relative framework import.
3771
3593
  ...(opts.typesImportUri !== undefined
@@ -3799,7 +3621,7 @@ export function generateDartBridgeClient(
3799
3621
  `import '${uri}' show ${[...names].sort().join(", ")};`
3800
3622
  ),
3801
3623
  `// Re-export business types only. The runtime import above is an implementation dependency, never`,
3802
- `// a tenant API: exporting it would create a second raw bridge/session/sync application lane.`,
3624
+ `// a tenant API: exporting it would create a second raw session/session/sync application lane.`,
3803
3625
  ...(opts.typesImportUri !== undefined
3804
3626
  ? [`export '${opts.typesImportUri}';`]
3805
3627
  : [`export '${mod.name}.dart';`]),
@@ -3822,43 +3644,35 @@ export function generateDartBridgeClient(
3822
3644
  : []),
3823
3645
  ...(clientInterface !== undefined
3824
3646
  ? [
3825
- `/// This client's STRUCTURAL INTERFACE REQUIREMENT (#72) as JSON — the directives (payload`,
3826
- `/// shapes) + aggregates (read shapes, sid-keyed) it depends on. \`connect()\` negotiates this`,
3827
- `/// against the workspace's installed offer by SHAPE (stable-id subtyping), not by law hash,`,
3828
- `/// so the domain can evolve without republishing this client.`,
3829
- `const String ${interfaceConstNameDart(mod.name)} = ${dartRawJson(
3830
- clientInterface
3831
- )};`,
3647
+ `/// Canonical compiler-authored USDA compatibility matrix. Dart carries`,
3648
+ `/// these bytes opaquely; only the kernel interprets them.`,
3649
+ `final Uint8List ${interfaceConstNameDart(mod.name)} = Uint8List.fromList(utf8.encode(${dartRawText(
3650
+ emitApplicationCompatibilityUsda({ [domain]: clientInterface })
3651
+ )}));`,
3832
3652
  ``,
3833
3653
  ]
3834
3654
  : []),
3835
- ...(opts.compat !== undefined
3655
+ ...(callEncoderSources.length > 0 || resultProtoDecoderSources.length > 0
3836
3656
  ? [
3837
- `/// The CLIENT/LAW COMPAT MANIFEST (§5) as JSON — the law hash, structural interface hash, and`,
3838
- `/// generator provenance this client was generated against. A DIAGNOSIS surface for connect-time`,
3839
- `/// classification (silent / shape-compatible / incompatible); it NEVER gates.`,
3840
- `const String ${compatConstNameDart(mod.name)} = ${dartRawJson(
3841
- opts.compat
3842
- )};`,
3843
- ``,
3657
+ ...DART_CALL_PROTO_PRELUDE,
3658
+ ...DART_CALL_USDA_PRELUDE,
3659
+ ...callEncoderSources,
3660
+ ...resultProtoDecoderSources,
3844
3661
  ]
3845
3662
  : []),
3846
- ...(callEncoderSources.length > 0
3847
- ? [...DART_CALL_USDA_PRELUDE, ...callEncoderSources]
3848
- : []),
3849
3663
  ...resultDecoderSources,
3850
3664
  ...pastDeclarations,
3851
3665
  ...conflictDeclarations,
3852
- `/// Typed async client for the \`${domain}\` domain, bound to a connected [NomosBridge].`,
3666
+ `/// Typed async client for the \`${domain}\` domain, bound to one connected [NomosSession].`,
3853
3667
  `///`,
3854
- `/// Pass \`actor\` (the verified principal uid) to author AS that user — the bridge's \`offerDirective\` op`,
3668
+ `/// Pass \`actor\` (the verified principal uid) to author AS that user — the generated client owns`,
3855
3669
  `/// carries it with the compiler-generated canonical USDA call as the captured principal,`,
3856
3670
  `/// so the kernel seals it as the captured principal and the ReBAC \`.requires(...)\` gate judges the real`,
3857
3671
  `/// author. A GATED directive (one whose law declares \`.requires(relation)\`) authored with no actor throws`,
3858
- `/// [MissingOfferAuthority] BEFORE any submit — an actorless gated offer can't be constructed. The bridge`,
3859
- `/// owns SIGNING (a device secret on \`connect\`); only the actor IDENTITY is passed here, never a secret.`,
3672
+ `/// [MissingOfferAuthority] BEFORE any submit — an actorless gated offer can't be constructed. The peer`,
3673
+ `/// runtime owns the renewable proof capability; only the actor IDENTITY is bound here, never a secret.`,
3860
3674
  `class ${className} {`,
3861
- ` final NomosBridge bridge;`,
3675
+ ` final NomosSession session;`,
3862
3676
  ` final String domainHash;`,
3863
3677
  ``,
3864
3678
  ` /// The verified principal uid every offer is authored as (sealed as \`security.actor\` by the one encoder).`,
@@ -3873,68 +3687,36 @@ export function generateDartBridgeClient(
3873
3687
  ` final NomosKeyStore? keyStore;`,
3874
3688
  ]
3875
3689
  : []),
3876
- ` ${className}(this.bridge, {this.domainHash = ${hashConst}, this.actor${
3690
+ ` ${className}(this.session, {this.domainHash = ${hashConst}, this.actor${
3877
3691
  manualEncryptionPresent ? ", this.keyStore" : ""
3878
3692
  }});`,
3879
3693
  ``,
3880
- ` /// THE STATIC INTERFACE DESCRIPTOR (session_bound_clients.md asks 5/9): what this client EXPECTS`,
3881
- ` /// of the workspace it binds to — the domain key, the law hash it was generated against, and the`,
3882
- ` /// structural interface (#72). Consumed by [bind] and by \`session.assertCompatible(${className}.interface)\`.`,
3883
- ` /// Standard OSGi Contract Namespace requirements derived from this law's shape.`,
3884
- ` static const List<Map<String, String>> kernelContracts = [${kernelContracts
3694
+ ` /// Standard OSGi Contract Namespace requirements derived from this law's shape, resolved by`,
3695
+ ` /// [bind]. The client's own compatibility matrix is served by [compatibilityMatrixUsda]; there`,
3696
+ ` /// is no separate static descriptor, because this class is a library-private part of the`,
3697
+ ` /// generated application and nothing — inside it or outside — could read one.`,
3698
+ ` static const List<NmsKernelContractRequirement> kernelContracts = [${kernelContracts
3885
3699
  .map(
3886
3700
  (contract) =>
3887
- `{${dartStr("namespace")}: ${dartStr(contract.namespace)}, ${dartStr(
3888
- "name"
3889
- )}: ${dartStr(contract.name)}, ${dartStr("version")}: ${dartStr(
3701
+ `NmsKernelContractRequirement(namespace: ${dartStr(
3702
+ contract.namespace
3703
+ )}, name: ${dartStr(contract.name)}, version: ${dartStr(
3890
3704
  contract.version
3891
- )}}`
3705
+ )})`
3892
3706
  )
3893
3707
  .join(", ")}];`,
3894
3708
  ``,
3895
- ` static const NomosClientInterface interface = NomosClientInterface(`,
3896
- ` domain: ${dartStr(domain)},`,
3897
- ` expectedDomainHash: ${hashConst},`,
3898
- ...(compatInterfaceHash !== undefined
3899
- ? [` expectedInterfaceHash: ${dartStr(compatInterfaceHash)},`]
3900
- : []),
3901
- ...(clientInterface !== undefined
3902
- ? [` interfaceJson: ${interfaceConstNameDart(mod.name)},`]
3903
- : []),
3904
- ...(opts.compat !== undefined
3905
- ? [` compatJson: ${compatConstNameDart(mod.name)},`]
3906
- : []),
3907
- ` );`,
3908
- ``,
3909
- ` /// THE SESSION-BOUND CONSTRUCTION PATH (session_bound_clients.md asks 2/5): bind this client to`,
3910
- ` /// [session] with an ASYNC PREFLIGHT — the session's workspace must be reachable, hold the`,
3911
- ` /// \`${domain}\` domain, and serve a structurally compatible interface (#72 shape-compat, the ONE`,
3912
- ` /// compatibility notion). An incompatible session throws [DomainClientSessionMismatch]`,
3913
- ` /// IMMEDIATELY — at provider construction, not two clicks into the app. The synchronous`,
3914
- ` /// constructor remains for codepaths that can't await; it lazily runs the SAME preflight on the`,
3915
- ` /// first dispatch.`,
3916
- ` static Future<void> _catchUpBeforeModelPreparation(NomosSession session) async {`,
3917
- ` try {`,
3918
- ` await session.sync(admit: true);`,
3919
- ` } catch (error) {`,
3920
- ` // Offline-first: inability to reach shared custody does not revoke the local workspace.`,
3921
- ` // The subsequent typed compatibility/model gate remains authoritative and will either`,
3922
- ` // accept the local law or surface the precise governed action still required.`,
3923
- ` print('[nomos-model-catch-up] ${domain} continuing from local custody: ' + error.toString());`,
3924
- ` }`,
3925
- ` }`,
3926
- ``,
3709
+ ` /// Bind this stateless domain facade to one already-open local workspace.`,
3710
+ ` /// Binding never synchronises custody and never rejects the whole domain because an unrelated`,
3711
+ ` /// member evolved. Each real query or offer is validated by the kernel against the law installed`,
3712
+ ` /// at this workspace's current local frontier. Compatibility is the kernel's verdict, never an`,
3713
+ ` /// application-start lifecycle gate.`,
3927
3714
  ` static Future<${className}> bind(NomosSession session, {String? actor${
3928
3715
  manualEncryptionPresent ? ", NomosKeyStore? keyStore" : ""
3929
3716
  }}) async {`,
3930
3717
  ` final candidate = ${className}(session, actor: actor${
3931
3718
  manualEncryptionPresent ? ", keyStore: keyStore" : ""
3932
3719
  });`,
3933
- ` // Binding proves that this client can read and author against the law the`,
3934
- ` // workspace already runs. It never deploys, stages, promotes, or rewrites`,
3935
- ` // workspace law. Model rollout is an explicit operator action through`,
3936
- ` // [model], outside application startup.`,
3937
- ` await session.assertCompatible(interface);`,
3938
3720
  ` // RELEASE COHERENCE: resolve this law's OSGi Contract Namespace requirements before use.`,
3939
3721
  ` await session.assertKernelCoherence(kernelContracts, lawHash: ${hashConst});`,
3940
3722
  ...(ownedScope === undefined
@@ -3944,80 +3726,13 @@ export function generateDartBridgeClient(
3944
3726
  ownedScope
3945
3727
  )}, domain: ${dartStr(domain)}, domainHash: ${hashConst});`,
3946
3728
  ]),
3947
- ` return candidate.._preflighted = true${
3729
+ ` return candidate${
3948
3730
  ownedScope === undefined ? "" : ".._ownedIdentityReady = true"
3949
3731
  };`,
3950
3732
  ` }`,
3951
3733
  ``,
3952
- ` /// OPEN-THEN-BIND (session_bound_clients.md ask 3) — the ONE-CALL path for a born/resident workspace:`,
3953
- ` /// \`await ${className}.open(bridge, ref: outcome.bornRefs.single)\` (or \`workspace: 'estate-42'\`).`,
3954
- ` /// It ACQUIRES the workspace's session on [bridge] first (an already-open one is reused; a device-`,
3955
- ` /// resident/parked/just-born one opens local-only in place) and THEN binds — so a not-open workspace`,
3956
- ` /// fails HERE, at open, never later on the client's first query. The generated stateful application`,
3957
- ` /// privately retains refreshable cloud access for a genuinely-absent authorized workspace.`,
3958
- ` static Future<${className}> open<TAggregate>(NomosBridge bridge, {NomosRef<TAggregate>? ref, String? workspace, String? actor${
3959
- manualEncryptionPresent ? ", NomosKeyStore? keyStore" : ""
3960
- }, Future<void> Function()? recoverAuthentication}) async {`,
3961
- ` final ws = ref == null ? workspace : NmsInternalNomosRefs.workspace(ref);`,
3962
- ` if (ws == null || ws.isEmpty) {`,
3963
- ` throw ArgumentError('${className}.open: pass a workspace: or ref: — the workspace to open and bind');`,
3964
- ` }`,
3965
- ` final session = await bridge.acquireSession(ws);`,
3966
- ...(authenticationRecovery === undefined
3967
- ? []
3968
- : [
3969
- ` if (recoverAuthentication != null) {`,
3970
- ` final posture = await session.nmsAuthenticationPosture(principal: actor);`,
3971
- ` if (!posture.isReadyFor(actor ?? '')) {`,
3972
- ` await recoverAuthentication();`,
3973
- ` await session.nmsAwaitAuthenticationReady(principal: actor);`,
3974
- ` }`,
3975
- ` }`,
3976
- ]),
3977
- ` return bind(session, actor: actor${
3978
- manualEncryptionPresent ? ", keyStore: keyStore" : ""
3979
- });`,
3980
- ` }`,
3981
- ``,
3982
- ` /// The session workspace this client is bound to (from the [NomosSession] handle, when constructed with`,
3983
- ` /// one) — the \`workspace\` of every read row's canonical [NomosRef]. '' on a bare (non-session) bridge.`,
3984
- ` String get _ws {`,
3985
- ` final b = bridge;`,
3986
- ` return b is NomosSession ? b.workspace : '';`,
3987
- ` }`,
3988
- ``,
3989
- ` /// The [NomosSession] this client dispatches through, when session-bound (the blessed shape);`,
3990
- ` /// null on a bare (non-session) bridge. Inspectable context: \`client.session?.workspace\`.`,
3991
- ` NomosSession? get session {`,
3992
- ` final b = bridge;`,
3993
- ` return b is NomosSession ? b : null;`,
3994
- ` }`,
3995
- ``,
3996
- ` // LAZY PREFLIGHT (the can't-await constructor path): the first dispatch runs the same`,
3997
- ` // assertCompatible check bind() runs eagerly. Only when session-bound; a bare bridge keeps the`,
3998
- ` // pre-session behavior (the kernel gate remains the fail-closed floor either way).`,
3999
- ` bool _preflighted = false;`,
4000
- ` Future<void> _preflightOnce() async {`,
4001
- ` if (_preflighted) return;`,
4002
- ` _preflighted = true;`,
4003
- ` final b = bridge;`,
4004
- ` if (b is NomosSession) {`,
4005
- ` await b.assertCompatible(interface);`,
4006
- ` }`,
4007
- ` }`,
4008
- ``,
4009
- ` // Command readiness is deliberately separate from client/read compatibility. Binding a`,
4010
- ` // generated application may construct clients for every installed domain; compiling every`,
4011
- ` // offer plan at that point recreates whole-law runtime work. The first actual offer prepares`,
4012
- ` // exactly this authenticated package/domain slice, once, before dispatch.`,
4013
- ` final Set<String> _preparedCommands = <String>{};`,
4014
- ` Future<void> _prepareCommand(String directiveId) async {`,
4015
- ` if (_preparedCommands.contains(directiveId)) return;`,
4016
- ` await bridge.prepareDomain(domain: ${dartStr(
4017
- domain
4018
- )}, directiveId: directiveId, packageHash: ${hashConst});`,
4019
- ` _preparedCommands.add(directiveId);`,
4020
- ` }`,
3734
+ ` /// Workspace of every canonical [NomosRef] returned by this client.`,
3735
+ ` String get _ws => session.workspace;`,
4021
3736
  ``,
4022
3737
  ...(ownedScope === undefined || Object.keys(ownedActions).length === 0
4023
3738
  ? []
@@ -4036,62 +3751,52 @@ export function generateDartBridgeClient(
4036
3751
  ` bool _ownedIdentityReady = false;`,
4037
3752
  ` Future<void> _ensureOwnedIdentity() async {`,
4038
3753
  ` if (_ownedIdentityReady) return;`,
4039
- ` await bridge.nomosEnsureOwnedIdentity(scope: ${dartStr(
3754
+ ` await session.nomosEnsureOwnedIdentity(scope: ${dartStr(
4040
3755
  ownedScope
4041
3756
  )}, domain: ${dartStr(domain)}, domainHash: domainHash);`,
4042
3757
  ` _ownedIdentityReady = true;`,
4043
3758
  ` }`,
4044
3759
  ``,
4045
3760
  ` Future<NomosOfferOutcome> _ownedRecordAction<TAggregate>(String action, NomosRef<TAggregate> record, String peer) async {`,
4046
- ` await _preflightOnce();`,
4047
3761
  ` await _ensureOwnedIdentity();`,
4048
3762
  ` if (NmsInternalNomosRefs.workspace(record) != _ws) throw ArgumentError('$action() cannot use a record from another workspace');`,
4049
3763
  ` final directiveId = _ownedDirectiveId(NmsInternalNomosRefs.type(record), action);`,
4050
3764
  ` if (directiveId == null) throw ArgumentError('$action() needs a generated owned record reference');`,
4051
- ` await _prepareCommand(directiveId);`,
4052
3765
  ` if (peer.trim().isEmpty) throw ArgumentError('$action() needs the person to act with');`,
4053
- ` final payload = await bridge.nomosPrepareOwnedRecordAction(action: action, scope: ${dartStr(
3766
+ ` final payload = await session.nomosPrepareOwnedRecordAction(action: action, scope: ${dartStr(
4054
3767
  ownedScope
4055
3768
  )}, record: record, peer: peer);`,
4056
- ` final callUsda = switch (directiveId) {`,
3769
+ ` final generatedCall = switch (directiveId) {`,
4057
3770
  ...[...ownedActionCallEncoders.entries()].map(
4058
3771
  ([directiveId, encoder]) =>
4059
3772
  ` ${dartStr(directiveId)} => ${
4060
3773
  encoder.functionName
4061
3774
  }(payload as ${encoder.payloadType}),`
4062
3775
  ),
4063
- ` _ => throw StateError('No generated USDA encoder for owned directive $directiveId'),`,
3776
+ ` _ => throw StateError('No generated Protobuf encoder for owned directive $directiveId'),`,
4064
3777
  ` };`,
4065
- ` return _offer(callUsda);`,
3778
+ ` return _offer(generatedCall);`,
4066
3779
  ` }`,
4067
3780
  ``,
4068
3781
  ]),
4069
3782
  ...(callEncoderSources.length > 0
4070
3783
  ? [
4071
- ` /// THE ONE DISPATCH LANE every generated directive method routes through: lazy preflight, then`,
4072
- ` /// the session's offer (the generated-internal use of the engine-level lane).`,
3784
+ ` /// THE ONE DISPATCH LANE every generated directive method routes through.`,
3785
+ ` /// The kernel prepares and validates the exact authenticated command`,
3786
+ ` /// route inside the offer gate, where readiness is shared by every host and cannot become a`,
3787
+ ` /// second foreground ceremony maintained by generated clients.`,
4073
3788
  ` Future<NomosOfferOutcome> _offer(NmsGeneratedCall call, {List<NomosConflictSnapshot> conflictSnapshots = const [], NomosOfferAuthenticationProof authenticationProof = NomosOfferAuthenticationProof.sessionCredentials}) async {`,
4074
- ` await _preflightOnce();`,
4075
- ` await _prepareCommand(call.directive);`,
4076
- ` Future<NomosOfferOutcome> attempt() => bridge.offerCallUsdaOutcome(call: call, actor: actor, conflictSnapshots: conflictSnapshots, authenticationProof: authenticationProof);`,
4077
- ...(authenticationRecovery === undefined
4078
- ? [` return attempt();`]
3789
+ ...(clientInterface === undefined
3790
+ ? []
4079
3791
  : [
4080
- ` if (authenticationProof != NomosOfferAuthenticationProof.sessionCredentials) return attempt();`,
4081
- ` try {`,
4082
- ` return await attempt();`,
4083
- ` } on NomosKernelCallFailure {`,
4084
- ` final posture = await bridge.nmsAuthenticationPosture(principal: actor);`,
4085
- ` if (posture.providerToken != NomosProviderTokenVerification.noMatchingKey) rethrow;`,
4086
- ` await ${safeMethod(
4087
- authenticationRecovery.id
4088
- )}(const ${dartActionInputClassName(
4089
- authenticationRecovery
4090
- )}());`,
4091
- ` await bridge.nmsAwaitAuthenticationReady(principal: actor);`,
4092
- ` return attempt();`,
4093
- ` }`,
3792
+ ` // PARTIAL COMPATIBILITY: examine the exact directive before dispatch. The`,
3793
+ ` // session caches this compiler matrix until Peer Office reports law/custody`,
3794
+ ` // movement, so repeated writes do no compatibility work. Unrelated reads and`,
3795
+ ` // writes remain usable when another member is incompatible.`,
3796
+ ` await session.assertOperationCompatible(compatibilityMatrixUsda, domain: call.domain, directive: call.directive);`,
4094
3797
  ]),
3798
+ ` Future<NomosOfferOutcome> attempt() => session.offerGeneratedCallOutcome(call: call, actor: actor, conflictSnapshots: conflictSnapshots, authenticationProof: authenticationProof);`,
3799
+ ` return attempt();`,
4095
3800
  ` }`,
4096
3801
  ``,
4097
3802
  ]
@@ -4102,13 +3807,13 @@ export function generateDartBridgeClient(
4102
3807
  : [
4103
3808
  ` /// Opt into all-device-loss recovery with one explicitly designated person.`,
4104
3809
  ` NomosRecovery get recovery => NomosRecovery(`,
4105
- ` bridge: bridge, domain: ${dartStr(
3810
+ ` session: session, domain: ${dartStr(
4106
3811
  domain
4107
3812
  )}, domainHash: domainHash, scope: ${dartStr(ownedScope)});`,
4108
3813
  ``,
4109
3814
  ` /// Add another of this person's devices. Requests are opaque; Nomos owns the handoff.`,
4110
3815
  ` NomosDevices get devices => NomosDevices(`,
4111
- ` bridge: bridge, domain: ${dartStr(
3816
+ ` session: session, domain: ${dartStr(
4112
3817
  domain
4113
3818
  )}, domainHash: domainHash, actor: actor, scope: ${dartStr(
4114
3819
  ownedScope
@@ -4118,64 +3823,16 @@ export function generateDartBridgeClient(
4118
3823
  ` ));`,
4119
3824
  ``,
4120
3825
  ]),
4121
- // THE OWNER CEREMONY (slice 2): grantAndWrap / revokeAndRotate / rotate — the operator-blind key-epoch
4122
- // handshake as one call. Bind `actor` (the owner) to author the fan-out. Only for a domain with a scope.
4123
- ...(domScopes.length > 0
4124
- ? [
4125
- ` /// OWNER CEREMONY (slice 2): \`grantAndWrap\` / \`revokeAndRotate\` / \`rotate\` — the operator-blind`,
4126
- ` /// key-epoch handshake as one call. Bind \`actor\` (the owner) to author the fan-out.`,
4127
- ` NomosEncryption get encryption => NomosEncryption(`,
4128
- ` bridge: bridge, domain: ${dartStr(
4129
- domain
4130
- )}, domainHash: domainHash, actor: actor,`,
4131
- ` scopes: const [${domScopes
4132
- .map((s) => dartStr(s))
4133
- .join(", ")}]);`,
4134
- ``,
4135
- ]
4136
- : []),
4137
3826
  ...(clientInterface !== undefined
4138
3827
  ? [
4139
- ` /// This client's structural interface requirement (#72) as JSON — hand it to the`,
4140
- ` /// bridge's compatibility check to negotiate by SHAPE against the workspace's offer.`,
4141
- ` String get interfaceJson => ${interfaceConstNameDart(mod.name)};`,
3828
+ ` /// This client's exact compiler-authored USDA compatibility matrix.`,
3829
+ ` Uint8List get compatibilityMatrixUsda => ${interfaceConstNameDart(mod.name)};`,
4142
3830
  ``,
4143
- ` Map<String, Object?> get _requirement =>`,
4144
- ` {${dartStr(
4145
- domain
4146
- )}: (jsonDecode(interfaceJson) as Map).cast<String, Object?>()};`,
4147
- ``,
4148
- ` /// SHAPE COMPATIBILITY (#72): one-shot verdict for THIS client against the workspace's`,
4149
- ` /// ON-LEDGER offer — \`{ ok, missing[], incompatible[] }\`, by shape not law hash.`,
4150
- ` Future<Map<String, Object?>> checkCompatibility() => bridge.checkCompatibility(_requirement);`,
4151
- ``,
4152
- ` /// SHAPE COMPATIBILITY as a LIVE BINDING (#72): a stream of verdicts that re-emits whenever`,
4153
- ` /// the workspace's installed law changes (a synced install/upgrade from another peer).`,
4154
- ` Stream<Map<String, Object?>> watchCompatibility() => bridge.watchCompatibility(_requirement);`,
4155
- ``,
4156
- ...(opts.compat !== undefined
4157
- ? [
4158
- ` /// THE COMPAT SUPERPOWER (#72b): compute the LIVE per-member verdict for THIS client against the`,
4159
- ` /// workspace's on-ledger offer + arm the pre-call refusal. Await it after connect so a KNOWN-`,
4160
- ` /// incompatible directive throws [LawMismatchError] CLIENT-SIDE at write time (never a server 422).`,
4161
- ` Future<NomosCompat?> checkCompat() => bridge.checkCompat(`,
4162
- ` (jsonDecode(${compatConstNameDart(
4163
- mod.name
4164
- )}) as Map).cast<String, Object?>(), _requirement);`,
4165
- ``,
4166
- ` /// THE FEATURE FLAG (dark-launch): true iff [member] exists on the offer AND is compatible — ship`,
4167
- ` /// UI with a member dark, deploy the law, it lights up. Await [checkCompat] once first to arm it.`,
4168
- ` Future<bool> has(String member) => bridge.compatHas(member);`,
4169
- ``,
4170
- ` /// COMPAT SUPERPOWER live events: emits the fresh verdict when a synced law change moves the offer.`,
4171
- ` Stream<NomosCompat> get onLawChanged => bridge.onLawChanged;`,
4172
- ``,
4173
- ]
4174
- : []),
4175
3831
  ]
4176
3832
  : []),
4177
3833
  ...methods,
4178
3834
  `}`,
3835
+ ...dartRefusalDecoders(mod, callUsda.graph, callUsda.paths),
4179
3836
  ``,
4180
3837
  ...(refExtensions.length > 0
4181
3838
  ? [
@@ -4218,7 +3875,7 @@ function dartEncClassMembers(manualEncryptionPresent: boolean): string[] {
4218
3875
  ` for (final record in records) {`,
4219
3876
  ` final type = record.type;`,
4220
3877
  ` final id = record.id;`,
4221
- ` final held = await bridge.nomosOwnedScopeKeys(scope, recordType: type, recordId: id);`,
3878
+ ` final held = await session.nomosOwnedScopeKeys(scope, recordType: type, recordId: id);`,
4222
3879
  ` for (final key in held) {`,
4223
3880
  ` if (!keys.any((candidate) => candidate.scope == key.scope && candidate.epoch == key.epoch)) keys.add(key);`,
4224
3881
  ` }`,
@@ -4232,9 +3889,10 @@ function dartEncClassMembers(manualEncryptionPresent: boolean): string[] {
4232
3889
  ` Future<List<TModel>> _readWithOwnedKeys<TModel, TAggregate>(`,
4233
3890
  ` List<({String scope, bool owned})> scopes,`,
4234
3891
  ` Future<List<TModel>> Function(List<NomosScopeKey>? keys) read,`,
4235
- ` NomosRef<TAggregate> Function(TModel row) reference,`,
4236
- ` ) async {`,
4237
- ` final first = await read(await _readKeys(scopes));`,
3892
+ ` NomosRef<TAggregate> Function(TModel row) reference, {`,
3893
+ ` List<TModel>? initial,`,
3894
+ ` }) async {`,
3895
+ ` final first = initial ?? await read(await _readKeys(scopes));`,
4238
3896
  ` if (!scopes.any((scope) => scope.owned) || first.isEmpty) return first;`,
4239
3897
  ` final records = first.map(reference).map((record) => (`,
4240
3898
  ` type: NmsInternalNomosRefs.type(record),`,