@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.
- package/assets/operation-contract.wasm +0 -0
- package/check_package.mjs +12 -15
- package/compile_package.mjs +17 -18
- package/compile_proof.mjs +16 -1
- package/dart/CHANGELOG.md +76 -1
- package/dart/README.md +25 -2
- package/dart/lib/src/admission_decision.dart +41 -0
- package/dart/lib/src/application_framework_calls.dart +52 -2
- package/dart/lib/src/application_model_adoption.dart +187 -0
- package/dart/lib/src/application_status.dart +73 -0
- package/dart/lib/src/console_enrolment.dart +271 -0
- package/dart/lib/src/console_http_io.dart +26 -0
- package/dart/lib/src/console_http_stub.dart +7 -0
- package/dart/lib/src/dev_cloud.dart +69 -22
- package/dart/lib/src/generated_call.dart +83 -23
- package/dart/lib/src/kernel_primitives.dart +119 -0
- package/dart/lib/src/nms_conformance_runtime.dart +1 -1
- package/dart/lib/src/nms_generated_runtime.dart +32 -10
- package/dart/lib/src/nms_test_environment.dart +1 -1
- package/dart/lib/src/node_runner_transport.dart +41 -46
- package/dart/lib/src/observed_session_directory.dart +70 -0
- package/dart/lib/src/operation_receipts.dart +112 -0
- package/dart/lib/src/peer_application_streams.dart +103 -0
- package/dart/lib/src/reception/dart_reception.dart +4280 -0
- package/dart/lib/src/reception/event_desk.dart +211 -0
- package/dart/lib/src/reception/extremum_read.dart +46 -0
- package/dart/lib/src/reception/local_copies.dart +371 -0
- package/dart/lib/src/reception/peer_office_connection.dart +11 -0
- package/dart/lib/src/reception/progress_desk.dart +267 -0
- package/dart/lib/src/reception/reception_contract.dart +11 -0
- package/dart/lib/src/reception/reception_session.dart +284 -0
- package/dart/lib/src/reception/sync_diagnostics.dart +26 -0
- package/dart/lib/src/reception/workspace_preparation_report.dart +126 -0
- package/dart/lib/src/replica_readiness.dart +123 -0
- package/dart/lib/src/runner/node-entry.mjs +23905 -15774
- package/dart/lib/src/runtime_v2_gateway.dart +56 -3
- package/dart/lib/src/runtime_v2_transport.dart +544 -3
- package/dart/lib/src/session_bound.dart +200 -311
- package/dart/lib/src/signing_identity_kernel.dart +84 -0
- package/dart/lib/src/sync_status_projection.dart +548 -0
- package/dart/lib/src/sync_status_reducer.dart +170 -0
- package/dart/lib/src/test_harness.dart +809 -1153
- package/dart/lib/src/testing/test_custody.dart +66 -0
- package/dart/lib/src/testing/test_peer.dart +328 -0
- package/dart/lib/src/typed_watch_registry.dart +169 -0
- package/dart/lib/src/workspace_open_progress.dart +27 -0
- package/dart/pubspec.lock +24 -1
- package/dart/pubspec.yaml +7 -2
- package/dart/pubspec_overrides.yaml +2 -0
- package/dart/test/admission_decision_test.dart +48 -0
- package/dart/test/background_model_adoption_test.dart +228 -0
- package/dart/test/bundle_version_pairing_test.dart +4 -4
- package/dart/test/child_authentication_repair_test.dart +359 -0
- package/dart/test/cloud_bound_local_shell_test.dart +119 -0
- package/dart/test/console_enrolment_refusal_test.dart +52 -0
- package/dart/test/console_enrolment_test.dart +227 -0
- package/dart/test/errors_test.dart +5 -5
- package/dart/test/event_plane_seam_test.dart +50 -164
- package/dart/test/extremum_read_test.dart +58 -0
- package/dart/test/fixtures/wedge/wedge-entry.mjs +3 -21
- package/dart/test/generated_query_test.dart +32 -0
- package/dart/test/harness_phase_timeout_test.dart +18 -23
- package/dart/test/kernel_author_after_read_test.dart +242 -0
- package/dart/test/kernel_fence_test.dart +137 -0
- package/dart/test/local_copies_test.dart +222 -0
- package/dart/test/model_adoption_test.dart +198 -0
- package/dart/test/node_peer_local_custody_test.dart +153 -0
- package/dart/test/offer_authentication_proof_test.dart +352 -52
- package/dart/test/operation_compatibility_test.dart +151 -0
- package/dart/test/platform_credential_effect_test.dart +386 -0
- package/dart/test/receiving_group_open_test.dart +213 -0
- package/dart/test/reception/workspace_preparation_report_test.dart +103 -0
- package/dart/test/reception_span_trace_test.dart +23 -0
- package/dart/test/replica_readiness_test.dart +156 -0
- package/dart/test/runtime_projections_test.dart +92 -0
- package/dart/test/runtime_v2_gateway_test.dart +131 -0
- package/dart/test/signing_identity_kernel_test.dart +75 -0
- package/dart/test/sync_status_preparation_report_test.dart +29 -0
- package/dart/test/sync_status_reducer_test.dart +419 -0
- package/dart/test/test_harness_test.dart +71 -95
- package/dart/test/typed_query_watch_test.dart +170 -0
- package/dart/test/typed_watch_registry_test.dart +249 -0
- package/dart_lints/README.md +18 -0
- package/dart_lints/lib/nomos_lints.dart +70 -0
- package/dart_lints/pubspec.lock +580 -0
- package/dart_lints/pubspec.yaml +12 -0
- package/dart_lints/test/reference_identity_test.dart +75 -0
- package/dart_types/CHANGELOG.md +18 -0
- package/dart_types/lib/nomos_kernel_protocol.dart +21 -1
- package/dart_types/lib/nomos_types.dart +9 -1
- package/dart_types/lib/src/admission_decision.dart +37 -0
- package/dart_types/lib/src/aggregate_meta.dart +1 -1
- package/dart_types/lib/src/approved_model.dart +65 -0
- package/dart_types/lib/src/custody.dart +10 -18
- package/dart_types/lib/src/error_info.dart +4 -4
- package/dart_types/lib/src/errors.dart +29 -29
- package/dart_types/lib/src/foreign_ref.dart +62 -33
- package/dart_types/lib/src/local_work_rejected.dart +3 -3
- package/dart_types/lib/src/nomos_ref.dart +3 -1
- package/dart_types/lib/src/principal.dart +2 -2
- package/dart_types/lib/src/proto/google/protobuf/any.pb.dart +163 -0
- package/dart_types/lib/src/proto/google/protobuf/any.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pb.dart +137 -0
- package/dart_types/lib/src/proto/nomos/discovery/v1/workspace_placement.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pb.dart +20721 -10433
- package/dart_types/lib/src/proto/nomos/kernel/v1/kernel.pbenum.dart +555 -27
- package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pb.dart +387 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/application_desk.pbenum.dart +46 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pb.dart +295 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/application_readiness_desk.pbenum.dart +139 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pb.dart +269 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/authentication_desk.pbenum.dart +103 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pb.dart +417 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/compatibility_desk.pbenum.dart +62 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pb.dart +9968 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/correspondence_desk.pbenum.dart +133 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pb.dart +204 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/credentials_desk.pbenum.dart +54 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pb.dart +1550 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/custody_desk.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pb.dart +710 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/framework.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pb.dart +845 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/identity_desk.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pb.dart +198 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/interaction_desk.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pb.dart +369 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/law_desk.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pb.dart +609 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/maintenance_desk.pbenum.dart +65 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pb.dart +358 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/model_adoption_desk.pbenum.dart +100 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pb.dart +2231 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pbenum.dart +271 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pb.dart +1286 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/placement_desk.pbenum.dart +11 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pb.dart +636 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/receiving_group_desk.pbenum.dart +116 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pb.dart +1637 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/records_desk.pbenum.dart +175 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pb.dart +1269 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/recovery_desk.pbenum.dart +129 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pb.dart +2782 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/residency_desk.pbenum.dart +97 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pb.dart +2232 -8627
- package/dart_types/lib/src/proto/nomos/runtime/v2/runtime.pbenum.dart +0 -358
- package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pb.dart +1639 -0
- package/dart_types/lib/src/proto/nomos/runtime/v2/sealing_desk.pbenum.dart +46 -0
- package/dart_types/lib/src/runtime_outcome.dart +133 -0
- package/dart_types/lib/src/subscriptions.dart +116 -23
- package/dart_types/pubspec.yaml +1 -1
- package/dart_types/test/extremum_subscriptions_test.dart +40 -0
- package/dart_types/test/foreign_ref_resolution_test.dart +75 -0
- package/dart_types/test/nomos_ref_address_test.dart +25 -0
- package/dart_types/test/ordered_subscriptions_test.dart +34 -0
- package/operation_contract_check.mjs +24 -0
- package/package.json +11 -6
- package/src/aggregate.ts +70 -10
- package/src/application_topology.ts +18 -11
- package/src/attested.ts +3 -0
- package/src/attested_core.ts +46 -3
- package/src/birth_meter_ensure.ts +19 -7
- package/src/births.ts +29 -4
- package/src/build_package.ts +140 -13
- package/src/business_birth.ts +181 -4
- package/src/codegen_call_proto.ts +1274 -0
- package/src/codegen_call_usda.ts +49 -6
- package/src/codegen_dart.ts +79 -44
- package/src/codegen_dart_client.ts +458 -800
- package/src/{codegen_dart_application.ts → codegen_dart_facade.ts} +331 -582
- package/src/codegen_dart_framework_calls.ts +320 -37
- package/src/codegen_dart_indexed_variant.ts +159 -0
- package/src/codegen_dart_scenario.ts +42 -13
- package/src/codegen_proof.ts +3 -3
- package/src/codegen_provider_dart.ts +5 -0
- package/src/codegen_query_proto.ts +158 -0
- package/src/codegen_refusal.ts +189 -0
- package/src/codegen_result_proto.ts +931 -0
- package/src/codegen_result_usda.ts +4 -0
- package/src/codegen_ts.ts +464 -616
- package/src/codegen_workspace_access.ts +105 -0
- package/src/compatibility_graph.ts +759 -0
- package/src/compatibility_usda.ts +264 -0
- package/src/compile_package_main.ts +1994 -1189
- package/src/custody_placement.ts +156 -0
- package/src/custody_placement_usda.ts +91 -0
- package/src/decl_shapes.ts +21 -2
- package/src/describe_model.ts +1 -0
- package/src/directive.ts +59 -2
- package/src/drivers.ts +51 -0
- package/src/engine_entry.ts +52 -8
- package/src/evolve_preview.ts +11 -4
- package/src/exists.ts +2 -0
- package/src/fields.ts +75 -11
- package/src/flow_gate.ts +2 -1
- package/src/framework/application_home.ts +170 -18
- package/src/framework/attested_receipts.ts +8 -3
- package/src/framework/auth_provider_law.ts +169 -9
- package/src/framework/birth_certificate_law.ts +4 -0
- package/src/framework/capability.ts +34 -3
- package/src/framework/child_authentication.ts +346 -0
- package/src/framework/console_governance.ts +295 -0
- package/src/framework/delegated_roles.ts +301 -0
- package/src/framework/domain_lifecycle.ts +26 -13
- package/src/framework/founding_genesis.ts +193 -0
- package/src/framework/framework_aggregates.ts +1 -1
- package/src/framework/genesis.ts +6 -1
- package/src/framework/governance_relations.ts +19 -0
- package/src/framework/home.ts +5 -734
- package/src/framework/legacy/child_auth_provider_epoch.ts +73 -0
- package/src/framework/model_authority_repair.ts +116 -0
- package/src/framework/model_authority_seed.ts +185 -0
- package/src/framework/model_transition.ts +211 -0
- package/src/framework/owned_custody.ts +1 -1
- package/src/framework/principal_enrollment.ts +302 -0
- package/src/framework/receiving_group.ts +857 -0
- package/src/framework/receiving_group_recovery.ts +314 -0
- package/src/framework/relations.ts +4 -8
- package/src/framework/signing_identity.ts +242 -95
- package/src/framework/source_roster.ts +11 -5
- package/src/framework/workspace_access.ts +149 -0
- package/src/framework/workspace_invariant.ts +73 -52
- package/src/framework/workspaces.ts +407 -40
- package/src/framework_call_definitions.ts +32 -3
- package/src/generated_client_bundle_boundary.ts +97 -0
- package/src/generated_client_names.ts +1 -0
- package/src/identity_usda.ts +27 -0
- package/src/index.ts +183 -12
- package/src/indexed_variant.ts +83 -0
- package/src/intent.ts +173 -45
- package/src/law_check.ts +8 -5
- package/src/law_dependency_index.ts +231 -0
- package/src/law_graph.ts +508 -71
- package/src/law_graph_usda.ts +170 -24
- package/src/law_identity.ts +119 -81
- package/src/law_source_map.ts +4 -1
- package/src/law_units.ts +498 -0
- package/src/law_value_type.ts +7 -3
- package/src/member_authentication.ts +302 -0
- package/src/null_meta.ts +1 -1
- package/src/openusd_compiled_layer.ts +132 -0
- package/src/operation_contract_check.ts +31 -0
- package/src/ordered_read.ts +2 -1
- package/src/package_config.ts +33 -12
- package/src/package_dependencies.ts +1 -0
- package/src/plan_source_slice.ts +30 -1
- package/src/protobuf_field_number.ts +36 -0
- package/src/provenance_wire.ts +6 -0
- package/src/query.ts +2 -1
- package/src/read.ts +50 -0
- package/src/relation.ts +4 -1
- package/src/relation_schema.ts +15 -2
- package/src/report.ts +2 -2
- package/src/sqlite_computation_bundle.ts +78 -0
- package/src/sqlite_computed.ts +102 -0
- package/src/sqlite_counts.ts +154 -0
- package/src/sqlite_layout.ts +823 -0
- package/src/sqlite_reads.ts +275 -0
- package/src/sqlite_samples.ts +185 -0
- package/src/stable_id_identity_bridge.ts +1 -1
- package/src/stable_ids_for_module.ts +16 -4
- package/src/test_call_usda.ts +6 -6
- package/src/usda_relationship_integrity.ts +20 -3
- package/src/usda_text.ts +21 -1
- package/src/value_object.ts +81 -11
- package/src/wire.ts +22 -0
- package/src/wire_encode.ts +227 -20
- package/src/workspace_sharding.ts +15 -6
- package/src/workspace_sharing.ts +51 -49
- package/src/zod_introspection.ts +2 -0
- package/compat_package.mjs +0 -46
- package/dart/lib/src/home.dart +0 -15
- package/dart/lib/src/runner/offline-install.mjs +0 -15367
- package/dart/lib/src/source_trust.dart +0 -51
- package/dart/lib/src/webview_bridge.dart +0 -6540
- package/dart/lib/src/workspace_name.dart +0 -30
- package/dart/test/acquire_session_credentials_test.dart +0 -150
- package/dart/test/acquire_session_test.dart +0 -534
- package/dart/test/adv_realm_interference_test.dart +0 -600
- package/dart/test/cloud_bound_topology_test.dart +0 -168
- package/dart/test/cluster_births_test.dart +0 -202
- package/dart/test/cluster_device_keyed_acceptance_test.dart +0 -105
- package/dart/test/cluster_local_autosync_test.dart +0 -123
- package/dart/test/cluster_scale_test.dart +0 -122
- package/dart/test/compat_test.dart +0 -61
- package/dart/test/dlq_session_surface_test.dart +0 -222
- package/dart/test/first_app_gauntlet_test.dart +0 -386
- package/dart/test/fixtures/wedge/fake-install.mjs +0 -11
- package/dart/test/four_layer_nested_topology_test.dart +0 -290
- package/dart/test/home_parity_test.dart +0 -13
- package/dart/test/local_sync_inert_test.dart +0 -107
- package/dart/test/node_runner_transport_test.dart +0 -78
- package/dart/test/parent_signer_recovery_test.dart +0 -155
- package/dart/test/residency_refusal_test.dart +0 -49
- package/dart/test/sealing_client_test.dart +0 -181
- package/dart/test/session_bound_test.dart +0 -285
- package/dart/test/stale_bundle_test.dart +0 -80
- package/dart/test/vo_read_typing_test.dart +0 -131
- package/dart/test/watch_after_offer_stall_test.dart +0 -100
- package/dart/test/webview_bridge_test.dart +0 -1930
- package/dart/test/workspace_name_test.dart +0 -24
- package/runtime/generated-application-host.js +0 -22860
- package/src/codegen_query_usda.ts +0 -214
- package/src/compat_manifest.ts +0 -26
- package/src/compat_package_main.ts +0 -224
- package/src/shape_compat.ts +0 -352
- package/src/usd_state.ts +0 -505
|
@@ -1,534 +0,0 @@
|
|
|
1
|
-
// acquireSession — the ATOMIC session-open (co2 DX ask): reuses a mounted session, opens a plane-resident
|
|
2
|
-
// (parked / resident-custody) workspace locally, JOINS an in-flight open (single-flight per workspace), and
|
|
3
|
-
// invokes the credentials callback ONLY when a cloud open is genuinely required. Proven hermetically over a
|
|
4
|
-
// fake transport (the same style as webview_bridge_test.dart) — the live-runner leg rides
|
|
5
|
-
// cluster_local_autosync_test.dart.
|
|
6
|
-
import 'dart:async';
|
|
7
|
-
|
|
8
|
-
import 'package:nomos_client/src/nms_generated_runtime.dart';
|
|
9
|
-
import 'package:nomos_types/nomos_kernel_protocol.dart' as protocol;
|
|
10
|
-
import 'package:test/test.dart';
|
|
11
|
-
|
|
12
|
-
/// A fake runner: answers connect (after a real async gap, so concurrency is observable) and
|
|
13
|
-
/// listWorkspaces (from [resident]); records every request.
|
|
14
|
-
class FakeRunner implements BridgeTransport {
|
|
15
|
-
final _incoming = StreamController<Map<String, Object?>>.broadcast();
|
|
16
|
-
final List<Map<String, Object?>> sent = [];
|
|
17
|
-
final List<protocol.RuntimeRequest> runtimeRequests = [];
|
|
18
|
-
final List<String>
|
|
19
|
-
resident; // workspaces the plane already holds (realm.list())
|
|
20
|
-
|
|
21
|
-
FakeRunner({this.resident = const []}) {
|
|
22
|
-
scheduleMicrotask(() => _incoming.add({
|
|
23
|
-
'v': kWebviewBridgeVersion,
|
|
24
|
-
'event': 'ready',
|
|
25
|
-
'bundleVersion': 'unbundled-dev'
|
|
26
|
-
}));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
int get connectCount => sent.where((m) => m['op'] == 'connect').length;
|
|
30
|
-
int autoSyncCount(String workspace) => runtimeRequests
|
|
31
|
-
.where((request) =>
|
|
32
|
-
request.whichCommand() ==
|
|
33
|
-
protocol.RuntimeRequest_Command.startAutoSync &&
|
|
34
|
-
request.startAutoSync.session == workspace)
|
|
35
|
-
.length;
|
|
36
|
-
Map<String, Object?> connectArgs(int i) =>
|
|
37
|
-
(sent.where((m) => m['op'] == 'connect').elementAt(i)['args'] as Map)
|
|
38
|
-
.cast<String, Object?>();
|
|
39
|
-
|
|
40
|
-
@override
|
|
41
|
-
Stream<Map<String, Object?>> get messages => _incoming.stream;
|
|
42
|
-
|
|
43
|
-
@override
|
|
44
|
-
Future<protocol.RuntimeResponse> invokeRuntime(
|
|
45
|
-
protocol.RuntimeRequest request,
|
|
46
|
-
) async {
|
|
47
|
-
runtimeRequests.add(request.deepCopy());
|
|
48
|
-
final response = protocol.RuntimeResponse(
|
|
49
|
-
protocolVersion: 2,
|
|
50
|
-
requestId: request.requestId,
|
|
51
|
-
);
|
|
52
|
-
switch (request.whichCommand()) {
|
|
53
|
-
case protocol.RuntimeRequest_Command.listWorkspaces:
|
|
54
|
-
final connected = sent
|
|
55
|
-
.where((message) => message['op'] == 'connect')
|
|
56
|
-
.map(
|
|
57
|
-
(message) => ((message['args'] as Map)['workspace']).toString())
|
|
58
|
-
.toSet();
|
|
59
|
-
response.workspaceList = protocol.WorkspaceList(
|
|
60
|
-
workspaces: [
|
|
61
|
-
for (final workspace in {...resident, ...connected})
|
|
62
|
-
protocol.WorkspaceSummary(
|
|
63
|
-
session: workspace,
|
|
64
|
-
workspace: workspace,
|
|
65
|
-
residency: connected.contains(workspace)
|
|
66
|
-
? protocol.WorkspaceResidency.WORKSPACE_RESIDENCY_MOUNTED
|
|
67
|
-
: protocol.WorkspaceResidency.WORKSPACE_RESIDENCY_PARKED,
|
|
68
|
-
syncPosture: protocol
|
|
69
|
-
.WorkspaceSyncPosture.WORKSPACE_SYNC_POSTURE_LOCAL_ONLY,
|
|
70
|
-
),
|
|
71
|
-
],
|
|
72
|
-
);
|
|
73
|
-
break;
|
|
74
|
-
case protocol.RuntimeRequest_Command.startAutoSync:
|
|
75
|
-
response.autoSyncStarted =
|
|
76
|
-
protocol.AutoSyncStarted(session: request.startAutoSync.session);
|
|
77
|
-
break;
|
|
78
|
-
case protocol.RuntimeRequest_Command.stopAutoSync:
|
|
79
|
-
response.autoSyncStopped =
|
|
80
|
-
protocol.AutoSyncStopped(session: request.stopAutoSync.session);
|
|
81
|
-
break;
|
|
82
|
-
case protocol.RuntimeRequest_Command.closeRealm:
|
|
83
|
-
response.realmClosed = protocol.RealmClosed();
|
|
84
|
-
break;
|
|
85
|
-
default:
|
|
86
|
-
throw StateError(
|
|
87
|
-
'FakeRunner does not implement ${request.whichCommand().name}',
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
return response;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
@override
|
|
94
|
-
void send(Map<String, Object?> message) {
|
|
95
|
-
sent.add(message);
|
|
96
|
-
final id = message['id'] as int;
|
|
97
|
-
final op = message['op'] as String;
|
|
98
|
-
final args = (message['args'] as Map).cast<String, Object?>();
|
|
99
|
-
Future<void>.delayed(const Duration(milliseconds: 5), () {
|
|
100
|
-
Object? result;
|
|
101
|
-
switch (op) {
|
|
102
|
-
case 'connect':
|
|
103
|
-
result = {'workspace': args['workspace']};
|
|
104
|
-
break;
|
|
105
|
-
case 'listWorkspaces':
|
|
106
|
-
// Realm truth: a CONNECTED workspace is mounted (holon live); a resident-but-unconnected one is
|
|
107
|
-
// parked custody. Reflect connects so the derived lifecycle `state` is observable in both postures.
|
|
108
|
-
final connected = sent
|
|
109
|
-
.where((m) => m['op'] == 'connect')
|
|
110
|
-
.map((m) => ((m['args'] as Map)['workspace']).toString())
|
|
111
|
-
.toSet();
|
|
112
|
-
final all = {...resident, ...connected};
|
|
113
|
-
result = {
|
|
114
|
-
'workspaces': [
|
|
115
|
-
for (final ws in all)
|
|
116
|
-
{
|
|
117
|
-
'session': ws,
|
|
118
|
-
'workspace': ws,
|
|
119
|
-
'mounted': connected.contains(ws),
|
|
120
|
-
'parked': !connected.contains(ws) && resident.contains(ws),
|
|
121
|
-
'syncPosture': 'local-only'
|
|
122
|
-
}
|
|
123
|
-
]
|
|
124
|
-
};
|
|
125
|
-
break;
|
|
126
|
-
case 'snapshotWorkspace':
|
|
127
|
-
result = {
|
|
128
|
-
'workspace': args['workspace'],
|
|
129
|
-
'head': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
|
130
|
-
if (args['ifHead'] == 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
|
|
131
|
-
'unchanged': true
|
|
132
|
-
else
|
|
133
|
-
'snapshot': 'resident-snapshot-b64',
|
|
134
|
-
};
|
|
135
|
-
break;
|
|
136
|
-
default:
|
|
137
|
-
result = {};
|
|
138
|
-
}
|
|
139
|
-
_incoming.add(
|
|
140
|
-
{'v': kWebviewBridgeVersion, 'id': id, 'ok': true, 'result': result});
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
void main() {
|
|
146
|
-
test(
|
|
147
|
-
'an already-connected session is reused — credentials NEVER invoked, no second connect',
|
|
148
|
-
() async {
|
|
149
|
-
final runner = FakeRunner();
|
|
150
|
-
final bridge = NomosBridge(runner);
|
|
151
|
-
await bridge.ready;
|
|
152
|
-
await bridge.connect(workspace: 'home', session: 'home');
|
|
153
|
-
expect(runner.connectCount, 1);
|
|
154
|
-
|
|
155
|
-
final s = await bridge.acquireSession('home',
|
|
156
|
-
ifAbsentCredentials: () async =>
|
|
157
|
-
fail('credentials must not be requested for a mounted session'));
|
|
158
|
-
expect(identical(s, bridge.session('home')), isTrue);
|
|
159
|
-
expect(runner.connectCount, 1, reason: 'no re-connect for a live session');
|
|
160
|
-
expect(runner.autoSyncCount('home'), 1,
|
|
161
|
-
reason: 'an acquired application workspace continuously syncs');
|
|
162
|
-
await bridge.dispose();
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
test(
|
|
166
|
-
'a plane-resident workspace binds retained cloud credentials so background sync owns it',
|
|
167
|
-
() async {
|
|
168
|
-
final runner = FakeRunner(resident: ['estate']);
|
|
169
|
-
final bridge = NomosBridge(runner);
|
|
170
|
-
await bridge.ready;
|
|
171
|
-
|
|
172
|
-
var asked = false;
|
|
173
|
-
final s =
|
|
174
|
-
await bridge.acquireSession('estate', ifAbsentCredentials: () async {
|
|
175
|
-
asked = true;
|
|
176
|
-
return const NomosSessionCredentials(cloud: 'https://never.invalid');
|
|
177
|
-
});
|
|
178
|
-
expect(asked, isTrue,
|
|
179
|
-
reason:
|
|
180
|
-
'a generated resident child must acquire its continuous cloud posture');
|
|
181
|
-
expect(s.workspace, 'estate');
|
|
182
|
-
expect(runner.connectCount, 1);
|
|
183
|
-
expect(runner.connectArgs(0)['cloud'], 'https://never.invalid');
|
|
184
|
-
await bridge.dispose();
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
test(
|
|
188
|
-
'concurrent acquisition SINGLE-FLIGHTS: one open, one credentials call, the same session',
|
|
189
|
-
() async {
|
|
190
|
-
final runner = FakeRunner();
|
|
191
|
-
final bridge = NomosBridge(runner);
|
|
192
|
-
await bridge.ready;
|
|
193
|
-
|
|
194
|
-
var credentialCalls = 0;
|
|
195
|
-
Future<NomosSessionCredentials> creds() async {
|
|
196
|
-
credentialCalls++;
|
|
197
|
-
await Future<void>.delayed(const Duration(milliseconds: 10));
|
|
198
|
-
return const NomosSessionCredentials(
|
|
199
|
-
cloud: 'https://cloud.example', authToken: 'tok', allowUnborn: true);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
final results = await Future.wait([
|
|
203
|
-
bridge.acquireSession('cloudy', ifAbsentCredentials: creds),
|
|
204
|
-
bridge.acquireSession('cloudy', ifAbsentCredentials: creds),
|
|
205
|
-
bridge.acquireSession('cloudy', ifAbsentCredentials: creds),
|
|
206
|
-
]);
|
|
207
|
-
expect(credentialCalls, 1,
|
|
208
|
-
reason: 'the credentials callback fires exactly once');
|
|
209
|
-
expect(runner.connectCount, 1,
|
|
210
|
-
reason: 'ONE connect for three concurrent acquires');
|
|
211
|
-
expect(identical(results[0], results[1]), isTrue);
|
|
212
|
-
expect(identical(results[1], results[2]), isTrue);
|
|
213
|
-
expect(runner.autoSyncCount('cloudy'), 1,
|
|
214
|
-
reason: 'the workspace lifecycle is single-flight too');
|
|
215
|
-
final args = runner.connectArgs(0);
|
|
216
|
-
expect(args['cloud'], 'https://cloud.example');
|
|
217
|
-
expect(args['authToken'], 'tok');
|
|
218
|
-
expect(args['allowUnborn'], isTrue);
|
|
219
|
-
await bridge.dispose();
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
test(
|
|
223
|
-
'genuinely absent + no credentials callback → a named StateError (never a silent cloudless mount)',
|
|
224
|
-
() async {
|
|
225
|
-
final runner = FakeRunner();
|
|
226
|
-
final bridge = NomosBridge(runner);
|
|
227
|
-
await bridge.ready;
|
|
228
|
-
await expectLater(bridge.acquireSession('nowhere'), throwsStateError);
|
|
229
|
-
expect(runner.connectCount, 0);
|
|
230
|
-
await bridge.dispose();
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
test(
|
|
234
|
-
'an absent generated child restores opaque local custody before cloud convergence',
|
|
235
|
-
() async {
|
|
236
|
-
final runner = FakeRunner();
|
|
237
|
-
final bridge = NomosBridge(runner);
|
|
238
|
-
await bridge.ready;
|
|
239
|
-
var loads = 0;
|
|
240
|
-
bridge.nomosInternalRetainLocalCustodyLoader((workspace) async {
|
|
241
|
-
loads++;
|
|
242
|
-
expect(workspace, 'catalogue');
|
|
243
|
-
return 'opaque-kernel-snapshot';
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
final child = await bridge.acquireSession(
|
|
247
|
-
'catalogue',
|
|
248
|
-
ifAbsentCredentials: () async => const NomosSessionCredentials(
|
|
249
|
-
cloud: 'https://cloud.example',
|
|
250
|
-
authToken: 'token',
|
|
251
|
-
),
|
|
252
|
-
);
|
|
253
|
-
|
|
254
|
-
expect(child.workspace, 'catalogue');
|
|
255
|
-
expect(loads, 1);
|
|
256
|
-
expect(runner.connectCount, 1);
|
|
257
|
-
expect(runner.connectArgs(0)['restoreFrom'], 'opaque-kernel-snapshot');
|
|
258
|
-
expect(runner.connectArgs(0)['cloud'], 'https://cloud.example');
|
|
259
|
-
await bridge.dispose();
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
test('opaque local custody can open without inventing cloud authority',
|
|
263
|
-
() async {
|
|
264
|
-
final runner = FakeRunner();
|
|
265
|
-
final bridge = NomosBridge(runner);
|
|
266
|
-
await bridge.ready;
|
|
267
|
-
bridge.nomosInternalRetainLocalCustodyLoader(
|
|
268
|
-
(_) async => 'opaque-kernel-snapshot',
|
|
269
|
-
);
|
|
270
|
-
|
|
271
|
-
final child = await bridge.acquireSession('offline-child');
|
|
272
|
-
|
|
273
|
-
expect(child.workspace, 'offline-child');
|
|
274
|
-
expect(runner.connectCount, 1);
|
|
275
|
-
final args = runner.connectArgs(0);
|
|
276
|
-
expect(args['restoreFrom'], 'opaque-kernel-snapshot');
|
|
277
|
-
expect(args.containsKey('cloud'), isFalse);
|
|
278
|
-
await bridge.dispose();
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
test(
|
|
282
|
-
'a NomosSession delegates acquireSession to the parent plane (one registry)',
|
|
283
|
-
() async {
|
|
284
|
-
final runner = FakeRunner();
|
|
285
|
-
final bridge = NomosBridge(runner);
|
|
286
|
-
await bridge.ready;
|
|
287
|
-
await bridge.connect(workspace: 'home', session: 'home');
|
|
288
|
-
await bridge.connect(workspace: 'estate', session: 'estate');
|
|
289
|
-
|
|
290
|
-
final viaSession = await bridge.session('home').acquireSession('estate',
|
|
291
|
-
ifAbsentCredentials: () async =>
|
|
292
|
-
fail('estate is already mounted — no credentials'));
|
|
293
|
-
expect(identical(viaSession, bridge.session('estate')), isTrue);
|
|
294
|
-
await bridge.dispose();
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
test('a resident child inherits its opening session identity', () async {
|
|
298
|
-
final runner = FakeRunner(resident: ['child']);
|
|
299
|
-
final bridge = NomosBridge(runner);
|
|
300
|
-
await bridge.ready;
|
|
301
|
-
await bridge.connect(
|
|
302
|
-
workspace: 'home',
|
|
303
|
-
session: 'home',
|
|
304
|
-
authToken: 'header.eyJzdWIiOiJhZGEifQ.signature',
|
|
305
|
-
);
|
|
306
|
-
|
|
307
|
-
final child = await bridge.session('home').acquireSession('child');
|
|
308
|
-
|
|
309
|
-
expect(child.principal, 'user:ada');
|
|
310
|
-
await bridge.dispose();
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
test('an in-place signing-key refresh is inherited by later sibling opens',
|
|
314
|
-
() async {
|
|
315
|
-
final runner = FakeRunner(resident: ['catalogue', 'estate']);
|
|
316
|
-
final bridge = NomosBridge(runner);
|
|
317
|
-
await bridge.ready;
|
|
318
|
-
await bridge.connect(workspace: 'home', session: 'home');
|
|
319
|
-
|
|
320
|
-
await bridge
|
|
321
|
-
.session('home')
|
|
322
|
-
.refreshCredentials(authorSecret: 'newly-enrolled-device-key');
|
|
323
|
-
await bridge.session('home').acquireSession('catalogue');
|
|
324
|
-
|
|
325
|
-
expect(runner.connectCount, 2);
|
|
326
|
-
expect(runner.connectArgs(1)['authorSecret'], 'newly-enrolled-device-key',
|
|
327
|
-
reason:
|
|
328
|
-
'refreshing the resident holon must also advance the plane credential inherited by siblings');
|
|
329
|
-
|
|
330
|
-
await bridge.session('home').refreshCredentials(authorSecret: '');
|
|
331
|
-
await bridge.session('home').acquireSession('estate');
|
|
332
|
-
expect(runner.connectArgs(2).containsKey('authorSecret'), isFalse,
|
|
333
|
-
reason:
|
|
334
|
-
'clearing a resident signing key must not leak it into later sibling opens');
|
|
335
|
-
await bridge.dispose();
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
test(
|
|
339
|
-
'generated child inherits typed model decisions and stages opaque USDZ privately',
|
|
340
|
-
() async {
|
|
341
|
-
final runner = FakeRunner(resident: ['child']);
|
|
342
|
-
final bridge = NomosBridge(runner);
|
|
343
|
-
await bridge.ready;
|
|
344
|
-
await bridge.connect(
|
|
345
|
-
workspace: 'home',
|
|
346
|
-
session: 'home',
|
|
347
|
-
authToken: 'header.eyJzdWIiOiJhZGEifQ.signature',
|
|
348
|
-
);
|
|
349
|
-
var handled = false;
|
|
350
|
-
final home = bridge.session('home');
|
|
351
|
-
home.nomosInternalRetainModelChangeHandler((change) async {
|
|
352
|
-
handled = change.expectedDomainHash == 'candidate';
|
|
353
|
-
});
|
|
354
|
-
final child = await home.acquireSession('child');
|
|
355
|
-
await home.nomosInternalEnsureGeneratedModelInChild(
|
|
356
|
-
childWorkspace: 'child',
|
|
357
|
-
domain: 'catalogue',
|
|
358
|
-
candidateHash: 'candidate',
|
|
359
|
-
lawUsdz: const [1, 2, 3],
|
|
360
|
-
);
|
|
361
|
-
await child.nomosInternalHandleModelChange(
|
|
362
|
-
const DomainClientModelAdoptionRequired(
|
|
363
|
-
expectedDomainKey: 'catalogue',
|
|
364
|
-
expectedDomainHash: 'candidate',
|
|
365
|
-
status: 'needs-decision',
|
|
366
|
-
summary: 'review',
|
|
367
|
-
review: DomainModelReview(
|
|
368
|
-
checkedActions: 1,
|
|
369
|
-
candidateActions: 1,
|
|
370
|
-
sameOutcome: true,
|
|
371
|
-
differences: [],
|
|
372
|
-
),
|
|
373
|
-
),
|
|
374
|
-
);
|
|
375
|
-
expect(handled, isTrue);
|
|
376
|
-
final stage = runner.sent.singleWhere(
|
|
377
|
-
(message) => message['op'] == 'stageGeneratedModelFromParent',
|
|
378
|
-
);
|
|
379
|
-
expect((stage['args'] as Map)['sourceSession'], 'home');
|
|
380
|
-
expect((stage['args'] as Map)['session'], 'child');
|
|
381
|
-
expect((stage['args'] as Map)['lawUsdz'], 'AQID');
|
|
382
|
-
await home.nomosInternalStageGeneratedModel(
|
|
383
|
-
domain: 'catalogue',
|
|
384
|
-
candidateHash: 'candidate',
|
|
385
|
-
lawUsdz: const [4, 5, 6],
|
|
386
|
-
);
|
|
387
|
-
final rootStage = runner.sent.singleWhere(
|
|
388
|
-
(message) => message['op'] == 'stageGeneratedModel',
|
|
389
|
-
);
|
|
390
|
-
expect((rootStage['args'] as Map)['session'], 'home');
|
|
391
|
-
expect((rootStage['args'] as Map)['lawUsdz'], 'BAUG');
|
|
392
|
-
await bridge.dispose();
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
test(
|
|
396
|
-
'a generated application session privately refreshes cloud access for an absent referenced workspace',
|
|
397
|
-
() async {
|
|
398
|
-
final runner = FakeRunner();
|
|
399
|
-
final bridge = NomosBridge(runner);
|
|
400
|
-
await bridge.ready;
|
|
401
|
-
await bridge.connect(
|
|
402
|
-
cloud: 'https://cloud.example',
|
|
403
|
-
workspace: 'home',
|
|
404
|
-
session: 'home',
|
|
405
|
-
authToken: 'header.eyJzdWIiOiJhZGEifQ.signature',
|
|
406
|
-
authorSecret: 'device-secret',
|
|
407
|
-
);
|
|
408
|
-
var refreshes = 0;
|
|
409
|
-
bridge.session('home').nomosInternalRetainCloudAccess(
|
|
410
|
-
cloud: 'https://cloud.example',
|
|
411
|
-
signIn: () async {
|
|
412
|
-
refreshes += 1;
|
|
413
|
-
return 'fresh-token-$refreshes';
|
|
414
|
-
},
|
|
415
|
-
);
|
|
416
|
-
|
|
417
|
-
final target = await bridge.session('home').acquireSession('shared-home');
|
|
418
|
-
expect(target.workspace, 'shared-home');
|
|
419
|
-
expect(refreshes, 1);
|
|
420
|
-
expect(runner.connectArgs(1)['cloud'], 'https://cloud.example');
|
|
421
|
-
expect(runner.connectArgs(1)['authToken'], 'fresh-token-1');
|
|
422
|
-
expect(runner.connectArgs(1)['authorSecret'], 'device-secret');
|
|
423
|
-
expect(target.principal, 'user:ada');
|
|
424
|
-
|
|
425
|
-
// The retained posture follows the opened handle, so navigation can continue without a public lane.
|
|
426
|
-
final child = await target.acquireSession('shared-child');
|
|
427
|
-
expect(child.workspace, 'shared-child');
|
|
428
|
-
expect(refreshes, 2);
|
|
429
|
-
expect(runner.connectArgs(2)['authToken'], 'fresh-token-2');
|
|
430
|
-
await bridge.dispose();
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
// ── SESSION-STATE DX cluster (co2): explicit lifecycle state + fail-at-bind + openable refs ──
|
|
434
|
-
|
|
435
|
-
test(
|
|
436
|
-
'listWorkspaces() reports explicit state: resident/parked before open, connected after',
|
|
437
|
-
() async {
|
|
438
|
-
final runner = FakeRunner(
|
|
439
|
-
resident: ['estate']); // realm returns mounted:false, parked:true
|
|
440
|
-
final bridge = NomosBridge(runner);
|
|
441
|
-
await bridge.ready;
|
|
442
|
-
|
|
443
|
-
// Before any connect: the plane-resident (parked) workspace surfaces with an explicit non-connected state.
|
|
444
|
-
var list = await bridge.listWorkspaces();
|
|
445
|
-
final before =
|
|
446
|
-
list.firstWhere((workspace) => workspace.workspace == 'estate');
|
|
447
|
-
expect(before.residency,
|
|
448
|
-
protocol.WorkspaceResidency.WORKSPACE_RESIDENCY_PARKED,
|
|
449
|
-
reason:
|
|
450
|
-
'parked custody is not connected — the app must acquire it first');
|
|
451
|
-
|
|
452
|
-
// After connecting it, the SAME workspace reports connected.
|
|
453
|
-
await bridge.connect(workspace: 'estate', session: 'estate');
|
|
454
|
-
list = await bridge.listWorkspaces();
|
|
455
|
-
final after =
|
|
456
|
-
list.firstWhere((workspace) => workspace.workspace == 'estate');
|
|
457
|
-
expect(after.residency,
|
|
458
|
-
protocol.WorkspaceResidency.WORKSPACE_RESIDENCY_MOUNTED);
|
|
459
|
-
await bridge.dispose();
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
test(
|
|
463
|
-
'plane snapshot exports resident custody without manufacturing a Dart session',
|
|
464
|
-
() async {
|
|
465
|
-
final runner = FakeRunner(resident: ['born-child']);
|
|
466
|
-
final bridge = NomosBridge(runner);
|
|
467
|
-
await bridge.ready;
|
|
468
|
-
|
|
469
|
-
final saved = await bridge.nomosInternalSnapshotWorkspace('born-child');
|
|
470
|
-
expect(saved.workspace, 'born-child');
|
|
471
|
-
expect(saved.head, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
|
|
472
|
-
expect(saved.snapshot, 'resident-snapshot-b64');
|
|
473
|
-
expect(saved.unchanged, isFalse);
|
|
474
|
-
expect(runner.connectCount, 0,
|
|
475
|
-
reason:
|
|
476
|
-
'save-all must not acquire an unopened child or invent host authority');
|
|
477
|
-
|
|
478
|
-
final unchanged = await bridge.nomosInternalSnapshotWorkspace('born-child',
|
|
479
|
-
ifHead: saved.head);
|
|
480
|
-
expect(unchanged.unchanged, isTrue);
|
|
481
|
-
expect(unchanged.snapshot, isNull);
|
|
482
|
-
expect(runner.connectCount, 0);
|
|
483
|
-
await bridge.dispose();
|
|
484
|
-
});
|
|
485
|
-
|
|
486
|
-
test(
|
|
487
|
-
'NomosSession.isConnected + assertConnected: fail at BIND, not on first query',
|
|
488
|
-
() async {
|
|
489
|
-
final runner = FakeRunner();
|
|
490
|
-
final bridge = NomosBridge(runner);
|
|
491
|
-
await bridge.ready;
|
|
492
|
-
|
|
493
|
-
// A held-but-unopened handle is valid to construct but not connected — assertConnected throws NOW.
|
|
494
|
-
final lazy = bridge.session('estate');
|
|
495
|
-
expect(lazy.isConnected, isFalse);
|
|
496
|
-
expect(lazy.assertConnected, throwsStateError);
|
|
497
|
-
|
|
498
|
-
await bridge.connect(workspace: 'estate', session: 'estate');
|
|
499
|
-
final live = bridge.session('estate');
|
|
500
|
-
expect(live.isConnected, isTrue);
|
|
501
|
-
expect(live.assertConnected, returnsNormally);
|
|
502
|
-
await bridge.dispose();
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
test(
|
|
506
|
-
'NomosRef.acquire(bridge) opens a born/resident ref directly → a live session',
|
|
507
|
-
() async {
|
|
508
|
-
final runner = FakeRunner(resident: ['estate-42']);
|
|
509
|
-
final bridge = NomosBridge(runner);
|
|
510
|
-
await bridge.ready;
|
|
511
|
-
|
|
512
|
-
// The shape a `.births()` outcome yields: outcome.bornRefs.single is a NomosRef on the born workspace.
|
|
513
|
-
final ref = NmsInternalNomosRefs.create<Object?>(
|
|
514
|
-
workspace: 'estate-42', type: 'nomos.Workspace', id: 'estate-42');
|
|
515
|
-
final session =
|
|
516
|
-
await ref.acquire(bridge); // no credentials — resident opens local-only
|
|
517
|
-
expect(session.workspace, 'estate-42');
|
|
518
|
-
expect(session.isConnected, isTrue);
|
|
519
|
-
expect(identical(session, bridge.session('estate-42')), isTrue);
|
|
520
|
-
await bridge.dispose();
|
|
521
|
-
});
|
|
522
|
-
|
|
523
|
-
test(
|
|
524
|
-
'NomosRef.acquire refuses a workspace-less ref (a bad locator fails HERE, not later)',
|
|
525
|
-
() async {
|
|
526
|
-
final runner = FakeRunner();
|
|
527
|
-
final bridge = NomosBridge(runner);
|
|
528
|
-
await bridge.ready;
|
|
529
|
-
final bad = NmsInternalNomosRefs.create<Object?>(
|
|
530
|
-
workspace: '', type: 'nomos.Workspace', id: 'x');
|
|
531
|
-
expect(() => bad.acquire(bridge), throwsArgumentError);
|
|
532
|
-
await bridge.dispose();
|
|
533
|
-
});
|
|
534
|
-
}
|