@githolon/dsl 0.108.6 → 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 +2083 -1248
  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,126 @@
1
+ import 'package:nomos_types/nomos_kernel_protocol.dart' as protocol;
2
+
3
+ import 'progress_desk.dart';
4
+
5
+ /// A disposable, read-only projection of work reported by the Peer Office.
6
+ /// Absence means unobserved, not ready. No application action is driven by it.
7
+ enum WorkspacePreparationStep {
8
+ restoringHistory,
9
+ installingLaw,
10
+ preparingReads,
11
+ preparingWrites,
12
+ preparingCustody,
13
+ preparingWorkspace,
14
+ complete,
15
+ }
16
+
17
+ final class WorkspacePreparationReport {
18
+ const WorkspacePreparationReport({
19
+ required this.step,
20
+ required this.active,
21
+ this.gitFrontier,
22
+ this.readFrontier,
23
+ this.sqliteFrontier,
24
+ this.retryAfterMillis,
25
+ this.stopped = false,
26
+ });
27
+
28
+ final WorkspacePreparationStep step;
29
+ final bool active;
30
+ final String? gitFrontier;
31
+ final String? readFrontier;
32
+ final String? sqliteFrontier;
33
+ final int? retryAfterMillis;
34
+ final bool stopped;
35
+ bool get retrying => retryAfterMillis != null;
36
+
37
+ /// Exact equality of reported frontiers, rather than a guess from residency.
38
+ bool? get sqliteCurrent {
39
+ if (readFrontier == null || sqliteFrontier == null) return null;
40
+ return readFrontier == sqliteFrontier;
41
+ }
42
+
43
+ static WorkspacePreparationReport fromMaintenance(
44
+ protocol.ReadMaintenanceProgress progress, {
45
+ WorkspacePreparationReport? previous,
46
+ }) {
47
+ final kernel = progress.hasKernel() ? progress.kernel : null;
48
+ final retry =
49
+ progress.hasRetryAfterMillis() ? progress.retryAfterMillis : null;
50
+ final step = progress.satisfiedByRead
51
+ ? WorkspacePreparationStep.complete
52
+ : kernel == null
53
+ ? switch (progress.cause) {
54
+ protocol.ReadMaintenanceCause
55
+ .READ_MAINTENANCE_CAUSE_DOMAIN_PREPARATION =>
56
+ WorkspacePreparationStep.preparingWrites,
57
+ protocol.ReadMaintenanceCause.READ_MAINTENANCE_CAUSE_OPEN ||
58
+ protocol
59
+ .ReadMaintenanceCause.READ_MAINTENANCE_CAUSE_READ_DEBT ||
60
+ protocol
61
+ .ReadMaintenanceCause.READ_MAINTENANCE_CAUSE_RESIDENCY =>
62
+ WorkspacePreparationStep.preparingReads,
63
+ _ => WorkspacePreparationStep.preparingWorkspace,
64
+ }
65
+ : switch (kernel.phase) {
66
+ protocol.MaintenancePhase.MAINTENANCE_PHASE_READ_DOCUMENTS ||
67
+ protocol.MaintenancePhase.MAINTENANCE_PHASE_SQLITE_INDEX ||
68
+ protocol.MaintenancePhase.MAINTENANCE_PHASE_READ_INDEX_CACHE =>
69
+ WorkspacePreparationStep.preparingReads,
70
+ protocol.MaintenancePhase.MAINTENANCE_PHASE_COMMAND_FRONTIER ||
71
+ protocol.MaintenancePhase.MAINTENANCE_PHASE_COMMAND_ROUTE =>
72
+ WorkspacePreparationStep.preparingWrites,
73
+ protocol.MaintenancePhase.MAINTENANCE_PHASE_GIT_CUSTODY =>
74
+ WorkspacePreparationStep.preparingCustody,
75
+ protocol.MaintenancePhase.MAINTENANCE_PHASE_COMPLETE =>
76
+ WorkspacePreparationStep.complete,
77
+ _ => WorkspacePreparationStep.preparingWorkspace,
78
+ };
79
+ return WorkspacePreparationReport(
80
+ step: step,
81
+ active: retry == null &&
82
+ !progress.stopped &&
83
+ !progress.satisfiedByRead &&
84
+ (kernel == null || kernel.maintenancePending),
85
+ retryAfterMillis: retry,
86
+ stopped: progress.stopped,
87
+ // A new demand may target a newer frontier. Never carry old readiness
88
+ // across its scheduled observation before the kernel reports a result.
89
+ gitFrontier: kernel == null
90
+ ? null
91
+ : kernel.hasGitFrontier()
92
+ ? kernel.gitFrontier
93
+ : previous?.gitFrontier,
94
+ readFrontier: kernel == null
95
+ ? null
96
+ : kernel.hasReadFrontier()
97
+ ? kernel.readFrontier
98
+ : previous?.readFrontier,
99
+ sqliteFrontier: kernel == null
100
+ ? null
101
+ : kernel.hasSqliteFrontier()
102
+ ? kernel.sqliteFrontier
103
+ : previous?.sqliteFrontier,
104
+ );
105
+ }
106
+
107
+ static WorkspacePreparationReport fromRestore(KernelProgress progress) =>
108
+ WorkspacePreparationReport(
109
+ step: switch (progress.phase) {
110
+ KernelProgressPhase.readChain ||
111
+ KernelProgressPhase.readTimeline ||
112
+ KernelProgressPhase.verifyIntents =>
113
+ WorkspacePreparationStep.restoringHistory,
114
+ KernelProgressPhase.hydrateLaw =>
115
+ WorkspacePreparationStep.installingLaw,
116
+ KernelProgressPhase.complete => WorkspacePreparationStep.complete,
117
+ _ => WorkspacePreparationStep.preparingWorkspace,
118
+ },
119
+ active: !progress.terminal,
120
+ // Restore may target a new frontier. Earlier accelerator observations
121
+ // cannot establish readiness for it.
122
+ gitFrontier: null,
123
+ readFrontier: null,
124
+ sqliteFrontier: null,
125
+ );
126
+ }
@@ -0,0 +1,123 @@
1
+ /// One-shot reads wait out a local copy that is not ready yet.
2
+ ///
3
+ /// A workspace this peer is still fetching, refetching, opening or indexing
4
+ /// answers a read with a retryable [NomosUnavailable] whose reason is
5
+ /// `localReplicaNotReady` or `workspaceOpening`. That is "not yet", not a
6
+ /// failure. [NmsTypedWatchRegistry] already waits it out before registering a
7
+ /// watch; this is the same rule for every one-shot read (queries, pages, counts,
8
+ /// sums, by-id and by-type USDA, historic queries), applied once where they all
9
+ /// reach the kernel. Callers therefore see either an answer or a real error.
10
+ /// They never see a state that passes by itself a moment later.
11
+ @internal
12
+ library;
13
+
14
+ import 'dart:async';
15
+
16
+ import 'package:meta/meta.dart' show internal, visibleForTesting;
17
+ import 'package:nomos_types/nomos_types.dart'
18
+ show NomosUnavailable, NomosUnavailableReason;
19
+
20
+ /// How long one read keeps asking before it reports the copy as unavailable.
21
+ /// A first sync of a large workspace at cutover takes minutes, not hours.
22
+ @visibleForTesting
23
+ Duration nmsReplicaReadyGiveUpAfter = const Duration(minutes: 10);
24
+
25
+ /// First pause between asks when the runtime gives no `retryAfter`. It doubles
26
+ /// per attempt, up to 16 times this value (the watch registry's schedule).
27
+ @visibleForTesting
28
+ Duration nmsReplicaReadyFirstDelay = const Duration(milliseconds: 250);
29
+
30
+ /// True for an unavailable answer that means "this copy is not ready yet".
31
+ bool nmsIsReplicaNotReady(Object error) =>
32
+ error is NomosUnavailable &&
33
+ error.retryable &&
34
+ (error.reason == NomosUnavailableReason.localReplicaNotReady ||
35
+ error.reason == NomosUnavailableReason.workspaceOpening);
36
+
37
+ /// Runs [read], asking again while it answers [nmsIsReplicaNotReady].
38
+ ///
39
+ /// [synced] names each workspace whose sync round just completed; the office
40
+ /// emits it the moment a copy it was fetching or opening is ready. A read
41
+ /// waiting on that workspace asks again at once instead of sleeping out its
42
+ /// `retryAfter`, which stays only as the fallback for a copy that becomes ready
43
+ /// without a sync (an index built in the background).
44
+ ///
45
+ /// Any other error, including a non-retryable or remote-side unavailability,
46
+ /// is rethrown at once, as is the last not-ready answer after
47
+ /// [nmsReplicaReadyGiveUpAfter].
48
+ @internal
49
+ Future<T> nmsUntilReplicaReady<T>(
50
+ Future<T> Function() read, {
51
+ Stream<String>? synced,
52
+ }) async {
53
+ final waited = Stopwatch()..start();
54
+ final wake = NmsReplicaWake(synced);
55
+ try {
56
+ for (var attempt = 0;; attempt++) {
57
+ wake.asking();
58
+ try {
59
+ return await read();
60
+ } on NomosUnavailable catch (unavailable) {
61
+ if (!nmsIsReplicaNotReady(unavailable) ||
62
+ waited.elapsed >= nmsReplicaReadyGiveUpAfter) {
63
+ rethrow;
64
+ }
65
+ await wake.wait(unavailable, attempt);
66
+ }
67
+ }
68
+ } finally {
69
+ await wake.close();
70
+ }
71
+ }
72
+
73
+ /// The pause after a "not ready yet" answer: the runtime's `retryAfter` (or
74
+ /// [nmsReplicaReadyFirstDelay]), doubling per attempt up to 16 times, cut short
75
+ /// the moment the workspace's sync completes.
76
+ ///
77
+ /// It listens from construction, so a sync that completes between the ask and
78
+ /// the wait is not missed: [asking] marks the start of each ask, and a wait for
79
+ /// a workspace that synced since then returns at once.
80
+ @internal
81
+ final class NmsReplicaWake {
82
+ NmsReplicaWake(Stream<String>? synced) {
83
+ _subscription = synced?.listen(_synced);
84
+ }
85
+
86
+ StreamSubscription<String>? _subscription;
87
+ final Set<String> _syncedSinceAsk = {};
88
+ String? _waitingOn;
89
+ Completer<void>? _woken;
90
+
91
+ void asking() => _syncedSinceAsk.clear();
92
+
93
+ Future<void> wait(NomosUnavailable unavailable, int attempt) async {
94
+ final workspace = unavailable.workspace;
95
+ if (_syncedSinceAsk.contains(workspace) ||
96
+ (workspace.isEmpty && _syncedSinceAsk.isNotEmpty)) {
97
+ return;
98
+ }
99
+ final base = unavailable.retryAfter ?? nmsReplicaReadyFirstDelay;
100
+ final woken = _woken = Completer<void>();
101
+ _waitingOn = workspace;
102
+ final timer = Timer(base * (1 << (attempt < 4 ? attempt : 4)), () {
103
+ if (!woken.isCompleted) woken.complete();
104
+ });
105
+ try {
106
+ await woken.future;
107
+ } finally {
108
+ timer.cancel();
109
+ _woken = null;
110
+ _waitingOn = null;
111
+ }
112
+ }
113
+
114
+ void _synced(String workspace) {
115
+ _syncedSinceAsk.add(workspace);
116
+ final woken = _woken;
117
+ final waitingOn = _waitingOn;
118
+ if (woken == null || woken.isCompleted || waitingOn == null) return;
119
+ if (waitingOn.isEmpty || waitingOn == workspace) woken.complete();
120
+ }
121
+
122
+ Future<void> close() async => _subscription?.cancel();
123
+ }