@githolon/dsl 0.108.7 → 0.110.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. package/assets/operation-contract.wasm +0 -0
  2. package/check_package.mjs +12 -15
  3. package/compile_package.mjs +17 -18
  4. package/compile_proof.mjs +16 -1
  5. package/dart/CHANGELOG.md +76 -1
  6. package/dart/README.md +25 -2
  7. package/dart/lib/src/admission_decision.dart +41 -0
  8. package/dart/lib/src/application_framework_calls.dart +52 -2
  9. package/dart/lib/src/application_model_adoption.dart +187 -0
  10. package/dart/lib/src/application_status.dart +73 -0
  11. package/dart/lib/src/console_enrolment.dart +271 -0
  12. package/dart/lib/src/console_http_io.dart +26 -0
  13. package/dart/lib/src/console_http_stub.dart +7 -0
  14. package/dart/lib/src/dev_cloud.dart +69 -22
  15. package/dart/lib/src/generated_call.dart +83 -23
  16. package/dart/lib/src/kernel_primitives.dart +119 -0
  17. package/dart/lib/src/nms_conformance_runtime.dart +1 -1
  18. package/dart/lib/src/nms_generated_runtime.dart +32 -10
  19. package/dart/lib/src/nms_test_environment.dart +1 -1
  20. package/dart/lib/src/node_runner_transport.dart +41 -46
  21. package/dart/lib/src/observed_session_directory.dart +70 -0
  22. package/dart/lib/src/operation_receipts.dart +112 -0
  23. package/dart/lib/src/peer_application_streams.dart +103 -0
  24. package/dart/lib/src/reception/dart_reception.dart +4280 -0
  25. package/dart/lib/src/reception/event_desk.dart +211 -0
  26. package/dart/lib/src/reception/extremum_read.dart +46 -0
  27. package/dart/lib/src/reception/local_copies.dart +371 -0
  28. package/dart/lib/src/reception/peer_office_connection.dart +11 -0
  29. package/dart/lib/src/reception/progress_desk.dart +267 -0
  30. package/dart/lib/src/reception/reception_contract.dart +11 -0
  31. package/dart/lib/src/reception/reception_session.dart +284 -0
  32. package/dart/lib/src/reception/sync_diagnostics.dart +26 -0
  33. package/dart/lib/src/reception/workspace_preparation_report.dart +126 -0
  34. package/dart/lib/src/replica_readiness.dart +123 -0
  35. package/dart/lib/src/runner/node-entry.mjs +23905 -15774
  36. package/dart/lib/src/runtime_v2_gateway.dart +56 -3
  37. package/dart/lib/src/runtime_v2_transport.dart +544 -3
  38. package/dart/lib/src/session_bound.dart +200 -311
  39. package/dart/lib/src/signing_identity_kernel.dart +84 -0
  40. package/dart/lib/src/sync_status_projection.dart +548 -0
  41. package/dart/lib/src/sync_status_reducer.dart +170 -0
  42. package/dart/lib/src/test_harness.dart +809 -1153
  43. package/dart/lib/src/testing/test_custody.dart +66 -0
  44. package/dart/lib/src/testing/test_peer.dart +328 -0
  45. package/dart/lib/src/typed_watch_registry.dart +169 -0
  46. package/dart/lib/src/workspace_open_progress.dart +27 -0
  47. package/dart/pubspec.lock +24 -1
  48. package/dart/pubspec.yaml +7 -2
  49. package/dart/pubspec_overrides.yaml +2 -0
  50. package/dart/test/admission_decision_test.dart +48 -0
  51. package/dart/test/background_model_adoption_test.dart +228 -0
  52. package/dart/test/bundle_version_pairing_test.dart +4 -4
  53. package/dart/test/child_authentication_repair_test.dart +359 -0
  54. package/dart/test/cloud_bound_local_shell_test.dart +119 -0
  55. package/dart/test/console_enrolment_refusal_test.dart +52 -0
  56. package/dart/test/console_enrolment_test.dart +227 -0
  57. package/dart/test/errors_test.dart +5 -5
  58. package/dart/test/event_plane_seam_test.dart +50 -164
  59. package/dart/test/extremum_read_test.dart +58 -0
  60. package/dart/test/fixtures/wedge/wedge-entry.mjs +3 -21
  61. package/dart/test/generated_query_test.dart +32 -0
  62. package/dart/test/harness_phase_timeout_test.dart +18 -23
  63. package/dart/test/kernel_author_after_read_test.dart +242 -0
  64. package/dart/test/kernel_fence_test.dart +137 -0
  65. package/dart/test/local_copies_test.dart +222 -0
  66. package/dart/test/model_adoption_test.dart +198 -0
  67. package/dart/test/node_peer_local_custody_test.dart +153 -0
  68. package/dart/test/offer_authentication_proof_test.dart +352 -52
  69. package/dart/test/operation_compatibility_test.dart +151 -0
  70. package/dart/test/platform_credential_effect_test.dart +386 -0
  71. package/dart/test/receiving_group_open_test.dart +213 -0
  72. package/dart/test/reception/workspace_preparation_report_test.dart +103 -0
  73. package/dart/test/reception_span_trace_test.dart +23 -0
  74. package/dart/test/replica_readiness_test.dart +156 -0
  75. package/dart/test/runtime_projections_test.dart +92 -0
  76. package/dart/test/runtime_v2_gateway_test.dart +131 -0
  77. package/dart/test/signing_identity_kernel_test.dart +75 -0
  78. package/dart/test/sync_status_preparation_report_test.dart +29 -0
  79. package/dart/test/sync_status_reducer_test.dart +419 -0
  80. package/dart/test/test_harness_test.dart +71 -95
  81. package/dart/test/typed_query_watch_test.dart +170 -0
  82. package/dart/test/typed_watch_registry_test.dart +249 -0
  83. package/dart_lints/README.md +18 -0
  84. package/dart_lints/lib/nomos_lints.dart +70 -0
  85. package/dart_lints/pubspec.lock +580 -0
  86. package/dart_lints/pubspec.yaml +12 -0
  87. package/dart_lints/test/reference_identity_test.dart +75 -0
  88. package/dart_types/CHANGELOG.md +18 -0
  89. package/dart_types/lib/nomos_kernel_protocol.dart +21 -1
  90. package/dart_types/lib/nomos_types.dart +9 -1
  91. package/dart_types/lib/src/admission_decision.dart +37 -0
  92. package/dart_types/lib/src/aggregate_meta.dart +1 -1
  93. package/dart_types/lib/src/approved_model.dart +65 -0
  94. package/dart_types/lib/src/custody.dart +10 -18
  95. package/dart_types/lib/src/error_info.dart +4 -4
  96. package/dart_types/lib/src/errors.dart +29 -29
  97. package/dart_types/lib/src/foreign_ref.dart +62 -33
  98. package/dart_types/lib/src/local_work_rejected.dart +3 -3
  99. package/dart_types/lib/src/nomos_ref.dart +3 -1
  100. package/dart_types/lib/src/principal.dart +2 -2
  101. package/dart_types/lib/src/proto/google/protobuf/any.pb.dart +163 -0
  102. package/dart_types/lib/src/proto/google/protobuf/any.pbenum.dart +11 -0
  103. package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pb.dart +137 -0
  104. package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pbenum.dart +11 -0
  105. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +20721 -10433
  106. package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pbenum.dart +555 -27
  107. package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pb.dart +387 -0
  108. package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pbenum.dart +46 -0
  109. package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pb.dart +295 -0
  110. package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pbenum.dart +139 -0
  111. package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pb.dart +269 -0
  112. package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pbenum.dart +103 -0
  113. package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pb.dart +417 -0
  114. package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pbenum.dart +62 -0
  115. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pb.dart +9968 -0
  116. package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pbenum.dart +133 -0
  117. package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pb.dart +204 -0
  118. package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pbenum.dart +54 -0
  119. package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pb.dart +1550 -0
  120. package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pbenum.dart +11 -0
  121. package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pb.dart +710 -0
  122. package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pbenum.dart +11 -0
  123. package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pb.dart +845 -0
  124. package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pbenum.dart +11 -0
  125. package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pb.dart +198 -0
  126. package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pbenum.dart +11 -0
  127. package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pb.dart +369 -0
  128. package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pbenum.dart +11 -0
  129. package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pb.dart +609 -0
  130. package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pbenum.dart +65 -0
  131. package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pb.dart +358 -0
  132. package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pbenum.dart +100 -0
  133. package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pb.dart +2231 -0
  134. package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pbenum.dart +271 -0
  135. package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pb.dart +1286 -0
  136. package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pbenum.dart +11 -0
  137. package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pb.dart +636 -0
  138. package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pbenum.dart +116 -0
  139. package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pb.dart +1637 -0
  140. package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pbenum.dart +175 -0
  141. package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pb.dart +1269 -0
  142. package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pbenum.dart +129 -0
  143. package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pb.dart +2782 -0
  144. package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pbenum.dart +97 -0
  145. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pb.dart +2232 -8627
  146. package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pbenum.dart +0 -358
  147. package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pb.dart +1639 -0
  148. package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pbenum.dart +46 -0
  149. package/dart_types/lib/src/runtime_outcome.dart +133 -0
  150. package/dart_types/lib/src/subscriptions.dart +116 -23
  151. package/dart_types/pubspec.yaml +1 -1
  152. package/dart_types/test/extremum_subscriptions_test.dart +40 -0
  153. package/dart_types/test/foreign_ref_resolution_test.dart +75 -0
  154. package/dart_types/test/nomos_ref_address_test.dart +25 -0
  155. package/dart_types/test/ordered_subscriptions_test.dart +34 -0
  156. package/operation_contract_check.mjs +24 -0
  157. package/package.json +11 -6
  158. package/src/aggregate.ts +70 -10
  159. package/src/application_topology.ts +18 -11
  160. package/src/attested.ts +3 -0
  161. package/src/attested_core.ts +46 -3
  162. package/src/birth_meter_ensure.ts +19 -7
  163. package/src/births.ts +29 -4
  164. package/src/build_package.ts +140 -13
  165. package/src/business_birth.ts +181 -4
  166. package/src/codegen_call_proto.ts +1274 -0
  167. package/src/codegen_call_usda.ts +49 -6
  168. package/src/codegen_dart.ts +79 -44
  169. package/src/codegen_dart_client.ts +458 -800
  170. package/src/{codegen_dart_application.ts → codegen_dart_facade.ts} +331 -582
  171. package/src/codegen_dart_framework_calls.ts +320 -37
  172. package/src/codegen_dart_indexed_variant.ts +159 -0
  173. package/src/codegen_dart_scenario.ts +42 -13
  174. package/src/codegen_proof.ts +3 -3
  175. package/src/codegen_provider_dart.ts +5 -0
  176. package/src/codegen_query_proto.ts +158 -0
  177. package/src/codegen_refusal.ts +189 -0
  178. package/src/codegen_result_proto.ts +931 -0
  179. package/src/codegen_result_usda.ts +4 -0
  180. package/src/codegen_ts.ts +464 -616
  181. package/src/codegen_workspace_access.ts +105 -0
  182. package/src/compatibility_graph.ts +759 -0
  183. package/src/compatibility_usda.ts +264 -0
  184. package/src/compile_package_main.ts +1994 -1189
  185. package/src/custody_placement.ts +156 -0
  186. package/src/custody_placement_usda.ts +91 -0
  187. package/src/decl_shapes.ts +21 -2
  188. package/src/describe_model.ts +1 -0
  189. package/src/directive.ts +59 -2
  190. package/src/drivers.ts +51 -0
  191. package/src/engine_entry.ts +52 -8
  192. package/src/evolve_preview.ts +11 -4
  193. package/src/exists.ts +2 -0
  194. package/src/fields.ts +75 -11
  195. package/src/flow_gate.ts +2 -1
  196. package/src/framework/application_home.ts +170 -18
  197. package/src/framework/attested_receipts.ts +8 -3
  198. package/src/framework/auth_provider_law.ts +169 -9
  199. package/src/framework/birth_certificate_law.ts +4 -0
  200. package/src/framework/capability.ts +34 -3
  201. package/src/framework/child_authentication.ts +346 -0
  202. package/src/framework/console_governance.ts +295 -0
  203. package/src/framework/delegated_roles.ts +301 -0
  204. package/src/framework/domain_lifecycle.ts +26 -13
  205. package/src/framework/founding_genesis.ts +193 -0
  206. package/src/framework/framework_aggregates.ts +1 -1
  207. package/src/framework/genesis.ts +6 -1
  208. package/src/framework/governance_relations.ts +19 -0
  209. package/src/framework/home.ts +5 -734
  210. package/src/framework/legacy/child_auth_provider_epoch.ts +73 -0
  211. package/src/framework/model_authority_repair.ts +116 -0
  212. package/src/framework/model_authority_seed.ts +185 -0
  213. package/src/framework/model_transition.ts +211 -0
  214. package/src/framework/owned_custody.ts +1 -1
  215. package/src/framework/principal_enrollment.ts +302 -0
  216. package/src/framework/receiving_group.ts +857 -0
  217. package/src/framework/receiving_group_recovery.ts +314 -0
  218. package/src/framework/relations.ts +4 -8
  219. package/src/framework/signing_identity.ts +242 -95
  220. package/src/framework/source_roster.ts +11 -5
  221. package/src/framework/workspace_access.ts +149 -0
  222. package/src/framework/workspace_invariant.ts +73 -52
  223. package/src/framework/workspaces.ts +407 -40
  224. package/src/framework_call_definitions.ts +32 -3
  225. package/src/generated_client_bundle_boundary.ts +97 -0
  226. package/src/generated_client_names.ts +1 -0
  227. package/src/identity_usda.ts +27 -0
  228. package/src/index.ts +183 -12
  229. package/src/indexed_variant.ts +83 -0
  230. package/src/intent.ts +173 -45
  231. package/src/law_check.ts +8 -5
  232. package/src/law_dependency_index.ts +231 -0
  233. package/src/law_graph.ts +508 -71
  234. package/src/law_graph_usda.ts +170 -24
  235. package/src/law_identity.ts +119 -81
  236. package/src/law_source_map.ts +4 -1
  237. package/src/law_units.ts +498 -0
  238. package/src/law_value_type.ts +7 -3
  239. package/src/member_authentication.ts +302 -0
  240. package/src/null_meta.ts +1 -1
  241. package/src/openusd_compiled_layer.ts +132 -0
  242. package/src/operation_contract_check.ts +31 -0
  243. package/src/ordered_read.ts +2 -1
  244. package/src/package_config.ts +33 -12
  245. package/src/package_dependencies.ts +1 -0
  246. package/src/plan_source_slice.ts +30 -1
  247. package/src/protobuf_field_number.ts +36 -0
  248. package/src/provenance_wire.ts +6 -0
  249. package/src/query.ts +2 -1
  250. package/src/read.ts +50 -0
  251. package/src/relation.ts +4 -1
  252. package/src/relation_schema.ts +15 -2
  253. package/src/report.ts +2 -2
  254. package/src/sqlite_computation_bundle.ts +78 -0
  255. package/src/sqlite_computed.ts +102 -0
  256. package/src/sqlite_counts.ts +154 -0
  257. package/src/sqlite_layout.ts +823 -0
  258. package/src/sqlite_reads.ts +275 -0
  259. package/src/sqlite_samples.ts +185 -0
  260. package/src/stable_id_identity_bridge.ts +1 -1
  261. package/src/stable_ids_for_module.ts +16 -4
  262. package/src/test_call_usda.ts +6 -6
  263. package/src/usda_relationship_integrity.ts +20 -3
  264. package/src/usda_text.ts +21 -1
  265. package/src/value_object.ts +81 -11
  266. package/src/wire.ts +22 -0
  267. package/src/wire_encode.ts +227 -20
  268. package/src/workspace_sharding.ts +15 -6
  269. package/src/workspace_sharing.ts +51 -49
  270. package/src/zod_introspection.ts +2 -0
  271. package/compat_package.mjs +0 -46
  272. package/dart/lib/src/home.dart +0 -15
  273. package/dart/lib/src/runner/offline-install.mjs +0 -15367
  274. package/dart/lib/src/source_trust.dart +0 -51
  275. package/dart/lib/src/webview_bridge.dart +0 -6540
  276. package/dart/lib/src/workspace_name.dart +0 -30
  277. package/dart/test/acquire_session_credentials_test.dart +0 -150
  278. package/dart/test/acquire_session_test.dart +0 -534
  279. package/dart/test/adv_realm_interference_test.dart +0 -600
  280. package/dart/test/cloud_bound_topology_test.dart +0 -168
  281. package/dart/test/cluster_births_test.dart +0 -202
  282. package/dart/test/cluster_device_keyed_acceptance_test.dart +0 -105
  283. package/dart/test/cluster_local_autosync_test.dart +0 -123
  284. package/dart/test/cluster_scale_test.dart +0 -122
  285. package/dart/test/compat_test.dart +0 -61
  286. package/dart/test/dlq_session_surface_test.dart +0 -222
  287. package/dart/test/first_app_gauntlet_test.dart +0 -386
  288. package/dart/test/fixtures/wedge/fake-install.mjs +0 -11
  289. package/dart/test/four_layer_nested_topology_test.dart +0 -290
  290. package/dart/test/home_parity_test.dart +0 -13
  291. package/dart/test/local_sync_inert_test.dart +0 -107
  292. package/dart/test/node_runner_transport_test.dart +0 -78
  293. package/dart/test/parent_signer_recovery_test.dart +0 -155
  294. package/dart/test/residency_refusal_test.dart +0 -49
  295. package/dart/test/sealing_client_test.dart +0 -181
  296. package/dart/test/session_bound_test.dart +0 -285
  297. package/dart/test/stale_bundle_test.dart +0 -80
  298. package/dart/test/vo_read_typing_test.dart +0 -131
  299. package/dart/test/watch_after_offer_stall_test.dart +0 -100
  300. package/dart/test/webview_bridge_test.dart +0 -1930
  301. package/dart/test/workspace_name_test.dart +0 -24
  302. package/runtime/generated-application-host.js +0 -22860
  303. package/src/codegen_query_usda.ts +0 -214
  304. package/src/compat_manifest.ts +0 -26
  305. package/src/compat_package_main.ts +0 -224
  306. package/src/shape_compat.ts +0 -352
  307. package/src/usd_state.ts +0 -505
@@ -0,0 +1,119 @@
1
+ // THE CONNECTED LANE, END TO END, against the node local-development platform
2
+ // shell — the local ADMITTING PEER.
3
+ //
4
+ // `NomosTestCloud` spawns `platform-shells/node/local-development/server.ts`,
5
+ // which mints this universe's trust root, stands `root` up against it, births
6
+ // `proof-platform` under root with a trust-root-signed birth certificate, and
7
+ // installs the compiled co2 application law onto it. `NomosTestHarness
8
+ // .cloudBound` then runs the REAL warranted onboarding: mint a device key in
9
+ // the local kernel, take a device-bound proof from the shell's identity
10
+ // provider, enrol the first device on the platform, birth the owner's receiving
11
+ // group there, and mount it as an ordinary cloud-bound session.
12
+ //
13
+ // Nothing here creates a workspace host-side, and nothing reaches past
14
+ // dispatch: every step is an ordinary typed offer through the platform's own law.
15
+ @TestOn('vm')
16
+ library;
17
+
18
+ import 'dart:io';
19
+
20
+ import 'package:nomos_client/src/nms_conformance_runtime.dart';
21
+ import 'package:test/test.dart';
22
+
23
+ // The compiled application's own pre-bound framework calls. The harness accepts
24
+ // no other transport for a framework directive.
25
+ import '../../../examples/co2-birth/build/application/co2_application/lib/src/generated/application.framework_calls.dart'
26
+ show nomosInternalApplicationFrameworkCalls;
27
+
28
+ String get _repoRoot => Directory.current.parent.parent.path;
29
+ String get _serverEntry =>
30
+ '$_repoRoot/platform-shells/node/local-development/server.ts';
31
+ String get _co2LawUsdz => '$_repoRoot/examples/co2-birth/build/co2.law.usdz';
32
+ String get _governanceCalls =>
33
+ '$_repoRoot/cloud/governance/build/governance.framework.mjs';
34
+ String get _runtimeDir =>
35
+ Platform.environment['NOMOS_CANDIDATE_RUNTIME'] ??
36
+ Platform.environment['NOMOS_DART_RUNTIME'] ??
37
+ Platform.environment['NOMOS_OFFLINE_RUNTIME'] ??
38
+ '${Platform.environment['HOME'] ?? ''}/.holon/runtime';
39
+
40
+ /// The prerequisites this test cannot build for itself.
41
+ String? _missingPrereq() {
42
+ if (!File(_serverEntry).existsSync()) {
43
+ return 'the local development shell is not in this checkout ($_serverEntry)';
44
+ }
45
+ if (!File(_co2LawUsdz).existsSync()) {
46
+ return 'compile the fixture first: cd examples/co2-birth && npx nomos-compile';
47
+ }
48
+ if (!File(_governanceCalls).existsSync()) {
49
+ return 'compile the governance package first: cd cloud/governance && npm run compile';
50
+ }
51
+ for (final artifact in const [
52
+ 'holon.wasm',
53
+ 'kernel.repository.xml',
54
+ 'bootstrap.law.usdz',
55
+ 'nomos.law.usdz',
56
+ ]) {
57
+ if (!File('$_runtimeDir/$artifact').existsSync()) {
58
+ return 'point NOMOS_CANDIDATE_RUNTIME at a complete runtime bundle (missing $artifact)';
59
+ }
60
+ }
61
+ return null;
62
+ }
63
+
64
+ void main() {
65
+ test(
66
+ 'CONNECTED: root births the platform, and a home is born and mounted on it',
67
+ () async {
68
+ final skip = _missingPrereq();
69
+ if (skip != null) {
70
+ markTestSkipped(skip);
71
+ return;
72
+ }
73
+ final diagnostics = <String>[];
74
+ void log(String line) {
75
+ diagnostics.add(line);
76
+ printOnFailure(line);
77
+ }
78
+
79
+ final cloud = await NomosTestCloud.start(
80
+ serverEntry: _serverEntry,
81
+ platform: 'proof-platform',
82
+ lawUsdzPaths: [_co2LawUsdz],
83
+ applicationMaxChildWorkspacesPerUser: 5,
84
+ runtimeDirectory: _runtimeDir,
85
+ mintTrustRoot: true,
86
+ testIdentityProvider: true,
87
+ readyTimeout: const Duration(minutes: 4),
88
+ onDiagnostic: log,
89
+ );
90
+ addTearDown(cloud.stop);
91
+
92
+ // The universe is pinned to a trust root every peer in it must agree on.
93
+ expect(cloud.trustRootPublicKey, isNotNull);
94
+ expect(cloud.testKRootPublic, equals(cloud.trustRootPublicKey));
95
+
96
+ final harness = await NomosTestHarness.cloudBound(
97
+ cloud: cloud,
98
+ lawUsdzPaths: [_co2LawUsdz],
99
+ platformWorkspace: 'proof-platform',
100
+ subject: 'user:proof-owner',
101
+ applicationFrameworkCalls: nomosInternalApplicationFrameworkCalls,
102
+ registerTearDown: addTearDown,
103
+ phaseTimeout: const Duration(minutes: 4),
104
+ onDiagnostic: log,
105
+ );
106
+
107
+ // Phase 6 mounted the born home: it is a real, verified, cloud-bound session.
108
+ final home = harness.homeWorkspace;
109
+ expect(home, isNotNull);
110
+ expect(home, isNot(equals('proof-platform')));
111
+ expect(harness.workspace, equals(home));
112
+
113
+ final remote = await cloud.remoteHead(home!);
114
+ expect(remote.initialized, isTrue);
115
+ expect(remote.head, hasLength(40));
116
+ },
117
+ timeout: const Timeout(Duration(minutes: 10)),
118
+ );
119
+ }
@@ -0,0 +1,52 @@
1
+ import 'dart:convert';
2
+
3
+ import 'package:nomos_client/src/console_enrolment.dart';
4
+ import 'package:test/test.dart';
5
+
6
+ void main() {
7
+ final device = NomosConsoleEnrolmentDevice.fromSeed(List.filled(32, 7));
8
+
9
+ Future<Object?> refusal(int status, Map<String, Object?> body) async {
10
+ try {
11
+ await enrolWithConsole(
12
+ console: 'http://console.test',
13
+ tenant: 'co2-platform',
14
+ scope: 'user',
15
+ providerToken: 'token',
16
+ device: device,
17
+ workspaces: const ['co2-platform'],
18
+ post: (_, __) async =>
19
+ NomosConsoleResponse(status: status, body: jsonEncode(body)),
20
+ );
21
+ } catch (error) {
22
+ return error;
23
+ }
24
+ return null;
25
+ }
26
+
27
+ test('a console refusal carries its stable code and retry verdict', () async {
28
+ final error = await refusal(403, {
29
+ 'error': 'home is not a workspace of tenant co2-platform',
30
+ 'code': 'workspace_not_in_tenant',
31
+ 'retryable': false,
32
+ });
33
+ expect(
34
+ error,
35
+ isA<NomosConsoleEnrolmentRefused>()
36
+ .having((e) => e.status, 'status', 403)
37
+ .having((e) => e.code, 'code', 'workspace_not_in_tenant')
38
+ .having((e) => e.retryable, 'retryable', isFalse)
39
+ .having((e) => e.message, 'message', contains('not a workspace')),
40
+ );
41
+ });
42
+
43
+ test('an older console without a verdict leaves it to the status', () async {
44
+ final error = await refusal(503, {'error': 'busy'});
45
+ expect(
46
+ error,
47
+ isA<NomosConsoleEnrolmentRefused>()
48
+ .having((e) => e.code, 'code', isEmpty)
49
+ .having((e) => e.retryable, 'retryable', isNull),
50
+ );
51
+ });
52
+ }
@@ -0,0 +1,227 @@
1
+ import 'dart:convert';
2
+ import 'dart:io';
3
+ import 'dart:typed_data';
4
+
5
+ import 'package:fixnum/fixnum.dart';
6
+ import 'package:nomos_client/src/console_enrolment.dart';
7
+ import 'package:nomos_client/src/runtime_v2_transport.dart';
8
+ import 'package:nomos_peer_host/nomos_peer_host.dart'
9
+ show NomosDeviceIdentityStore, NomosProviderCredentialStore;
10
+ import 'package:nomos_types/nomos_kernel_protocol.dart' as p;
11
+ import 'package:test/test.dart';
12
+
13
+ /// The golden vector every device-side client reproduces byte for byte
14
+ /// (`peer-office/test/fixtures/console_enrol_request_vector.json`).
15
+ final Map<String,
16
+ Object?> vector = jsonDecode(File.fromUri(Directory.current.uri.resolve(
17
+ '../../peer-office/test/fixtures/console_enrol_request_vector.json'))
18
+ .readAsStringSync()) as Map<String, Object?>;
19
+
20
+ Uint8List _hex(String hex) => Uint8List.fromList([
21
+ for (var i = 0; i < hex.length; i += 2)
22
+ int.parse(hex.substring(i, i + 2), radix: 16),
23
+ ]);
24
+ String _toHex(List<int> bytes) =>
25
+ bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();
26
+
27
+ class _Platform
28
+ with NmsPlatformCredentialProviderHost
29
+ implements NomosRuntimeV2Transport {
30
+ final frames = <p.RuntimeRequest>[];
31
+ final List<p.RuntimeResponse> answers;
32
+ _Platform(this.answers);
33
+ int sequence = 0;
34
+ @override
35
+ int nextRuntimeRequestId() => ++sequence;
36
+ @override
37
+ Future<p.RuntimeResponse> invokeRuntime(p.RuntimeRequest request) async {
38
+ frames.add(request);
39
+ return answers.removeAt(0);
40
+ }
41
+ }
42
+
43
+ class _Store implements NomosDeviceIdentityStore {
44
+ _Store(this.saved);
45
+ final Map<String, Uint8List> saved;
46
+ @override
47
+ Future<Uint8List?> load(String identity) async => saved[identity];
48
+ @override
49
+ Future<void> save(String identity, Uint8List secret) async =>
50
+ saved[identity] = secret;
51
+ }
52
+
53
+ class _Cache implements NomosProviderCredentialStore {
54
+ @override
55
+ Future<List<String>> loadCandidates(String entry) async => ['cached-token'];
56
+ @override
57
+ Future<void> retainCandidate(String entry, String authToken) async {}
58
+ }
59
+
60
+ void main() {
61
+ final seed = _hex(vector['seedHex'] as String);
62
+ final workspaces = (vector['workspaces'] as List).cast<String>();
63
+ final body = vector['body'] as Map<String, Object?>;
64
+
65
+ test(
66
+ 'reproduces the golden enrolment vector byte for byte, signature included',
67
+ () {
68
+ final device = NomosConsoleEnrolmentDevice.fromSeed(seed);
69
+ expect(consoleBase64Url(device.publicKey), vector['devicePublicKey']);
70
+ expect(consoleDeviceKeyHash(device.publicKey), vector['keyHash']);
71
+ final bytes = consoleEnrolRequestBytes(
72
+ tenant: vector['tenant'] as String,
73
+ scope: vector['scope'] as String,
74
+ keyHash: vector['keyHash'] as String,
75
+ workspaces: workspaces,
76
+ providerToken: vector['providerToken'] as String,
77
+ );
78
+ expect(_toHex(bytes), vector['enrolRequestBytesHex']);
79
+ final request = consoleEnrolmentRequest(
80
+ tenant: vector['tenant'] as String,
81
+ scope: vector['scope'] as String,
82
+ providerToken: vector['providerToken'] as String,
83
+ device: device,
84
+ workspaces: workspaces,
85
+ );
86
+ expect(request.path, vector['path']);
87
+ expect(request.body, body);
88
+ // The wire JSON is the TS client's JSON.stringify, key order included.
89
+ expect(jsonEncode(request.body), jsonEncode(body));
90
+ });
91
+
92
+ test(
93
+ 'the shell performs the enrolment effect: fresh token, device signature, typed receipt',
94
+ () async {
95
+ const identity = 'co2-platform|co2:pYn3MMqQ';
96
+ final signIns = <String?>[];
97
+ final posts = <(Uri, Map<String, Object?>)>[];
98
+ var status = 201;
99
+ final platform = _Platform([
100
+ p.RuntimeResponse(
101
+ protocolVersion: 2,
102
+ requestId: Int64(7),
103
+ receivingGroupOpened:
104
+ p.ReceivingGroupOpened(workspace: 'nomos-rg-a')),
105
+ ])
106
+ ..registerDeviceIdentityStore(_Store({identity: seed}))
107
+ ..registerProviderCredentialStore(_Cache())
108
+ ..registerCredentialProvider(
109
+ capability: 'home',
110
+ cloud: 'http://127.0.0.1:8788',
111
+ signIn: ({String? deviceChallenge}) async {
112
+ signIns.add(deviceChallenge);
113
+ return vector['providerToken'] as String;
114
+ },
115
+ )
116
+ ..registerConsolePost((url, text) async {
117
+ final sent = jsonDecode(text) as Map<String, Object?>;
118
+ posts.add((url, sent));
119
+ return NomosConsoleResponse(
120
+ status: status,
121
+ body: status == 201
122
+ ? jsonEncode({
123
+ 'keyHash': vector['keyHash'],
124
+ 'principal': 'co2:pYn3MMqQ',
125
+ 'workspaces': {for (final w in workspaces) w: '$w-head'},
126
+ 'revoked': false,
127
+ })
128
+ : jsonEncode({
129
+ 'error':
130
+ 'this provider token has already been used; sign in again'
131
+ }),
132
+ );
133
+ });
134
+ final effect = p.PeerConsoleEnrolmentEffect(
135
+ effectId: 'open-1:console:enrol-1',
136
+ deviceIdentity: identity,
137
+ capability: 'home',
138
+ console: 'http://127.0.0.1:8797/',
139
+ tenant: vector['tenant'] as String,
140
+ scope: vector['scope'] as String,
141
+ workspaces: workspaces,
142
+ );
143
+
144
+ final receipt = await platform.performConsoleEnrolment(effect);
145
+ expect(receipt.effectId, effect.effectId);
146
+ expect(receipt.hasConsoleEnrolled(), isTrue, reason: '$receipt');
147
+ expect(receipt.consoleEnrolled.principal, 'co2:pYn3MMqQ');
148
+ expect(receipt.consoleEnrolled.keyHash, vector['keyHash']);
149
+ expect(receipt.consoleEnrolled.heads['nomos-rg-a'], 'nomos-rg-a-head');
150
+ expect(signIns, [null],
151
+ reason: 'a plain ID token: never signIn(deviceChallenge: <hash>)');
152
+ expect(posts.single.$1.toString(),
153
+ 'http://127.0.0.1:8797/v1/tenants/co2-platform/providers/co2/enrolments');
154
+ expect(posts.single.$2, body,
155
+ reason: 'the golden request, signature included');
156
+ expect(receipt.writeToBuffer().length, greaterThan(0));
157
+ expect(utf8.decode(receipt.writeToBuffer(), allowMalformed: true),
158
+ isNot(contains(vector['providerToken'])),
159
+ reason: 'the token never returns to the runtime');
160
+
161
+ status = 409;
162
+ final spent = await platform.performConsoleEnrolment(effect);
163
+ expect(spent.hasConsoleEnrolmentRefused(), isTrue);
164
+ expect(spent.consoleEnrolmentRefused.status, 409);
165
+ expect(
166
+ spent.consoleEnrolmentRefused.message, contains('already been used'));
167
+ expect(signIns, [null, null],
168
+ reason: 'every attempt asks the provider afresh, bypassing the cache');
169
+
170
+ // The effect rides the ordinary credential-effect driver.
171
+ final driven = _Platform([
172
+ p.RuntimeResponse(
173
+ protocolVersion: 2,
174
+ requestId: Int64(9),
175
+ receivingGroupOpened:
176
+ p.ReceivingGroupOpened(workspace: 'nomos-rg-a')),
177
+ ])
178
+ ..registerDeviceIdentityStore(_Store({identity: seed}))
179
+ ..registerCredentialProvider(
180
+ capability: 'home',
181
+ cloud: 'x',
182
+ signIn: ({String? deviceChallenge}) async => 'token')
183
+ ..registerConsolePost((url, text) async =>
184
+ const NomosConsoleResponse(status: 403, body: '{"error":"no"}'));
185
+ var calls = 0;
186
+ final result = await driven.driveCredentialEffects(
187
+ p.RuntimeRequest(protocolVersion: 2, requestId: Int64(9)),
188
+ (frame) async {
189
+ calls += 1;
190
+ if (calls == 1) {
191
+ return p.RuntimeResponse(
192
+ protocolVersion: 2,
193
+ requestId: Int64(9),
194
+ correspondencePending: p.CorrespondencePending(
195
+ workId: 'open-1', consoleEnrolment: effect),
196
+ );
197
+ }
198
+ expect(
199
+ frame.continueCorrespondence.receipt.consoleEnrolmentRefused.status,
200
+ 403);
201
+ return p.RuntimeResponse(
202
+ protocolVersion: 2,
203
+ requestId: Int64(9),
204
+ receivingGroupOpened:
205
+ p.ReceivingGroupOpened(workspace: 'nomos-rg-a'));
206
+ },
207
+ );
208
+ expect(result.hasReceivingGroupOpened(), isTrue);
209
+ });
210
+
211
+ test(
212
+ 'a shell without the identity or a provider answers typed, never guesses',
213
+ () async {
214
+ final effect = p.PeerConsoleEnrolmentEffect(
215
+ effectId: 'e', deviceIdentity: 'missing', capability: 'home');
216
+ final bare = _Platform([]);
217
+ expect((await bare.performConsoleEnrolment(effect)).hasFailure(), isTrue);
218
+ final noKey = _Platform([])
219
+ ..registerDeviceIdentityStore(_Store({}))
220
+ ..registerCredentialProvider(
221
+ capability: 'home',
222
+ cloud: 'x',
223
+ signIn: ({String? deviceChallenge}) async => 't');
224
+ final receipt = await noKey.performConsoleEnrolment(effect);
225
+ expect(receipt.failure.message, contains('no usable identity'));
226
+ });
227
+ }
@@ -1,6 +1,6 @@
1
1
  // NOMOS — TYPED ERROR MINTING (§7 structured runtime error DX). `nomosErrorFromInfo` routes a structured
2
2
  // `NomosErrorInfo` to the MOST SPECIFIC typed class by stable code prefix, so an app's `errorBuilder` branches
3
- // on `is` and reads structured fields (not scraped prose). Every typed error still extends `NomosBridgeError`.
3
+ // on `is` and reads structured fields (not scraped prose). Every typed error still extends `NomosRuntimeError`.
4
4
  import 'package:nomos_client/src/nms_generated_runtime.dart';
5
5
  import 'package:test/test.dart';
6
6
 
@@ -52,7 +52,7 @@ void main() {
52
52
  'nomos.law.incompatibleMember': 'mood',
53
53
  },
54
54
  ));
55
- expect(e, isA<NomosBridgeError>()); // still catchable generically
55
+ expect(e, isA<NomosRuntimeError>()); // still catchable generically
56
56
  expect(e, isA<LawMismatchError>());
57
57
  final m = e as LawMismatchError;
58
58
  expect(m.code, 'nomos.law.mismatch');
@@ -127,7 +127,7 @@ void main() {
127
127
  'nomos.authz.directiveId': 'birthEstateWorkspace',
128
128
  },
129
129
  ));
130
- expect(e, isA<NomosBridgeError>());
130
+ expect(e, isA<NomosRuntimeError>());
131
131
  expect(e, isA<AuthzRefusedError>());
132
132
  expect(e, isA<ParentSignerEnrollmentMissing>());
133
133
  final p = e as ParentSignerEnrollmentMissing;
@@ -181,8 +181,8 @@ void main() {
181
181
  () {
182
182
  expect(nomosErrorFromInfo(info('nomos.custody.missing_object')),
183
183
  isA<CustodyError>());
184
- final g = nomosErrorFromInfo(info('nomos.bridge.error'));
185
- expect(g, isA<NomosBridgeError>());
184
+ final g = nomosErrorFromInfo(info('nomos.reception.error'));
185
+ expect(g, isA<NomosRuntimeError>());
186
186
  expect(g, isNot(isA<LawMismatchError>()));
187
187
  });
188
188
  }