@githolon/dsl 0.115.0 → 0.116.4

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 (39) hide show
  1. package/assets/operation-contract.wasm +0 -0
  2. package/dart/CHANGELOG.md +19 -0
  3. package/dart/lib/src/nms_generated_runtime.dart +1 -0
  4. package/dart/lib/src/result_usda.dart +64 -27
  5. package/dart/lib/src/runner/node-entry.mjs +701 -207
  6. package/dart/lib/src/sync_status_projection.dart +11 -0
  7. package/dart/pubspec.lock +1 -1
  8. package/dart/pubspec.yaml +2 -2
  9. package/dart/test/kernel_refused_follow_test.dart +36 -0
  10. package/dart/test/result_usda_test.dart +67 -0
  11. package/dart_types/CHANGELOG.md +6 -0
  12. package/dart_types/lib/src/proto/nomos/runtime/v2/observability_desk.pbenum.dart +11 -1
  13. package/dart_types/lib/src/vo_canonical.dart +185 -0
  14. package/dart_types/pubspec.lock +1 -1
  15. package/dart_types/pubspec.yaml +3 -1
  16. package/dart_types/test/vo_canonical_test.dart +91 -0
  17. package/package.json +2 -2
  18. package/src/aggregate.ts +3 -1
  19. package/src/baseline_usda.ts +2 -3
  20. package/src/build_package.ts +47 -7
  21. package/src/codegen_call_usda.ts +6 -3
  22. package/src/codegen_dart.ts +19 -57
  23. package/src/codegen_result_usda.ts +8 -4
  24. package/src/compile_package_main.ts +11 -4
  25. package/src/engine_entry.ts +12 -4
  26. package/src/identity_usda.ts +3 -52
  27. package/src/index.ts +10 -0
  28. package/src/intent.ts +28 -3
  29. package/src/law_check.ts +34 -0
  30. package/src/law_graph_usda.ts +2 -3
  31. package/src/law_layer_prims.ts +3 -28
  32. package/src/law_units.ts +7 -6
  33. package/src/law_version.ts +2 -1
  34. package/src/point_guard.ts +5 -1
  35. package/src/release_inspection.ts +6 -4
  36. package/src/release_publication.ts +6 -5
  37. package/src/usda_text.ts +78 -3
  38. package/src/value_identity.ts +355 -0
  39. package/src/value_object.ts +29 -1
@@ -1056,7 +1056,7 @@ var require_uri_all = __commonJS({
1056
1056
 
1057
1057
  // ../../platform-shells/node/stdio/entry.ts
1058
1058
  init_define_NOMOS_KERNEL_RELEASE();
1059
- import { randomUUID as randomUUID2 } from "node:crypto";
1059
+ import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
1060
1060
  import { existsSync as existsSync5, mkdirSync as mkdirSync5, mkdtempSync as mkdtempSync4, readFileSync as readFileSync3, rmSync as rmSync4, writeFileSync as writeFileSync5 } from "node:fs";
1061
1061
  import { tmpdir as tmpdir3 } from "node:os";
1062
1062
  import { join as join5 } from "node:path";
@@ -5747,8 +5747,10 @@ var PrepareRemoteOfferResponseSchema = /* @__PURE__ */ messageDesc(file_nomos_ke
5747
5747
  var SignOfferPreparationRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 37);
5748
5748
  var SigningIdentityRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 39);
5749
5749
  var KernelRefusalSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 55);
5750
+ var QueryResponseSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 56);
5750
5751
  var ApplicationResultDeltaSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 58);
5751
5752
  var InterfaceCompatibilityQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 60);
5753
+ var ReadIndexPendingSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 64);
5752
5754
  var MaintenanceQuantumQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 65);
5753
5755
  var CarriedWorkspaceOfferSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 80);
5754
5756
  var PrepareOutboundOfferSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 84);
@@ -6017,7 +6019,7 @@ var CustodyBreakPolicySchema = /* @__PURE__ */ enumDesc(file_nomos_runtime_v2_re
6017
6019
  var CustodyBreakPolicy = /* @__PURE__ */ tsEnum(CustodyBreakPolicySchema);
6018
6020
 
6019
6021
  // ../../adapter/proto/nomos/runtime/v2/observability_desk_pb.js
6020
- var file_nomos_runtime_v2_observability_desk = /* @__PURE__ */ fileDesc("Cilub21vcy9ydW50aW1lL3YyL29ic2VydmFiaWxpdHlfZGVzay5wcm90bxIQbm9tb3MucnVudGltZS52MiJCCgxUcmFjZUNvbnRleHQSEAoIdHJhY2VfaWQYASABKAwSDwoHc3Bhbl9pZBgCIAEoDBIPCgdzYW1wbGVkGAMgASgIIp0CCg5SdW50aW1lRmFpbHVyZRIMCgRjb2RlGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSEQoJY29tcG9uZW50GAMgASgJEhYKCXdvcmtzcGFjZRgEIAEoCUgAiAEBEhMKBmRvbWFpbhgFIAEoCUgBiAEBEhYKCWRpcmVjdGl2ZRgGIAEoCUgCiAEBEjkKCmF0dHJpYnV0ZXMYByADKAsyJS5ub21vcy5ydW50aW1lLnYyLkRpYWdub3N0aWNBdHRyaWJ1dGUSMgoEa2luZBgIIAEoDjIkLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZUZhaWx1cmVLaW5kQgwKCl93b3Jrc3BhY2VCCQoHX2RvbWFpbkIMCgpfZGlyZWN0aXZlIr4BChJSdW50aW1lVW5hdmFpbGFibGUSOgoGcmVhc29uGAEgASgOMioubm9tb3MucnVudGltZS52Mi5SdW50aW1lVW5hdmFpbGFibGVSZWFzb24SEQoJd29ya3NwYWNlGAIgASgJEhEKCXJldHJ5YWJsZRgDIAEoCBIfChJyZXRyeV9hZnRlcl9taWxsaXMYBCABKA1IAIgBARIOCgZkZXRhaWwYBSABKAlCFQoTX3JldHJ5X2FmdGVyX21pbGxpcyJ+Cg5SdW50aW1lUmVmdXNhbBI2CgZyZWFzb24YASABKA4yJi5ub21vcy5ydW50aW1lLnYyLlJ1bnRpbWVSZWZ1c2FsUmVhc29uEhEKCXdvcmtzcGFjZRgCIAEoCRIRCglyZXRyeWFibGUYAyABKAgSDgoGZGV0YWlsGAQgASgJIqUBChNEaWFnbm9zdGljQXR0cmlidXRlEgwKBG5hbWUYASABKAkSFgoMc3RyaW5nX3ZhbHVlGAIgASgJSAASFwoNaW50ZWdlcl92YWx1ZRgDIAEoEkgAEhYKDGRvdWJsZV92YWx1ZRgEIAEoAUgAEhcKDWJvb2xlYW5fdmFsdWUYBSABKAhIABIVCgtieXRlc192YWx1ZRgGIAEoDEgAQgcKBXZhbHVlIvALCgxSdW50aW1lRXZlbnQSEAoIc2VxdWVuY2UYASABKAQSFAoHc2Vzc2lvbhgCIAEoCUgBiAEBEi8KBXJlYWR5GAogASgLMh4ubm9tb3MucnVudGltZS52Mi5SdW50aW1lUmVhZHlIABI3Cg13YXRjaF9jaGFuZ2VkGAsgASgLMh4ubm9tb3MucnVudGltZS52Mi5XYXRjaENoYW5nZWRIABI5Cg5zeW5jX2NvbXBsZXRlZBgMIAEoCzIfLm5vbW9zLnJ1bnRpbWUudjIuU3luY0NvbXBsZXRlZEgAEjUKDGxpbmtfY2hhbmdlZBgNIAEoCzIdLm5vbW9zLnJ1bnRpbWUudjIuTGlua0NoYW5nZWRIABI5Cg5zaWduYWxfY2hhbmdlZBgOIAEoCzIfLm5vbW9zLnJ1bnRpbWUudjIuU2lnbmFsQ2hhbmdlZEgAEjsKD2N1c3RvZHlfY2hhbmdlZBgPIAEoCzIgLm5vbW9zLnJ1bnRpbWUudjIuQ3VzdG9keUNoYW5nZWRIABJCChNsb2NhbF93b3JrX3JlamVjdGVkGBAgASgLMiMubm9tb3MucnVudGltZS52Mi5Mb2NhbFdvcmtSZWplY3RlZEgAEjMKC2xhd19jaGFuZ2VkGBEgASgLMhwubm9tb3MucnVudGltZS52Mi5MYXdDaGFuZ2VkSAASQwoPa2VybmVsX3Byb2dyZXNzGBIgASgLMigubm9tb3MucnVudGltZS52Mi5LZXJuZWxQcm9ncmVzc09ic2VydmVkSAASLQoEc3BhbhgTIAEoCzIdLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZVNwYW5IABI/ChF0cmFuc2Zlcl9wcm9ncmVzcxgUIAEoCzIiLm5vbW9zLnJ1bnRpbWUudjIuVHJhbnNmZXJQcm9ncmVzc0gAEkkKFG1haW50ZW5hbmNlX3Byb2dyZXNzGBUgASgLMikubm9tb3MucnVudGltZS52Mi5SZWFkTWFpbnRlbmFuY2VQcm9ncmVzc0gAEjsKDXNvY2tldF9lZmZlY3QYFiABKAsyIi5ub21vcy5ydW50aW1lLnYyLlBlZXJTb2NrZXRFZmZlY3RIABJUChxjcmVkZW50aWFsX3JlZnJlc2hfcmVxdWVzdGVkGBcgASgLMiwubm9tb3MucnVudGltZS52Mi5DcmVkZW50aWFsUmVmcmVzaFJlcXVlc3RlZEgAElIKG3JlY2VpdmluZ19ncm91cF9jb252ZXJnZW5jZRgYIAEoCzIrLm5vbW9zLnJ1bnRpbWUudjIuUmVjZWl2aW5nR3JvdXBDb252ZXJnZW5jZUgAEkoKF21vZGVsX2Fkb3B0aW9uX3Byb2dyZXNzGBkgASgLMicubm9tb3MucnVudGltZS52Mi5Nb2RlbEFkb3B0aW9uUHJvZ3Jlc3NIABI7Cg9mb2xsb3dzX3N1bW1hcnkYGiABKAsyIC5ub21vcy5ydW50aW1lLnYyLkZvbGxvd3NTdW1tYXJ5SAASRAoUbG9jYWxfY29weV9wcmVzZXJ2ZWQYGyABKAsyJC5ub21vcy5ydW50aW1lLnYyLlByZXNlcnZlZExvY2FsQ29weUgAEk4KGWZvcmVpZ25fcGxhY2VtZW50X2lnbm9yZWQYHCABKAsyKS5ub21vcy5ydW50aW1lLnYyLkZvcmVpZ25QbGFjZW1lbnRJZ25vcmVkSAASQwoTYmluZGluZ19xdWFyYW50aW5lZBgdIAEoCzIkLm5vbW9zLnJ1bnRpbWUudjIuUXVhcmFudGluZWRCaW5kaW5nSAASPwoRd3JpdGVfcHJlcGFyYXRpb24YHiABKAsyIi5ub21vcy5ydW50aW1lLnYyLldyaXRlUHJlcGFyYXRpb25IABJKChdyZWFkX2FjY2Vzc19wcmVwYXJhdGlvbhgfIAEoCzInLm5vbW9zLnJ1bnRpbWUudjIuUmVhZEFjY2Vzc1ByZXBhcmF0aW9uSABCBwoFZXZlbnRCCgoIX3Nlc3Npb24ivAEKDkZvbGxvd3NTdW1tYXJ5EhAKCGZvbGxvd2VkGAEgASgNEg8KB3NldHRsZWQYAiABKA0SDAoEbGl2ZRgDIAEoDRI3Cgp3b3Jrc3BhY2VzGAQgAygLMiMubm9tb3MucnVudGltZS52Mi5Gb2xsb3dPYnNlcnZhdGlvbhIkChdvYnNlcnZlZF9hdF91bml4X21pbGxpcxgFIAEoBEgAiAEBQhoKGF9vYnNlcnZlZF9hdF91bml4X21pbGxpcyL7AwoRRm9sbG93T2JzZXJ2YXRpb24SEQoJd29ya3NwYWNlGAEgASgJEjcKBXBoYXNlGAIgASgOMigubm9tb3MucnVudGltZS52Mi5Gb2xsb3dPYnNlcnZhdGlvblBoYXNlEgwKBGxpdmUYAyABKAgSEwoGZGV0YWlsGAQgASgJSACIAQESIQoUcmV0cnlfYXRfdW5peF9taWxsaXMYBSABKARIAYgBARIfChJkdWVfYXRfdW5peF9taWxsaXMYBiABKARIAogBARIUCgdhdHRlbXB0GAcgASgNSAOIAQESGgoNYWN0aXZlX2VmZmVjdBgIIAEoCUgEiAEBEhMKBnVuc2VudBgJIAEoDUgFiAEBEhsKDnVuYWNrbm93bGVkZ2VkGAogASgNSAaIAQESQgoRY3VzdG9kaWFuX3dhcm1pbmcYCyABKAsyIi5ub21vcy5ydW50aW1lLnYyLkN1c3RvZGlhbldhcm1pbmdIB4gBAUIJCgdfZGV0YWlsQhcKFV9yZXRyeV9hdF91bml4X21pbGxpc0IVChNfZHVlX2F0X3VuaXhfbWlsbGlzQgoKCF9hdHRlbXB0QhAKDl9hY3RpdmVfZWZmZWN0QgkKB191bnNlbnRCEQoPX3VuYWNrbm93bGVkZ2VkQhQKEl9jdXN0b2RpYW5fd2FybWluZyKFAQoQQ3VzdG9kaWFuV2FybWluZxIZChFzaW5jZV91bml4X21pbGxpcxgBIAEoBBIiChpleHBlY3RlZF9yZWFkeV91bml4X21pbGxpcxgCIAEoBBIhChlzdGFsbGVkX2FmdGVyX3VuaXhfbWlsbGlzGAMgASgEEg8KB3N0YWxsZWQYBCABKAgiVgoaQ3JlZGVudGlhbFJlZnJlc2hSZXF1ZXN0ZWQSOAoHcGVuZGluZxgBIAEoCzInLm5vbW9zLnJ1bnRpbWUudjIuQ29ycmVzcG9uZGVuY2VQZW5kaW5nIj4KDFJ1bnRpbWVSZWFkeRIXCg9ydW50aW1lX3ZlcnNpb24YASABKAkSFQoNa2VybmVsX3NoYTI1NhgCIAEoDCKNAwoMV2F0Y2hDaGFuZ2VkEhcKD3N1YnNjcmlwdGlvbl9pZBgBIAEoCRITCgtyZXN1bHRfdXNkYRgCIAEoDBI2CgdmYWlsdXJlGAMgASgLMiAubm9tb3MucnVudGltZS52Mi5SdW50aW1lRmFpbHVyZUgAiAEBEjUKEmFwcGxpY2F0aW9uX3Jlc3VsdBgEIAEoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnlIAYgBARIaCg1pbnRlZ2VyX3ZhbHVlGAUgASgDSAKIAQESRwoRYXBwbGljYXRpb25fZGVsdGEYBiABKAsyJy5ub21vcy5rZXJuZWwudjEuQXBwbGljYXRpb25SZXN1bHREZWx0YUgDiAEBEhwKD3Jlc3VsdF9mcm9udGllchgHIAEoCUgEiAEBQgoKCF9mYWlsdXJlQhUKE19hcHBsaWNhdGlvbl9yZXN1bHRCEAoOX2ludGVnZXJfdmFsdWVCFAoSX2FwcGxpY2F0aW9uX2RlbHRhQhIKEF9yZXN1bHRfZnJvbnRpZXIinAEKDVN5bmNDb21wbGV0ZWQSDgoGcmVhc29uGAEgASgJEjcKBnJlc3VsdBgCIAEoCzInLm5vbW9zLnJ1bnRpbWUudjIuU3luY1dvcmtzcGFjZVJlc3BvbnNlEjYKB2ZhaWx1cmUYAyABKAsyIC5ub21vcy5ydW50aW1lLnYyLlJ1bnRpbWVGYWlsdXJlSACIAQFCCgoIX2ZhaWx1cmUigAEKC0xpbmtDaGFuZ2VkEiwKBnN0YXR1cxgBIAEoDjIcLm5vbW9zLnJ1bnRpbWUudjIuTGlua1N0YXR1cxI3CgdjbG9zdXJlGAIgASgLMiEubm9tb3MucnVudGltZS52Mi5MaXZlTGlua0Nsb3N1cmVIAIgBAUIKCghfY2xvc3VyZSI4Cg1TaWduYWxDaGFuZ2VkEg4KBmRvbWFpbhgBIAEoCRIXCg9wcm9qZWN0aW9uX3VzZGEYAiABKAwiUAoKTGF3Q2hhbmdlZBIOCgZkb21haW4YASABKAkSFgoOcGFja2FnZV9zaGEyNTYYAiABKAkSGgoSY29tcGF0aWJpbGl0eV91c2RhGAMgASgMIt0BCgtSdW50aW1lU3BhbhIQCgh0cmFjZV9pZBgBIAEoDBIPCgdzcGFuX2lkGAIgASgMEhsKDnBhcmVudF9zcGFuX2lkGAMgASgMSACIAQESDAoEbmFtZRgEIAEoCRIaChJzdGFydGVkX3VuaXhfbmFub3MYBSABKAQSFgoOZHVyYXRpb25fbmFub3MYBiABKAQSOQoKYXR0cmlidXRlcxgHIAMoCzIlLm5vbW9zLnJ1bnRpbWUudjIuRGlhZ25vc3RpY0F0dHJpYnV0ZUIRCg9fcGFyZW50X3NwYW5faWQi6gEKFktlcm5lbFByb2dyZXNzT2JzZXJ2ZWQSOQoIc25hcHNob3QYASABKAsyJy5ub21vcy5rZXJuZWwudjEuS2VybmVsUHJvZ3Jlc3NTbmFwc2hvdBIkChxob3N0X29ic2VydmVkX2VsYXBzZWRfbWljcm9zGAIgASgEEioKImhvc3Rfb2JzZXJ2ZWRfcGhhc2VfZWxhcHNlZF9taWNyb3MYAyABKAQSHgoWcHJvY2Vzc19yZXNpZGVudF9ieXRlcxgEIAEoBBIjChtwcm9jZXNzX3BlYWtfcmVzaWRlbnRfYnl0ZXMYBSABKAQiggEKEFRyYW5zZmVyUHJvZ3Jlc3MSFgoOcmVjZWl2ZWRfYnl0ZXMYASABKAQSGAoLdG90YWxfYnl0ZXMYAiABKARIAIgBARIsCgRraW5kGAMgASgOMh4ubm9tb3MucnVudGltZS52Mi5UcmFuc2ZlcktpbmRCDgoMX3RvdGFsX2J5dGVzIjkKEFdyaXRlUHJlcGFyYXRpb24SEgoKcmVxdWVzdF9pZBgBIAEoCRIRCgl3b3Jrc3BhY2UYAiABKAkiPgoVUmVhZEFjY2Vzc1ByZXBhcmF0aW9uEhIKCnJlcXVlc3RfaWQYASABKAkSEQoJd29ya3NwYWNlGAIgASgJKsoBChJSdW50aW1lRmFpbHVyZUtpbmQSJAogUlVOVElNRV9GQUlMVVJFX0tJTkRfVU5TUEVDSUZJRUQQABIhCh1SVU5USU1FX0ZBSUxVUkVfS0lORF9JTlRFUk5BTBABEiEKHVJVTlRJTUVfRkFJTFVSRV9LSU5EX1BST1RPQ09MEAISIgoeUlVOVElNRV9GQUlMVVJFX0tJTkRfSU5URUdSSVRZEAMSJAogUlVOVElNRV9GQUlMVVJFX0tJTkRfVU5TVVBQT1JURUQQBCqnAwoYUnVudGltZVVuYXZhaWxhYmxlUmVhc29uEioKJlJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1VOU1BFQ0lGSUVEEAASMgouUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fUkVNT1RFX09OTFlfT0ZGTElORRABEjEKLVJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1JFTU9URV9VTlJFQUNIQUJMRRACEi0KKVJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1JFTU9URV9USU1FT1VUEAMSNgoyUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fTE9DQUxfUkVQTElDQV9OT1RfUkVBRFkQBBI1CjFSVU5USU1FX1VOQVZBSUxBQkxFX1JFQVNPTl9DUkVERU5USUFMX1VOQVZBSUxBQkxFEAUSMAosUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fV09SS1NQQUNFX09QRU5JTkcQBhIoCiRSVU5USU1FX1VOQVZBSUxBQkxFX1JFQVNPTl9QRUVSX0JVU1kQByrwAQoUUnVudGltZVJlZnVzYWxSZWFzb24SJgoiUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9VTlNQRUNJRklFRBAAEi0KKVJVTlRJTUVfUkVGVVNBTF9SRUFTT05fSU5WQUxJRF9DUkVERU5USUFMEAESKAokUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9BQ0NFU1NfREVOSUVEEAISKwonUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9QTEFDRU1FTlRfUE9MSUNZEAMSKgomUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9TRVNTSU9OX1VOQk9VTkQQBCqVBAoWRm9sbG93T2JzZXJ2YXRpb25QaGFzZRIoCiRGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfVU5TUEVDSUZJRUQQABIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfREVTSVJFRBABEiAKHEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9EVUUQAhIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfUlVOTklORxADEiQKIEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9TRVRUTEVEEAQSMAosRk9MTE9XX09CU0VSVkFUSU9OX1BIQVNFX0FXQUlUSU5HX0RFUEVOREVOQ1kQBRIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfT0ZGTElORRAGEi8KK0ZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9JTlZBTElEX0NSRURFTlRJQUwQBxIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfQkFDS09GRhAIEiwKKEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9SRUJPUk5fUkVNT1RFTFkQCRIsCihGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfUkVQTEFDSU5HX0xPQ0FMEAoSMgouRk9MTE9XX09CU0VSVkFUSU9OX1BIQVNFX0xPQ0FMX0NPUFlfVU5SRUFEQUJMRRALKlcKCkxpbmtTdGF0dXMSGwoXTElOS19TVEFUVVNfVU5TUEVDSUZJRUQQABIUChBMSU5LX1NUQVRVU19PUEVOEAESFgoSTElOS19TVEFUVVNfQ0xPU0VEEAIqdgoMVHJhbnNmZXJLaW5kEh0KGVRSQU5TRkVSX0tJTkRfVU5TUEVDSUZJRUQQABIXChNUUkFOU0ZFUl9LSU5EX0RFTFRBEAESFgoSVFJBTlNGRVJfS0lORF9GVUxMEAISFgoSVFJBTlNGRVJfS0lORF9QVVNIEANiBnByb3RvMw", [file_google_protobuf_any, file_nomos_kernel_v1_kernel, file_nomos_kernel_v1_progress, file_nomos_runtime_v2_correspondence_desk, file_nomos_runtime_v2_custody_desk, file_nomos_runtime_v2_placement_desk, file_nomos_runtime_v2_maintenance_desk, file_nomos_runtime_v2_model_adoption_desk, file_nomos_runtime_v2_receiving_group_desk, file_nomos_runtime_v2_recovery_desk]);
6022
+ var file_nomos_runtime_v2_observability_desk = /* @__PURE__ */ fileDesc("Cilub21vcy9ydW50aW1lL3YyL29ic2VydmFiaWxpdHlfZGVzay5wcm90bxIQbm9tb3MucnVudGltZS52MiJCCgxUcmFjZUNvbnRleHQSEAoIdHJhY2VfaWQYASABKAwSDwoHc3Bhbl9pZBgCIAEoDBIPCgdzYW1wbGVkGAMgASgIIp0CCg5SdW50aW1lRmFpbHVyZRIMCgRjb2RlGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSEQoJY29tcG9uZW50GAMgASgJEhYKCXdvcmtzcGFjZRgEIAEoCUgAiAEBEhMKBmRvbWFpbhgFIAEoCUgBiAEBEhYKCWRpcmVjdGl2ZRgGIAEoCUgCiAEBEjkKCmF0dHJpYnV0ZXMYByADKAsyJS5ub21vcy5ydW50aW1lLnYyLkRpYWdub3N0aWNBdHRyaWJ1dGUSMgoEa2luZBgIIAEoDjIkLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZUZhaWx1cmVLaW5kQgwKCl93b3Jrc3BhY2VCCQoHX2RvbWFpbkIMCgpfZGlyZWN0aXZlIr4BChJSdW50aW1lVW5hdmFpbGFibGUSOgoGcmVhc29uGAEgASgOMioubm9tb3MucnVudGltZS52Mi5SdW50aW1lVW5hdmFpbGFibGVSZWFzb24SEQoJd29ya3NwYWNlGAIgASgJEhEKCXJldHJ5YWJsZRgDIAEoCBIfChJyZXRyeV9hZnRlcl9taWxsaXMYBCABKA1IAIgBARIOCgZkZXRhaWwYBSABKAlCFQoTX3JldHJ5X2FmdGVyX21pbGxpcyJ+Cg5SdW50aW1lUmVmdXNhbBI2CgZyZWFzb24YASABKA4yJi5ub21vcy5ydW50aW1lLnYyLlJ1bnRpbWVSZWZ1c2FsUmVhc29uEhEKCXdvcmtzcGFjZRgCIAEoCRIRCglyZXRyeWFibGUYAyABKAgSDgoGZGV0YWlsGAQgASgJIqUBChNEaWFnbm9zdGljQXR0cmlidXRlEgwKBG5hbWUYASABKAkSFgoMc3RyaW5nX3ZhbHVlGAIgASgJSAASFwoNaW50ZWdlcl92YWx1ZRgDIAEoEkgAEhYKDGRvdWJsZV92YWx1ZRgEIAEoAUgAEhcKDWJvb2xlYW5fdmFsdWUYBSABKAhIABIVCgtieXRlc192YWx1ZRgGIAEoDEgAQgcKBXZhbHVlIvALCgxSdW50aW1lRXZlbnQSEAoIc2VxdWVuY2UYASABKAQSFAoHc2Vzc2lvbhgCIAEoCUgBiAEBEi8KBXJlYWR5GAogASgLMh4ubm9tb3MucnVudGltZS52Mi5SdW50aW1lUmVhZHlIABI3Cg13YXRjaF9jaGFuZ2VkGAsgASgLMh4ubm9tb3MucnVudGltZS52Mi5XYXRjaENoYW5nZWRIABI5Cg5zeW5jX2NvbXBsZXRlZBgMIAEoCzIfLm5vbW9zLnJ1bnRpbWUudjIuU3luY0NvbXBsZXRlZEgAEjUKDGxpbmtfY2hhbmdlZBgNIAEoCzIdLm5vbW9zLnJ1bnRpbWUudjIuTGlua0NoYW5nZWRIABI5Cg5zaWduYWxfY2hhbmdlZBgOIAEoCzIfLm5vbW9zLnJ1bnRpbWUudjIuU2lnbmFsQ2hhbmdlZEgAEjsKD2N1c3RvZHlfY2hhbmdlZBgPIAEoCzIgLm5vbW9zLnJ1bnRpbWUudjIuQ3VzdG9keUNoYW5nZWRIABJCChNsb2NhbF93b3JrX3JlamVjdGVkGBAgASgLMiMubm9tb3MucnVudGltZS52Mi5Mb2NhbFdvcmtSZWplY3RlZEgAEjMKC2xhd19jaGFuZ2VkGBEgASgLMhwubm9tb3MucnVudGltZS52Mi5MYXdDaGFuZ2VkSAASQwoPa2VybmVsX3Byb2dyZXNzGBIgASgLMigubm9tb3MucnVudGltZS52Mi5LZXJuZWxQcm9ncmVzc09ic2VydmVkSAASLQoEc3BhbhgTIAEoCzIdLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZVNwYW5IABI/ChF0cmFuc2Zlcl9wcm9ncmVzcxgUIAEoCzIiLm5vbW9zLnJ1bnRpbWUudjIuVHJhbnNmZXJQcm9ncmVzc0gAEkkKFG1haW50ZW5hbmNlX3Byb2dyZXNzGBUgASgLMikubm9tb3MucnVudGltZS52Mi5SZWFkTWFpbnRlbmFuY2VQcm9ncmVzc0gAEjsKDXNvY2tldF9lZmZlY3QYFiABKAsyIi5ub21vcy5ydW50aW1lLnYyLlBlZXJTb2NrZXRFZmZlY3RIABJUChxjcmVkZW50aWFsX3JlZnJlc2hfcmVxdWVzdGVkGBcgASgLMiwubm9tb3MucnVudGltZS52Mi5DcmVkZW50aWFsUmVmcmVzaFJlcXVlc3RlZEgAElIKG3JlY2VpdmluZ19ncm91cF9jb252ZXJnZW5jZRgYIAEoCzIrLm5vbW9zLnJ1bnRpbWUudjIuUmVjZWl2aW5nR3JvdXBDb252ZXJnZW5jZUgAEkoKF21vZGVsX2Fkb3B0aW9uX3Byb2dyZXNzGBkgASgLMicubm9tb3MucnVudGltZS52Mi5Nb2RlbEFkb3B0aW9uUHJvZ3Jlc3NIABI7Cg9mb2xsb3dzX3N1bW1hcnkYGiABKAsyIC5ub21vcy5ydW50aW1lLnYyLkZvbGxvd3NTdW1tYXJ5SAASRAoUbG9jYWxfY29weV9wcmVzZXJ2ZWQYGyABKAsyJC5ub21vcy5ydW50aW1lLnYyLlByZXNlcnZlZExvY2FsQ29weUgAEk4KGWZvcmVpZ25fcGxhY2VtZW50X2lnbm9yZWQYHCABKAsyKS5ub21vcy5ydW50aW1lLnYyLkZvcmVpZ25QbGFjZW1lbnRJZ25vcmVkSAASQwoTYmluZGluZ19xdWFyYW50aW5lZBgdIAEoCzIkLm5vbW9zLnJ1bnRpbWUudjIuUXVhcmFudGluZWRCaW5kaW5nSAASPwoRd3JpdGVfcHJlcGFyYXRpb24YHiABKAsyIi5ub21vcy5ydW50aW1lLnYyLldyaXRlUHJlcGFyYXRpb25IABJKChdyZWFkX2FjY2Vzc19wcmVwYXJhdGlvbhgfIAEoCzInLm5vbW9zLnJ1bnRpbWUudjIuUmVhZEFjY2Vzc1ByZXBhcmF0aW9uSABCBwoFZXZlbnRCCgoIX3Nlc3Npb24ivAEKDkZvbGxvd3NTdW1tYXJ5EhAKCGZvbGxvd2VkGAEgASgNEg8KB3NldHRsZWQYAiABKA0SDAoEbGl2ZRgDIAEoDRI3Cgp3b3Jrc3BhY2VzGAQgAygLMiMubm9tb3MucnVudGltZS52Mi5Gb2xsb3dPYnNlcnZhdGlvbhIkChdvYnNlcnZlZF9hdF91bml4X21pbGxpcxgFIAEoBEgAiAEBQhoKGF9vYnNlcnZlZF9hdF91bml4X21pbGxpcyL7AwoRRm9sbG93T2JzZXJ2YXRpb24SEQoJd29ya3NwYWNlGAEgASgJEjcKBXBoYXNlGAIgASgOMigubm9tb3MucnVudGltZS52Mi5Gb2xsb3dPYnNlcnZhdGlvblBoYXNlEgwKBGxpdmUYAyABKAgSEwoGZGV0YWlsGAQgASgJSACIAQESIQoUcmV0cnlfYXRfdW5peF9taWxsaXMYBSABKARIAYgBARIfChJkdWVfYXRfdW5peF9taWxsaXMYBiABKARIAogBARIUCgdhdHRlbXB0GAcgASgNSAOIAQESGgoNYWN0aXZlX2VmZmVjdBgIIAEoCUgEiAEBEhMKBnVuc2VudBgJIAEoDUgFiAEBEhsKDnVuYWNrbm93bGVkZ2VkGAogASgNSAaIAQESQgoRY3VzdG9kaWFuX3dhcm1pbmcYCyABKAsyIi5ub21vcy5ydW50aW1lLnYyLkN1c3RvZGlhbldhcm1pbmdIB4gBAUIJCgdfZGV0YWlsQhcKFV9yZXRyeV9hdF91bml4X21pbGxpc0IVChNfZHVlX2F0X3VuaXhfbWlsbGlzQgoKCF9hdHRlbXB0QhAKDl9hY3RpdmVfZWZmZWN0QgkKB191bnNlbnRCEQoPX3VuYWNrbm93bGVkZ2VkQhQKEl9jdXN0b2RpYW5fd2FybWluZyKFAQoQQ3VzdG9kaWFuV2FybWluZxIZChFzaW5jZV91bml4X21pbGxpcxgBIAEoBBIiChpleHBlY3RlZF9yZWFkeV91bml4X21pbGxpcxgCIAEoBBIhChlzdGFsbGVkX2FmdGVyX3VuaXhfbWlsbGlzGAMgASgEEg8KB3N0YWxsZWQYBCABKAgiVgoaQ3JlZGVudGlhbFJlZnJlc2hSZXF1ZXN0ZWQSOAoHcGVuZGluZxgBIAEoCzInLm5vbW9zLnJ1bnRpbWUudjIuQ29ycmVzcG9uZGVuY2VQZW5kaW5nIj4KDFJ1bnRpbWVSZWFkeRIXCg9ydW50aW1lX3ZlcnNpb24YASABKAkSFQoNa2VybmVsX3NoYTI1NhgCIAEoDCKNAwoMV2F0Y2hDaGFuZ2VkEhcKD3N1YnNjcmlwdGlvbl9pZBgBIAEoCRITCgtyZXN1bHRfdXNkYRgCIAEoDBI2CgdmYWlsdXJlGAMgASgLMiAubm9tb3MucnVudGltZS52Mi5SdW50aW1lRmFpbHVyZUgAiAEBEjUKEmFwcGxpY2F0aW9uX3Jlc3VsdBgEIAEoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnlIAYgBARIaCg1pbnRlZ2VyX3ZhbHVlGAUgASgDSAKIAQESRwoRYXBwbGljYXRpb25fZGVsdGEYBiABKAsyJy5ub21vcy5rZXJuZWwudjEuQXBwbGljYXRpb25SZXN1bHREZWx0YUgDiAEBEhwKD3Jlc3VsdF9mcm9udGllchgHIAEoCUgEiAEBQgoKCF9mYWlsdXJlQhUKE19hcHBsaWNhdGlvbl9yZXN1bHRCEAoOX2ludGVnZXJfdmFsdWVCFAoSX2FwcGxpY2F0aW9uX2RlbHRhQhIKEF9yZXN1bHRfZnJvbnRpZXIinAEKDVN5bmNDb21wbGV0ZWQSDgoGcmVhc29uGAEgASgJEjcKBnJlc3VsdBgCIAEoCzInLm5vbW9zLnJ1bnRpbWUudjIuU3luY1dvcmtzcGFjZVJlc3BvbnNlEjYKB2ZhaWx1cmUYAyABKAsyIC5ub21vcy5ydW50aW1lLnYyLlJ1bnRpbWVGYWlsdXJlSACIAQFCCgoIX2ZhaWx1cmUigAEKC0xpbmtDaGFuZ2VkEiwKBnN0YXR1cxgBIAEoDjIcLm5vbW9zLnJ1bnRpbWUudjIuTGlua1N0YXR1cxI3CgdjbG9zdXJlGAIgASgLMiEubm9tb3MucnVudGltZS52Mi5MaXZlTGlua0Nsb3N1cmVIAIgBAUIKCghfY2xvc3VyZSI4Cg1TaWduYWxDaGFuZ2VkEg4KBmRvbWFpbhgBIAEoCRIXCg9wcm9qZWN0aW9uX3VzZGEYAiABKAwiUAoKTGF3Q2hhbmdlZBIOCgZkb21haW4YASABKAkSFgoOcGFja2FnZV9zaGEyNTYYAiABKAkSGgoSY29tcGF0aWJpbGl0eV91c2RhGAMgASgMIt0BCgtSdW50aW1lU3BhbhIQCgh0cmFjZV9pZBgBIAEoDBIPCgdzcGFuX2lkGAIgASgMEhsKDnBhcmVudF9zcGFuX2lkGAMgASgMSACIAQESDAoEbmFtZRgEIAEoCRIaChJzdGFydGVkX3VuaXhfbmFub3MYBSABKAQSFgoOZHVyYXRpb25fbmFub3MYBiABKAQSOQoKYXR0cmlidXRlcxgHIAMoCzIlLm5vbW9zLnJ1bnRpbWUudjIuRGlhZ25vc3RpY0F0dHJpYnV0ZUIRCg9fcGFyZW50X3NwYW5faWQi6gEKFktlcm5lbFByb2dyZXNzT2JzZXJ2ZWQSOQoIc25hcHNob3QYASABKAsyJy5ub21vcy5rZXJuZWwudjEuS2VybmVsUHJvZ3Jlc3NTbmFwc2hvdBIkChxob3N0X29ic2VydmVkX2VsYXBzZWRfbWljcm9zGAIgASgEEioKImhvc3Rfb2JzZXJ2ZWRfcGhhc2VfZWxhcHNlZF9taWNyb3MYAyABKAQSHgoWcHJvY2Vzc19yZXNpZGVudF9ieXRlcxgEIAEoBBIjChtwcm9jZXNzX3BlYWtfcmVzaWRlbnRfYnl0ZXMYBSABKAQiggEKEFRyYW5zZmVyUHJvZ3Jlc3MSFgoOcmVjZWl2ZWRfYnl0ZXMYASABKAQSGAoLdG90YWxfYnl0ZXMYAiABKARIAIgBARIsCgRraW5kGAMgASgOMh4ubm9tb3MucnVudGltZS52Mi5UcmFuc2ZlcktpbmRCDgoMX3RvdGFsX2J5dGVzIjkKEFdyaXRlUHJlcGFyYXRpb24SEgoKcmVxdWVzdF9pZBgBIAEoCRIRCgl3b3Jrc3BhY2UYAiABKAkiPgoVUmVhZEFjY2Vzc1ByZXBhcmF0aW9uEhIKCnJlcXVlc3RfaWQYASABKAkSEQoJd29ya3NwYWNlGAIgASgJKsoBChJSdW50aW1lRmFpbHVyZUtpbmQSJAogUlVOVElNRV9GQUlMVVJFX0tJTkRfVU5TUEVDSUZJRUQQABIhCh1SVU5USU1FX0ZBSUxVUkVfS0lORF9JTlRFUk5BTBABEiEKHVJVTlRJTUVfRkFJTFVSRV9LSU5EX1BST1RPQ09MEAISIgoeUlVOVElNRV9GQUlMVVJFX0tJTkRfSU5URUdSSVRZEAMSJAogUlVOVElNRV9GQUlMVVJFX0tJTkRfVU5TVVBQT1JURUQQBCqnAwoYUnVudGltZVVuYXZhaWxhYmxlUmVhc29uEioKJlJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1VOU1BFQ0lGSUVEEAASMgouUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fUkVNT1RFX09OTFlfT0ZGTElORRABEjEKLVJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1JFTU9URV9VTlJFQUNIQUJMRRACEi0KKVJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1JFTU9URV9USU1FT1VUEAMSNgoyUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fTE9DQUxfUkVQTElDQV9OT1RfUkVBRFkQBBI1CjFSVU5USU1FX1VOQVZBSUxBQkxFX1JFQVNPTl9DUkVERU5USUFMX1VOQVZBSUxBQkxFEAUSMAosUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fV09SS1NQQUNFX09QRU5JTkcQBhIoCiRSVU5USU1FX1VOQVZBSUxBQkxFX1JFQVNPTl9QRUVSX0JVU1kQByrwAQoUUnVudGltZVJlZnVzYWxSZWFzb24SJgoiUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9VTlNQRUNJRklFRBAAEi0KKVJVTlRJTUVfUkVGVVNBTF9SRUFTT05fSU5WQUxJRF9DUkVERU5USUFMEAESKAokUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9BQ0NFU1NfREVOSUVEEAISKwonUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9QTEFDRU1FTlRfUE9MSUNZEAMSKgomUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9TRVNTSU9OX1VOQk9VTkQQBCrCBAoWRm9sbG93T2JzZXJ2YXRpb25QaGFzZRIoCiRGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfVU5TUEVDSUZJRUQQABIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfREVTSVJFRBABEiAKHEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9EVUUQAhIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfUlVOTklORxADEiQKIEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9TRVRUTEVEEAQSMAosRk9MTE9XX09CU0VSVkFUSU9OX1BIQVNFX0FXQUlUSU5HX0RFUEVOREVOQ1kQBRIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfT0ZGTElORRAGEi8KK0ZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9JTlZBTElEX0NSRURFTlRJQUwQBxIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfQkFDS09GRhAIEiwKKEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9SRUJPUk5fUkVNT1RFTFkQCRIsCihGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfUkVQTEFDSU5HX0xPQ0FMEAoSMgouRk9MTE9XX09CU0VSVkFUSU9OX1BIQVNFX0xPQ0FMX0NPUFlfVU5SRUFEQUJMRRALEisKJ0ZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9LRVJORUxfUkVGVVNFRBAMKlcKCkxpbmtTdGF0dXMSGwoXTElOS19TVEFUVVNfVU5TUEVDSUZJRUQQABIUChBMSU5LX1NUQVRVU19PUEVOEAESFgoSTElOS19TVEFUVVNfQ0xPU0VEEAIqdgoMVHJhbnNmZXJLaW5kEh0KGVRSQU5TRkVSX0tJTkRfVU5TUEVDSUZJRUQQABIXChNUUkFOU0ZFUl9LSU5EX0RFTFRBEAESFgoSVFJBTlNGRVJfS0lORF9GVUxMEAISFgoSVFJBTlNGRVJfS0lORF9QVVNIEANiBnByb3RvMw", [file_google_protobuf_any, file_nomos_kernel_v1_kernel, file_nomos_kernel_v1_progress, file_nomos_runtime_v2_correspondence_desk, file_nomos_runtime_v2_custody_desk, file_nomos_runtime_v2_placement_desk, file_nomos_runtime_v2_maintenance_desk, file_nomos_runtime_v2_model_adoption_desk, file_nomos_runtime_v2_receiving_group_desk, file_nomos_runtime_v2_recovery_desk]);
6021
6023
  var RuntimeFailureSchema = /* @__PURE__ */ messageDesc(file_nomos_runtime_v2_observability_desk, 1);
6022
6024
  var RuntimeUnavailableSchema = /* @__PURE__ */ messageDesc(file_nomos_runtime_v2_observability_desk, 2);
6023
6025
  var RuntimeRefusalSchema = /* @__PURE__ */ messageDesc(file_nomos_runtime_v2_observability_desk, 3);
@@ -8032,6 +8034,11 @@ var kernelReadinessPending = (message) => {
8032
8034
  if (!READINESS_DEBT.test(message)) return void 0;
8033
8035
  return new KernelReadinessPending(/source workspace '([^']+)'/.exec(message)?.[1]?.trim(), message);
8034
8036
  };
8037
+ var READ_INDEX_BUILDING = /the read index of (.+?) is (?:being built \(\d+ of \d+ documents\)|built \(\d+ documents\) and is being bound); read maintenance (?:continues|finishes) it/;
8038
+ var kernelReadIndexBuilding = (message) => {
8039
+ const workspace = READ_INDEX_BUILDING.exec(message)?.[1]?.trim();
8040
+ return workspace === void 0 ? void 0 : { workspace };
8041
+ };
8035
8042
  var requiredForeignWorkspace = (message) => {
8036
8043
  const patterns = [
8037
8044
  /workspace '([^']+)' must be resident in the kernel/,
@@ -8055,9 +8062,31 @@ function throwIfKernelControlRequired(failure) {
8055
8062
  throw new KernelWorkspaceResidencyRequired(workspace, failure.message);
8056
8063
  }
8057
8064
  }
8065
+ var KernelRefusal = class extends Error {
8066
+ code;
8067
+ failure;
8068
+ constructor(failure) {
8069
+ super(`${failure.code}: ${failure.message}`);
8070
+ this.name = "KernelRefusal";
8071
+ this.code = failure.code;
8072
+ this.failure = failure;
8073
+ }
8074
+ };
8058
8075
  function throwKernelFailure(failure) {
8059
8076
  throwIfKernelControlRequired(failure);
8060
- throw new Error(`${failure.code}: ${failure.message}`);
8077
+ throw new KernelRefusal(failure);
8078
+ }
8079
+ var KERNEL_FAILURE_TEXT = /^(NMS-[A-Z0-9]+(?:-[A-Z0-9]+)*): ([\s\S]*)$/;
8080
+ var ENVIRONMENTAL = /NMS-KERNEL-TRAP|\btrap\b|unreachable|out of bounds|out of memory|memory allocation|\block\b|File exists|No such file|os error|I\/O|Permission denied|No space|\bE(?:EXIST|NOENT|ACCES|NOSPC|IO|AGAIN|BUSY)\b/i;
8081
+ function deterministicKernelRefusal(error) {
8082
+ if (error instanceof KernelWorkspaceResidencyRequired || error instanceof KernelHistoryRequired || error instanceof KernelReadinessPending) return void 0;
8083
+ if (error instanceof KernelRefusal && (error.failure.historyRequired !== void 0 || error.failure.identityProviderWitnessRequired !== void 0)) return void 0;
8084
+ const text = error instanceof Error ? error.message : typeof error === "string" ? error : "";
8085
+ const match = KERNEL_FAILURE_TEXT.exec(text);
8086
+ if (!match) return void 0;
8087
+ const [, code, message] = match;
8088
+ if (ENVIRONMENTAL.test(text) || READINESS_DEBT.test(message) || requiredForeignWorkspace(message) !== void 0) return void 0;
8089
+ return { code, message };
8061
8090
  }
8062
8091
  function rethrowTypedKernelFailure(error) {
8063
8092
  if (error instanceof KernelWorkspaceResidencyRequired || error instanceof KernelHistoryRequired) throw error;
@@ -14096,8 +14125,9 @@ function memoryCheckpointStaging() {
14096
14125
 
14097
14126
  // ../src/runtime/live_inbound_stream.ts
14098
14127
  var LEVEL_BATCH = "level:";
14128
+ var HISTORY_REQUIRED = "nomos.stream.history_required";
14129
+ var CONTAINMENT_ASK_SUFFIX = ":contain";
14099
14130
  var STREAM_WINDOW_CHUNKS = 8;
14100
- var ASK_AGAIN_NANOS = 15000000000n;
14101
14131
  var historySlot = (workspace) => `${workspace}#history`;
14102
14132
  var LiveInboundStream = class {
14103
14133
  #ports;
@@ -14115,7 +14145,10 @@ var LiveInboundStream = class {
14115
14145
  }
14116
14146
  return inbound;
14117
14147
  }
14118
- /** When this workspace's stream last delivered anything (a waiting procedure is progressing). */
14148
+ /** When this workspace's stream last delivered data to an ask (a waiting procedure is progressing).
14149
+ * A refusal, a frontier, unrelated traffic on the socket and this copy's own re-asking are not
14150
+ * progress: a procedure whose stream only ever says "ask again" gives up and its round fails over
14151
+ * (CAP-838). */
14119
14152
  lastHeard(workspace) {
14120
14153
  return this.#by.get(workspace)?.lastHeard;
14121
14154
  }
@@ -14138,7 +14171,8 @@ var LiveInboundStream = class {
14138
14171
  inbound.wants.level = {
14139
14172
  effectId: effect.effectId,
14140
14173
  maxOffers: Math.max(1, request.value.maxOffers),
14141
- remountAfterOffers: request.value.remountAfterOffers
14174
+ remountAfterOffers: request.value.remountAfterOffers,
14175
+ contain: effect.effectId.endsWith(CONTAINMENT_ASK_SUFFIX)
14142
14176
  };
14143
14177
  this.#askLevel(effect.workspace, inbound);
14144
14178
  }
@@ -14198,7 +14232,7 @@ var LiveInboundStream = class {
14198
14232
  const batch = inbound.levelBatch;
14199
14233
  if (batch) {
14200
14234
  inbound.levelBatch = void 0;
14201
- if (batch.base === this.#ports.head(effect.workspace)) {
14235
+ if (batch.base === this.#ports.head(effect.workspace) || batch.base === request.value.head) {
14202
14236
  inbound.wants.level = void 0;
14203
14237
  return create(PeerStreamReceiptSchema, {
14204
14238
  outcome: { case: "pack", value: batch },
@@ -14209,14 +14243,14 @@ var LiveInboundStream = class {
14209
14243
  this.#askLevel(effect.workspace, inbound);
14210
14244
  }
14211
14245
  const head = this.#ports.head(effect.workspace);
14212
- if (head && inbound.announced && head === inbound.announced) {
14246
+ if (inbound.announced && (head === inbound.announced || inbound.askedFrom === inbound.announced)) {
14213
14247
  inbound.wants.level = void 0;
14214
14248
  return create(PeerStreamReceiptSchema, {
14215
- outcome: { case: "level", value: head },
14249
+ outcome: { case: "level", value: inbound.announced },
14216
14250
  ...inbound.sealed ? { sealed: inbound.sealed } : {}
14217
14251
  });
14218
14252
  }
14219
- return this.#refusalReceipt(inbound);
14253
+ return this.#refusalReceipt(inbound, inbound.wants.level?.effectId === effect.effectId && inbound.wants.level.contain);
14220
14254
  }
14221
14255
  if (request.case === "history" || request.case === "ref") {
14222
14256
  const want = inbound.wants.packs.get(request.value.requestId);
@@ -14231,10 +14265,16 @@ var LiveInboundStream = class {
14231
14265
  return void 0;
14232
14266
  }
14233
14267
  /** A terminal refusal (not one that only says when to ask again) ends the procedure's wait. */
14234
- #refusalReceipt(inbound) {
14268
+ #refusalReceipt(inbound, contain = false) {
14235
14269
  const refused = inbound.refused;
14236
- if (!refused || refused.retryAfterMillis !== void 0) return void 0;
14270
+ if (!refused) return void 0;
14271
+ const answersContainment = contain && refused.code === HISTORY_REQUIRED;
14272
+ if (refused.retryAfterMillis !== void 0 && !answersContainment) return void 0;
14237
14273
  inbound.refused = void 0;
14274
+ if (answersContainment) {
14275
+ inbound.askAgainAt = void 0;
14276
+ inbound.wants.level = void 0;
14277
+ }
14238
14278
  return create(PeerStreamReceiptSchema, { outcome: { case: "refusal", value: refused } });
14239
14279
  }
14240
14280
  /** The procedure gave up (it timed out, or its work ended). */
@@ -14265,7 +14305,9 @@ var LiveInboundStream = class {
14265
14305
  /** One frame from the peer. True when it was the stream's (the live desk handles the rest). */
14266
14306
  frame(workspace, message) {
14267
14307
  const inbound = this.#of(workspace);
14268
- inbound.lastHeard = this.#ports.monotonicNanoseconds();
14308
+ if (message.case === "checkpointOffer" || message.case === "checkpointChunk" || message.case === "pack") {
14309
+ inbound.lastHeard = this.#ports.monotonicNanoseconds();
14310
+ }
14269
14311
  switch (message.case) {
14270
14312
  case "frontier":
14271
14313
  if (message.value.response && message.value.head) {
@@ -14320,18 +14362,26 @@ var LiveInboundStream = class {
14320
14362
  return false;
14321
14363
  }
14322
14364
  }
14323
- /** Re-ask what is due: a refusal's retry time passed, or an ask heard nothing for too long. */
14365
+ /**
14366
+ * Ask again when a refusal said when to (the peer was opening, or acquiring history). Nothing else
14367
+ * here runs on a timer (CAP-838): the socket is ordered and reliable, every ask is answered on it,
14368
+ * and an ask is re-sent only when its socket re-opens (`opened`) or its refusal's time comes. The
14369
+ * stream used to re-ask whatever had heard nothing for 15 s, and that resend - itself counted as
14370
+ * hearing - hid an ask answered "come back" for ever.
14371
+ */
14324
14372
  drive(workspace) {
14325
14373
  const inbound = this.#by.get(workspace);
14326
- if (!inbound || !this.wanted(workspace)) return void 0;
14374
+ if (!inbound || inbound.askAgainAt === void 0) return void 0;
14375
+ if (!this.wanted(workspace)) {
14376
+ inbound.askAgainAt = void 0;
14377
+ return void 0;
14378
+ }
14327
14379
  const now2 = this.#ports.monotonicNanoseconds();
14328
- const due2 = inbound.askAgainAt ?? inbound.lastHeard + ASK_AGAIN_NANOS;
14329
- if (now2 < due2) return due2 - now2;
14380
+ if (now2 < inbound.askAgainAt) return inbound.askAgainAt - now2;
14330
14381
  inbound.askAgainAt = void 0;
14331
14382
  inbound.refused = void 0;
14332
- inbound.lastHeard = now2;
14333
14383
  this.opened(workspace);
14334
- return ASK_AGAIN_NANOS;
14384
+ return void 0;
14335
14385
  }
14336
14386
  #offered(workspace, inbound, offer) {
14337
14387
  inbound.refused = void 0;
@@ -14374,6 +14424,7 @@ var LiveInboundStream = class {
14374
14424
  const held = !taken ? -1 : "pack" in taken ? taken.pack.byteLength : taken.bytes;
14375
14425
  if (held !== transfer.bytes || transfer.received !== transfer.bytes) {
14376
14426
  if (taken && "stagedPackFile" in taken) this.#staging.clear(workspace);
14427
+ if (inbound.wants.checkpoint) this.#askCheckpoint(workspace, inbound);
14377
14428
  return;
14378
14429
  }
14379
14430
  inbound.complete = {
@@ -14491,8 +14542,12 @@ var LiveInboundStream = class {
14491
14542
  this.#askCheckpoint(workspace, inbound);
14492
14543
  return;
14493
14544
  }
14545
+ inbound.announced = void 0;
14546
+ inbound.sealed = void 0;
14547
+ const head = this.#ports.head(workspace) ?? "";
14548
+ inbound.askedFrom = head;
14494
14549
  this.#ports.send(workspace, { case: "frontier", value: create(LiveFrontierSchema, {
14495
- head: this.#ports.head(workspace) ?? "",
14550
+ head,
14496
14551
  response: false,
14497
14552
  maxOffers: level.maxOffers,
14498
14553
  remountAfterOffers: level.remountAfterOffers,
@@ -15011,6 +15066,24 @@ function placementMovedBy(request, response) {
15011
15066
  return void 0;
15012
15067
  }
15013
15068
  var PLACEMENT_REFERENCE = "refs/nomos/placement";
15069
+ function readIndexPendingAnswer(request, message) {
15070
+ if (request.operation.case !== "query" || request.operation.value.query.case === "maintenanceQuantum") return void 0;
15071
+ const building = kernelReadIndexBuilding(message);
15072
+ if (building === void 0) return void 0;
15073
+ const target3 = request.operation.value.target;
15074
+ return create(CallResponseSchema, {
15075
+ protocolVersion: request.protocolVersion,
15076
+ requestId: request.requestId,
15077
+ outcome: { case: "query", value: create(QueryResponseSchema, {
15078
+ result: { case: "readIndexPending", value: create(ReadIndexPendingSchema, {
15079
+ workspace: target3?.workspace || building.workspace,
15080
+ branch: target3?.branch ?? "",
15081
+ // The sliced build names no frontier: it restarts at whatever head main holds when it continues.
15082
+ requestedFrontier: ""
15083
+ }) }
15084
+ }) }
15085
+ });
15086
+ }
15014
15087
  var KernelPort = class {
15015
15088
  #kernel;
15016
15089
  #activeOperation;
@@ -16035,6 +16108,8 @@ var KernelPort = class {
16035
16108
  const nested = request.operation.case === "custody" ? request.operation.value.operation.case ?? "empty" : request.operation.case === "query" ? request.operation.value.query.case === "named" ? `named:${request.operation.value.query.value.operation}` : request.operation.value.query.case ?? "empty" : "";
16036
16109
  error.message = `kernel-operation=${top}/${nested}: ${error.message}`;
16037
16110
  }
16111
+ const pending = readIndexPendingAnswer(request, error instanceof Error ? error.message : String(error));
16112
+ if (pending !== void 0) return pending;
16038
16113
  rethrowTypedKernelFailure(error);
16039
16114
  }
16040
16115
  if (response.requestId !== request.requestId) {
@@ -16045,6 +16120,9 @@ var KernelPort = class {
16045
16120
  this.#residency.after(request, response);
16046
16121
  const placementMoved = placementMovedBy(request, response);
16047
16122
  if (placementMoved !== void 0) this.#onPlacementMoved(placementMoved);
16123
+ if (response.outcome.case === "failure") {
16124
+ return readIndexPendingAnswer(request, response.outcome.value.message) ?? response;
16125
+ }
16048
16126
  return response;
16049
16127
  }
16050
16128
  /** [#call] with the opt-in timeline trace: encode, kernel and decode timed separately. */
@@ -22674,6 +22752,7 @@ var ReadMaintenanceDesk = class {
22674
22752
  for (const [key, value] of entries.filter(([key2]) => key2 !== workspace)) this.#pending.set(key, value);
22675
22753
  }
22676
22754
  this.#revision += 1;
22755
+ if (read && (!existing?.read || isReadDemand)) this.#observer.readinessMayChange?.(workspace);
22677
22756
  if (!existing || existing.read?.cause !== read?.cause || existing.background?.cause !== background?.cause) {
22678
22757
  this.#trace.emit(session ?? existing?.session, {
22679
22758
  case: "maintenanceProgress",
@@ -22690,32 +22769,65 @@ var ReadMaintenanceDesk = class {
22690
22769
  * (a waiting read's own turn advances read readiness only).
22691
22770
  */
22692
22771
  tick(request, sessionlessNotBeforeNanoseconds = 0n, backgroundNotBeforeNanoseconds = 0n, durability = true) {
22772
+ const turn = this.#turn(
22773
+ request,
22774
+ sessionlessNotBeforeNanoseconds,
22775
+ { case: "until", atNanoseconds: backgroundNotBeforeNanoseconds },
22776
+ durability
22777
+ );
22778
+ return turn.case === "ran" ? turn.ticked : create(MaintenanceTickedSchema, {
22779
+ pending: turn.pending,
22780
+ nextTickAfterMillis: turn.nextDelayMillis ?? 0
22781
+ });
22782
+ }
22783
+ /**
22784
+ * A waiting read's turn: advance read readiness only. It never runs a background command, closure
22785
+ * warm, pack import or durability flush on the foreground's turn, and never reports a wake for
22786
+ * that background work: with only background work owed its wake is `none`.
22787
+ */
22788
+ tickReadReadiness() {
22789
+ const turn = this.#turn(void 0, 0n, { case: "readReadinessOnly" }, false);
22790
+ if (turn.case === "ran") {
22791
+ return { ticked: turn.ticked, wake: { case: "after", millis: turn.ticked.nextTickAfterMillis } };
22792
+ }
22793
+ return {
22794
+ ticked: create(MaintenanceTickedSchema, { pending: turn.pending, nextTickAfterMillis: turn.nextDelayMillis ?? 0 }),
22795
+ wake: turn.nextDelayMillis === void 0 ? { case: "none" } : { case: "after", millis: turn.nextDelayMillis }
22796
+ };
22797
+ }
22798
+ #turn(request, sessionlessNotBeforeNanoseconds, backgroundHold, durability) {
22693
22799
  const now2 = this.#clock.monotonicNanoseconds();
22800
+ const backgroundNotBeforeNanoseconds = backgroundHold.case === "until" ? backgroundHold.atNanoseconds : void 0;
22694
22801
  const custodySlice = (workspace2) => this.#custodyBurstSlice(now2, workspace2);
22695
22802
  const due2 = (demand2) => {
22696
22803
  const held = demand2.session || demand2.awaited || demand2.retryNotBeforeNanoseconds > sessionlessNotBeforeNanoseconds ? demand2.retryNotBeforeNanoseconds : sessionlessNotBeforeNanoseconds;
22697
- const ordinary = demand2.read || demand2.awaited || held > backgroundNotBeforeNanoseconds ? held : backgroundNotBeforeNanoseconds;
22804
+ if (!demand2.read && !demand2.awaited && backgroundNotBeforeNanoseconds === void 0) return void 0;
22805
+ const ordinary = demand2.read || demand2.awaited || backgroundNotBeforeNanoseconds === void 0 || held > backgroundNotBeforeNanoseconds ? held : backgroundNotBeforeNanoseconds;
22698
22806
  const hold = demand2.read || demand2.awaited || !demand2.background?.maintainGitCustody ? void 0 : custodySlice(demand2.workspace);
22699
22807
  if (!hold) return ordinary;
22700
22808
  if (hold.slice && durability) return held > hold.at ? held : hold.at;
22701
22809
  return ordinary > hold.at ? ordinary : hold.at;
22702
22810
  };
22703
- const entry = [...this.#pending.entries()].find(([, demand2]) => due2(demand2) <= now2);
22811
+ const entry = [...this.#pending.entries()].find(([, demand2]) => {
22812
+ const at = due2(demand2);
22813
+ return at !== void 0 && at <= now2;
22814
+ });
22704
22815
  const flush = this.#flush;
22705
22816
  if (durability && flush && this.#flushDueAt(flush) <= now2 && !entry?.[1].read && (flush.local || !entry || flush.owedSinceNanoseconds + DURABILITY_FLUSH_MAX_DELAY_NANOSECONDS <= now2)) {
22706
- return this.#tickFlush(flush, request);
22817
+ return { case: "ran", ticked: this.#tickFlush(flush, request) };
22707
22818
  }
22708
22819
  const pinDue = (pin) => {
22820
+ if (backgroundNotBeforeNanoseconds === void 0) return void 0;
22709
22821
  const held = pin.session ? 0n : sessionlessNotBeforeNanoseconds;
22710
22822
  return [pin.notBeforeNanoseconds, held, backgroundNotBeforeNanoseconds].reduce((latest, at) => at > latest ? at : latest, 0n);
22711
22823
  };
22712
22824
  if (!entry) {
22713
- const pin = [...this.#pins.entries()].find(([, idle]) => pinDue(idle) <= now2);
22714
- if (pin) return this.#tickPin(pin[0], pin[1], request);
22715
- return create(MaintenanceTickedSchema, {
22716
- pending: this.hasPending(),
22717
- nextTickAfterMillis: this.#nextDelay(now2, due2, pinDue)
22825
+ const pin = [...this.#pins.entries()].find(([, idle]) => {
22826
+ const at = pinDue(idle);
22827
+ return at !== void 0 && at <= now2;
22718
22828
  });
22829
+ if (pin) return { case: "ran", ticked: this.#tickPin(pin[0], pin[1], request) };
22830
+ return { case: "idle", pending: this.hasPending(), nextDelayMillis: this.#nextDelay(now2, due2, pinDue, durability) };
22719
22831
  }
22720
22832
  const [workspace, demand] = entry;
22721
22833
  const mount = demand.session ? this.#sessions.mountForSession(demand.session) : this.#sessions.mountForWorkspace(workspace);
@@ -22764,7 +22876,7 @@ var ReadMaintenanceDesk = class {
22764
22876
  read: read !== void 0,
22765
22877
  awaited: demand.awaited === true,
22766
22878
  session: demand.session !== void 0,
22767
- backgroundHoldMs: Number((backgroundNotBeforeNanoseconds - now2) / 1000000n),
22879
+ backgroundHoldMs: backgroundNotBeforeNanoseconds === void 0 ? "read-readiness-only" : Number((backgroundNotBeforeNanoseconds - now2) / 1000000n),
22768
22880
  sessionlessHoldMs: Number((sessionlessNotBeforeNanoseconds - now2) / 1000000n),
22769
22881
  caller: (new Error().stack ?? "").split("\n").slice(2, 6).map((frame2) => frame2.trim()).join(" < ")
22770
22882
  })}`);
@@ -22813,12 +22925,13 @@ var ReadMaintenanceDesk = class {
22813
22925
  this.#observer.frontierAdvanced?.(workspace);
22814
22926
  }
22815
22927
  }
22816
- return create(MaintenanceTickedSchema, {
22928
+ this.#observer.readinessMayChange?.(workspace);
22929
+ return { case: "ran", ticked: create(MaintenanceTickedSchema, {
22817
22930
  pending: this.#pending.size > 0,
22818
22931
  progress: observed,
22819
22932
  // With no debt left, an armed idle pin names when the host should wake next.
22820
- nextTickAfterMillis: progress.maintenancePending ? 20 : this.#pending.size === 0 && this.hasIdleWork() ? this.#nextDelay(this.#clock.monotonicNanoseconds()) : 0
22821
- });
22933
+ nextTickAfterMillis: progress.maintenancePending ? 20 : this.#pending.size === 0 && this.hasIdleWork() ? this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0 : 0
22934
+ }) };
22822
22935
  } catch (error) {
22823
22936
  const format = localCopyFormatRefusal(error);
22824
22937
  if (format !== void 0) {
@@ -22834,10 +22947,10 @@ var ReadMaintenanceDesk = class {
22834
22947
  stopped: true
22835
22948
  })
22836
22949
  });
22837
- return create(MaintenanceTickedSchema, {
22950
+ return { case: "ran", ticked: create(MaintenanceTickedSchema, {
22838
22951
  pending: this.#pending.size > 0,
22839
- nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds())
22840
- });
22952
+ nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
22953
+ }) };
22841
22954
  }
22842
22955
  const failures = demand.failures + 1;
22843
22956
  this.#pending.delete(workspace);
@@ -22865,12 +22978,12 @@ var ReadMaintenanceDesk = class {
22865
22978
  retryAfterMillis: retryMillis
22866
22979
  })
22867
22980
  });
22868
- return create(MaintenanceTickedSchema, {
22981
+ return { case: "ran", ticked: create(MaintenanceTickedSchema, {
22869
22982
  pending: true,
22870
22983
  // Backoff belongs to the failed workspace. Another workspace's ready
22871
22984
  // index or changed watches must not wait for this retry deadline.
22872
- nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds())
22873
- });
22985
+ nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
22986
+ }) };
22874
22987
  }
22875
22988
  }
22876
22989
  /** Owe the kernel its ordered flush. The first write it covers fixes `owedSince`; the shared
@@ -22935,7 +23048,7 @@ var ReadMaintenanceDesk = class {
22935
23048
  }
22936
23049
  return create(MaintenanceTickedSchema, {
22937
23050
  pending: this.hasPending(),
22938
- nextTickAfterMillis: progress.maintenancePending ? 20 : this.#nextDelay(this.#clock.monotonicNanoseconds())
23051
+ nextTickAfterMillis: progress.maintenancePending ? 20 : this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
22939
23052
  });
22940
23053
  } catch (error) {
22941
23054
  const failures = flush.failures + 1;
@@ -22959,7 +23072,7 @@ var ReadMaintenanceDesk = class {
22959
23072
  };
22960
23073
  return create(MaintenanceTickedSchema, {
22961
23074
  pending: this.hasPending(),
22962
- nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds())
23075
+ nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
22963
23076
  });
22964
23077
  }
22965
23078
  }
@@ -22990,7 +23103,7 @@ var ReadMaintenanceDesk = class {
22990
23103
  }
22991
23104
  return create(MaintenanceTickedSchema, {
22992
23105
  pending: this.hasPending(),
22993
- nextTickAfterMillis: progress.maintenancePending ? 20 : this.#nextDelay(this.#clock.monotonicNanoseconds())
23106
+ nextTickAfterMillis: progress.maintenancePending ? 20 : this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
22994
23107
  });
22995
23108
  } catch (error) {
22996
23109
  slowQuantumObserver?.(`[nomos-kernel-perf] ${JSON.stringify({
@@ -23002,28 +23115,31 @@ var ReadMaintenanceDesk = class {
23002
23115
  })}`);
23003
23116
  return create(MaintenanceTickedSchema, {
23004
23117
  pending: this.hasPending(),
23005
- nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds())
23118
+ nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
23006
23119
  });
23007
23120
  }
23008
23121
  }
23009
- #nextDelay(now2, due2 = (demand) => demand.retryNotBeforeNanoseconds, pinDue = (pin) => pin.notBeforeNanoseconds) {
23122
+ /** Milliseconds until the earliest owed work this turn serves; `undefined` when none is owed. */
23123
+ #nextDelay(now2, due2 = (demand) => demand.retryNotBeforeNanoseconds, pinDue = (pin) => pin.notBeforeNanoseconds, flushes = true) {
23010
23124
  let earliest;
23011
23125
  for (const demand of this.#pending.values()) {
23012
23126
  const at = due2(demand);
23127
+ if (at === void 0) continue;
23013
23128
  if (at <= now2) return 0;
23014
23129
  if (earliest === void 0 || at < earliest) earliest = at;
23015
23130
  }
23016
23131
  for (const pin of this.#pins.values()) {
23017
23132
  const at = pinDue(pin);
23133
+ if (at === void 0) continue;
23018
23134
  if (at <= now2) return 0;
23019
23135
  if (earliest === void 0 || at < earliest) earliest = at;
23020
23136
  }
23021
- if (this.#flush) {
23137
+ if (flushes && this.#flush) {
23022
23138
  const at = this.#flushDueAt(this.#flush);
23023
23139
  if (at <= now2) return 0;
23024
23140
  if (earliest === void 0 || at < earliest) earliest = at;
23025
23141
  }
23026
- return earliest === void 0 ? 0 : Number((earliest - now2 + 999999n) / 1000000n);
23142
+ return earliest === void 0 ? void 0 : Number((earliest - now2 + 999999n) / 1000000n);
23027
23143
  }
23028
23144
  /** Drop any demand for a workspace no maintenance can serve (an unreadable copy). */
23029
23145
  forget(workspace) {
@@ -23064,15 +23180,19 @@ var ReadMaintenanceDesk = class {
23064
23180
 
23065
23181
  // ../src/runtime/read_response_desk.ts
23066
23182
  init_define_NOMOS_KERNEL_RELEASE();
23183
+ var READ_RETENTION_MILLIS = 12e4;
23184
+ var READ_RESUME_MAX_MILLIS = 1e3;
23067
23185
  var ReadResponseDesk = class {
23068
23186
  #waiting = /* @__PURE__ */ new Map();
23069
23187
  #clock;
23070
23188
  #tick;
23189
+ #owe;
23071
23190
  #read;
23072
23191
  #sequence = 0;
23073
- constructor(clock2, tick, read) {
23192
+ constructor(clock2, tick, owe, read) {
23074
23193
  this.#clock = clock2;
23075
23194
  this.#tick = tick;
23195
+ this.#owe = owe;
23076
23196
  this.#read = read;
23077
23197
  }
23078
23198
  #now() {
@@ -23085,18 +23205,27 @@ var ReadResponseDesk = class {
23085
23205
  const now2 = this.#now();
23086
23206
  for (const [id, work] of this.#waiting) if (work.deadline <= now2) this.#waiting.delete(id);
23087
23207
  const workId2 = `local-read-${++this.#sequence}`;
23088
- this.#waiting.set(workId2, { request, dependency, deadline: now2 + 12e4, notBefore: now2 });
23208
+ this.#waiting.set(workId2, {
23209
+ request,
23210
+ dependency,
23211
+ deadline: now2 + READ_RETENTION_MILLIS,
23212
+ notBefore: now2,
23213
+ idle: false,
23214
+ // The office owed this frontier's debt when the kernel first answered pending.
23215
+ owedFor: dependency.requestedFrontier,
23216
+ waiters: /* @__PURE__ */ new Set()
23217
+ });
23089
23218
  return create(LocalReadPendingSchema, { workId: workId2 });
23090
23219
  }
23091
23220
  resume(workId2, requestId) {
23092
23221
  const work = this.#waiting.get(workId2);
23093
23222
  if (!work || work.request.requestId !== requestId) throw new Error(`unknown local read continuation '${workId2}'`);
23094
23223
  const now2 = this.#now();
23224
+ work.waiters.clear();
23095
23225
  if (now2 >= work.deadline) {
23096
23226
  this.#waiting.delete(workId2);
23097
23227
  throw new Error(`Local read index for '${work.dependency.workspace}' did not catch up to ${work.dependency.requestedFrontier} within its retained maintenance window`);
23098
23228
  }
23099
- if (now2 < work.notBefore) return this.#pending(workId2, work, now2);
23100
23229
  try {
23101
23230
  const response = this.#read(work.request);
23102
23231
  if (response.outcome.case !== "query" || response.outcome.value.result.case !== "readIndexPending") {
@@ -23104,24 +23233,65 @@ var ReadResponseDesk = class {
23104
23233
  return { case: "ready", request: work.request, response };
23105
23234
  }
23106
23235
  work.dependency = response.outcome.value.result.value;
23107
- const tick = this.#tick();
23236
+ if (now2 < work.notBefore) return this.#pending(workId2, work, now2);
23237
+ let { ticked, wake } = this.#tick();
23238
+ if (wake.case === "none" && ticked.progress === void 0 && work.owedFor !== work.dependency.requestedFrontier) {
23239
+ work.owedFor = work.dependency.requestedFrontier;
23240
+ this.#owe(work.request);
23241
+ ({ ticked, wake } = this.#tick());
23242
+ }
23108
23243
  const afterTick = this.#now();
23109
- work.notBefore = afterTick + tick.nextTickAfterMillis;
23110
- work.deadline = afterTick + Math.max(12e4, tick.nextTickAfterMillis + 6e4);
23244
+ work.idle = wake.case === "none";
23245
+ const backoff = wake.case === "after" ? wake.millis : 0;
23246
+ work.notBefore = afterTick + backoff;
23247
+ work.deadline = afterTick + Math.max(READ_RETENTION_MILLIS, backoff + 6e4);
23111
23248
  return this.#pending(workId2, work, afterTick);
23112
23249
  } catch (error) {
23113
23250
  this.#waiting.delete(workId2);
23114
23251
  throw error;
23115
23252
  }
23116
23253
  }
23254
+ /**
23255
+ * Wait in process for a held read to become worth continuing. `notify` is called once, when read
23256
+ * readiness for its workspace changes (a slice or binding finished, a frontier advanced, readiness
23257
+ * newly owed). `afterMillis` is the only timer the shell needs: the read's own scheduled quantum
23258
+ * when it has one, otherwise its deadline. Undefined for an unknown or finished read.
23259
+ */
23260
+ onResumable(workId2, notify) {
23261
+ const work = this.#waiting.get(workId2);
23262
+ if (!work) return void 0;
23263
+ const now2 = this.#now();
23264
+ const due2 = work.idle ? work.deadline : Math.min(work.notBefore, work.deadline);
23265
+ work.waiters.add(notify);
23266
+ return { afterMillis: Math.max(0, due2 - now2), cancel: () => {
23267
+ work.waiters.delete(notify);
23268
+ } };
23269
+ }
23270
+ /** Read readiness for `workspace` changed: every read waiting on it may continue now. */
23271
+ readinessChanged(workspace) {
23272
+ const now2 = this.#now();
23273
+ for (const work of this.#waiting.values()) {
23274
+ if (work.dependency.workspace !== workspace) continue;
23275
+ work.idle = false;
23276
+ if (work.notBefore > now2) work.notBefore = now2;
23277
+ const waiters = [...work.waiters];
23278
+ work.waiters.clear();
23279
+ for (const notify of waiters) notify();
23280
+ }
23281
+ }
23282
+ /** The protocol wake is a bounded re-poll inside the read's retention deadline, never the raw backoff. */
23117
23283
  #pending(workId2, work, now2) {
23284
+ const due2 = work.idle ? READ_RESUME_MAX_MILLIS : work.notBefore - now2;
23285
+ const resumeAfterMillis = Math.max(0, Math.min(due2, work.deadline - now2, READ_RESUME_MAX_MILLIS));
23118
23286
  return { case: "pending", value: create(LocalReadPendingSchema, {
23119
23287
  workId: workId2,
23120
- resumeAfterMillis: Math.max(0, work.notBefore - now2)
23288
+ resumeAfterMillis: Number.isFinite(resumeAfterMillis) ? Math.ceil(resumeAfterMillis) : READ_RESUME_MAX_MILLIS
23121
23289
  }) };
23122
23290
  }
23123
23291
  clear() {
23292
+ const waiters = [...this.#waiting.values()].flatMap((work) => [...work.waiters]);
23124
23293
  this.#waiting.clear();
23294
+ for (const notify of waiters) notify();
23125
23295
  }
23126
23296
  };
23127
23297
 
@@ -24027,13 +24197,15 @@ var ReplicaFollowEventKind = Object.freeze({
24027
24197
  DependencyAdvanced: "dependency_advanced",
24028
24198
  RebornRemotely: "reborn_remotely",
24029
24199
  LocalCopyDropAuthorized: "local_copy_drop_authorized",
24030
- LocalCopyUnreadable: "local_copy_unreadable"
24200
+ LocalCopyUnreadable: "local_copy_unreadable",
24201
+ RuntimeStarted: "runtime_started"
24031
24202
  });
24032
24203
  var ReplicaFollowEffectKind = Object.freeze({
24033
24204
  ScheduleWake: "schedule_wake",
24034
24205
  RunSync: "run_sync",
24035
24206
  RefreshCredential: "refresh_credential"
24036
24207
  });
24208
+ var KERNEL_REFUSAL_EVENT_FLOOR_MILLIS = 1e4;
24037
24209
  var boundedRetry = (policy, attempt) => Math.min(policy.fallbackMillis, Math.max(250, policy.debounceMillis) * 2 ** Math.min(attempt - 1, 20));
24038
24210
  var attempts = (state) => {
24039
24211
  switch (state.case) {
@@ -24060,13 +24232,14 @@ var due = (atUnixMillis) => ({
24060
24232
  state: { case: ReplicaFollowPhase.Due, dueAtUnixMillis: atUnixMillis },
24061
24233
  effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis }]
24062
24234
  });
24063
- var run = (attempt, replaceLocalHead, warmingSinceUnixMillis) => ({
24235
+ var run = (attempt, replaceLocalHead, warmingSinceUnixMillis, refused) => ({
24064
24236
  state: {
24065
24237
  case: ReplicaFollowPhase.Running,
24066
24238
  attempt,
24067
24239
  observed: false,
24068
24240
  ...replaceLocalHead === void 0 ? {} : { replaceLocalHead },
24069
- ...warmingSinceUnixMillis === void 0 ? {} : { warmingSinceUnixMillis }
24241
+ ...warmingSinceUnixMillis === void 0 ? {} : { warmingSinceUnixMillis },
24242
+ ...refused === void 0 ? {} : { refused }
24070
24243
  },
24071
24244
  effects: [{ case: ReplicaFollowEffectKind.RunSync }]
24072
24245
  });
@@ -24075,6 +24248,16 @@ var replacing = (expectedLocalHead, attempt, atUnixMillis) => ({
24075
24248
  effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis }]
24076
24249
  });
24077
24250
  var quiet = (state) => ({ state, effects: [] });
24251
+ var blockedRefusal = (state) => state.case === ReplicaFollowPhase.Backoff && state.refusal?.blocked ? state.refusal : void 0;
24252
+ var refusedEvent = (state, refusal2, nowUnixMillis) => {
24253
+ const earliest = Math.max(nowUnixMillis, refusal2.atUnixMillis + KERNEL_REFUSAL_EVENT_FLOOR_MILLIS);
24254
+ const rerunAtUnixMillis = refusal2.rerunAtUnixMillis === void 0 ? earliest : Math.min(refusal2.rerunAtUnixMillis, earliest);
24255
+ return {
24256
+ state: { ...state, refusal: { ...refusal2, rerunAtUnixMillis } },
24257
+ effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: rerunAtUnixMillis }]
24258
+ };
24259
+ };
24260
+ var refusedByKernel = (state) => state.case === ReplicaFollowPhase.Backoff && (state.refusal !== void 0 || deterministicKernelRefusal(state.failure) !== void 0);
24078
24261
  function reduceReplicaFollow(state, event, policy) {
24079
24262
  switch (event.case) {
24080
24263
  case ReplicaFollowEventKind.Activate:
@@ -24087,6 +24270,9 @@ function reduceReplicaFollow(state, event, policy) {
24087
24270
  if (state.case === ReplicaFollowPhase.Running) {
24088
24271
  return { state: { ...state, observed: true }, effects: [] };
24089
24272
  }
24273
+ if (state.case === ReplicaFollowPhase.Backoff && state.refusal?.blocked) {
24274
+ return refusedEvent(state, state.refusal, event.nowUnixMillis);
24275
+ }
24090
24276
  if (state.case === ReplicaFollowPhase.RebornRemotely || state.case === ReplicaFollowPhase.LocalCopyUnreadable) return quiet(state);
24091
24277
  if (state.case === ReplicaFollowPhase.InvalidCredential) {
24092
24278
  return {
@@ -24096,6 +24282,9 @@ function reduceReplicaFollow(state, event, policy) {
24096
24282
  }
24097
24283
  return due(event.nowUnixMillis);
24098
24284
  case ReplicaFollowEventKind.Reconnected:
24285
+ if (state.case === ReplicaFollowPhase.Backoff && state.refusal?.blocked) {
24286
+ return refusedEvent(state, state.refusal, event.nowUnixMillis);
24287
+ }
24099
24288
  switch (state.case) {
24100
24289
  case ReplicaFollowPhase.Running:
24101
24290
  return { state: { ...state, observed: true }, effects: [] };
@@ -24141,15 +24330,25 @@ function reduceReplicaFollow(state, event, policy) {
24141
24330
  }
24142
24331
  return run(state.attempt + 1, state.expectedLocalHead);
24143
24332
  case ReplicaFollowPhase.Offline:
24144
- case ReplicaFollowPhase.Backoff:
24333
+ case ReplicaFollowPhase.Backoff: {
24334
+ const blocked = blockedRefusal(state);
24335
+ if (blocked) {
24336
+ if (blocked.rerunAtUnixMillis === void 0) return quiet(state);
24337
+ if (event.nowUnixMillis < blocked.rerunAtUnixMillis) {
24338
+ return { state, effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: blocked.rerunAtUnixMillis }] };
24339
+ }
24340
+ return run(state.attempt + 1, void 0, void 0, state.failure);
24341
+ }
24145
24342
  if (event.nowUnixMillis < state.retryAtUnixMillis) {
24146
24343
  return { state, effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: state.retryAtUnixMillis }] };
24147
24344
  }
24148
24345
  return run(
24149
24346
  state.attempt + 1,
24150
24347
  void 0,
24151
- state.case === ReplicaFollowPhase.Backoff ? state.warming?.sinceUnixMillis : void 0
24348
+ state.case === ReplicaFollowPhase.Backoff ? state.warming?.sinceUnixMillis : void 0,
24349
+ state.case === ReplicaFollowPhase.Backoff && state.refusal ? state.failure : void 0
24152
24350
  );
24351
+ }
24153
24352
  case ReplicaFollowPhase.InvalidCredential:
24154
24353
  if (!state.refreshDue && event.nowUnixMillis < state.retryAtUnixMillis) {
24155
24354
  return { state, effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: state.retryAtUnixMillis }] };
@@ -24226,6 +24425,31 @@ function reduceReplicaFollow(state, event, policy) {
24226
24425
  };
24227
24426
  }
24228
24427
  case ReplicaFollowEventKind.Failed: {
24428
+ if (event.refusal && !(state.case === ReplicaFollowPhase.Running && state.replaceLocalHead !== void 0)) {
24429
+ const attempt2 = Math.max(1, attempts(state));
24430
+ const blocked = state.case === ReplicaFollowPhase.Running && state.refused === event.failure || state.case === ReplicaFollowPhase.Backoff && state.refusal !== void 0 && state.failure === event.failure;
24431
+ const refusal2 = {
24432
+ code: event.refusal.code,
24433
+ blocked,
24434
+ runtime: event.refusal.runtime,
24435
+ atUnixMillis: event.nowUnixMillis
24436
+ };
24437
+ if (!blocked) {
24438
+ const retryAtUnixMillis2 = event.nowUnixMillis + boundedRetry(policy, attempt2);
24439
+ return {
24440
+ state: { case: ReplicaFollowPhase.Backoff, attempt: attempt2, retryAtUnixMillis: retryAtUnixMillis2, failure: event.failure, refusal: refusal2 },
24441
+ effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: retryAtUnixMillis2 }]
24442
+ };
24443
+ }
24444
+ const waiting = {
24445
+ case: ReplicaFollowPhase.Backoff,
24446
+ attempt: attempt2,
24447
+ retryAtUnixMillis: event.nowUnixMillis,
24448
+ failure: event.failure,
24449
+ refusal: refusal2
24450
+ };
24451
+ return state.case === ReplicaFollowPhase.Running && state.observed ? refusedEvent(waiting, refusal2, event.nowUnixMillis) : quiet(waiting);
24452
+ }
24229
24453
  if (state.case === ReplicaFollowPhase.Running && state.observed) {
24230
24454
  return due(event.nowUnixMillis);
24231
24455
  }
@@ -24263,6 +24487,11 @@ function reduceReplicaFollow(state, event, policy) {
24263
24487
  return quiet({ case: ReplicaFollowPhase.RebornRemotely, rebirth: event.rebirth });
24264
24488
  case ReplicaFollowEventKind.LocalCopyUnreadable:
24265
24489
  return quiet({ case: ReplicaFollowPhase.LocalCopyUnreadable, format: event.format });
24490
+ case ReplicaFollowEventKind.RuntimeStarted:
24491
+ if (state.case === ReplicaFollowPhase.Backoff && refusedByKernel(state) && state.refusal?.runtime !== event.runtime) {
24492
+ return due(event.nowUnixMillis);
24493
+ }
24494
+ return quiet(state);
24266
24495
  case ReplicaFollowEventKind.LocalCopyDropAuthorized:
24267
24496
  if (state.case === ReplicaFollowPhase.Running) return invalid(state, event);
24268
24497
  return replacing(event.expectedLocalHead, 0, event.nowUnixMillis);
@@ -24309,11 +24538,15 @@ var ReplicaFollowController = class {
24309
24538
  #replicaId;
24310
24539
  /** Local children whose births custody refused (CAP-804): quarantined, never followed. */
24311
24540
  #birthRefusals;
24312
- constructor(desk, clock2, replicaId2, birthRefusals) {
24541
+ /** The kernel/runtime identity this process runs: a refusal is recorded under it, and a refusal
24542
+ * drawn under another identity is retried once when this process starts. */
24543
+ #runtime;
24544
+ constructor(desk, clock2, replicaId2, birthRefusals, runtime = "unidentified") {
24313
24545
  this.#desk = desk;
24314
24546
  this.#clock = clock2;
24315
24547
  this.#replicaId = replicaId2;
24316
24548
  this.#birthRefusals = birthRefusals ?? new BirthRefusalRegister(new MemoryPeerDeskStore());
24549
+ this.#runtime = runtime;
24317
24550
  }
24318
24551
  /** The durable quarantine of a local child whose birth custody refused; undefined otherwise. */
24319
24552
  birthRefusal(workspace) {
@@ -24412,6 +24645,13 @@ var ReplicaFollowController = class {
24412
24645
  recover() {
24413
24646
  const now2 = this.#now();
24414
24647
  if (!this.#recovered) {
24648
+ for (const follow of this.#desk.all()) {
24649
+ this.#desk.transition(follow.spec.workspace, {
24650
+ case: ReplicaFollowEventKind.RuntimeStarted,
24651
+ nowUnixMillis: now2,
24652
+ runtime: this.#runtime
24653
+ });
24654
+ }
24415
24655
  for (const follow of this.#desk.all()) {
24416
24656
  if (follow.state.case === ReplicaFollowPhase.Settled || follow.state.case === ReplicaFollowPhase.AwaitingDependency) {
24417
24657
  this.#placementRecheck.add(follow.spec.workspace);
@@ -24500,11 +24740,12 @@ var ReplicaFollowController = class {
24500
24740
  placementAnnounced(workspace) {
24501
24741
  if (!this.followForWorkspace(workspace)) return void 0;
24502
24742
  this.#placementRecheck.add(workspace);
24503
- return this.reconnected(workspace);
24743
+ return this.reconnected(workspace, true);
24504
24744
  }
24505
- /** The upstream live link opened or reopened: reconcile once for missed pushes. */
24506
- reconnected(workspace) {
24507
- return this.#event(workspace, ReplicaFollowEventKind.Reconnected);
24745
+ /** The upstream live link opened or reopened: reconcile once for missed pushes. With
24746
+ * `remoteAdvanced`, the upstream announced a new frontier. Either re-runs a blocked refusal. */
24747
+ reconnected(workspace, remoteAdvanced = false) {
24748
+ return this.#event(workspace, ReplicaFollowEventKind.Reconnected, remoteAdvanced);
24508
24749
  }
24509
24750
  /** Another workspace advanced or settled; every held dependency gets one retry. */
24510
24751
  dependencyAdvanced(except) {
@@ -24517,11 +24758,11 @@ var ReplicaFollowController = class {
24517
24758
  }
24518
24759
  return woken;
24519
24760
  }
24520
- #event(workspace, kind) {
24761
+ #event(workspace, kind, remoteAdvanced = false) {
24521
24762
  const follow = this.#recovered ? this.#desk.get(workspace) : void 0;
24522
24763
  if (!follow) return void 0;
24523
24764
  const nowUnixMillis = this.#now();
24524
- this.#desk.transition(workspace, { case: kind, nowUnixMillis });
24765
+ this.#desk.transition(workspace, kind === ReplicaFollowEventKind.Reconnected && remoteAdvanced ? { case: kind, nowUnixMillis, remoteAdvanced } : { case: kind, nowUnixMillis });
24525
24766
  const nextDueAt = dueAt(this.#desk.get(workspace));
24526
24767
  return nextDueAt === void 0 ? void 0 : Math.max(0, nextDueAt - nowUnixMillis);
24527
24768
  }
@@ -24668,7 +24909,9 @@ var ReplicaFollowController = class {
24668
24909
  * still opening the workspace and named when to ask again. */
24669
24910
  failed(workspace, error, custodianRetryAfterMillis) {
24670
24911
  if (!this.#recovered) this.recover();
24671
- custodianRetryAfterMillis ??= warmingFromFailureMessage(error instanceof Error ? error.message : String(error));
24912
+ const refusal2 = deterministicKernelRefusal(error);
24913
+ if (refusal2 !== void 0) custodianRetryAfterMillis = void 0;
24914
+ else custodianRetryAfterMillis ??= warmingFromFailureMessage(error instanceof Error ? error.message : String(error));
24672
24915
  if (!this.#desk.get(workspace)) return;
24673
24916
  const format = localCopyFormatRefusal(error);
24674
24917
  if (format !== void 0) {
@@ -24683,9 +24926,15 @@ var ReplicaFollowController = class {
24683
24926
  case: ReplicaFollowEventKind.Failed,
24684
24927
  nowUnixMillis: this.#now(),
24685
24928
  failure: error instanceof Error ? error.message : String(error),
24686
- ...custodianRetryAfterMillis === void 0 ? {} : { custodianRetryAfterMillis }
24929
+ ...custodianRetryAfterMillis === void 0 ? {} : { custodianRetryAfterMillis },
24930
+ ...refusal2 === void 0 ? {} : { refusal: { code: refusal2.code, runtime: this.#runtime } }
24687
24931
  });
24688
24932
  }
24933
+ /** The kernel refusal behind this follow's backoff (`blocked` once the kernel repeated it). */
24934
+ refusal(workspace) {
24935
+ const state = this.followForWorkspace(workspace)?.state;
24936
+ return state?.case === ReplicaFollowPhase.Backoff ? state.refusal : void 0;
24937
+ }
24689
24938
  /** Closing an interaction realm must not erase a peer-owned follow. */
24690
24939
  closeInteractionRealm() {
24691
24940
  }
@@ -24718,9 +24967,12 @@ function dueAt(follow) {
24718
24967
  case ReplicaFollowPhase.RebornRemotely:
24719
24968
  case ReplicaFollowPhase.LocalCopyUnreadable:
24720
24969
  return void 0;
24970
+ case ReplicaFollowPhase.Backoff: {
24971
+ const blocked = blockedRefusal(follow.state);
24972
+ return blocked ? blocked.rerunAtUnixMillis : follow.state.retryAtUnixMillis;
24973
+ }
24721
24974
  case ReplicaFollowPhase.Offline:
24722
24975
  case ReplicaFollowPhase.InvalidCredential:
24723
- case ReplicaFollowPhase.Backoff:
24724
24976
  return follow.state.retryAtUnixMillis;
24725
24977
  default: {
24726
24978
  const exhaustive = follow.state;
@@ -24736,6 +24988,10 @@ function delayUntilDue(follow, nowUnixMillis) {
24736
24988
  return nextDueAt === void 0 ? void 0 : Math.max(0, nextDueAt - nowUnixMillis);
24737
24989
  }
24738
24990
 
24991
+ // ../src/runtime/runtime_identity.ts
24992
+ init_define_NOMOS_KERNEL_RELEASE();
24993
+ var PEER_RUNTIME_IDENTITY = "0.116.4" ? `@githolon/runtime@${"0.116.4"}` : "@githolon/runtime@unbundled";
24994
+
24739
24995
  // ../src/runtime/replica_follow_desk.ts
24740
24996
  init_define_NOMOS_KERNEL_RELEASE();
24741
24997
  var REPLICA_FOLLOW_NAMESPACE = "nomos.peer-desk.replica-follow/v2";
@@ -24764,6 +25020,16 @@ var decodeWarming = (value) => {
24764
25020
  ...Number.isFinite(warming.hintMillis) ? { hintMillis: warming.hintMillis } : {}
24765
25021
  } } : {};
24766
25022
  };
25023
+ var decodeRefusal = (value) => {
25024
+ const refusal2 = value;
25025
+ return refusal2 && typeof refusal2.code === "string" && typeof refusal2.runtime === "string" && Number.isFinite(refusal2.atUnixMillis) ? { refusal: {
25026
+ code: refusal2.code,
25027
+ blocked: refusal2.blocked === true,
25028
+ runtime: refusal2.runtime,
25029
+ atUnixMillis: refusal2.atUnixMillis,
25030
+ ...Number.isFinite(refusal2.rerunAtUnixMillis) ? { rerunAtUnixMillis: refusal2.rerunAtUnixMillis } : {}
25031
+ } } : {};
25032
+ };
24767
25033
  var decodeState = (record, value) => {
24768
25034
  if (!value || typeof value !== "object") throw corrupt(record, "state is not an object");
24769
25035
  const state = value;
@@ -24778,7 +25044,8 @@ var decodeState = (record, value) => {
24778
25044
  attempt: state.attempt,
24779
25045
  observed: state.observed === true,
24780
25046
  ...state.replaceLocalHead === void 0 ? {} : { replaceLocalHead: state.replaceLocalHead },
24781
- ...Number.isFinite(state.warmingSinceUnixMillis) ? { warmingSinceUnixMillis: state.warmingSinceUnixMillis } : {}
25047
+ ...Number.isFinite(state.warmingSinceUnixMillis) ? { warmingSinceUnixMillis: state.warmingSinceUnixMillis } : {},
25048
+ ...typeof state.refused === "string" ? { refused: state.refused } : {}
24782
25049
  };
24783
25050
  case ReplicaFollowPhase.Settled:
24784
25051
  return {
@@ -24810,7 +25077,8 @@ var decodeState = (record, value) => {
24810
25077
  attempt: state.attempt,
24811
25078
  retryAtUnixMillis: state.retryAtUnixMillis,
24812
25079
  failure: state.failure,
24813
- ...decodeWarming(state.warming)
25080
+ ...decodeWarming(state.warming),
25081
+ ...decodeRefusal(state.refusal)
24814
25082
  };
24815
25083
  case ReplicaFollowPhase.RebornRemotely: {
24816
25084
  const rebirth = state.rebirth ?? {};
@@ -25000,9 +25268,15 @@ var ReplicaFollowDesk = class {
25000
25268
  break;
25001
25269
  }
25002
25270
  case ReplicaFollowPhase.Offline:
25003
- case ReplicaFollowPhase.Backoff:
25004
- wakes.push({ workspace: follow.spec.workspace, atUnixMillis: follow.state.retryAtUnixMillis });
25271
+ case ReplicaFollowPhase.Backoff: {
25272
+ const blocked = blockedRefusal(follow.state);
25273
+ if (blocked && blocked.rerunAtUnixMillis === void 0) break;
25274
+ wakes.push({
25275
+ workspace: follow.spec.workspace,
25276
+ atUnixMillis: blocked?.rerunAtUnixMillis ?? follow.state.retryAtUnixMillis
25277
+ });
25005
25278
  break;
25279
+ }
25006
25280
  case ReplicaFollowPhase.InvalidCredential:
25007
25281
  wakes.push({
25008
25282
  workspace: follow.spec.workspace,
@@ -25640,6 +25914,8 @@ var refusal = (requestId, code, message, retryAfterMillis) => frame({ case: "ref
25640
25914
  message,
25641
25915
  ...retryAfterMillis === void 0 ? {} : { retryAfterMillis }
25642
25916
  }) });
25917
+ var OFF_MAIN_AFTER_MILLIS = 6e4;
25918
+ var MAX_UNFOUND_HEADS = 1024;
25643
25919
  var LiveStreamServer = class {
25644
25920
  #kernel;
25645
25921
  #now;
@@ -25653,6 +25929,10 @@ var LiveStreamServer = class {
25653
25929
  /** By workspace: the history slices copies are fetching (a few, newest last). */
25654
25930
  #slices = /* @__PURE__ */ new Map();
25655
25931
  #cachedBytes = 0;
25932
+ /** By workspace and asked head: when this peer first answered "acquiring its own history" to a level
25933
+ * ask from a head it could not find. A shallow custody can never prove the head is off its main (its
25934
+ * walk is never `complete`), so after OFF_MAIN_AFTER_MILLIS of the same answer it says so anyway. */
25935
+ #unfound = /* @__PURE__ */ new Map();
25656
25936
  constructor(kernel, now2 = Date.now, historyWanted = () => {
25657
25937
  }, sealed = () => void 0) {
25658
25938
  this.#kernel = kernel;
@@ -25700,9 +25980,12 @@ var LiveStreamServer = class {
25700
25980
  if (!head) return [...answer, ...this.#checkpoint(workspace, requestId, create(LiveCheckpointRequestSchema))];
25701
25981
  if (head === main) return answer;
25702
25982
  let behind;
25983
+ let offMain = false;
25703
25984
  try {
25704
25985
  const summary = this.#kernel.historySummary(mount, requestId, head, main);
25705
25986
  behind = summary.reachedBase ? summary.commitCount : void 0;
25987
+ offMain = !summary.reachedBase && (summary.complete || !this.#shallow(mount, requestId));
25988
+ if (summary.reachedBase) this.#unfound.delete(`${workspace}\0${head}`);
25706
25989
  } catch {
25707
25990
  behind = void 0;
25708
25991
  }
@@ -25711,6 +25994,22 @@ var LiveStreamServer = class {
25711
25994
  if (remountAfter > 0) {
25712
25995
  return [...answer, ...this.#checkpoint(workspace, requestId, create(LiveCheckpointRequestSchema), behind ?? 0n)];
25713
25996
  }
25997
+ const key = `${workspace}\0${head}`;
25998
+ const firstUnfound = this.#unfound.get(key);
25999
+ if (!offMain && firstUnfound === void 0) {
26000
+ if (this.#unfound.size >= MAX_UNFOUND_HEADS) this.#unfound.delete(this.#unfound.keys().next().value);
26001
+ this.#unfound.set(key, this.#now());
26002
+ } else if (!offMain && this.#now() - firstUnfound >= OFF_MAIN_AFTER_MILLIS) {
26003
+ offMain = true;
26004
+ }
26005
+ if (offMain) {
26006
+ this.#unfound.delete(key);
26007
+ return [...answer, refusal(
26008
+ "",
26009
+ "nomos.stream.off_main",
26010
+ "the copy's head is not on this peer's main; it must converge its own work, not level from it"
26011
+ )];
26012
+ }
25714
26013
  this.#historyWanted(workspace);
25715
26014
  return [...answer, refusal(
25716
26015
  "",
@@ -25722,6 +26021,17 @@ var LiveStreamServer = class {
25722
26021
  const maxOffers = Math.min(Math.max(1, frontier.maxOffers || MAX_STREAM_BATCH_OFFERS), MAX_STREAM_BATCH_OFFERS);
25723
26022
  return [...answer, this.#batch(workspace, requestId, head, main, maxOffers)];
25724
26023
  }
26024
+ /** Whether this peer's custody of the workspace is shallow. Unknown counts as shallow: it keeps the
26025
+ * existing wait for history rather than calling a head off main. */
26026
+ #shallow(mount, requestId) {
26027
+ const boundaries = this.#kernel.shallowBoundaries;
26028
+ if (!boundaries) return true;
26029
+ try {
26030
+ return boundaries.call(this.#kernel, mount, requestId).length > 0;
26031
+ } catch {
26032
+ return true;
26033
+ }
26034
+ }
25725
26035
  /**
25726
26036
  * The `maxOffers` offers directly above `base`, as the commits this peer admitted them in: one
25727
26037
  * bounded walk and one bounded pack (O(batch)). The copy's kernel adopts exactly these commits on
@@ -26089,7 +26399,6 @@ var OwnOffers = class {
26089
26399
  };
26090
26400
  var LiveCorrespondenceDesk = class {
26091
26401
  #links = /* @__PURE__ */ new Map();
26092
- #pending = /* @__PURE__ */ new Map();
26093
26402
  /** What procedures asked of each workspace's stream, and what it delivered (peer_catchup.md). */
26094
26403
  inbound;
26095
26404
  #own = new OwnOffers();
@@ -26125,13 +26434,6 @@ var LiveCorrespondenceDesk = class {
26125
26434
  * never held. Absent (a custodian, a relay, a test), every write goes out on the next drive.
26126
26435
  */
26127
26436
  writeBurst;
26128
- /**
26129
- * An application peer's receive step (CAP-757; sized by time, CAP-762). A received batch of other
26130
- * senders' offers larger than one step is not admitted on the socket, in one kernel-thread hold:
26131
- * the follow receives it instead, in yielding steps of the policy's current size. Absent (a
26132
- * custodian, a relay, a test), every received batch is admitted as it arrives.
26133
- */
26134
- receiveStep;
26135
26437
  /** The last progress counted per workspace, served while a burst holds recounting back. */
26136
26438
  #progress = /* @__PURE__ */ new Map();
26137
26439
  /** When a held-back progress recount became owed; it reports at the burst's next due point. */
@@ -26221,10 +26523,12 @@ var LiveCorrespondenceDesk = class {
26221
26523
  sent: link.stream?.sent,
26222
26524
  unansweredAgesMs: (link.stream?.unanswered ?? []).map((entry) => Number((now2 - (entry.due - LIVE_ANSWER_WINDOW)) / 1000000n)),
26223
26525
  custodianLocal: link.custodian?.local,
26224
- convergeDue: link.convergeDue !== void 0
26526
+ convergeDue: link.convergeDue !== void 0,
26527
+ resident: false
26225
26528
  };
26226
26529
  try {
26227
26530
  if (this.kernel.isResident(link.binding.workspace) !== false) {
26531
+ state.resident = true;
26228
26532
  const mount = workspaceMount(link.binding.workspace);
26229
26533
  state.head = this.kernel.head(mount, ++this.#requestId);
26230
26534
  state.tracked = this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2);
@@ -26293,7 +26597,7 @@ var LiveCorrespondenceDesk = class {
26293
26597
  }
26294
26598
  #count(link, mount) {
26295
26599
  const head = this.kernel.head(mount, ++this.#requestId);
26296
- const acknowledged = this.#cursor(link, mount)?.local ?? this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2);
26600
+ const acknowledged = this.#cursor(link, mount)?.local ?? this.#heldPeerMain(link, mount, head) ?? this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2);
26297
26601
  if (!head || !acknowledged) return void 0;
26298
26602
  const count = (base, tip) => {
26299
26603
  if (base === tip) return 0;
@@ -26327,6 +26631,14 @@ var LiveCorrespondenceDesk = class {
26327
26631
  #holds(mount, base, tip) {
26328
26632
  return this.#chain(mount, base, tip)?.reachedBase === true;
26329
26633
  }
26634
+ /** The custodian's main as last heard, when this copy holds it on its own head's chain above the
26635
+ * sealed bookmark: the commits up to it came from the stream and are the custodian's (CAP-838). */
26636
+ #heldPeerMain(link, mount, head, tracked = this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2)) {
26637
+ const main = link.peerMain;
26638
+ if (!main || !head || main === tracked) return void 0;
26639
+ if (tracked && !this.#holds(mount, tracked, main)) return void 0;
26640
+ return this.#holds(mount, main, head) ? main : void 0;
26641
+ }
26330
26642
  /** This connection's admission cursor, while it still leads the saved bookmark. A cursor on local
26331
26643
  * history (admitted, not yet sealed) remembers the bookmark it was set above; once anything else
26332
26644
  * moves the bookmark (a follow round adopting the custodian's main) the bookmark rules again, so
@@ -26403,7 +26715,7 @@ var LiveCorrespondenceDesk = class {
26403
26715
  evidencePack: options.carryCommits || intents.some((intent) => intent.transportRequirement === IntentTransportRequirement.COMMIT_TREE) ? this.kernel.packDelta(mount, requestId, batchHead, base) : new Uint8Array()
26404
26716
  });
26405
26717
  }
26406
- receive(request, receipt) {
26718
+ receive(receipt) {
26407
26719
  const link = [...this.#links.values()].find((item) => item.id === receipt.connectionId);
26408
26720
  if (!link) return;
26409
26721
  if (receipt.observation.case === "closed" || receipt.observation.case === "closure") {
@@ -26417,6 +26729,7 @@ var LiveCorrespondenceDesk = class {
26417
26729
  link.ownMains = [];
26418
26730
  delete link.lastAnnounced;
26419
26731
  delete link.lastPlacementAnnounced;
26732
+ link.peerMain = void 0;
26420
26733
  link.dirty = true;
26421
26734
  link.due = this.clock.monotonicNanoseconds() + BigInt(Math.min(3e4, 250 * 2 ** Math.min(link.failures++, 7))) * 1000000n;
26422
26735
  return;
@@ -26426,7 +26739,6 @@ var LiveCorrespondenceDesk = class {
26426
26739
  link.openedAt = this.clock.monotonicNanoseconds();
26427
26740
  link.failures = 0;
26428
26741
  link.unheard = void 0;
26429
- if (!link.publisher) this.#hello(link);
26430
26742
  if (!link.publisher) this.inbound.opened(link.binding.workspace);
26431
26743
  this.linkOpened?.(link.binding.workspace);
26432
26744
  return;
@@ -26460,18 +26772,6 @@ var LiveCorrespondenceDesk = class {
26460
26772
  if (this.inbound.frame(link.binding.workspace, frame2.message)) return;
26461
26773
  if (frame2.message.case === "frontier") {
26462
26774
  this.#announced(link, frame2.message.value.head);
26463
- if (this.kernel.isResident(link.binding.workspace) === false) return;
26464
- if (!frame2.message.value.response) {
26465
- this.#send(link, { case: "frontier", value: {
26466
- head: this.kernel.head(workspaceMount(link.binding.workspace), ++this.#requestId) ?? "",
26467
- response: true
26468
- } });
26469
- }
26470
- try {
26471
- const batch2 = this.export(link.binding, frame2.message.value.head, ++this.#requestId);
26472
- if (batch2.source.case === "inline" && batch2.source.value.offers.length) this.#send(link, { case: "offers", value: batch2 });
26473
- } catch {
26474
- }
26475
26775
  return;
26476
26776
  }
26477
26777
  if (frame2.message.case === "admission") {
@@ -26479,48 +26779,18 @@ var LiveCorrespondenceDesk = class {
26479
26779
  this.progressChanged?.(link.binding.workspace);
26480
26780
  return;
26481
26781
  }
26482
- if (frame2.message.case !== "offers") return;
26483
- const batch = frame2.message.value;
26484
- if (batch.protocolVersion !== 2 || !batch.requestId || batch.source.case !== "inline" || !batch.source.value.offers.length) return;
26485
- const offers = batch.source.value.offers.filter((offer) => !this.#own.hasCommit(link.binding.workspace, offer.commitOid));
26486
- if (!offers.length) return;
26487
- if (this.kernel.isResident(link.binding.workspace) === false && !this.inbound.wanted(link.binding.workspace)) {
26488
- this.remoteAdvanced?.(link.binding.workspace);
26489
- return;
26490
- }
26491
- if (this.receiveStep !== void 0 && offers.length > this.receiveStep.offers) {
26492
- this.remoteAdvanced?.(link.binding.workspace);
26493
- return;
26494
- }
26495
- if ([...this.#pending.values()].some((pending) => pending.link === link && pending.bytes.length === bytes.length && pending.bytes.every((byte, index) => byte === bytes[index]))) return;
26496
- if (this.#pending.size >= 32) return;
26497
- this.#pending.set(request.requestId, { link, bytes });
26498
- return create(RuntimeRequestSchema, {
26499
- protocolVersion: 2,
26500
- requestId: request.requestId,
26501
- target: { workspace: link.binding.workspace, session: link.binding.replicaId },
26502
- // HTTP sender reconciliation controls are not part of a live proposal.
26503
- // Keeping fastForwardOnly while removing baseHead silently skips every
26504
- // offer against a nonempty local head. The Kernel judges sealed causality;
26505
- // live receivers neither ask for a return archive nor confirm the sender.
26506
- command: { case: "admitCustodyOffers", value: create(CustodyOfferBatchRequestSchema, {
26507
- ...batch,
26508
- baseHead: void 0,
26509
- observedHead: void 0,
26510
- fastForwardOnly: false,
26511
- ...offers.length === batch.source.value.offers.length ? {} : { source: { case: "inline", value: { ...batch.source.value, offers } } }
26512
- }) }
26513
- });
26782
+ }
26783
+ /** The newest local commit the custodian admitted unchanged over this workspace's open link: its
26784
+ * main holds that commit, sealed or not, so it is no work to offer (CAP-838). */
26785
+ admittedLocal(workspace) {
26786
+ const link = this.#links.get(workspace);
26787
+ const cursor = link?.state === "open" && !link.publisher ? link.custodian : void 0;
26788
+ return cursor && cursor.main === cursor.local ? cursor.local : void 0;
26514
26789
  }
26515
26790
  /** Offers this replica sent another way (the HTTP lane): their echo on the live link is its own. */
26516
26791
  offered(workspace, commitOids) {
26517
26792
  this.#own.commits(workspace, commitOids);
26518
26793
  }
26519
- /** Whether this request is the admission of a batch relayed to this follower over its live link.
26520
- * Such an admission is never answered to a sender, so it keeps no custody receipts (CAP-759). */
26521
- relayed(requestId) {
26522
- return this.#pending.has(requestId);
26523
- }
26524
26794
  /**
26525
26795
  * The custodian judged a live batch. Admission acknowledges the batch at once; its admitted main
26526
26796
  * becomes this connection's cursor when it is already in local verified history. The saved
@@ -26540,9 +26810,10 @@ var LiveCorrespondenceDesk = class {
26540
26810
  ...admission.sealedMain ? { sealed: admission.sealedMain } : {}
26541
26811
  };
26542
26812
  }
26543
- if (!admission?.main || this.kernel.isResident(workspace) === false) return;
26813
+ if (!admission?.main) return;
26544
26814
  const ownBatchHead = this.#own.batchHead(workspace, live.requestId);
26545
26815
  const ours = ownBatchHead !== void 0;
26816
+ if (this.kernel.isResident(workspace) === false) return;
26546
26817
  let stale = false;
26547
26818
  if (ours) link.unheard = void 0;
26548
26819
  if (ours && link.stream) {
@@ -26630,6 +26901,7 @@ var LiveCorrespondenceDesk = class {
26630
26901
  * upstream head it already recorded. Re-announcing a known frontier - which is all an
26631
26902
  * upstream can do while this replica is ahead or held on a dependency - is not an event. */
26632
26903
  #announced(link, head) {
26904
+ if (head) link.peerMain = head;
26633
26905
  if (!head || link.lastAnnounced === head) return;
26634
26906
  link.lastAnnounced = head;
26635
26907
  if (this.kernel.isResident(link.binding.workspace) === false) {
@@ -26654,15 +26926,6 @@ var LiveCorrespondenceDesk = class {
26654
26926
  if (frontier === this.kernel.resolveRef(mount, ++this.#requestId, PLACEMENT_REF3)) return;
26655
26927
  this.placementAdvanced?.(link.binding.workspace);
26656
26928
  }
26657
- settled(request, response) {
26658
- if (response.outcome.case === "correspondencePending" || response.outcome.case === "localReadPending") return;
26659
- this.#pending.delete(request.requestId);
26660
- }
26661
- failed(requestId) {
26662
- const pending = this.#pending.get(requestId);
26663
- this.#pending.delete(requestId);
26664
- if (pending) this.remoteAdvanced?.(pending.link.binding.workspace);
26665
- }
26666
26929
  disconnect(workspace) {
26667
26930
  const link = this.#links.get(workspace);
26668
26931
  if (!link) return;
@@ -26670,7 +26933,6 @@ var LiveCorrespondenceDesk = class {
26670
26933
  if (link.state === "open") this.linkClosed?.(workspace, closure);
26671
26934
  this.#links.delete(workspace);
26672
26935
  this.#progress.delete(workspace);
26673
- for (const [id, pending] of this.#pending) if (pending.link === link) this.#pending.delete(id);
26674
26936
  }
26675
26937
  /** The digest of the settled-letter outcomes this copy holds; empty when it cannot tell. */
26676
26938
  #outcomesDigest(workspace) {
@@ -26708,14 +26970,6 @@ var LiveCorrespondenceDesk = class {
26708
26970
  transfer.retain(create(PeerGitRefsFetchedSchema, { refs: [...wanted.refs], pack }));
26709
26971
  this.progressChanged?.(link.binding.workspace);
26710
26972
  }
26711
- #hello(link) {
26712
- if (this.kernel.isResident(link.binding.workspace) === false) return;
26713
- const head = this.kernel.head(workspaceMount(link.binding.workspace), ++this.#requestId);
26714
- this.#send(link, { case: "frontier", value: {
26715
- head: head ?? "",
26716
- outcomesDigest: this.#outcomesDigest(link.binding.workspace)
26717
- } });
26718
- }
26719
26973
  drive() {
26720
26974
  const now2 = this.clock.monotonicNanoseconds();
26721
26975
  let wake;
@@ -26764,7 +27018,8 @@ var LiveCorrespondenceDesk = class {
26764
27018
  link.custodian = void 0;
26765
27019
  }
26766
27020
  this.#cursor(link, mount);
26767
- const answered2 = link.publisher ? link.published ??= head ?? "" : link.custodian?.local ?? this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2) ?? "";
27021
+ let answered2 = link.publisher ? link.published ??= head ?? "" : link.custodian?.local ?? this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2) ?? "";
27022
+ if (!link.publisher && !link.custodian) answered2 = this.#heldPeerMain(link, mount, head, answered2) ?? answered2;
26768
27023
  const fence = link.custodian?.main ?? answered2;
26769
27024
  if (link.stream && !(head && this.#holds(mount, link.stream.sent, head))) {
26770
27025
  link.stream = void 0;
@@ -26865,7 +27120,6 @@ var LiveCorrespondenceDesk = class {
26865
27120
  }
26866
27121
  close() {
26867
27122
  for (const workspace of [...this.#links.keys()]) this.disconnect(workspace);
26868
- this.#pending.clear();
26869
27123
  }
26870
27124
  };
26871
27125
 
@@ -27825,6 +28079,7 @@ var PLACEMENT_REF4 = "refs/nomos/placement";
27825
28079
  var RECEIVED_PLACEMENT_REF = "refs/remotes/nomos/placement";
27826
28080
  var STREAM_BATCH_OFFERS = 64;
27827
28081
  var REMOUNT_AFTER_OFFERS = 128;
28082
+ var MAX_REMOUNTS_LOST = 2;
27828
28083
  var HISTORY_SLICES = [8, 64, 256, 256];
27829
28084
  var WorkspaceSyncPhase = Object.freeze({
27830
28085
  Idle: "idle",
@@ -27845,7 +28100,11 @@ var deferredLocal = "refs/nomos/sync-deferred-local";
27845
28100
  var judgedThisLifetime = /* @__PURE__ */ new Map();
27846
28101
  function releaseSyncJudgment(workspace) {
27847
28102
  judgedThisLifetime.delete(workspace);
28103
+ notContainedThisLifetime.delete(workspace);
27848
28104
  }
28105
+ var notContainedThisLifetime = /* @__PURE__ */ new Map();
28106
+ var MAX_NOT_CONTAINED = 1024;
28107
+ var NOT_CONTAINED_REFUSALS = /* @__PURE__ */ new Set(["nomos.stream.off_main", "nomos.stream.history_required"]);
27849
28108
  var MAX_REBASES_PER_ROUND = 2;
27850
28109
  var elapsedMillis = (clock2, started) => {
27851
28110
  const finished = clock2.monotonicNanoseconds();
@@ -27901,6 +28160,7 @@ var WorkspaceSyncWork = class {
27901
28160
  #lastStep;
27902
28161
  #probeOnly;
27903
28162
  #liveConnected;
28163
+ #liveAdmitted;
27904
28164
  /** Set when this round adopted the upstream's own head as its base (see #establishBase). */
27905
28165
  #establishedBase;
27906
28166
  #receiveState;
@@ -27917,6 +28177,11 @@ var WorkspaceSyncWork = class {
27917
28177
  /** The custodian head this round last offered or pulled from. */
27918
28178
  #rebaseFrom;
27919
28179
  #rebases = 0;
28180
+ #remountsLost = 0;
28181
+ /** This round's level ask is a containment question (CAP-870): on a refusal, take this path. */
28182
+ #containment;
28183
+ /** The stale bookmark a contained round replaces: its custodian's main holds the local head. */
28184
+ #containedBookmark;
27920
28185
  /** Local intents this round's rebase refused and parked on the refused-offer desk. */
27921
28186
  #parkedLocal = 0;
27922
28187
  /** An application-authorized drop: replace local custody at exactly this head. */
@@ -27938,6 +28203,7 @@ var WorkspaceSyncWork = class {
27938
28203
  this.#placementFetched = args.placementFetched;
27939
28204
  this.#probeOnly = args.probeOnly ?? false;
27940
28205
  this.#liveConnected = args.liveConnected === true;
28206
+ this.#liveAdmitted = args.liveAdmitted;
27941
28207
  this.#receiveState = args.receiveState;
27942
28208
  this.#completeHistory = args.completeHistory === true;
27943
28209
  this.#repairMissingCommit = args.repairMissingCommit === true;
@@ -28012,9 +28278,15 @@ var WorkspaceSyncWork = class {
28012
28278
  if (this.#receiveState) return this.#acquire("full");
28013
28279
  if (this.#replaceLocalHead !== void 0) return this.#acquire(this.#repairMissingCommit ? "full" : "mount");
28014
28280
  if (!this.#localHead) return this.#acquire(this.#completeHistory ? "full" : "mount");
28015
- if (this.#liveConnected && !this.#probeOnly && this.#holdsLocalWork() && this.#previousHead) {
28016
- return this.#offerOrReconcile();
28281
+ const unadmitted = this.#holdsLocalWork() && this.#localHead !== this.#liveAdmitted;
28282
+ if (this.#liveConnected && unadmitted && this.#previousHead) {
28283
+ if (this.#mayBeContained()) return this.#askContainment("offer");
28284
+ return this.#notContained();
28017
28285
  }
28286
+ if (this.#liveConnected && this.#probeOnly && this.#previousHead && this.#holdsUnsyncedCommits() && this.#command.admit && this.#localHead === this.#liveAdmitted) {
28287
+ return this.#acquire("level");
28288
+ }
28289
+ if (this.#liveConnected && !this.#probeOnly && !unadmitted) return this.#acquire("level");
28018
28290
  const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
28019
28291
  return this.#beginOffer(encodeInlineCustodyOffer({
28020
28292
  session: this.#binding.replicaId,
@@ -28023,6 +28295,60 @@ var WorkspaceSyncWork = class {
28023
28295
  intents: []
28024
28296
  }), { case: "awaiting", requestId }, true);
28025
28297
  }
28298
+ /** Whether the custodian's main may hold this copy's head: not already refused in this lifetime. */
28299
+ #mayBeContained() {
28300
+ return !!this.#localHead && this.#offerHead === void 0 && notContainedThisLifetime.get(this.#mount.workspace) !== this.#localHead;
28301
+ }
28302
+ /** The probe named a custodian main that is not on this copy's own chain, so the copy's head may be
28303
+ * on the custodian's. A main below the local head (the custodian is behind) cannot contain it. A
28304
+ * complete copy answers a main it does not hold after one existence check, and one it holds after
28305
+ * a walk to where the two chains join. A kernel that cannot say keeps the existing path. */
28306
+ #custodianMainOffLocalChain() {
28307
+ if (!this.#kernel.historySummary || !this.#desiredHead || !this.#localHead) return false;
28308
+ try {
28309
+ return !this.#kernel.historySummary(this.#mount, this.#requestId, this.#desiredHead, this.#localHead).reachedBase;
28310
+ } catch (error) {
28311
+ return error instanceof KernelHistoryRequired;
28312
+ }
28313
+ }
28314
+ /** Level from the local head (CAP-870). The stream answers with the custodian's commits above it
28315
+ * (or "level") only when its main holds that head; then this round converges onto them, moves the
28316
+ * bookmark, and offers nothing. One custodian lookup, O(commits behind); no local enumeration. */
28317
+ #askContainment(otherwise) {
28318
+ this.#containment = otherwise;
28319
+ return this.#acquire("level");
28320
+ }
28321
+ /** The stream answered from the local head: it is on the custodian's main. The stale bookmark
28322
+ * stays this round's to replace; the local head is the round's base from here. */
28323
+ #contained() {
28324
+ this.#containment = void 0;
28325
+ this.#containedBookmark = this.#previousHead;
28326
+ this.#previousHead = this.#localHead;
28327
+ }
28328
+ /** The custodian's main does not hold the local head (or the stream could not say): the copy holds
28329
+ * work of its own. Go straight on to the pull/rebase/offer path. A dependency planner's probe hands
28330
+ * the round back to it to plan the outbound suffix. */
28331
+ #notContained(code) {
28332
+ const otherwise = this.#containment ?? "offer";
28333
+ this.#containment = void 0;
28334
+ if (code !== void 0 && NOT_CONTAINED_REFUSALS.has(code) && this.#localHead) {
28335
+ if (notContainedThisLifetime.size >= MAX_NOT_CONTAINED && !notContainedThisLifetime.has(this.#mount.workspace)) {
28336
+ notContainedThisLifetime.delete(notContainedThisLifetime.keys().next().value);
28337
+ }
28338
+ notContainedThisLifetime.set(this.#mount.workspace, this.#localHead);
28339
+ }
28340
+ if (this.#probeOnly) {
28341
+ this.#needsReconciliation = true;
28342
+ return this.#finish(create(SyncWorkspaceResponseSchema, {
28343
+ workspace: this.#mount.workspace,
28344
+ currentHead: this.#localHead,
28345
+ previousHead: this.#previousHead,
28346
+ stillAhead: true,
28347
+ offerReceipt: this.#offerReceipt
28348
+ }));
28349
+ }
28350
+ return otherwise === "pull" ? this.#pullBeforeOffer() : this.#offerOrReconcile();
28351
+ }
28026
28352
  #offerOrReconcile() {
28027
28353
  if (this.#command.admit && this.#localHead && this.#localHead !== this.#previousHead) {
28028
28354
  const suffix = this.#kernel.transportIntentsAbove(
@@ -28101,7 +28427,14 @@ var WorkspaceSyncWork = class {
28101
28427
  return this.#previousHead === void 0 && this.#localHead !== void 0 && this.#replaceLocalHead === void 0;
28102
28428
  }
28103
28429
  #holdsLocalWork() {
28104
- return this.#command.admit && !!this.#localHead && this.#localHead !== this.#previousHead;
28430
+ return this.#command.admit && this.#holdsUnsyncedCommits();
28431
+ }
28432
+ /** Commits on local main the provider has not been seen to admit, whether or not this round may
28433
+ * offer them. Remount replaces local main, so it asks this, never the admit-gated question: a copy
28434
+ * holding unsynced work is offered and rebased, never remounted. A copy without a bookmark cannot
28435
+ * prove it holds nothing of its own. */
28436
+ #holdsUnsyncedCommits() {
28437
+ return !!this.#localHead && this.#localHead !== this.#previousHead;
28105
28438
  }
28106
28439
  /** Ask only for the custodian's delta; the offer follows once this peer has rebased. */
28107
28440
  #pullBeforeOffer() {
@@ -28139,13 +28472,13 @@ var WorkspaceSyncWork = class {
28139
28472
  }
28140
28473
  if (purpose === "level") {
28141
28474
  this.#state = { phase: WorkspaceSyncPhase.Stream, purpose, startedAt };
28142
- return this.#streamEffect("level", { case: "level", value: create(LiveFrontierSchema, {
28475
+ return this.#streamEffect(this.#containment ? "contain" : "level", { case: "level", value: create(LiveFrontierSchema, {
28143
28476
  head: this.#localHead ?? "",
28144
28477
  response: false,
28145
28478
  maxOffers: this.#receiveStep?.offers ?? STREAM_BATCH_OFFERS,
28146
28479
  // Only a copy holding no work above its bookmark may be remounted instead of replaying, and
28147
28480
  // never one whose durable copy must hold the complete history (a head-only mount it cannot keep).
28148
- remountAfterOffers: this.#holdsLocalWork() || this.#completeHistory ? 0 : REMOUNT_AFTER_OFFERS
28481
+ remountAfterOffers: this.#holdsUnsyncedCommits() || this.#completeHistory ? 0 : REMOUNT_AFTER_OFFERS
28149
28482
  }) });
28150
28483
  }
28151
28484
  const outcomes = new EffectOutcomeTransfer(this.#kernel, this.#mount, this.#requestId);
@@ -28222,6 +28555,7 @@ var WorkspaceSyncWork = class {
28222
28555
  }
28223
28556
  if (answer.outcome.case === "refusal") {
28224
28557
  const refusal2 = answer.outcome.value;
28558
+ if (state.purpose === "level" && this.#containment) return this.#notContained(refusal2.code);
28225
28559
  if (state.afterPlacement) return this.#finish(state.afterPlacement);
28226
28560
  return this.#transportFailure(`${refusal2.code}: ${refusal2.message}`, false);
28227
28561
  }
@@ -28258,6 +28592,11 @@ var WorkspaceSyncWork = class {
28258
28592
  state.startedAt
28259
28593
  );
28260
28594
  }
28595
+ if (state.purpose === "level" && this.#containment) {
28596
+ const answeredFromHead = answer.outcome.case === "level" || answer.outcome.case === "pack" && answer.outcome.value.base === this.#localHead;
28597
+ if (!answeredFromHead) return this.#notContained();
28598
+ this.#contained();
28599
+ }
28261
28600
  if (state.purpose === "level" && answer.outcome.case === "pack" && answer.outcome.value.base) {
28262
28601
  const batch = answer.outcome.value;
28263
28602
  if (batch.base !== this.#previousHead && batch.base !== this.#kernel.head(this.#mount, this.#requestId)) {
@@ -28396,13 +28735,19 @@ var WorkspaceSyncWork = class {
28396
28735
  /**
28397
28736
  * A copy holding no work above its bookmark, too far behind to replay the backlog: mount the
28398
28737
  * peer's checkpoint in place of its exact local main (O(state), the same trust as a cold mount).
28399
- * The kernel keeps the replaced head at refs/heads/custody-preserved/<old>; that head was only a
28400
- * bookmark of the provider's own main, so the preservation is released at once.
28738
+ * The kernel keeps the replaced head at refs/heads/custody-preserved/<old>. That ref is custody the
28739
+ * kernel guards (custody may not delete an effectful branch), so it is left where it is: a remount
28740
+ * that deleted it threw after main had already moved, leaving the bookmark behind main and the
28741
+ * round failed for ever (2026-10-08, estate-5b493d6b).
28742
+ *
28743
+ * The copy may have moved while the checkpoint streamed (a live batch, a local write). Then it is
28744
+ * no longer the copy the remount was asked for: take the round up again from its new head. Local
28745
+ * work is offered first; a copy that is still only behind asks to level again.
28401
28746
  */
28402
28747
  #remount(candidateHead, receivedBytes, prefetchMillis) {
28403
28748
  const expected = this.#kernel.head(this.#mount, this.#requestId);
28404
- if (expected === void 0 || expected !== this.#localHead || this.#holdsLocalWork()) {
28405
- return this.#transportFailure("the copy changed while its remount was streaming", false);
28749
+ if (expected === void 0 || expected !== this.#localHead || this.#holdsUnsyncedCommits()) {
28750
+ return this.#remountLost(expected);
28406
28751
  }
28407
28752
  const started = this.#clock.monotonicNanoseconds();
28408
28753
  if (candidateHead !== expected) {
@@ -28410,7 +28755,6 @@ var WorkspaceSyncWork = class {
28410
28755
  if (!restored.accepted || restored.head !== candidateHead) {
28411
28756
  throw new Error(`kernel refused to remount '${this.#mount.workspace}' at ${candidateHead}`);
28412
28757
  }
28413
- this.#kernel.deleteRef?.(this.#mount, this.#requestId, `refs/heads/custody-preserved/${expected}`);
28414
28758
  this.#providerCustodyMounted();
28415
28759
  }
28416
28760
  return this.#converged(create(SyncResponseSchema, {
@@ -28420,6 +28764,25 @@ var WorkspaceSyncWork = class {
28420
28764
  admittedRemoteHead: candidateHead
28421
28765
  }), candidateHead, receivedBytes, prefetchMillis, started);
28422
28766
  }
28767
+ /** The remount's copy changed under it. Bounded: a copy that keeps moving under live traffic is
28768
+ * levelled by its live link anyway, and the next round starts from wherever it got to. */
28769
+ #remountLost(head) {
28770
+ if (head === void 0 || ++this.#remountsLost > MAX_REMOUNTS_LOST) {
28771
+ return this.#transportFailure("the copy changed while its remount was streaming", false);
28772
+ }
28773
+ this.#localHead = head;
28774
+ this.#previousHead = this.#kernel.resolveRef(this.#mount, this.#requestId, trackedMain);
28775
+ if (this.#desiredHead === this.#localHead) {
28776
+ return this.#converged(create(SyncResponseSchema, {
28777
+ admitted: true,
28778
+ head,
28779
+ candidateHead: head,
28780
+ admittedRemoteHead: head
28781
+ }), head, 0, 0);
28782
+ }
28783
+ if (this.#holdsLocalWork() && this.#desiredHead !== this.#previousHead) return this.#pullBeforeOffer();
28784
+ return this.#offerOrReconcile();
28785
+ }
28423
28786
  resume(receipt) {
28424
28787
  if (receipt.effectId === this.#lastReceiptEffectId && this.#lastStep) {
28425
28788
  return this.#lastStep;
@@ -28584,6 +28947,10 @@ var WorkspaceSyncWork = class {
28584
28947
  offerReceipt: this.#offerReceipt
28585
28948
  }));
28586
28949
  }
28950
+ const custodianMoved = this.#holdsLocalWork() && this.#desiredHead !== this.#previousHead;
28951
+ if (custodianMoved && this.#mayBeContained() && this.#custodianMainOffLocalChain()) {
28952
+ return this.#askContainment("pull");
28953
+ }
28587
28954
  if (this.#probeOnly) {
28588
28955
  this.#needsReconciliation = true;
28589
28956
  return this.#finish(create(SyncWorkspaceResponseSchema, {
@@ -28594,9 +28961,7 @@ var WorkspaceSyncWork = class {
28594
28961
  offerReceipt: this.#offerReceipt
28595
28962
  }));
28596
28963
  }
28597
- if (this.#holdsLocalWork() && this.#desiredHead !== this.#previousHead) {
28598
- return this.#pullBeforeOffer();
28599
- }
28964
+ if (custodianMoved) return this.#pullBeforeOffer();
28600
28965
  return this.#offerOrReconcile();
28601
28966
  }
28602
28967
  this.#admissionSummary = summarizeCustodyAdmission(admission);
@@ -28930,7 +29295,8 @@ var WorkspaceSyncWork = class {
28930
29295
  }));
28931
29296
  }
28932
29297
  #converged(verdict, candidateHead, receivedBytes, prefetchMillis, started = this.#clock.monotonicNanoseconds(), rebirth) {
28933
- if (verdict.admitted && this.#candidateDurable && candidateHead !== this.#previousHead && this.#kernel.resolveRef(this.#mount, this.#requestId, trackedMain) === this.#previousHead) {
29298
+ const tracked = verdict.admitted && this.#candidateDurable ? this.#kernel.resolveRef(this.#mount, this.#requestId, trackedMain) : void 0;
29299
+ if (verdict.admitted && this.#candidateDurable && tracked !== candidateHead && (tracked === this.#previousHead || this.#containedBookmark !== void 0 && tracked === this.#containedBookmark)) {
28934
29300
  this.#kernel.writeRef(
28935
29301
  this.#mount,
28936
29302
  this.#requestId,
@@ -29219,10 +29585,16 @@ var WorkspaceDependencySyncWork = class {
29219
29585
  this.#plan = [this.#args.root];
29220
29586
  return this.#advance();
29221
29587
  }
29222
- if (this.#args.liveConnected && this.#args.kernel.resolveRef(this.#args.root.mount, this.#args.requestId, trackedMain2)) {
29588
+ const { kernel, requestId, root } = this.#args;
29589
+ const tracked = this.#args.liveConnected ? kernel.resolveRef(root.mount, requestId, trackedMain2) : void 0;
29590
+ if (tracked && kernel.head(root.mount, requestId) === tracked) {
29223
29591
  this.#plan = this.#planDependencies();
29224
29592
  return this.#advance();
29225
29593
  }
29594
+ if (tracked) {
29595
+ this.#current = this.#work(root, `${this.workId}:contain`, true);
29596
+ return this.#accept(this.#current.start());
29597
+ }
29226
29598
  this.#current = this.#work(this.#args.root, `${this.workId}:frontier`, true);
29227
29599
  return this.#accept(this.#current.start());
29228
29600
  }
@@ -30545,6 +30917,11 @@ var ReplicaFollowLane = class {
30545
30917
  const delay = this.#controller.reconnected(workspace);
30546
30918
  if (delay !== void 0) this.#scheduleAt(workspace, this.#now() + delay);
30547
30919
  }
30920
+ /** The upstream announced a new frontier: news even to a follow the kernel refused. */
30921
+ remoteAdvanced(workspace) {
30922
+ const delay = this.#controller.reconnected(workspace, true);
30923
+ if (delay !== void 0) this.#scheduleAt(workspace, this.#now() + delay);
30924
+ }
30548
30925
  /** The upstream rang for a new placement frontier (see ReplicaFollowController). */
30549
30926
  placementAnnounced(workspace) {
30550
30927
  const delay = this.#controller.placementAnnounced(workspace);
@@ -30859,6 +31236,7 @@ var CorrespondenceDesk = class {
30859
31236
  #onPlacementFetched;
30860
31237
  #onShallowMount;
30861
31238
  #onOffered;
31239
+ #liveAdmitted;
30862
31240
  #onOutboxHistoryRequired;
30863
31241
  #backgroundHistory;
30864
31242
  #receiveStep;
@@ -30915,6 +31293,7 @@ var CorrespondenceDesk = class {
30915
31293
  this.#onPlacementFetched = args.onPlacementFetched;
30916
31294
  this.#onShallowMount = args.onShallowMount;
30917
31295
  this.#onOffered = args.onOffered;
31296
+ this.#liveAdmitted = args.liveAdmitted;
30918
31297
  this.#onOutboxHistoryRequired = args.onOutboxHistoryRequired;
30919
31298
  this.#backgroundHistory = args.backgroundHistory !== false;
30920
31299
  this.#receiveStep = args.receiveStep;
@@ -31241,6 +31620,12 @@ var CorrespondenceDesk = class {
31241
31620
  this.#followLane.reconnected(workspace);
31242
31621
  this.reportFollows();
31243
31622
  }
31623
+ /** The upstream announced a new frontier for this workspace over its live link: an event which
31624
+ * re-runs a round the kernel refused (its inputs changed). */
31625
+ replicaRemoteAdvanced(workspace) {
31626
+ this.#followLane.remoteAdvanced(workspace);
31627
+ this.reportFollows();
31628
+ }
31244
31629
  /** The upstream rang for a new placement frontier: the next round re-checks placement even
31245
31630
  * though main has not moved. */
31246
31631
  replicaPlacementAnnounced(workspace) {
@@ -31277,10 +31662,11 @@ var CorrespondenceDesk = class {
31277
31662
  const state = this.#follows.followForWorkspace(workspace)?.state;
31278
31663
  if (!state) return [];
31279
31664
  const isSettled = state.case === ReplicaFollowPhase.Settled;
31665
+ const refused = state.case === ReplicaFollowPhase.Backoff && state.refusal?.blocked === true;
31280
31666
  const isLive = this.#openLinks.has(workspace);
31281
31667
  if (isSettled) settled += 1;
31282
31668
  if (isLive) live += 1;
31283
- const phase = {
31669
+ const phase = refused ? FollowObservationPhase.KERNEL_REFUSED : {
31284
31670
  [ReplicaFollowPhase.Desired]: FollowObservationPhase.DESIRED,
31285
31671
  [ReplicaFollowPhase.Due]: FollowObservationPhase.DUE,
31286
31672
  [ReplicaFollowPhase.Running]: FollowObservationPhase.RUNNING,
@@ -31294,7 +31680,7 @@ var CorrespondenceDesk = class {
31294
31680
  [ReplicaFollowPhase.LocalCopyUnreadable]: FollowObservationPhase.LOCAL_COPY_UNREADABLE
31295
31681
  }[state.case];
31296
31682
  const detail = state.case === ReplicaFollowPhase.AwaitingDependency ? state.reason : state.case === ReplicaFollowPhase.InvalidCredential || state.case === ReplicaFollowPhase.Backoff ? state.failure : state.case === ReplicaFollowPhase.RebornRemotely ? state.rebirth.detail : state.case === ReplicaFollowPhase.LocalCopyUnreadable ? state.format : void 0;
31297
- const retryAt = state.case === ReplicaFollowPhase.Offline || state.case === ReplicaFollowPhase.InvalidCredential || state.case === ReplicaFollowPhase.Backoff ? state.retryAtUnixMillis : void 0;
31683
+ const retryAt = refused ? state.case === ReplicaFollowPhase.Backoff ? state.refusal?.rerunAtUnixMillis : void 0 : state.case === ReplicaFollowPhase.Offline || state.case === ReplicaFollowPhase.InvalidCredential || state.case === ReplicaFollowPhase.Backoff ? state.retryAtUnixMillis : void 0;
31298
31684
  const dueAt2 = state.case === ReplicaFollowPhase.Due || state.case === ReplicaFollowPhase.ReplacingLocal ? state.dueAtUnixMillis : void 0;
31299
31685
  const attempt = state.case === ReplicaFollowPhase.Running || state.case === ReplicaFollowPhase.Offline || state.case === ReplicaFollowPhase.InvalidCredential || state.case === ReplicaFollowPhase.Backoff || state.case === ReplicaFollowPhase.ReplacingLocal ? state.attempt : void 0;
31300
31686
  const activeEffect = state.case === ReplicaFollowPhase.Running ? this.#activeSyncEffect(workspace) : void 0;
@@ -31792,6 +32178,7 @@ var CorrespondenceDesk = class {
31792
32178
  workId: id,
31793
32179
  probeOnly,
31794
32180
  liveConnected: this.#openLinks.has(target3.mount.workspace),
32181
+ ...this.#openLinks.has(target3.mount.workspace) && this.#liveAdmitted?.(target3.mount.workspace) ? { liveAdmitted: this.#liveAdmitted(target3.mount.workspace) } : {},
31795
32182
  ...beforeConverge === void 0 ? {} : { beforeConverge },
31796
32183
  ...target3.receiveState === void 0 ? {} : { receiveState: target3.receiveState },
31797
32184
  ...target3.offerHead === void 0 ? {} : { offerHead: target3.offerHead },
@@ -33418,10 +33805,10 @@ var OfferReadinessDesk = class {
33418
33805
  while (true) {
33419
33806
  this.#ports.owe(owed.workspace);
33420
33807
  while (this.#ports.owes(owed.workspace)) {
33421
- const tick = this.#ports.tick();
33808
+ const { ticked, wake: readiness } = this.#ports.tick();
33422
33809
  const delayMillis = Math.min(LONGEST_WAKE_MILLIS, Math.max(
33423
33810
  FIRST_WAKE_MILLIS,
33424
- tick.progress !== void 0 ? FIRST_WAKE_MILLIS : tick.nextTickAfterMillis
33811
+ ticked.progress !== void 0 ? FIRST_WAKE_MILLIS : readiness.case === "after" ? readiness.millis : LONGEST_WAKE_MILLIS
33425
33812
  ));
33426
33813
  const receipt = yield { case: "wake", value: create(PeerWakeEffectSchema, {
33427
33814
  effectId: `${workId2}:repay-${++wake}`,
@@ -33553,7 +33940,6 @@ function isAnsweredStateRead(command, response) {
33553
33940
  }
33554
33941
  var INTERACTIVE_PEER_CLASSES = /* @__PURE__ */ new Set(["personal-device", "browser"]);
33555
33942
  var INTERACTION_FIRST_MILLIS = 15e3;
33556
- var READ_READINESS_ONLY = 1n << 62n;
33557
33943
  var PLACEMENT_READ_RETRY_MILLIS = 60000n;
33558
33944
  var STREAM_WAKE_FIRST_MILLIS = 20;
33559
33945
  var HISTORY_STREAM_SLICES = [8, 64, 256];
@@ -33572,7 +33958,6 @@ var APPLICATION_WAITS = /* @__PURE__ */ new Set([
33572
33958
  "continueLocalRead"
33573
33959
  ]);
33574
33960
  var APPLICATION_WAIT_NANOS = 5000000000n;
33575
- var READ_INDEX_BUILDING = /the read index of .+ is being built|read maintenance continues it/;
33576
33961
  var PeerOffice = class {
33577
33962
  #kernel;
33578
33963
  #sessions = new SessionDirectory();
@@ -33767,7 +34152,6 @@ var PeerOffice = class {
33767
34152
  }
33768
34153
  }, (workspace) => this.#residency.lastRetainedHead(workspace));
33769
34154
  if (this.#writeBurst) this.#live.writeBurst = this.#writeBurst;
33770
- if (this.#interactivePeer) this.#live.receiveStep = this.#receiveStepBudget;
33771
34155
  this.#credentials = new CredentialSessions(this.#sessions, credentials, observations);
33772
34156
  this.#readability = new LocalCopyReadability((workspace, format) => {
33773
34157
  this.#follows.markLocalCopyUnreadable(workspace, format);
@@ -33785,7 +34169,8 @@ var PeerOffice = class {
33785
34169
  new ReplicaFollowDesk(seatedStore),
33786
34170
  observations,
33787
34171
  this.#replicaId,
33788
- new BirthRefusalRegister(seatedStore)
34172
+ new BirthRefusalRegister(seatedStore),
34173
+ PEER_RUNTIME_IDENTITY
33789
34174
  );
33790
34175
  this.#compatibility = new CompatibilityDesk(
33791
34176
  this.#queries,
@@ -33804,13 +34189,20 @@ var PeerOffice = class {
33804
34189
  this.#trace,
33805
34190
  observations,
33806
34191
  {
33807
- readReady: (workspace) => this.#subscriptions.readIndexReady(workspace),
33808
- frontierAdvanced: (workspace) => this.#subscriptions.readIndexAdvanced(workspace),
33809
- localCopyUnreadable: (workspace, format) => this.#readability.mark(
33810
- workspace,
33811
- this.#kernel.head(workspaceMount(workspace), 0n),
33812
- format
33813
- ),
34192
+ // A read waiting on this workspace is released by the readiness event itself, not a timer.
34193
+ readReady: (workspace) => {
34194
+ this.#subscriptions.readIndexReady(workspace);
34195
+ this.#readResponses?.readinessChanged(workspace);
34196
+ },
34197
+ frontierAdvanced: (workspace) => {
34198
+ this.#subscriptions.readIndexAdvanced(workspace);
34199
+ this.#readResponses?.readinessChanged(workspace);
34200
+ },
34201
+ readinessMayChange: (workspace) => this.#readResponses?.readinessChanged(workspace),
34202
+ localCopyUnreadable: (workspace, format) => {
34203
+ this.#readability.mark(workspace, this.#kernel.head(workspaceMount(workspace), 0n), format);
34204
+ this.#readResponses?.readinessChanged(workspace);
34205
+ },
33814
34206
  isLocalCopyUnreadable: (workspace) => this.#readability.decide(workspace) !== void 0
33815
34207
  },
33816
34208
  // The kernel owes this peer's writes to an ordered background flush the desk schedules.
@@ -33872,7 +34264,7 @@ var PeerOffice = class {
33872
34264
  aggregateIds: new Set([...admitted.affected, ...admitted.created].map((ref) => ref.id)),
33873
34265
  // What the offer changed, typed as reads resolve it: watches it cannot change are not read.
33874
34266
  stateChange: admitted.stateChange
33875
- }, () => this.#readMaintenance.tick(void 0, 0n, READ_READINESS_ONLY, false).progress !== void 0));
34267
+ }, () => this.#readMaintenance.tickReadReadiness().ticked.progress !== void 0));
33876
34268
  noteTimeline("ownOffer", `${delivery.delivered}/${delivery.watches}`);
33877
34269
  noteTimeline("ownOfferSkipped", delivery.skipped);
33878
34270
  });
@@ -33887,7 +34279,12 @@ var PeerOffice = class {
33887
34279
  observations,
33888
34280
  // A waiting read advances read readiness only: it must never run a background command or
33889
34281
  // closure warm on the foreground's turn.
33890
- () => this.#readMaintenance.tick(void 0, 0n, READ_READINESS_ONLY, false),
34282
+ () => this.#readMaintenance.tickReadReadiness(),
34283
+ // A read the kernel still finds behind, with nothing owing its index, owes it again (as a watch does).
34284
+ (request) => {
34285
+ if (request.command.case !== "kernelCall") throw new Error("local read continuation lost its query");
34286
+ this.#readMaintenance.schedule(request.command.value.session, ReadMaintenanceCause.READ_DEBT);
34287
+ },
33891
34288
  (request) => {
33892
34289
  if (request.command.case !== "kernelCall") throw new Error("local read continuation lost its query");
33893
34290
  return this.#application.call(request, request.command.value);
@@ -33988,6 +34385,7 @@ var PeerOffice = class {
33988
34385
  onShallowMount: (workspace, credentialCapability) => this.#historyAcquisition.materialise(workspace, credentialCapability),
33989
34386
  // The edge echoes an HTTP offer batch back over this replica's own live link (CAP-764).
33990
34387
  onOffered: (workspace, commitOids) => this.#live.offered(workspace, commitOids),
34388
+ liveAdmitted: (workspace) => this.#live.admittedLocal(workspace),
33991
34389
  onOutboxHistoryRequired: (workspace, credentialCapability) => this.#historyAcquisition.requestFromBackground(workspace, credentialCapability),
33992
34390
  backgroundHistory: profile.backgroundHistory !== false,
33993
34391
  onSyncCompleted: (session, event) => {
@@ -34013,7 +34411,7 @@ var PeerOffice = class {
34013
34411
  this.#origins.ignored(workspace, origin2, "follow");
34014
34412
  return false;
34015
34413
  };
34016
- this.#live.remoteAdvanced = (workspace) => this.#correspondence.replicaLinkOpened(workspace);
34414
+ this.#live.remoteAdvanced = (workspace) => this.#correspondence.replicaRemoteAdvanced(workspace);
34017
34415
  this.#live.declined = (workspace) => this.#correspondence.liveAdmissionDeclined(workspace);
34018
34416
  this.#live.acknowledged = (workspace, ack) => this.#correspondence.liveAdmissionAcknowledged(workspace, ack);
34019
34417
  this.#live.intentsAdmitted = (workspace, intentIds, local) => this.#correspondence.liveIntentsAdmitted(workspace, intentIds, local);
@@ -34225,7 +34623,7 @@ var PeerOffice = class {
34225
34623
  },
34226
34624
  owes: (workspace) => this.#readMaintenance.owesReadReadiness(workspace),
34227
34625
  // Read readiness only, as a waiting read takes: never a background command or pack import (CAP-806).
34228
- tick: () => this.#readMaintenance.tick(void 0, 0n, READ_READINESS_ONLY, false),
34626
+ tick: () => this.#readMaintenance.tickReadReadiness(),
34229
34627
  emit: (session, event) => this.#trace.emit(session, event)
34230
34628
  });
34231
34629
  this.#modelAdoption = new ModelAdoptionDesk({
@@ -34623,9 +35021,8 @@ var PeerOffice = class {
34623
35021
  let pendingEffectId;
34624
35022
  try {
34625
35023
  if (request.command.case === "socketReceipt") {
34626
- const admission = this.#live.receive(request, request.command.value);
34627
- if (!admission) return this.#response(request, { case: "socketObserved", value: create(PeerSocketObservedSchema) });
34628
- request = admission;
35024
+ this.#live.receive(request.command.value);
35025
+ return this.#response(request, { case: "socketObserved", value: create(PeerSocketObservedSchema) });
34629
35026
  }
34630
35027
  const result = timelinePhase("access", () => this.#access.handle(request));
34631
35028
  if (result.outcome.case === "correspondencePending") {
@@ -34634,11 +35031,9 @@ var PeerOffice = class {
34634
35031
  }
34635
35032
  if (result.outcome.case === "watchStarted") this.#subscriptions.retainDependencies(result.outcome.value.subscriptionId, scope);
34636
35033
  this.#subscriptions.recoverySettled(result);
34637
- this.#live.settled(request, result);
34638
35034
  this.#correspondence.observeResponse(result);
34639
35035
  return result;
34640
35036
  } catch (error) {
34641
- this.#live.failed(request.requestId);
34642
35037
  const failure = this.#failure(request, "nomos.runtime.workspace_access", error instanceof Error ? error.message : String(error));
34643
35038
  this.#subscriptions.recoverySettled(failure);
34644
35039
  this.#correspondence.observeResponse(failure);
@@ -34905,11 +35300,7 @@ var PeerOffice = class {
34905
35300
  try {
34906
35301
  const mount = this.#sessions.mountForWorkspace(request.target.workspace);
34907
35302
  const previousHead = this.#kernel.head(mount, request.requestId);
34908
- const admission = this.#custodyAdmission.admit(
34909
- request,
34910
- request.command.value,
34911
- { journal: !this.#live.relayed(request.requestId) }
34912
- );
35303
+ const admission = this.#custodyAdmission.admit(request, request.command.value);
34913
35304
  admission.sealedMain = this.#residency.retainedHead(request.target.workspace);
34914
35305
  if (custodyAdmissionNeedsReadMaintenance(admission)) {
34915
35306
  admission.localMaintenance = this.#readMaintenance.scheduleWorkspace(
@@ -35026,16 +35417,17 @@ var PeerOffice = class {
35026
35417
  });
35027
35418
  case "historicQuery": {
35028
35419
  const answered2 = this.#historicQueries.execute(request, request.command.value);
35029
- if (answered2.outcome.case === "failure" && READ_INDEX_BUILDING.test(answered2.outcome.value.message)) {
35420
+ if (answered2.outcome.case === "query" && answered2.outcome.value.result.case === "readIndexPending") {
35030
35421
  this.#readMaintenance.schedule(request.command.value.session, ReadMaintenanceCause.READ_DEBT);
35422
+ const workspace = answered2.outcome.value.result.value.workspace || (this.#sessions.bindingIfPresent(request.command.value.session)?.workspace ?? "");
35031
35423
  return this.#response(request, {
35032
35424
  case: "unavailable",
35033
35425
  value: create(RuntimeUnavailableSchema, {
35034
35426
  reason: RuntimeUnavailableReason.LOCAL_REPLICA_NOT_READY,
35035
- workspace: this.#sessions.bindingIfPresent(request.command.value.session)?.workspace ?? "",
35427
+ workspace,
35036
35428
  retryable: true,
35037
35429
  retryAfterMillis: 250,
35038
- detail: answered2.outcome.value.message
35430
+ detail: `the read index of ${workspace} is being built on this device; read maintenance continues it`
35039
35431
  })
35040
35432
  });
35041
35433
  }
@@ -35455,6 +35847,10 @@ var PeerOffice = class {
35455
35847
  nextEvent() {
35456
35848
  return this.#trace.nextEvent();
35457
35849
  }
35850
+ /** In-process shells wait on a held local read here instead of polling `resumeAfterMillis`. */
35851
+ localReadResumable(workId2, notify) {
35852
+ return this.#readResponses.onResumable(workId2, notify);
35853
+ }
35458
35854
  close() {
35459
35855
  if (this.retentionOutstanding() > 0) {
35460
35856
  throw new Error("custody retention pending; retain the acknowledged frontiers before disposing the peer");
@@ -35804,6 +36200,23 @@ function createPeerOfficeFrameRunner(kernel, credentials, profile, observations,
35804
36200
  lanes?.wake(delayMillis);
35805
36201
  };
35806
36202
  const runner = {
36203
+ localReadResumable(workId2) {
36204
+ let resolve4;
36205
+ const resumable = new Promise((done) => {
36206
+ resolve4 = done;
36207
+ });
36208
+ let timer;
36209
+ const wait = peer2.localReadResumable(workId2, () => {
36210
+ if (timer !== void 0) clearTimeout(timer);
36211
+ resolve4();
36212
+ });
36213
+ if (wait === void 0) return void 0;
36214
+ timer = setTimeout(() => {
36215
+ wait.cancel();
36216
+ resolve4();
36217
+ }, wait.afterMillis);
36218
+ return resumable;
36219
+ },
35807
36220
  handleFrame(frame2) {
35808
36221
  const response = peer2.invoke(frame2).responseProtobuf;
35809
36222
  drainEvents();
@@ -36032,7 +36445,7 @@ async function drivePeerFrame(runner, initialFrame, fetchImpl = globalThis.fetch
36032
36445
  if (response.outcome.case === "localReadPending") {
36033
36446
  if (yieldLocalReadToCaller) return responseFrame;
36034
36447
  const pending2 = response.outcome.value;
36035
- await new Promise((resolve4) => setTimeout(resolve4, pending2.resumeAfterMillis));
36448
+ await (runner.localReadResumable?.(pending2.workId) ?? new Promise((resolve4) => setTimeout(resolve4, pending2.resumeAfterMillis)));
36036
36449
  responseFrame = await turn(() => runner.handleFrame(toBinary(RuntimeRequestSchema, create(RuntimeRequestSchema, {
36037
36450
  protocolVersion: response.protocolVersion,
36038
36451
  requestId: response.requestId,
@@ -37239,11 +37652,30 @@ var sha256Hex2 = async (bytes) => {
37239
37652
  const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
37240
37653
  return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
37241
37654
  };
37242
- var okBytes = async (fetchImpl, url) => {
37655
+ var okBytes = async (fetchImpl, url, progress, expectedBytes) => {
37243
37656
  const response = await fetchImpl(url);
37244
37657
  if (!response.ok) throw new Error(`runtime artifact ${url}: HTTP ${response.status}`);
37245
- return new Uint8Array(await response.arrayBuffer());
37658
+ const reader = progress ? response.body?.getReader() : void 0;
37659
+ if (!reader) return new Uint8Array(await response.arrayBuffer());
37660
+ const total = expectedBytes ?? Number(response.headers.get("content-length") ?? 0);
37661
+ const chunks = [];
37662
+ let received = 0;
37663
+ for (; ; ) {
37664
+ const { done, value } = await reader.read();
37665
+ if (done) break;
37666
+ chunks.push(value);
37667
+ received += value.byteLength;
37668
+ progress(received, total);
37669
+ }
37670
+ const bytes = new Uint8Array(received);
37671
+ let offset = 0;
37672
+ for (const chunk of chunks) {
37673
+ bytes.set(chunk, offset);
37674
+ offset += chunk.byteLength;
37675
+ }
37676
+ return bytes;
37246
37677
  };
37678
+ var elapsedSince = (started) => globalThis.performance.now() - started;
37247
37679
  async function selectReleaseKernel(args) {
37248
37680
  const fetchImpl = args.fetchImpl ?? ((input, init) => globalThis.fetch(input, init));
37249
37681
  const base = args.base.replace(/\/+$/, "");
@@ -37271,11 +37703,27 @@ async function selectReleaseKernel(args) {
37271
37703
  }
37272
37704
  }
37273
37705
  const url = new URL(relativeUrl, repositoryUrl).toString();
37274
- const bytes = await okBytes(fetchImpl, url);
37275
- if (expected && (bytes.byteLength !== expected.size || await sha256Hex2(bytes) !== expected.sha256)) {
37276
- throw new Error(`runtime artifact ${url} does not match the OSGi resource it was selected by`);
37706
+ const report = (progress) => {
37707
+ try {
37708
+ args.onProgress?.(progress);
37709
+ } catch {
37710
+ }
37711
+ };
37712
+ let started = globalThis.performance.now();
37713
+ const bytes = await okBytes(fetchImpl, url, args.onProgress ? (receivedBytes, totalBytes) => report({ stage: "download", artifact: name, receivedBytes, totalBytes }) : void 0, expected?.size);
37714
+ report({ stage: "fetched", artifact: name, millis: elapsedSince(started) });
37715
+ if (expected) {
37716
+ started = globalThis.performance.now();
37717
+ if (bytes.byteLength !== expected.size || await sha256Hex2(bytes) !== expected.sha256) {
37718
+ throw new Error(`runtime artifact ${url} does not match the OSGi resource it was selected by`);
37719
+ }
37720
+ report({ stage: "verified", artifact: name, millis: elapsedSince(started) });
37721
+ }
37722
+ if (expected && args.cache) {
37723
+ started = globalThis.performance.now();
37724
+ await args.cache.write(resource.contentSha256, name, bytes);
37725
+ report({ stage: "stored", artifact: name, millis: elapsedSince(started) });
37277
37726
  }
37278
- if (expected && args.cache) await args.cache.write(resource.contentSha256, name, bytes);
37279
37727
  return bytes;
37280
37728
  };
37281
37729
  await verifySelectedKernel({
@@ -37339,6 +37787,34 @@ async function verifySelectedKernel(args) {
37339
37787
  }
37340
37788
  }
37341
37789
 
37790
+ // ../../platform-shells/shared/retained_boot_fetch.ts
37791
+ init_define_NOMOS_KERNEL_RELEASE();
37792
+ function retainedBootFetch(base, fetchImpl, store, repositoryUrl) {
37793
+ const root = base.replace(/\/+$/, "");
37794
+ return async (input, init) => {
37795
+ const url = String(input);
37796
+ const bootArtifact = url === (repositoryUrl ?? `${root}/v1/runtime/repository.xml`) || url === `${root}/v1/runtime/nomos.law.usdz`;
37797
+ if (!bootArtifact) return fetchImpl(input, init);
37798
+ const networkInit = { ...init, cache: "no-store", signal: init?.signal ?? AbortSignal.timeout(15e3) };
37799
+ if (!store) return fetchImpl(input, networkInit);
37800
+ let response;
37801
+ let failure;
37802
+ try {
37803
+ response = await fetchImpl(input, networkInit);
37804
+ } catch (error) {
37805
+ failure = error;
37806
+ }
37807
+ if (response !== void 0 && response.status < 500) {
37808
+ if (response.ok) await store.put(url, response.clone());
37809
+ return response;
37810
+ }
37811
+ const retained = await store.match(url);
37812
+ if (retained) return retained;
37813
+ if (response !== void 0) return response;
37814
+ throw failure;
37815
+ };
37816
+ }
37817
+
37342
37818
  // ../../runtime/kernel_local_dev_trust.ts
37343
37819
  init_define_NOMOS_KERNEL_RELEASE();
37344
37820
  var LOCAL_DEV_KERNEL_TRUST_ROOT_ENV = "NOMOS_LOCAL_DEV_KERNEL_TRUST_ROOT";
@@ -37408,10 +37884,28 @@ var physicalFetch = async (input, init) => {
37408
37884
  }, { signal: gitHttpBackendLifetime.signal });
37409
37885
  return new Response(result.body, { status: result.status, headers: result.headers });
37410
37886
  };
37887
+ var diskBootStore = (directory2) => {
37888
+ const file = (url) => join5(directory2, createHash2("sha256").update(url).digest("hex"));
37889
+ return {
37890
+ async match(url) {
37891
+ if (!existsSync5(`${file(url)}.body`) || !existsSync5(`${file(url)}.headers.json`)) return void 0;
37892
+ return new Response(new Uint8Array(readFileSync3(`${file(url)}.body`)), {
37893
+ headers: JSON.parse(readFileSync3(`${file(url)}.headers.json`, "utf8"))
37894
+ });
37895
+ },
37896
+ async put(url, response) {
37897
+ mkdirSync5(directory2, { recursive: true });
37898
+ writeFileSync5(`${file(url)}.body`, new Uint8Array(await response.arrayBuffer()));
37899
+ writeFileSync5(`${file(url)}.headers.json`, JSON.stringify(Object.fromEntries(response.headers)));
37900
+ }
37901
+ };
37902
+ };
37411
37903
  var fetchReleaseBundle = async (cloud) => {
37412
37904
  const cacheRoot = join5(data, "runtime");
37413
37905
  const selected = await selectReleaseKernel({
37414
37906
  base: cloud,
37907
+ // Offline-first: an unreachable channel boots the last selection this peer verified, verified again now.
37908
+ fetchImpl: retainedBootFetch(cloud, (input, init) => fetch(input, init), diskBootStore(join5(cacheRoot, "boot"))),
37415
37909
  release: define_NOMOS_KERNEL_RELEASE_default,
37416
37910
  // The pinned production roots; plus a developer's local-dev root only when named explicitly AND the custodian is
37417
37911
  // on this machine (CAP-813) — announced on stderr either way.