@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.
- 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 +80 -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 +214 -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 +268 -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 +23950 -15776
- 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 +550 -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_event_desk_close_test.dart +16 -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 +1276 -0
- package/src/codegen_call_usda.ts +49 -6
- package/src/codegen_dart.ts +83 -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 +2017 -1195
- 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
|
@@ -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:
|
|
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 (
|
|
23
|
+
/// surface (Reception dispatch, birth lanes) with the full session context.
|
|
24
24
|
@internal
|
|
25
25
|
library;
|
|
26
26
|
|
|
27
|
-
import '
|
|
27
|
+
import 'dart:typed_data';
|
|
28
28
|
|
|
29
|
-
import 'dart
|
|
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 '
|
|
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
|
-
///
|
|
46
|
-
|
|
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.
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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 (
|
|
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
|
|
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
|
|
415
|
-
if (
|
|
416
|
-
|
|
336
|
+
final matrix = iface.compatibilityMatrixUsda;
|
|
337
|
+
if (matrix == null) return;
|
|
338
|
+
late nomos_protocol.InterfaceCompatibilityVerdict answer;
|
|
417
339
|
try {
|
|
418
|
-
|
|
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:
|
|
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
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
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 (
|
|
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
|
|
500
|
-
//
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
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:
|
|
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));
|