@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
@@ -5,21 +5,48 @@ import type { DomainModule } from "./codegen_dart.js";
5
5
  import { dartMemberName, introspectPayload } from "./codegen_dart.js";
6
6
  import type { PayloadFieldSpec } from "./codegen_dart.js";
7
7
  import {
8
- DART_CALL_USDA_PRELUDE,
9
- emitDartCallUsdaEncoder,
10
- type DartCallUsdaFieldAccess,
11
- } from "./codegen_call_usda.js";
8
+ DART_CALL_PROTO_PRELUDE,
9
+ emitDartCallProtoEncoder,
10
+ type DartCallProtoFieldAccess,
11
+ } from "./codegen_call_proto.js";
12
12
  import type { LawGraph } from "./law_graph.js";
13
13
  import { isBusinessIntent } from "./intent.js";
14
+ import { MemberAuthenticationKind } from "./member_authentication.js";
14
15
  import { fixedFrameworkCallDefinitions } from "./framework_call_definitions.js";
15
16
  import { collectFixedFrameworkDartEnums } from "./framework_call_dart_enums.js";
16
17
  import { APPLICATION_HOME_DOMAIN } from "./framework/application_home_domain.js";
18
+ import { RECOVER_RECEIVING_GROUP_DEVICE_ID as FRAMEWORK_RECOVERY_DOOR_ID } from "./framework/receiving_group_recovery.js";
19
+ import { REPAIR_CHILD_AUTHENTICATION_ID as FRAMEWORK_CHILD_REPAIR_ID } from "./framework/child_authentication.js";
20
+ import {
21
+ PARENT_MODEL_AUTHORITY_SEAT_AGGREGATE,
22
+ PARENT_MODEL_AUTHORITY_SEAT_ID,
23
+ SEAT_MODEL_AUTHORITY_ID as FRAMEWORK_MODEL_AUTHORITY_SEAT_ID,
24
+ } from "./framework/model_authority_repair.js";
17
25
  import { workspaceSharingInvitationRedeemPayload } from "./workspace_sharing.js";
18
26
  import { zodArrayElement, zodDef, zodObjectShape } from "./zod_introspection.js";
19
27
 
20
28
  type AnyDirective = Directive<unknown>;
21
29
 
22
- const frameworkFieldAccess = (field: PayloadFieldSpec): DartCallUsdaFieldAccess => {
30
+ /** Resolve the authored effect behind a public business intent. Application
31
+ * languages intentionally expose only nominal intents in `module.directives`,
32
+ * while fixed framework-call encoders must derive their payload from the exact
33
+ * private effect composed by that intent. */
34
+ const authoredDirective = (
35
+ module: DomainModule,
36
+ directiveId: string,
37
+ ): AnyDirective | undefined =>
38
+ (module.directives as AnyDirective[]).find(
39
+ (candidate) => candidate.id === directiveId,
40
+ ) ??
41
+ (module.applicationIntents ?? [])
42
+ .flatMap((candidate) =>
43
+ isBusinessIntent(candidate)
44
+ ? candidate.steps.map((step) => step.directive as AnyDirective)
45
+ : [],
46
+ )
47
+ .find((candidate) => candidate.id === directiveId);
48
+
49
+ const frameworkFieldAccess = (field: PayloadFieldSpec): DartCallProtoFieldAccess => {
23
50
  const member = `payload.${dartMemberName(field.name)}`;
24
51
  if (field.nullAdmits === true) return { value: member, slot: true };
25
52
  const value = field.optional ? `${member}!` : member;
@@ -45,6 +72,12 @@ const frameworkFieldAccess = (field: PayloadFieldSpec): DartCallUsdaFieldAccess
45
72
  }
46
73
  };
47
74
 
75
+ /** The exact Dart type `introspectPayload` derives for `inheritedModelAuthorityEvidence.holders`. The
76
+ * hand-written `NmsModelAuthorityHolder` typedef in `application_framework_calls.dart` is structurally
77
+ * this type; asserting it here means a schema change breaks the COMPILER, never the app. */
78
+ const MODEL_AUTHORITY_HOLDERS_DART_TYPE =
79
+ "List<({String principal, List<({String deviceKeySubject, String grantedAt, String? verifiedVia, int? validFromEpoch})> signers})>";
80
+
48
81
  const FIXED_CALLS = fixedFrameworkCallDefinitions
49
82
  .filter((definition) => definition.dartBirth === true)
50
83
  .map((definition) => ({ kind: definition.kind, directive: definition.directive.id }));
@@ -100,20 +133,62 @@ export interface DartFrameworkCallLaw {
100
133
  readonly paths: ReadonlyMap<string, string>;
101
134
  }
102
135
 
136
+ /** Exact fixed framework effects for which this composed law emits Dart calls.
137
+ * The operation-schema compiler consumes this selector instead of maintaining
138
+ * a second list of framework payloads. */
139
+ export function dartFrameworkOperationDirectiveIds(
140
+ law: DartFrameworkCallLaw,
141
+ ): readonly string[] {
142
+ const fixed = FIXED_CALLS.filter((definition) =>
143
+ law.graph.nodes.some((node) =>
144
+ node.kind === "intent" &&
145
+ (node.entity.label === definition.directive ||
146
+ node.publicRoute === definition.directive),
147
+ ),
148
+ ).map((definition) => definition.directive);
149
+ // The declared receiving-group recovery door is bound exactly like a fixed framework call (below),
150
+ // so its payload needs the same host transport contract: without this entry the generated encoder
151
+ // names a `Payload_…` message the operation proto never carries.
152
+ const declaresFrameworkDoor = law.graph.nodes.some((node) =>
153
+ node.kind === "intent" && node.entity.label === FRAMEWORK_RECOVERY_DOOR_ID);
154
+ // The framework child-authentication repair (composed whenever the package births children) is bound
155
+ // the same way, so its `{workspace, user, deviceKeySubject?}` payload rides the operation transport.
156
+ const declaresChildRepair = law.graph.nodes.some((node) =>
157
+ node.kind === "intent" && node.entity.label === FRAMEWORK_CHILD_REPAIR_ID);
158
+ // The model-authority self-seat (composed on the same era rule) is bound the same way, so its
159
+ // holder-set payload rides the operation transport.
160
+ const declaresModelAuthorityPull = law.graph.nodes.some((node) =>
161
+ node.kind === "intent" && node.entity.label === FRAMEWORK_MODEL_AUTHORITY_SEAT_ID);
162
+ return [
163
+ ...fixed,
164
+ ...(declaresFrameworkDoor ? [FRAMEWORK_RECOVERY_DOOR_ID] : []),
165
+ ...(declaresChildRepair ? [FRAMEWORK_CHILD_REPAIR_ID] : []),
166
+ ...(declaresModelAuthorityPull ? [FRAMEWORK_MODEL_AUTHORITY_SEAT_ID] : []),
167
+ ];
168
+ }
169
+
103
170
  /** Emit the pre-bind framework call factory from the exact composed law graph.
104
171
  * The output contains no schemas or dynamic values: every field access and USDA
105
172
  * relationship is expanded by the compiler. */
106
173
  export function generateDartApplicationFrameworkCalls(
107
174
  laws: readonly DartFrameworkCallLaw[],
175
+ descriptor: {
176
+ /** The compiled law package identity — the descriptor's own closure, `currentLaw[<application-home domain>]`. */
177
+ readonly lawSha256: string;
178
+ },
108
179
  ): string | undefined {
180
+ if (!/^[0-9a-f]{64}$/.test(descriptor.lawSha256)) {
181
+ throw new Error(
182
+ `Dart framework call codegen: the application birth contract needs the compiled law package sha256 identity, not '${descriptor.lawSha256}'`,
183
+ );
184
+ }
109
185
  const frameworkEnumDartTypes = collectFixedFrameworkDartEnums().dartTypes;
110
186
  const fixedEmitted = FIXED_CALLS.flatMap((definition) => laws.flatMap((law) => {
111
187
  const declares = law.graph.nodes.some((node) =>
112
188
  node.kind === "intent" &&
113
189
  (node.entity.label === definition.directive || node.publicRoute === definition.directive));
114
190
  if (!declares) return [];
115
- const directive = (law.module.directives as AnyDirective[]).find((candidate) =>
116
- candidate.id === definition.directive);
191
+ const directive = authoredDirective(law.module, definition.directive);
117
192
  if (directive === undefined) {
118
193
  throw new Error(
119
194
  `Dart framework call codegen: '${law.graph.domain.entity.label}/${definition.directive}' has no authored directive`,
@@ -128,11 +203,11 @@ export function generateDartApplicationFrameworkCalls(
128
203
  : `${field.dartType}${field.optional ? "?" : ""}`;
129
204
  const payloadType = `({${fields.map((field) =>
130
205
  `${parameterType(field)} ${dartMemberName(field.name)}`).join(", ")}})`;
131
- const access = new Map<string, DartCallUsdaFieldAccess>(fields.map((field) => [
206
+ const access = new Map<string, DartCallProtoFieldAccess>(fields.map((field) => [
132
207
  field.name,
133
208
  frameworkFieldAccess(field),
134
209
  ]));
135
- const encoder = emitDartCallUsdaEncoder(
210
+ const encoder = emitDartCallProtoEncoder(
136
211
  law.graph,
137
212
  law.paths,
138
213
  law.graph.domain.entity.label,
@@ -151,11 +226,11 @@ export function generateDartApplicationFrameworkCalls(
151
226
  : `${field.dartType}${field.optional ? "?" : ""}`;
152
227
  const payloadType = `({${fields.map((field) =>
153
228
  `${parameterType(field)} ${dartMemberName(field.name)}`).join(", ")}})`;
154
- const access = new Map<string, DartCallUsdaFieldAccess>(fields.map((field) => [
229
+ const access = new Map<string, DartCallProtoFieldAccess>(fields.map((field) => [
155
230
  field.name,
156
231
  frameworkFieldAccess(field),
157
232
  ]));
158
- const encoder = emitDartCallUsdaEncoder(
233
+ const encoder = emitDartCallProtoEncoder(
159
234
  law.graph,
160
235
  law.paths,
161
236
  law.graph.domain.entity.label,
@@ -181,11 +256,146 @@ export function generateDartApplicationFrameworkCalls(
181
256
  // verifier epoch); every target must independently declare the narrow recovery door.
182
257
  // The host never chooses an operation name and the compiler refuses an ambiguous or
183
258
  // differently-shaped candidate.
259
+ // THE DECLARED DOOR BINDS FIRST. When the application declared its receiving-group recovery posture,
260
+ // the framework composed `nomosInternalRecoverReceivingGroupDevice7c1f5e` into the application-home
261
+ // domain; it is presentation-internal, so it is never a public application intent and the structural
262
+ // search below cannot see it. Bind it exactly like a fixed framework call (by id, from the composed
263
+ // graph). A tenant-authored door beside it is refused: one application has one recovery route.
264
+ const frameworkDoor = laws.flatMap((law) => {
265
+ const declares = law.graph.nodes.some((node) =>
266
+ node.kind === "intent" && node.entity.label === FRAMEWORK_RECOVERY_DOOR_ID);
267
+ if (!declares) return [];
268
+ const directive = authoredDirective(law.module, FRAMEWORK_RECOVERY_DOOR_ID);
269
+ if (directive === undefined) {
270
+ throw new Error(
271
+ `Dart framework call codegen: '${law.graph.domain.entity.label}/${FRAMEWORK_RECOVERY_DOOR_ID}' has no authored directive`,
272
+ );
273
+ }
274
+ const fields = introspectPayload(directive.payloadSchema as z.ZodTypeAny, new Map());
275
+ const payloadType = fields.length === 1 ? `({String user})` : `({String user, String? deviceKeySubject})`;
276
+ const access = new Map<string, DartCallProtoFieldAccess>(fields.map((field) => [
277
+ field.name, frameworkFieldAccess(field),
278
+ ]));
279
+ const encoder = emitDartCallProtoEncoder(
280
+ law.graph, law.paths, law.graph.domain.entity.label, FRAMEWORK_RECOVERY_DOOR_ID, payloadType, access,
281
+ );
282
+ return [{
283
+ kind: "recoverExistingReceivingGroupDevice",
284
+ directive: FRAMEWORK_RECOVERY_DOOR_ID,
285
+ domain: law.graph.domain.entity.label,
286
+ fields,
287
+ payloadType,
288
+ encoder,
289
+ routeByDirective: false as const,
290
+ }];
291
+ });
292
+ // THE CHILD-AUTHENTICATION REPAIR IS FRAMEWORK LAW (receiving_group_lifecycle.md cut 1 item 3): when the
293
+ // package births children the application-home domain composes `nomosInternalRepairChildAuthentication7c1f5e`,
294
+ // the ONE parent action that repairs a child refusing this device's key, addressed by workspace. It is
295
+ // presentation-internal, so it is bound here by id exactly like the recovery door; the Reception's repair
296
+ // lane calls it and no tenant ever routes a child kind by name.
297
+ const frameworkChildRepair = laws.flatMap((law) => {
298
+ const declares = law.graph.nodes.some((node) =>
299
+ node.kind === "intent" && node.entity.label === FRAMEWORK_CHILD_REPAIR_ID);
300
+ if (!declares) return [];
301
+ const directive = authoredDirective(law.module, FRAMEWORK_CHILD_REPAIR_ID);
302
+ if (directive === undefined) {
303
+ throw new Error(
304
+ `Dart framework call codegen: '${law.graph.domain.entity.label}/${FRAMEWORK_CHILD_REPAIR_ID}' has no authored directive`,
305
+ );
306
+ }
307
+ const fields = introspectPayload(directive.payloadSchema as z.ZodTypeAny, new Map());
308
+ const expected: readonly [string, boolean][] = [["workspace", false], ["user", false], ["deviceKeySubject", true]];
309
+ if (
310
+ fields.length !== expected.length ||
311
+ fields.some((field, index) =>
312
+ field.name !== expected[index]![0] || field.optional !== expected[index]![1] ||
313
+ field.dartType !== "String" || field.shape !== "scalar" || field.nullAdmits === true)
314
+ ) {
315
+ throw new Error(
316
+ `Dart framework call codegen: the framework child-authentication repair '${FRAMEWORK_CHILD_REPAIR_ID}' must accept { workspace: string, user: string, deviceKeySubject?: string }`,
317
+ );
318
+ }
319
+ const payloadType = `({String workspace, String user, String? deviceKeySubject})`;
320
+ const access = new Map<string, DartCallProtoFieldAccess>(fields.map((field) => [
321
+ field.name, frameworkFieldAccess(field),
322
+ ]));
323
+ const encoder = emitDartCallProtoEncoder(
324
+ law.graph, law.paths, law.graph.domain.entity.label, FRAMEWORK_CHILD_REPAIR_ID, payloadType, access,
325
+ );
326
+ return [{
327
+ kind: "repairChildAuthentication",
328
+ directive: FRAMEWORK_CHILD_REPAIR_ID,
329
+ domain: law.graph.domain.entity.label,
330
+ fields,
331
+ payloadType,
332
+ encoder,
333
+ routeByDirective: false as const,
334
+ }];
335
+ });
336
+ if (frameworkChildRepair.length > 1) {
337
+ throw new Error(
338
+ `Dart framework call codegen: the framework child-authentication repair is composed into ${frameworkChildRepair.length} domains; exactly one is allowed`,
339
+ );
340
+ }
341
+ // THE MODEL-AUTHORITY SELF-HEAL IS FRAMEWORK LAW (parent_directed_model_transition.md, the third door):
342
+ // when the package births children the application-home domain composes
343
+ // `nomosInternalPullParentModelAuthority7c1f5e`, the ONE child-side action that asks this workspace's own
344
+ // verified parent for the model-lifecycle authority it should have been born holding. Bound here by id
345
+ // exactly like the child repair; the Reception offers it and no tenant passes a parameter for it.
346
+ const frameworkModelAuthorityPull = laws.flatMap((law) => {
347
+ const declares = law.graph.nodes.some((node) =>
348
+ node.kind === "intent" && node.entity.label === FRAMEWORK_MODEL_AUTHORITY_SEAT_ID);
349
+ if (!declares) return [];
350
+ const directive = authoredDirective(law.module, FRAMEWORK_MODEL_AUTHORITY_SEAT_ID);
351
+ if (directive === undefined) {
352
+ throw new Error(
353
+ `Dart framework call codegen: '${law.graph.domain.entity.label}/${FRAMEWORK_MODEL_AUTHORITY_SEAT_ID}' has no authored directive`,
354
+ );
355
+ }
356
+ const fields = introspectPayload(directive.payloadSchema as z.ZodTypeAny, new Map());
357
+ const expected: readonly [string, string, string][] = [
358
+ ["holders", "recordList", MODEL_AUTHORITY_HOLDERS_DART_TYPE],
359
+ ["seatedAt", "scalar", "String"],
360
+ ];
361
+ if (
362
+ fields.length !== expected.length ||
363
+ fields.some((field, index) =>
364
+ field.name !== expected[index]![0] || field.shape !== expected[index]![1] ||
365
+ field.dartType !== expected[index]![2] || field.optional !== false || field.nullAdmits === true)
366
+ ) {
367
+ throw new Error(
368
+ `Dart framework call codegen: the framework model-authority self-seat '${FRAMEWORK_MODEL_AUTHORITY_SEAT_ID}' must accept { holders: [{ principal, signers: [...] }], seatedAt: string }`,
369
+ );
370
+ }
371
+ const payloadType =
372
+ `({${MODEL_AUTHORITY_HOLDERS_DART_TYPE} holders, String seatedAt})`;
373
+ const access = new Map<string, DartCallProtoFieldAccess>(fields.map((field) => [
374
+ field.name, frameworkFieldAccess(field),
375
+ ]));
376
+ const encoder = emitDartCallProtoEncoder(
377
+ law.graph, law.paths, law.graph.domain.entity.label, FRAMEWORK_MODEL_AUTHORITY_SEAT_ID, payloadType, access,
378
+ );
379
+ return [{
380
+ kind: "seatParentModelAuthority",
381
+ directive: FRAMEWORK_MODEL_AUTHORITY_SEAT_ID,
382
+ domain: law.graph.domain.entity.label,
383
+ fields,
384
+ payloadType,
385
+ encoder,
386
+ routeByDirective: false as const,
387
+ }];
388
+ });
389
+ if (frameworkModelAuthorityPull.length > 1) {
390
+ throw new Error(
391
+ `Dart framework call codegen: the framework model-authority self-heal is composed into ${frameworkModelAuthorityPull.length} domains; exactly one is allowed`,
392
+ );
393
+ }
184
394
  const recoveryCandidates = laws.flatMap((law) =>
185
395
  (law.module.applicationIntents ?? []).flatMap((candidate) => {
186
396
  if (
187
397
  !isBusinessIntent(candidate) ||
188
- candidate.offerAuthenticationProof !== "enrolledDevice" ||
398
+ candidate.authentication?.kind !== MemberAuthenticationKind.EnrolledDevice ||
189
399
  candidate.steps.length !== 0 ||
190
400
  candidate.workspaceEffects.length === 0 ||
191
401
  !candidate.workspaceEffects.every(
@@ -194,23 +404,25 @@ export function generateDartApplicationFrameworkCalls(
194
404
  ) return [];
195
405
  const fields = introspectPayload(candidate.contract.accepts, new Map());
196
406
  if (
197
- fields.length !== 1 ||
407
+ (fields.length !== 1 && fields.length !== 2) ||
198
408
  fields[0]!.name !== "user" ||
199
409
  fields[0]!.dartType !== "String" ||
200
410
  fields[0]!.shape !== "scalar" ||
201
411
  fields[0]!.optional ||
202
- fields[0]!.nullAdmits === true
412
+ fields[0]!.nullAdmits === true ||
413
+ (fields.length === 2 && (fields[1]!.name !== "deviceKeySubject" ||
414
+ fields[1]!.dartType !== "String" || fields[1]!.shape !== "scalar" ||
415
+ !fields[1]!.optional))
203
416
  ) {
204
417
  throw new Error(
205
- `Dart framework call codegen: existing receiving-group recovery intent '${candidate.id}' must accept exactly { user: string }`,
418
+ `Dart framework call codegen: existing receiving-group recovery intent '${candidate.id}' must accept { user: string, deviceKeySubject?: string }`,
206
419
  );
207
420
  }
208
- const payloadType = `({String user})`;
209
- const access = new Map<string, DartCallUsdaFieldAccess>([[
210
- "user",
211
- { value: "payload.user" },
212
- ]]);
213
- const encoder = emitDartCallUsdaEncoder(
421
+ const payloadType = fields.length === 1 ? `({String user})` : `({String user, String? deviceKeySubject})`;
422
+ const access = new Map<string, DartCallProtoFieldAccess>(fields.map((field) => [
423
+ field.name, frameworkFieldAccess(field),
424
+ ]));
425
+ const encoder = emitDartCallProtoEncoder(
214
426
  law.graph,
215
427
  law.paths,
216
428
  law.graph.domain.entity.label,
@@ -228,12 +440,26 @@ export function generateDartApplicationFrameworkCalls(
228
440
  routeByDirective: false as const,
229
441
  }];
230
442
  }));
443
+ if (frameworkDoor.length > 0 && recoveryCandidates.length > 0) {
444
+ throw new Error(
445
+ `Dart framework call codegen: the application declared its receiving-group recovery posture (the framework composed ` +
446
+ `'${FRAMEWORK_RECOVERY_DOOR_ID}') and still authors its own recovery intent '${recoveryCandidates[0]!.directive}'; ` +
447
+ `delete the tenant door — one application has one recovery route`,
448
+ );
449
+ }
231
450
  if (recoveryCandidates.length > 1) {
232
451
  throw new Error(
233
452
  `Dart framework call codegen: application composes ${recoveryCandidates.length} existing receiving-group recovery intents; exactly one is allowed`,
234
453
  );
235
454
  }
236
- const emitted = [...fixedEmitted, ...invitationEmitted, ...recoveryCandidates];
455
+ const recoveryDoors = frameworkDoor.length > 0 ? frameworkDoor : recoveryCandidates;
456
+ const emitted = [
457
+ ...fixedEmitted,
458
+ ...invitationEmitted,
459
+ ...recoveryDoors,
460
+ ...frameworkChildRepair,
461
+ ...frameworkModelAuthorityPull,
462
+ ];
237
463
  if (emitted.length === 0) return undefined;
238
464
 
239
465
  const certificateEntry = emitted.find((entry) =>
@@ -251,8 +477,12 @@ export function generateDartApplicationFrameworkCalls(
251
477
  if (certificateEntry === undefined || certificateField === undefined) {
252
478
  throw new Error("Dart framework call codegen: cannot locate the BirthCertificate law record");
253
479
  }
254
- const directive = (laws.find((law) => law.graph.domain.entity.label === certificateEntry.domain)?.module.directives as AnyDirective[] | undefined)
255
- ?.find((candidate) => candidate.id === certificateEntry.directive);
480
+ const certificateLaw = laws.find(
481
+ (law) => law.graph.domain.entity.label === certificateEntry.domain,
482
+ );
483
+ const directive = certificateLaw === undefined
484
+ ? undefined
485
+ : authoredDirective(certificateLaw.module, certificateEntry.directive);
256
486
  if (directive === undefined) {
257
487
  throw new Error("Dart framework call codegen: cannot locate the BirthCertificate directive");
258
488
  }
@@ -288,6 +518,8 @@ export function generateDartApplicationFrameworkCalls(
288
518
  .filter((definition) => definition.dartBirth === true)
289
519
  .map((definition) => definition.kind),
290
520
  "recoverExistingReceivingGroupDevice",
521
+ "repairChildAuthentication",
522
+ "seatParentModelAuthority",
291
523
  "redeemInvitation",
292
524
  ])].flatMap((kind) => {
293
525
  const alternatives = emitted.filter((entry) => entry.kind === kind);
@@ -295,15 +527,46 @@ export function generateDartApplicationFrameworkCalls(
295
527
  (kind === "recoverExistingReceivingGroupDevice"
296
528
  ? [{ name: "user", dartType: "String", shape: "scalar", optional: false } satisfies PayloadFieldSpec]
297
529
  : invitationContractFields);
530
+ if (kind === "seatParentModelAuthority") {
531
+ const seat = alternatives[0];
532
+ return [
533
+ ` @override`,
534
+ ` NmsGeneratedCall seatParentModelAuthority({required List<NmsModelAuthorityHolder> holders, required String seatedAt}) {`,
535
+ ...(seat === undefined
536
+ ? [` throw StateError("The compiled application has no framework model-authority self-seat law (it births no children).");`]
537
+ : [
538
+ ` final payload = (holders: holders, seatedAt: seatedAt);`,
539
+ ` return ${seat.encoder.functionName}(payload);`,
540
+ ]),
541
+ ` }`,
542
+ ``,
543
+ ];
544
+ }
545
+ if (kind === "repairChildAuthentication") {
546
+ const repair = alternatives[0];
547
+ return [
548
+ ` @override`,
549
+ ` NmsGeneratedCall repairChildAuthentication({required String workspace, required String user, String? deviceKeySubject}) {`,
550
+ ...(repair === undefined
551
+ ? [` throw StateError("The compiled application has no framework child-authentication repair law (it births no children).");`]
552
+ : [
553
+ ` final payload = (workspace: workspace, user: user, deviceKeySubject: deviceKeySubject);`,
554
+ ` return ${repair.encoder.functionName}(payload);`,
555
+ ]),
556
+ ` }`,
557
+ ``,
558
+ ];
559
+ }
298
560
  if (kind === "recoverExistingReceivingGroupDevice") {
299
561
  const recovery = alternatives[0];
300
562
  return [
301
563
  ` @override`,
302
- ` NmsGeneratedCall recoverExistingReceivingGroupDevice({required String user}) {`,
564
+ ` NmsGeneratedCall recoverExistingReceivingGroupDevice({required String user, String? deviceKeySubject}) {`,
303
565
  ...(recovery === undefined
304
566
  ? [` throw StateError("The compiled application has no existing receiving-group device recovery law.");`]
305
567
  : [
306
- ` final payload = (user: user,);`,
568
+ recovery.fields.length === 1 ? ` final payload = (user: user,);` :
569
+ ` final payload = (user: user, deviceKeySubject: deviceKeySubject);`,
307
570
  ` return ${recovery.encoder.functionName}(payload);`,
308
571
  ]),
309
572
  ` }`,
@@ -326,14 +589,23 @@ export function generateDartApplicationFrameworkCalls(
326
589
  ...(routeByDirective ? [` required String directive,`] : []),
327
590
  ...signature,
328
591
  ` }) {`,
329
- ` final payload = (`,
330
- ...payload,
331
- ` );`,
332
- ` return switch (${routeByDirective ? "'$domain/$directive'" : "domain"}) {`,
333
- ...alternatives.map((entry) =>
334
- ` ${JSON.stringify(routeByDirective ? `${entry.domain}/${entry.directive}` : entry.domain)} => ${entry.encoder.functionName}(payload),`),
335
- ` _ => throw StateError("The compiled application has no '${kind}' call in domain '$domain'."),`,
336
- ` };`,
592
+ // With no alternative the switch is only its unreachable default, so binding the payload
593
+ // would leave a dead local — `dart analyze` reports unused_local_variable and exits
594
+ // non-zero on the generated package. Refuse the same way the three fixed methods above do.
595
+ ...(alternatives.length === 0
596
+ ? [
597
+ ` throw StateError("The compiled application has no '${kind}' call in domain '$domain'.");`,
598
+ ]
599
+ : [
600
+ ` final payload = (`,
601
+ ...payload,
602
+ ` );`,
603
+ ` return switch (${routeByDirective ? "'$domain/$directive'" : "domain"}) {`,
604
+ ...alternatives.map((entry) =>
605
+ ` ${JSON.stringify(routeByDirective ? `${entry.domain}/${entry.directive}` : entry.domain)} => ${entry.encoder.functionName}(payload),`),
606
+ ` _ => throw StateError("The compiled application has no '${kind}' call in domain '$domain'."),`,
607
+ ` };`,
608
+ ]),
337
609
  ` }`,
338
610
  ``,
339
611
  ];
@@ -343,14 +615,16 @@ export function generateDartApplicationFrameworkCalls(
343
615
  `// AUTO-GENERATED by nomos-compile — pre-bind framework calls for this exact application law.`,
344
616
  `// No host authority or payload schema lives here. Do not edit.`,
345
617
  `// ignore_for_file: invalid_use_of_internal_member, unused_element, unused_import, unused_shown_name`,
346
- `import 'dart:convert' show base64Encode, utf8;`,
618
+ `import 'dart:convert' show base64Encode;`,
347
619
  `import 'dart:typed_data' show Uint8List;`,
348
- `import 'package:nomos_types/nomos_kernel_protocol.dart' show BirthCertificate;`,
620
+ `import 'package:fixnum/fixnum.dart' show Int64;`,
621
+ `import 'operation_payloads.pb.dart' as _nmsop;`,
622
+ `import 'package:nomos_types/nomos_kernel_protocol.dart' show ApplicationBirthContract, BirthCertificate;`,
349
623
  `import 'package:nomos_types/nomos_types.dart' show NomosSlot, Sha256Digest;`,
350
624
  `import 'package:nomos_client/src/application_framework_calls.dart';`,
351
625
  `import 'package:nomos_client/src/generated_call.dart';`,
352
626
  ``,
353
- ...DART_CALL_USDA_PRELUDE,
627
+ ...DART_CALL_PROTO_PRELUDE,
354
628
  ...(certificateRecordType === undefined
355
629
  ? []
356
630
  : [
@@ -365,6 +639,15 @@ export function generateDartApplicationFrameworkCalls(
365
639
  ` const _NmsCompiledApplicationFrameworkCalls();`,
366
640
  ` @override`,
367
641
  ` String get applicationHomeDomain => ${JSON.stringify(APPLICATION_HOME_DOMAIN)};`,
642
+ ` @override`,
643
+ ` String get applicationAuthorityDomain => ${JSON.stringify(recoveryDoors[0]?.domain ?? APPLICATION_HOME_DOMAIN)};`,
644
+ ` @override`,
645
+ ` String get parentModelAuthoritySeatAggregate => ${JSON.stringify(PARENT_MODEL_AUTHORITY_SEAT_AGGREGATE)};`,
646
+ ` @override`,
647
+ ` String get parentModelAuthoritySeatId => ${JSON.stringify(PARENT_MODEL_AUTHORITY_SEAT_ID)};`,
648
+ ` @override`,
649
+ ` ApplicationBirthContract get applicationBirthContract =>`,
650
+ ` ApplicationBirthContract(lawSha256: ${JSON.stringify(descriptor.lawSha256)});`,
368
651
  ``,
369
652
  ...methods,
370
653
  `}`,
@@ -0,0 +1,159 @@
1
+ import type { IndexedVariant } from "./indexed_variant.js";
2
+ import { dartMemberName, dartTypeOfVoField, unionArmClassName } from "./codegen_dart.js";
3
+
4
+ /** Stateless, generated proof of a runtime field/value relationship. Constructors
5
+ * remain library-private: callers narrow the binding and receive only its edit API.
6
+ */
7
+ export function emitDartIndexedVariant(d: IndexedVariant): string {
8
+ const n = d.name;
9
+ const v = d.value.name;
10
+ const entries = Object.entries(d.cases).sort(([a], [b]) => a.localeCompare(b));
11
+ const armClass = (arm: string) => unionArmClassName(v, arm);
12
+ const caseClass = (kind: string) => unionArmClassName(n, kind);
13
+ const kindsByArm = new Map<string, string[]>();
14
+ for (const [kind, arm] of entries) kindsByArm.set(arm, [...(kindsByArm.get(arm) ?? []), kind]);
15
+ const classes = entries.map(([kind, arm]) => {
16
+ const shape = d.value.descriptor.union![arm]!;
17
+ const fields = "ref" in shape
18
+ ? [{ member: "value", type: shape.ref, optional: false }]
19
+ : Object.entries(shape.fields).filter(([, f]) => f.type !== "literal").map(([key, f]) => ({
20
+ member: dartMemberName(key),
21
+ type: dartTypeOfVoField(f, armClass(arm), key) + (f.optional && !f.nullable ? "?" : ""),
22
+ optional: f.optional === true,
23
+ }));
24
+ const args = fields.length === 1
25
+ ? `${fields[0]!.type} value`
26
+ : fields.length === 0 ? "" : `{${fields.map((f) => `${f.optional ? "" : "required "}${f.type} ${f.member}`).join(", ")}}`;
27
+ const construct = "ref" in shape ? `${armClass(arm)}(value)`
28
+ : `${armClass(arm)}(${fields.map((f) => `${f.member}: ${fields.length === 1 ? "value" : f.member}`).join(", ")})`;
29
+ return `final class ${caseClass(kind)} extends ${n}Editable {
30
+ final ${armClass(arm)}? value;
31
+ const ${caseClass(kind)}._(String id, String? definitionVersion, this.value) : super._('${kind}', id, definitionVersion);
32
+ ${n}Edit edit(${args}) => ${n}Edit._(id, kind, definitionVersion, ${construct});
33
+ }`;
34
+ });
35
+ const decodeCases = entries.map(([kind, arm]) => {
36
+ const shape = d.value.descriptor.union![arm]!;
37
+ const keys = "ref" in shape ? ["value"] : Object.keys(shape.fields).filter((key) => shape.fields[key]!.type !== "literal");
38
+ return ` '${kind}' => ${armClass(arm)}.fromProjected(${keys.length === 1
39
+ ? `{'type': '${arm}', '${keys[0]}': input}`
40
+ : `{'type': '${arm}', ...(input as Map).cast<String, Object?>()}`}),`;
41
+ });
42
+ return `/// Runtime narrowing for the declared ${n} discriminator/value relationship.
43
+ sealed class ${n}Binding {
44
+ final String id;
45
+ final String kind;
46
+ final String? definitionVersion;
47
+ const ${n}Binding._(this.id, this.kind, this.definitionVersion);
48
+
49
+ /// Recover a definition kind only when the declared relationship is unambiguous.
50
+ static String? kindOf(${v}? value) => switch (value) {
51
+ ${[...kindsByArm].filter(([, kinds]) => kinds.length === 1).map(([arm, kinds]) => ` ${armClass(arm)}() => '${kinds[0]}',`).join("\n")}
52
+ _ => null,
53
+ };
54
+
55
+ static ${n}Binding resolve({required String id, required String kind, ${v}? value, String? definitionVersion}) {
56
+ switch (kind) {
57
+ ${entries.map(([kind, arm]) => ` case '${kind}':
58
+ if (value != null && value is! ${armClass(arm)}) {
59
+ return ${n}ShapeMismatch._(id, kind, definitionVersion, value);
60
+ }
61
+ return ${caseClass(kind)}._(id, definitionVersion, value as ${armClass(arm)}?);`).join("\n")}
62
+ default:
63
+ return ${n}Unsupported._(id, kind, definitionVersion);
64
+ }
65
+ }
66
+ }
67
+
68
+ sealed class ${n}Editable extends ${n}Binding {
69
+ const ${n}Editable._(String kind, String id, String? definitionVersion) : super._(id, kind, definitionVersion);
70
+ ${n}Edit clear() => ${n}Edit._(id, kind, definitionVersion, null);
71
+ }
72
+
73
+ ${classes.join("\n\n")}
74
+
75
+ sealed class ${n}Rejection extends ${n}Binding implements Exception {
76
+ const ${n}Rejection._(super.id, super.kind, super.definitionVersion) : super._();
77
+ String get message;
78
+ @override
79
+ String toString() => message;
80
+ }
81
+
82
+ final class ${n}Unsupported extends ${n}Rejection {
83
+ const ${n}Unsupported._(super.id, super.kind, super.definitionVersion) : super._();
84
+ @override
85
+ String get message => 'Unsupported ${n} kind: $kind';
86
+ }
87
+
88
+ final class ${n}ShapeMismatch extends ${n}Rejection {
89
+ final ${v} value;
90
+ const ${n}ShapeMismatch._(super.id, super.kind, super.definitionVersion, this.value) : super._();
91
+ @override
92
+ String get message => '${n} $id has a value incompatible with $kind';
93
+ }
94
+
95
+ final class ${n}DefinitionChanged extends ${n}Rejection {
96
+ const ${n}DefinitionChanged._(super.id, super.kind, super.definitionVersion) : super._();
97
+ @override
98
+ String get message => '${n} $id changed; reopen its editor';
99
+ }
100
+
101
+ final class ${n}InvalidInput extends ${n}Rejection {
102
+ const ${n}InvalidInput._(super.id, super.kind, super.definitionVersion) : super._();
103
+ @override
104
+ String get message => 'Invalid input for ${n} $id ($kind)';
105
+ }
106
+
107
+ /// An edit can only be constructed by a narrowed field or the checked JSON boundary.
108
+ final class ${n}Edit {
109
+ final String id;
110
+ final String kind;
111
+ final String? definitionVersion;
112
+ final ${v}? _value;
113
+ ${n}Edit._(this.id, this.kind, this.definitionVersion, ${v}? value)
114
+ : _value = value == null ? null : ${v}.fromProjected(_${n}Snapshot(value.toJson()) as Map<String, Object?>);
115
+ // Copy at both boundaries: mutable nested collections cannot change an already-created edit.
116
+ ${v}? get value => _value == null ? null : ${v}.fromProjected(_${n}Snapshot(_value.toJson()) as Map<String, Object?>);
117
+
118
+ /// Recheck the current definition immediately before submitting. No I/O.
119
+ ${n}Rejection? rejectionFor(${n}Binding current) {
120
+ if (current is ${n}Rejection) return current;
121
+ if (current.id != id || current.kind != kind || current.definitionVersion != definitionVersion) {
122
+ return ${n}DefinitionChanged._(id, kind, definitionVersion);
123
+ }
124
+ return null;
125
+ }
126
+
127
+ /// Only for untyped external input (JSON/actions). UI code uses the narrowed edit method.
128
+ static ${n}Edit decode(${n}Binding field, Object? input) {
129
+ if (field is ${n}Rejection) throw field;
130
+ if (input == null) return (field as ${n}Editable).clear();
131
+ try {
132
+ final ${v} value;
133
+ if (input is ${v}) {
134
+ value = input;
135
+ } else if (input is Map && input.containsKey('type')) {
136
+ value = ${v}.fromProjected(input.cast<String, Object?>());
137
+ } else {
138
+ value = switch (field.kind) {
139
+ ${decodeCases.join("\n")}
140
+ _ => throw ${n}Unsupported._(field.id, field.kind, field.definitionVersion),
141
+ };
142
+ }
143
+ final checked = ${n}Binding.resolve(id: field.id, kind: field.kind, definitionVersion: field.definitionVersion, value: value);
144
+ if (checked is ${n}Rejection) throw checked;
145
+ return ${n}Edit._(field.id, field.kind, field.definitionVersion, value);
146
+ } on ${n}Rejection {
147
+ rethrow;
148
+ } on Object {
149
+ throw ${n}InvalidInput._(field.id, field.kind, field.definitionVersion);
150
+ }
151
+ }
152
+ }
153
+
154
+ Object? _${n}Snapshot(Object? value) => switch (value) {
155
+ Map value => value.map((key, item) => MapEntry(key as String, _${n}Snapshot(item))),
156
+ List value => value.map(_${n}Snapshot).toList(),
157
+ _ => value,
158
+ };`;
159
+ }