@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
@@ -6,7 +6,7 @@
6
6
  /// SESSION-BOUND CLIENTS (architecture/session_bound_clients.md) — the typed contract between a
7
7
  /// generated `<Domain>Client` and the [NomosSession] it is constructed with.
8
8
  ///
9
- /// THE FOUR-LAYER SPLIT: the ENGINE ([NomosBridge]/[NomosEngine]) is ONLY the multi-workspace
9
+ /// THE FOUR-LAYER SPLIT: Reception is only the language-native multi-workspace
10
10
  /// runtime (mount/connect/session registry/sync/custody/follow-ref); a SESSION is exactly one
11
11
  /// workspace; a GENERATED CLIENT is exactly one session + one domain interface expectation + one
12
12
  /// actor context; everything else is a stateless value. This file carries:
@@ -20,17 +20,17 @@
20
20
  /// the session's workspace does not serve the expected domain compatibly.
21
21
  /// * [DomainNotInstalledForSession] — the context-rich replacement for the kernel's generic
22
22
  /// "no active installed law declares domain 'x'" refusal, thrown wherever that error used to
23
- /// surface (bridge dispatch, birth lanes) with the full session context.
23
+ /// surface (Reception dispatch, birth lanes) with the full session context.
24
24
  @internal
25
25
  library;
26
26
 
27
- import 'package:meta/meta.dart' show internal;
27
+ import 'dart:typed_data';
28
28
 
29
- import 'dart:convert';
29
+ import 'package:meta/meta.dart' show internal;
30
30
 
31
31
  import 'package:nomos_types/nomos_kernel_protocol.dart' as nomos_protocol;
32
32
 
33
- import 'webview_bridge.dart';
33
+ import 'reception/dart_reception.dart';
34
34
 
35
35
  /// The STATIC INTERFACE DESCRIPTOR a generated client exposes as `XClient.interface` — what the
36
36
  /// client EXPECTS of the workspace it binds to: the domain key, the law hash it was generated
@@ -42,29 +42,75 @@ class NomosClientInterface {
42
42
  /// sha256 of the `.package.usda` this client was generated against (advisory provenance).
43
43
  final String expectedDomainHash;
44
44
 
45
- /// sha256 of the canonical structural interface JSON (from the baked compat manifest), when known.
46
- final String? expectedInterfaceHash;
47
-
48
- /// The structural interface (#72) as JSON — the directives + read shapes this client depends
49
- /// on. Empty ⇒ no structural requirement was baked (hash-only provenance).
50
- final String interfaceJson;
51
-
52
- /// The compiler-baked compat manifest (§5) as JSON, when present — diagnosis only, never a gate.
53
- final String? compatJson;
45
+ /// Canonical compiler-authored USDA compatibility matrix. The generated
46
+ /// client and Peer Office carry it opaquely; the kernel interprets it.
47
+ final Uint8List? compatibilityMatrixUsda;
54
48
 
55
49
  const NomosClientInterface({
56
50
  required this.domain,
57
51
  required this.expectedDomainHash,
58
- this.expectedInterfaceHash,
59
- this.interfaceJson = '',
60
- this.compatJson,
52
+ this.compatibilityMatrixUsda,
53
+ });
54
+ }
55
+
56
+ /// The strongest remediation fact the local peer can prove without inventing
57
+ /// a fleet policy decision that belongs to console.nomos.cafe.
58
+ enum NomosCompatibilityGuidance {
59
+ none,
60
+ observeRemote,
61
+ workspaceUpdatePending,
62
+ controlPlaneDecisionRequired,
63
+ }
64
+
65
+ /// Exhaustive pre-dispatch posture for one exact generated operation.
66
+ sealed class NomosOperationCompatibility {
67
+ const NomosOperationCompatibility({
68
+ required this.domain,
69
+ required this.directive,
61
70
  });
62
71
 
63
- /// The `{domain: interface}` requirement map the shape-compat check consumes, or null when no
64
- /// structural interface was baked.
65
- Map<String, Object?>? get requirement => interfaceJson.isEmpty
66
- ? null
67
- : {domain: (jsonDecode(interfaceJson) as Map).cast<String, Object?>()};
72
+ final String domain;
73
+ final String directive;
74
+ }
75
+
76
+ final class NomosOperationAvailable extends NomosOperationCompatibility {
77
+ const NomosOperationAvailable({
78
+ required super.domain,
79
+ required super.directive,
80
+ required this.workspaceFrontier,
81
+ });
82
+
83
+ final String workspaceFrontier;
84
+ }
85
+
86
+ /// A generated write that the installed law cannot safely decode or execute.
87
+ /// It is both a sealed posture value and the typed exception raised by
88
+ /// [NomosSessionCompat.assertOperationCompatible].
89
+ final class NomosOperationUnavailable extends NomosOperationCompatibility
90
+ implements Exception {
91
+ const NomosOperationUnavailable({
92
+ required super.domain,
93
+ required super.directive,
94
+ required this.guidance,
95
+ required this.differences,
96
+ required this.workspaceFrontier,
97
+ });
98
+
99
+ final NomosCompatibilityGuidance guidance;
100
+ final List<nomos_protocol.InterfaceMemberVerdict> differences;
101
+ final String workspaceFrontier;
102
+
103
+ @override
104
+ String toString() {
105
+ final detail = differences
106
+ .map((difference) => difference.diagnostic.isNotEmpty
107
+ ? difference.diagnostic
108
+ : '${difference.member}'
109
+ '${difference.field_4.isEmpty ? '' : '.${difference.field_4}'}')
110
+ .join('; ');
111
+ return 'NomosOperationUnavailable($domain/$directive, '
112
+ '${guidance.name}: ${detail.isEmpty ? 'not supported by installed law' : detail})';
113
+ }
68
114
  }
69
115
 
70
116
  /// The four distinguishable causes of a session/client mismatch (ask 9 of
@@ -136,11 +182,6 @@ class DomainClientSessionMismatch implements Exception {
136
182
  required this.hint,
137
183
  });
138
184
 
139
- /// True only for the one bind failure a staged generated successor can
140
- /// lawfully resolve by proving itself against this workspace's history.
141
- bool get canAttemptGeneratedModelAdoption =>
142
- cause == SessionMismatchCause.clientExpectsNewerInterface;
143
-
144
185
  @override
145
186
  String toString() =>
146
187
  'DomainClientSessionMismatch: session "${sessionId ?? '(unbound)'}" (workspace '
@@ -152,171 +193,9 @@ class DomainClientSessionMismatch implements Exception {
152
193
  'active law: ${activeDomainHashes.isEmpty ? '(unknown)' : activeDomainHashes.join(', ')})';
153
194
  }
154
195
 
155
- /// A generated candidate reached the lawful model-adoption boundary while
156
- /// binding, but exact-history proof requires a deliberate business decision or
157
- /// could not complete. The old model remains active and no compatibility
158
- /// fallback is used.
159
- enum DomainModelDifferenceKind { rules, outcome, evidence }
160
-
161
- final class DomainModelDifference {
162
- final DomainModelDifferenceKind kind;
163
- final String? area;
164
- final String? action;
165
- final String summary;
166
-
167
- const DomainModelDifference({
168
- required this.kind,
169
- this.area,
170
- this.action,
171
- required this.summary,
172
- });
173
- }
174
-
175
- final class DomainModelReview {
176
- final int checkedActions;
177
- final int candidateActions;
178
- final bool? sameOutcome;
179
- final List<DomainModelDifference> differences;
180
-
181
- const DomainModelReview({
182
- required this.checkedActions,
183
- required this.candidateActions,
184
- required this.sameOutcome,
185
- required this.differences,
186
- });
187
- }
188
-
189
- class DomainClientModelAdoptionRequired implements Exception {
190
- final String expectedDomainKey;
191
- final String expectedDomainHash;
192
- final String status;
193
- final String summary;
194
- final DomainModelReview review;
195
- final Future<void> Function()? _stage;
196
- final Future<void> Function(String reason)? _accept;
197
-
198
- const DomainClientModelAdoptionRequired({
199
- required this.expectedDomainKey,
200
- required this.expectedDomainHash,
201
- required this.status,
202
- required this.summary,
203
- required this.review,
204
- Future<void> Function()? stage,
205
- Future<void> Function(String reason)? accept,
206
- }) : _stage = stage,
207
- _accept = accept;
208
-
209
- bool get canStage => _stage != null;
210
-
211
- Future<void> stage() {
212
- final stage = _stage;
213
- if (stage == null) {
214
- throw StateError('This generated model is not waiting to be staged.');
215
- }
216
- return stage();
217
- }
218
-
219
- bool get canAccept => _accept != null;
220
-
221
- /// Accept the candidate after reviewing the compiler-derived consequences.
222
- /// Stable identities, retirements and value evolutions come from candidate
223
- /// law; application code supplies accountability, never mechanical waivers.
224
- Future<void> accept(String reason) {
225
- final value = reason.trim();
226
- if (value.isEmpty) {
227
- throw ArgumentError.value(
228
- reason,
229
- 'reason',
230
- 'must explain why changing prior business outcomes is intended',
231
- );
232
- }
233
- final accept = _accept;
234
- if (accept == null) {
235
- throw StateError('This generated model change cannot be accepted.');
236
- }
237
- return accept(value);
238
- }
239
-
240
- @override
241
- String toString() => 'DomainClientModelAdoptionRequired: generated model for '
242
- '"$expectedDomainKey" ($expectedDomainHash) is $status. $summary';
243
- }
244
-
245
- /// A generated model step repeated without converging after several retries.
246
- ///
247
- /// The limit is per immutable lifecycle step, not a cap on how many historical
248
- /// model generations a long-lived workspace may lawfully adopt. That distinction
249
- /// lets an old workspace catch up across an arbitrary backlog while still making
250
- /// a genuinely stuck stage/accept loop fail loudly and with useful context.
251
- final class DomainClientModelLifecycleStalled implements Exception {
252
- const DomainClientModelLifecycleStalled({
253
- required this.domain,
254
- required this.candidateHash,
255
- required this.status,
256
- required this.attempts,
257
- });
258
-
259
- final String domain;
260
- final String candidateHash;
261
- final String status;
262
- final int attempts;
263
-
264
- @override
265
- String toString() => 'DomainClientModelLifecycleStalled: generated model for '
266
- '"$domain" ($candidateHash) remained $status after $attempts governed '
267
- 'attempts without progress.';
268
- }
269
-
270
- /// Converge every pending generated-model generation, bounded by repeated work.
271
- ///
272
- /// A workspace can legitimately be more than a fixed number of generations
273
- /// behind. Each distinct domain/hash/status tuple is evidence of progress, so it
274
- /// gets its own retry budget. Only repetition of the same immutable step is a
275
- /// stall.
276
- Future<T> nmsInternalConvergeGeneratedModel<T>({
277
- required Future<T> Function() attempt,
278
- required Future<void> Function(DomainClientModelAdoptionRequired change)
279
- handle,
280
- }) async {
281
- const maxAttemptsPerStep = 12;
282
- final attemptsByStep = <String, int>{};
283
- while (true) {
284
- try {
285
- return await attempt();
286
- } on DomainClientModelAdoptionRequired catch (change) {
287
- // A lifecycle response with no lawful next action is a terminal refusal,
288
- // not a convergence step. Preserve the kernel's exact diagnostic instead
289
- // of retrying until a generic stall obscures it.
290
- if (!change.canStage && !change.canAccept) throw change;
291
- final step = '${change.expectedDomainKey}\u0000'
292
- '${change.expectedDomainHash}\u0000'
293
- '${change.status}\u0000'
294
- '${change.canStage}\u0000${change.canAccept}';
295
- final attempts = (attemptsByStep[step] ?? 0) + 1;
296
- attemptsByStep[step] = attempts;
297
- if (attempts > maxAttemptsPerStep) {
298
- throw DomainClientModelLifecycleStalled(
299
- domain: change.expectedDomainKey,
300
- candidateHash: change.expectedDomainHash,
301
- status: change.status,
302
- attempts: attempts,
303
- );
304
- }
305
- try {
306
- await handle(change);
307
- } on DomainClientModelAdoptionRequired catch (nextChange) {
308
- // A transient preflight/acceptance race re-enters the same typed step.
309
- // The per-step budget above prevents a genuine loop without limiting
310
- // how many distinct historical generations may converge.
311
- if (!nextChange.canStage && !nextChange.canAccept) throw nextChange;
312
- }
313
- }
314
- }
315
- }
316
-
317
196
  /// The context-rich replacement for the kernel's generic
318
197
  /// `no active installed law declares domain 'x' … deploy the domain package first` refusal —
319
- /// thrown wherever that error used to surface (bridge dispatch, birth lanes) so an app dev sees
198
+ /// thrown wherever that error used to surface (Reception dispatch, birth lanes) so an app dev sees
320
199
  /// WHICH session refused, what it actually runs, and the likely causes.
321
200
  class DomainNotInstalledForSession implements Exception {
322
201
  /// The domain key the dispatch named.
@@ -325,7 +204,7 @@ class DomainNotInstalledForSession implements Exception {
325
204
  /// The law hash the dispatch carried (advisory), when any.
326
205
  final String? expectedDomainHash;
327
206
 
328
- /// The runner session the dispatch routed to (null on a bare single-session bridge).
207
+ /// The peer-office session the dispatch routed to.
329
208
  final String? sessionId;
330
209
 
331
210
  /// The workspace that session is pinned to.
@@ -383,47 +262,87 @@ class DomainNotInstalledForSession implements Exception {
383
262
  /// constructor, and directly from tests (ask 9). Throws [DomainClientSessionMismatch] with the
384
263
  /// cause classified; returns normally when the session serves the client's law compatibly.
385
264
  extension NomosSessionCompat on NomosSession {
265
+ /// Examine one exact generated write against the installed local law. The
266
+ /// session caches the kernel verdict until Peer Office reports a law/custody
267
+ /// change, so ordinary repeated writes perform no compatibility round-trip.
268
+ Future<NomosOperationCompatibility> operationCompatibility(
269
+ Uint8List applicationMatrixUsda, {
270
+ required String domain,
271
+ required String directive,
272
+ }) async {
273
+ final answer = await checkCompatibility(applicationMatrixUsda);
274
+ final failures = answer.examined.members
275
+ .where((member) =>
276
+ member.domain == domain &&
277
+ (member.kind ==
278
+ nomos_protocol
279
+ .InterfaceMemberKind.INTERFACE_MEMBER_KIND_DOMAIN ||
280
+ member.member == directive) &&
281
+ member.status !=
282
+ nomos_protocol.InterfaceCompatibilityStatus
283
+ .INTERFACE_COMPATIBILITY_STATUS_EXACT &&
284
+ member.status !=
285
+ nomos_protocol.InterfaceCompatibilityStatus
286
+ .INTERFACE_COMPATIBILITY_STATUS_COMPATIBLE)
287
+ .toList(growable: false);
288
+ if (failures.isEmpty) {
289
+ return NomosOperationAvailable(
290
+ domain: domain,
291
+ directive: directive,
292
+ workspaceFrontier: answer.examined.workspaceFrontier,
293
+ );
294
+ }
295
+ final guidance = switch (answer.localLawCurrency) {
296
+ nomos_protocol.LocalLawCurrency.LOCAL_LAW_CURRENCY_BEHIND =>
297
+ NomosCompatibilityGuidance.workspaceUpdatePending,
298
+ nomos_protocol.LocalLawCurrency.LOCAL_LAW_CURRENCY_CURRENT =>
299
+ NomosCompatibilityGuidance.controlPlaneDecisionRequired,
300
+ nomos_protocol.LocalLawCurrency.LOCAL_LAW_CURRENCY_UNOBSERVED ||
301
+ nomos_protocol.LocalLawCurrency.LOCAL_LAW_CURRENCY_UNSPECIFIED =>
302
+ NomosCompatibilityGuidance.observeRemote,
303
+ _ => NomosCompatibilityGuidance.observeRemote,
304
+ };
305
+ return NomosOperationUnavailable(
306
+ domain: domain,
307
+ directive: directive,
308
+ guidance: guidance,
309
+ differences: failures,
310
+ workspaceFrontier: answer.examined.workspaceFrontier,
311
+ );
312
+ }
313
+
314
+ Future<void> assertOperationCompatible(
315
+ Uint8List applicationMatrixUsda, {
316
+ required String domain,
317
+ required String directive,
318
+ }) async {
319
+ final posture = await operationCompatibility(
320
+ applicationMatrixUsda,
321
+ domain: domain,
322
+ directive: directive,
323
+ );
324
+ if (posture case final NomosOperationUnavailable unavailable) {
325
+ throw unavailable;
326
+ }
327
+ }
328
+
386
329
  Future<void> assertCompatible(NomosClientInterface iface) async {
387
- // The exact generated package identity is stronger than a structural comparison. The kernel's
388
- // point-readable `law/current.usda` answers this bounded happy path without materialising the
389
- // complete interface offer. Structural discovery is reserved for genuine version skew.
390
330
  List<String> activeKeys = const [];
391
331
  List<String> activeHashes = const [];
392
- try {
393
- final law = await lawStatus(iface.expectedDomainHash);
394
- activeHashes = ((law['current'] as List?) ?? const [])
395
- .map((value) => value.toString())
396
- .toList(growable: false);
397
- if (activeHashes.contains(iface.expectedDomainHash)) return;
398
- activeKeys = ((law['currentDomains'] as List?) ?? const [])
399
- .map((value) => value.toString())
400
- .toList(growable: false);
401
- // Compatibility is member-scoped, not one enormous application-wide ceremony. Once the
402
- // authenticated current-law index proves this domain is served, generated reads decode their
403
- // exact USDA result types and generated offers are judged by the current kernel route. A new
404
- // member therefore fails closed when used without blocking every older compatible feature.
405
- if (activeKeys.contains(iface.domain)) return;
406
- } catch (_) {
407
- // Preserve the structural fallback for older kernels which do not expose the typed current
408
- // frontier. Its error classification below remains the authoritative diagnostic path.
409
- }
410
332
 
411
333
  // 1. THE SHAPE AXIS (#72) — the one compatibility notion. The kernel compares the
412
334
  // compact generated requirement directly with its authenticated current-law index. Do not
413
335
  // export/materialise the complete interface merely to prove the successful path.
414
- final requirement = iface.requirement;
415
- if (requirement == null) return;
416
- Map<String, Object?> verdict;
336
+ final matrix = iface.compatibilityMatrixUsda;
337
+ if (matrix == null) return;
338
+ late nomos_protocol.InterfaceCompatibilityVerdict answer;
417
339
  try {
418
- final raw = await checkCompatibility(requirement);
419
- verdict = (raw['verdict'] is Map)
420
- ? (raw['verdict'] as Map).cast<String, Object?>()
421
- : raw;
340
+ answer = await checkCompatibility(matrix);
422
341
  } catch (e) {
423
342
  throw DomainClientSessionMismatch(
424
343
  expectedDomainKey: iface.domain,
425
344
  expectedDomainHash: iface.expectedDomainHash,
426
- expectedInterfaceHash: iface.expectedInterfaceHash,
345
+ expectedInterfaceHash: null,
427
346
  sessionId: workspace,
428
347
  sessionWorkspace: workspace,
429
348
  activeDomainKeys: activeKeys,
@@ -431,101 +350,82 @@ extension NomosSessionCompat on NomosSession {
431
350
  hint: 'the shape-compatibility check itself failed: $e',
432
351
  );
433
352
  }
434
- if (verdict['ok'] == true) return;
435
-
436
- // 2. HASH DIAGNOSIS — only a failed verdict needs retained installation inventory.
437
- if (iface.compatJson != null && iface.compatJson!.isNotEmpty) {
438
- try {
439
- final c = await checkCompat(
440
- (jsonDecode(iface.compatJson!) as Map).cast<String, Object?>(),
441
- iface.requirement);
442
- if (c != null) activeHashes = c.workspaceRuns;
443
- } catch (_) {
444
- /* diagnosis only — never replace the shape verdict */
445
- }
446
- }
447
-
448
- // 3. DIAGNOSTIC OFFER — only a failed verdict needs the complete active-domain names to
449
- // distinguish a newer client from the wrong package or a genuinely absent deployment.
450
- try {
451
- final offer = await interfaceOffer();
452
- if (offer != null) activeKeys = offer.keys.toList()..sort();
453
- } catch (e) {
454
- final isProjectionFault =
455
- e.toString().contains('nomos.projection.read_failed') ||
456
- e.toString().contains('projection read failed');
457
- throw DomainClientSessionMismatch(
458
- expectedDomainKey: iface.domain,
459
- expectedDomainHash: iface.expectedDomainHash,
460
- expectedInterfaceHash: iface.expectedInterfaceHash,
461
- sessionId: workspace,
462
- sessionWorkspace: workspace,
463
- activeDomainHashes: activeHashes,
464
- cause: isProjectionFault
465
- ? SessionMismatchCause.projectionReadFailed
466
- : null,
467
- hint: isProjectionFault
468
- ? 'the workspace law could NOT be READ — a projection/mount failure (NOT undeployed law): $e'
469
- : 'the session workspace is not reachable/mounted on this plane: $e',
470
- );
471
- }
472
-
473
- final missing =
474
- ((verdict['missing'] as List?) ?? const []).map((e) => '$e').toList();
475
- final incompatible = ((verdict['incompatible'] as List?) ?? const [])
476
- .map((e) => '$e')
477
- .toList();
353
+ final verdict = answer.examined;
354
+ if (verdict.compatible) return;
355
+
356
+ final failures = verdict.members
357
+ .where((member) =>
358
+ member.status ==
359
+ nomos_protocol.InterfaceCompatibilityStatus
360
+ .INTERFACE_COMPATIBILITY_STATUS_UNAVAILABLE ||
361
+ member.status ==
362
+ nomos_protocol.InterfaceCompatibilityStatus
363
+ .INTERFACE_COMPATIBILITY_STATUS_INCOMPATIBLE)
364
+ .toList(growable: false);
365
+ final missing = failures
366
+ .where((member) =>
367
+ member.status ==
368
+ nomos_protocol.InterfaceCompatibilityStatus
369
+ .INTERFACE_COMPATIBILITY_STATUS_UNAVAILABLE)
370
+ .map((member) => member.field_4.isEmpty
371
+ ? '${member.domain}/${member.member}'
372
+ : '${member.domain}/${member.member}/${member.field_4}')
373
+ .toList(growable: false);
374
+ final incompatible = failures
375
+ .where((member) =>
376
+ member.status ==
377
+ nomos_protocol.InterfaceCompatibilityStatus
378
+ .INTERFACE_COMPATIBILITY_STATUS_INCOMPATIBLE)
379
+ .map((member) => member.diagnostic.isEmpty
380
+ ? '${member.domain}/${member.member}'
381
+ : member.diagnostic)
382
+ .toList(growable: false);
383
+ final domainMissing = failures.any((member) =>
384
+ member.reason ==
385
+ nomos_protocol.InterfaceCompatibilityReason
386
+ .INTERFACE_COMPATIBILITY_REASON_DOMAIN_MISSING);
478
387
 
479
388
  // 4. CLASSIFY the four causes (ask 9).
480
389
  SessionMismatchCause cause;
481
390
  String hint;
482
- if (nmsInternalClientExpectsNewerInterface(
483
- domain: iface.domain,
484
- activeDomainKeys: activeKeys,
485
- missing: missing,
486
- incompatible: incompatible,
487
- )) {
391
+ if (!domainMissing) {
488
392
  cause = SessionMismatchCause.clientExpectsNewerInterface;
489
393
  final differences = [...incompatible, ...missing];
490
394
  hint =
491
395
  'the domain is installed but type-divergent from what this client requires '
492
396
  '(${differences.join('; ')}) — recompile the client against the deployed law, or evolve the law';
493
- } else if (activeKeys.isNotEmpty && !activeKeys.contains(iface.domain)) {
494
- cause = SessionMismatchCause.wrongPackageMounted;
495
- hint =
496
- 'this workspace runs a DIFFERENT package (${activeKeys.join(', ')}) — '
497
- 'bind this client to the session whose workspace holds "${iface.domain}"';
498
397
  } else {
499
- // The domain (or its whole offer) is absent here. Stale-vs-never-deployed: if this session is
500
- // cloud-bound and behind, a sync may bring the law; otherwise it was never deployed.
501
- var behind = 0;
502
- var cloudBound = false;
503
- try {
504
- final m = await metrics();
505
- behind = ((m['behind'] as num?) ?? 0).toInt();
506
- final listed = await listWorkspaces();
507
- cloudBound = listed.any((candidate) =>
508
- candidate.workspace == workspace &&
509
- candidate.syncPosture ==
510
- nomos_protocol
511
- .WorkspaceSyncPosture.WORKSPACE_SYNC_POSTURE_CLOUD_BOUND);
512
- } catch (_) {/* best-effort */}
513
- if (cloudBound && behind > 0) {
514
- cause = SessionMismatchCause.liveCloudHasLawButLocalStale;
515
- hint =
516
- 'local custody is $behind commit(s) behind its cloud — sync/pull, then re-bind '
517
- '(missing: ${missing.join('; ')})';
518
- } else {
519
- cause = SessionMismatchCause.trulyNotDeployed;
520
- hint =
521
- 'no installed law on this workspace declares "${iface.domain}" — '
522
- 'deploy the domain package first (missing: ${missing.join('; ')})';
398
+ // The domain (or its whole offer) is absent here. Stale-vs-never-deployed is
399
+ // a CORRESPONDENCE fact, and THE OFFICE STATES IT. Reception used to guess by
400
+ // reading a `SyncStatus.behind` count the reducer only ever set to 0 or null,
401
+ // so the "stale" arm was unreachable and every absence read as "never
402
+ // deployed". The desk's verdict now names the currency; this renders it.
403
+ switch (answer.localLawCurrency) {
404
+ case nomos_protocol.LocalLawCurrency.LOCAL_LAW_CURRENCY_BEHIND:
405
+ cause = SessionMismatchCause.liveCloudHasLawButLocalStale;
406
+ hint =
407
+ 'local custody trails its remote frontier — sync, then re-bind '
408
+ '(missing: ${missing.join('; ')})';
409
+ break;
410
+ case nomos_protocol.LocalLawCurrency.LOCAL_LAW_CURRENCY_UNOBSERVED:
411
+ cause = SessionMismatchCause.liveCloudHasLawButLocalStale;
412
+ hint =
413
+ 'no installed law on this workspace declares "${iface.domain}", and no '
414
+ 'remote frontier has been observed, so it may yet arrive — sync and '
415
+ 're-bind; if it still refuses, deploy the domain package '
416
+ '(missing: ${missing.join('; ')})';
417
+ break;
418
+ default:
419
+ cause = SessionMismatchCause.trulyNotDeployed;
420
+ hint =
421
+ 'no installed law on this workspace declares "${iface.domain}" — '
422
+ 'deploy the domain package first (missing: ${missing.join('; ')})';
523
423
  }
524
424
  }
525
425
  throw DomainClientSessionMismatch(
526
426
  expectedDomainKey: iface.domain,
527
427
  expectedDomainHash: iface.expectedDomainHash,
528
- expectedInterfaceHash: iface.expectedInterfaceHash,
428
+ expectedInterfaceHash: null,
529
429
  sessionId: workspace,
530
430
  sessionWorkspace: workspace,
531
431
  activeDomainKeys: activeKeys,
@@ -535,14 +435,3 @@ extension NomosSessionCompat on NomosSession {
535
435
  );
536
436
  }
537
437
  }
538
-
539
- /// Generator/runtime classification seam. A required member missing from an
540
- /// already installed domain is a newer-client shape, not an absent deployment.
541
- bool nmsInternalClientExpectsNewerInterface({
542
- required String domain,
543
- required List<String> activeDomainKeys,
544
- required List<String> missing,
545
- required List<String> incompatible,
546
- }) =>
547
- incompatible.isNotEmpty ||
548
- (missing.isNotEmpty && activeDomainKeys.contains(domain));