githolon 0.115.0 → 0.116.2

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.
@@ -23,8 +23,10 @@ var SignOfferPreparationRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_k
23
23
  var SigningIdentityRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 39);
24
24
  var GenerateSigningKeyPairSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 40);
25
25
  var KernelRefusalSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 55);
26
+ var QueryResponseSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 56);
26
27
  var ApplicationResultDeltaSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 58);
27
28
  var InterfaceCompatibilityQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 60);
29
+ var ReadIndexPendingSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 64);
28
30
  var MaintenanceQuantumQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 65);
29
31
  var CarriedWorkspaceOfferSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 80);
30
32
  var PrepareOutboundOfferSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 84);
@@ -655,7 +657,7 @@ var CustodyBreakPolicySchema = /* @__PURE__ */ enumDesc13(file_nomos_runtime_v2_
655
657
  var CustodyBreakPolicy = /* @__PURE__ */ tsEnum13(CustodyBreakPolicySchema);
656
658
 
657
659
  // ../adapter/proto/nomos/runtime/v2/observability_desk_pb.js
658
- var file_nomos_runtime_v2_observability_desk = /* @__PURE__ */ fileDesc21("Cilub21vcy9ydW50aW1lL3YyL29ic2VydmFiaWxpdHlfZGVzay5wcm90bxIQbm9tb3MucnVudGltZS52MiJCCgxUcmFjZUNvbnRleHQSEAoIdHJhY2VfaWQYASABKAwSDwoHc3Bhbl9pZBgCIAEoDBIPCgdzYW1wbGVkGAMgASgIIp0CCg5SdW50aW1lRmFpbHVyZRIMCgRjb2RlGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSEQoJY29tcG9uZW50GAMgASgJEhYKCXdvcmtzcGFjZRgEIAEoCUgAiAEBEhMKBmRvbWFpbhgFIAEoCUgBiAEBEhYKCWRpcmVjdGl2ZRgGIAEoCUgCiAEBEjkKCmF0dHJpYnV0ZXMYByADKAsyJS5ub21vcy5ydW50aW1lLnYyLkRpYWdub3N0aWNBdHRyaWJ1dGUSMgoEa2luZBgIIAEoDjIkLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZUZhaWx1cmVLaW5kQgwKCl93b3Jrc3BhY2VCCQoHX2RvbWFpbkIMCgpfZGlyZWN0aXZlIr4BChJSdW50aW1lVW5hdmFpbGFibGUSOgoGcmVhc29uGAEgASgOMioubm9tb3MucnVudGltZS52Mi5SdW50aW1lVW5hdmFpbGFibGVSZWFzb24SEQoJd29ya3NwYWNlGAIgASgJEhEKCXJldHJ5YWJsZRgDIAEoCBIfChJyZXRyeV9hZnRlcl9taWxsaXMYBCABKA1IAIgBARIOCgZkZXRhaWwYBSABKAlCFQoTX3JldHJ5X2FmdGVyX21pbGxpcyJ+Cg5SdW50aW1lUmVmdXNhbBI2CgZyZWFzb24YASABKA4yJi5ub21vcy5ydW50aW1lLnYyLlJ1bnRpbWVSZWZ1c2FsUmVhc29uEhEKCXdvcmtzcGFjZRgCIAEoCRIRCglyZXRyeWFibGUYAyABKAgSDgoGZGV0YWlsGAQgASgJIqUBChNEaWFnbm9zdGljQXR0cmlidXRlEgwKBG5hbWUYASABKAkSFgoMc3RyaW5nX3ZhbHVlGAIgASgJSAASFwoNaW50ZWdlcl92YWx1ZRgDIAEoEkgAEhYKDGRvdWJsZV92YWx1ZRgEIAEoAUgAEhcKDWJvb2xlYW5fdmFsdWUYBSABKAhIABIVCgtieXRlc192YWx1ZRgGIAEoDEgAQgcKBXZhbHVlIvALCgxSdW50aW1lRXZlbnQSEAoIc2VxdWVuY2UYASABKAQSFAoHc2Vzc2lvbhgCIAEoCUgBiAEBEi8KBXJlYWR5GAogASgLMh4ubm9tb3MucnVudGltZS52Mi5SdW50aW1lUmVhZHlIABI3Cg13YXRjaF9jaGFuZ2VkGAsgASgLMh4ubm9tb3MucnVudGltZS52Mi5XYXRjaENoYW5nZWRIABI5Cg5zeW5jX2NvbXBsZXRlZBgMIAEoCzIfLm5vbW9zLnJ1bnRpbWUudjIuU3luY0NvbXBsZXRlZEgAEjUKDGxpbmtfY2hhbmdlZBgNIAEoCzIdLm5vbW9zLnJ1bnRpbWUudjIuTGlua0NoYW5nZWRIABI5Cg5zaWduYWxfY2hhbmdlZBgOIAEoCzIfLm5vbW9zLnJ1bnRpbWUudjIuU2lnbmFsQ2hhbmdlZEgAEjsKD2N1c3RvZHlfY2hhbmdlZBgPIAEoCzIgLm5vbW9zLnJ1bnRpbWUudjIuQ3VzdG9keUNoYW5nZWRIABJCChNsb2NhbF93b3JrX3JlamVjdGVkGBAgASgLMiMubm9tb3MucnVudGltZS52Mi5Mb2NhbFdvcmtSZWplY3RlZEgAEjMKC2xhd19jaGFuZ2VkGBEgASgLMhwubm9tb3MucnVudGltZS52Mi5MYXdDaGFuZ2VkSAASQwoPa2VybmVsX3Byb2dyZXNzGBIgASgLMigubm9tb3MucnVudGltZS52Mi5LZXJuZWxQcm9ncmVzc09ic2VydmVkSAASLQoEc3BhbhgTIAEoCzIdLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZVNwYW5IABI/ChF0cmFuc2Zlcl9wcm9ncmVzcxgUIAEoCzIiLm5vbW9zLnJ1bnRpbWUudjIuVHJhbnNmZXJQcm9ncmVzc0gAEkkKFG1haW50ZW5hbmNlX3Byb2dyZXNzGBUgASgLMikubm9tb3MucnVudGltZS52Mi5SZWFkTWFpbnRlbmFuY2VQcm9ncmVzc0gAEjsKDXNvY2tldF9lZmZlY3QYFiABKAsyIi5ub21vcy5ydW50aW1lLnYyLlBlZXJTb2NrZXRFZmZlY3RIABJUChxjcmVkZW50aWFsX3JlZnJlc2hfcmVxdWVzdGVkGBcgASgLMiwubm9tb3MucnVudGltZS52Mi5DcmVkZW50aWFsUmVmcmVzaFJlcXVlc3RlZEgAElIKG3JlY2VpdmluZ19ncm91cF9jb252ZXJnZW5jZRgYIAEoCzIrLm5vbW9zLnJ1bnRpbWUudjIuUmVjZWl2aW5nR3JvdXBDb252ZXJnZW5jZUgAEkoKF21vZGVsX2Fkb3B0aW9uX3Byb2dyZXNzGBkgASgLMicubm9tb3MucnVudGltZS52Mi5Nb2RlbEFkb3B0aW9uUHJvZ3Jlc3NIABI7Cg9mb2xsb3dzX3N1bW1hcnkYGiABKAsyIC5ub21vcy5ydW50aW1lLnYyLkZvbGxvd3NTdW1tYXJ5SAASRAoUbG9jYWxfY29weV9wcmVzZXJ2ZWQYGyABKAsyJC5ub21vcy5ydW50aW1lLnYyLlByZXNlcnZlZExvY2FsQ29weUgAEk4KGWZvcmVpZ25fcGxhY2VtZW50X2lnbm9yZWQYHCABKAsyKS5ub21vcy5ydW50aW1lLnYyLkZvcmVpZ25QbGFjZW1lbnRJZ25vcmVkSAASQwoTYmluZGluZ19xdWFyYW50aW5lZBgdIAEoCzIkLm5vbW9zLnJ1bnRpbWUudjIuUXVhcmFudGluZWRCaW5kaW5nSAASPwoRd3JpdGVfcHJlcGFyYXRpb24YHiABKAsyIi5ub21vcy5ydW50aW1lLnYyLldyaXRlUHJlcGFyYXRpb25IABJKChdyZWFkX2FjY2Vzc19wcmVwYXJhdGlvbhgfIAEoCzInLm5vbW9zLnJ1bnRpbWUudjIuUmVhZEFjY2Vzc1ByZXBhcmF0aW9uSABCBwoFZXZlbnRCCgoIX3Nlc3Npb24ivAEKDkZvbGxvd3NTdW1tYXJ5EhAKCGZvbGxvd2VkGAEgASgNEg8KB3NldHRsZWQYAiABKA0SDAoEbGl2ZRgDIAEoDRI3Cgp3b3Jrc3BhY2VzGAQgAygLMiMubm9tb3MucnVudGltZS52Mi5Gb2xsb3dPYnNlcnZhdGlvbhIkChdvYnNlcnZlZF9hdF91bml4X21pbGxpcxgFIAEoBEgAiAEBQhoKGF9vYnNlcnZlZF9hdF91bml4X21pbGxpcyL7AwoRRm9sbG93T2JzZXJ2YXRpb24SEQoJd29ya3NwYWNlGAEgASgJEjcKBXBoYXNlGAIgASgOMigubm9tb3MucnVudGltZS52Mi5Gb2xsb3dPYnNlcnZhdGlvblBoYXNlEgwKBGxpdmUYAyABKAgSEwoGZGV0YWlsGAQgASgJSACIAQESIQoUcmV0cnlfYXRfdW5peF9taWxsaXMYBSABKARIAYgBARIfChJkdWVfYXRfdW5peF9taWxsaXMYBiABKARIAogBARIUCgdhdHRlbXB0GAcgASgNSAOIAQESGgoNYWN0aXZlX2VmZmVjdBgIIAEoCUgEiAEBEhMKBnVuc2VudBgJIAEoDUgFiAEBEhsKDnVuYWNrbm93bGVkZ2VkGAogASgNSAaIAQESQgoRY3VzdG9kaWFuX3dhcm1pbmcYCyABKAsyIi5ub21vcy5ydW50aW1lLnYyLkN1c3RvZGlhbldhcm1pbmdIB4gBAUIJCgdfZGV0YWlsQhcKFV9yZXRyeV9hdF91bml4X21pbGxpc0IVChNfZHVlX2F0X3VuaXhfbWlsbGlzQgoKCF9hdHRlbXB0QhAKDl9hY3RpdmVfZWZmZWN0QgkKB191bnNlbnRCEQoPX3VuYWNrbm93bGVkZ2VkQhQKEl9jdXN0b2RpYW5fd2FybWluZyKFAQoQQ3VzdG9kaWFuV2FybWluZxIZChFzaW5jZV91bml4X21pbGxpcxgBIAEoBBIiChpleHBlY3RlZF9yZWFkeV91bml4X21pbGxpcxgCIAEoBBIhChlzdGFsbGVkX2FmdGVyX3VuaXhfbWlsbGlzGAMgASgEEg8KB3N0YWxsZWQYBCABKAgiVgoaQ3JlZGVudGlhbFJlZnJlc2hSZXF1ZXN0ZWQSOAoHcGVuZGluZxgBIAEoCzInLm5vbW9zLnJ1bnRpbWUudjIuQ29ycmVzcG9uZGVuY2VQZW5kaW5nIj4KDFJ1bnRpbWVSZWFkeRIXCg9ydW50aW1lX3ZlcnNpb24YASABKAkSFQoNa2VybmVsX3NoYTI1NhgCIAEoDCKNAwoMV2F0Y2hDaGFuZ2VkEhcKD3N1YnNjcmlwdGlvbl9pZBgBIAEoCRITCgtyZXN1bHRfdXNkYRgCIAEoDBI2CgdmYWlsdXJlGAMgASgLMiAubm9tb3MucnVudGltZS52Mi5SdW50aW1lRmFpbHVyZUgAiAEBEjUKEmFwcGxpY2F0aW9uX3Jlc3VsdBgEIAEoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnlIAYgBARIaCg1pbnRlZ2VyX3ZhbHVlGAUgASgDSAKIAQESRwoRYXBwbGljYXRpb25fZGVsdGEYBiABKAsyJy5ub21vcy5rZXJuZWwudjEuQXBwbGljYXRpb25SZXN1bHREZWx0YUgDiAEBEhwKD3Jlc3VsdF9mcm9udGllchgHIAEoCUgEiAEBQgoKCF9mYWlsdXJlQhUKE19hcHBsaWNhdGlvbl9yZXN1bHRCEAoOX2ludGVnZXJfdmFsdWVCFAoSX2FwcGxpY2F0aW9uX2RlbHRhQhIKEF9yZXN1bHRfZnJvbnRpZXIinAEKDVN5bmNDb21wbGV0ZWQSDgoGcmVhc29uGAEgASgJEjcKBnJlc3VsdBgCIAEoCzInLm5vbW9zLnJ1bnRpbWUudjIuU3luY1dvcmtzcGFjZVJlc3BvbnNlEjYKB2ZhaWx1cmUYAyABKAsyIC5ub21vcy5ydW50aW1lLnYyLlJ1bnRpbWVGYWlsdXJlSACIAQFCCgoIX2ZhaWx1cmUigAEKC0xpbmtDaGFuZ2VkEiwKBnN0YXR1cxgBIAEoDjIcLm5vbW9zLnJ1bnRpbWUudjIuTGlua1N0YXR1cxI3CgdjbG9zdXJlGAIgASgLMiEubm9tb3MucnVudGltZS52Mi5MaXZlTGlua0Nsb3N1cmVIAIgBAUIKCghfY2xvc3VyZSI4Cg1TaWduYWxDaGFuZ2VkEg4KBmRvbWFpbhgBIAEoCRIXCg9wcm9qZWN0aW9uX3VzZGEYAiABKAwiUAoKTGF3Q2hhbmdlZBIOCgZkb21haW4YASABKAkSFgoOcGFja2FnZV9zaGEyNTYYAiABKAkSGgoSY29tcGF0aWJpbGl0eV91c2RhGAMgASgMIt0BCgtSdW50aW1lU3BhbhIQCgh0cmFjZV9pZBgBIAEoDBIPCgdzcGFuX2lkGAIgASgMEhsKDnBhcmVudF9zcGFuX2lkGAMgASgMSACIAQESDAoEbmFtZRgEIAEoCRIaChJzdGFydGVkX3VuaXhfbmFub3MYBSABKAQSFgoOZHVyYXRpb25fbmFub3MYBiABKAQSOQoKYXR0cmlidXRlcxgHIAMoCzIlLm5vbW9zLnJ1bnRpbWUudjIuRGlhZ25vc3RpY0F0dHJpYnV0ZUIRCg9fcGFyZW50X3NwYW5faWQi6gEKFktlcm5lbFByb2dyZXNzT2JzZXJ2ZWQSOQoIc25hcHNob3QYASABKAsyJy5ub21vcy5rZXJuZWwudjEuS2VybmVsUHJvZ3Jlc3NTbmFwc2hvdBIkChxob3N0X29ic2VydmVkX2VsYXBzZWRfbWljcm9zGAIgASgEEioKImhvc3Rfb2JzZXJ2ZWRfcGhhc2VfZWxhcHNlZF9taWNyb3MYAyABKAQSHgoWcHJvY2Vzc19yZXNpZGVudF9ieXRlcxgEIAEoBBIjChtwcm9jZXNzX3BlYWtfcmVzaWRlbnRfYnl0ZXMYBSABKAQiggEKEFRyYW5zZmVyUHJvZ3Jlc3MSFgoOcmVjZWl2ZWRfYnl0ZXMYASABKAQSGAoLdG90YWxfYnl0ZXMYAiABKARIAIgBARIsCgRraW5kGAMgASgOMh4ubm9tb3MucnVudGltZS52Mi5UcmFuc2ZlcktpbmRCDgoMX3RvdGFsX2J5dGVzIjkKEFdyaXRlUHJlcGFyYXRpb24SEgoKcmVxdWVzdF9pZBgBIAEoCRIRCgl3b3Jrc3BhY2UYAiABKAkiPgoVUmVhZEFjY2Vzc1ByZXBhcmF0aW9uEhIKCnJlcXVlc3RfaWQYASABKAkSEQoJd29ya3NwYWNlGAIgASgJKsoBChJSdW50aW1lRmFpbHVyZUtpbmQSJAogUlVOVElNRV9GQUlMVVJFX0tJTkRfVU5TUEVDSUZJRUQQABIhCh1SVU5USU1FX0ZBSUxVUkVfS0lORF9JTlRFUk5BTBABEiEKHVJVTlRJTUVfRkFJTFVSRV9LSU5EX1BST1RPQ09MEAISIgoeUlVOVElNRV9GQUlMVVJFX0tJTkRfSU5URUdSSVRZEAMSJAogUlVOVElNRV9GQUlMVVJFX0tJTkRfVU5TVVBQT1JURUQQBCqnAwoYUnVudGltZVVuYXZhaWxhYmxlUmVhc29uEioKJlJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1VOU1BFQ0lGSUVEEAASMgouUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fUkVNT1RFX09OTFlfT0ZGTElORRABEjEKLVJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1JFTU9URV9VTlJFQUNIQUJMRRACEi0KKVJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1JFTU9URV9USU1FT1VUEAMSNgoyUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fTE9DQUxfUkVQTElDQV9OT1RfUkVBRFkQBBI1CjFSVU5USU1FX1VOQVZBSUxBQkxFX1JFQVNPTl9DUkVERU5USUFMX1VOQVZBSUxBQkxFEAUSMAosUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fV09SS1NQQUNFX09QRU5JTkcQBhIoCiRSVU5USU1FX1VOQVZBSUxBQkxFX1JFQVNPTl9QRUVSX0JVU1kQByrwAQoUUnVudGltZVJlZnVzYWxSZWFzb24SJgoiUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9VTlNQRUNJRklFRBAAEi0KKVJVTlRJTUVfUkVGVVNBTF9SRUFTT05fSU5WQUxJRF9DUkVERU5USUFMEAESKAokUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9BQ0NFU1NfREVOSUVEEAISKwonUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9QTEFDRU1FTlRfUE9MSUNZEAMSKgomUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9TRVNTSU9OX1VOQk9VTkQQBCqVBAoWRm9sbG93T2JzZXJ2YXRpb25QaGFzZRIoCiRGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfVU5TUEVDSUZJRUQQABIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfREVTSVJFRBABEiAKHEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9EVUUQAhIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfUlVOTklORxADEiQKIEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9TRVRUTEVEEAQSMAosRk9MTE9XX09CU0VSVkFUSU9OX1BIQVNFX0FXQUlUSU5HX0RFUEVOREVOQ1kQBRIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfT0ZGTElORRAGEi8KK0ZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9JTlZBTElEX0NSRURFTlRJQUwQBxIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfQkFDS09GRhAIEiwKKEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9SRUJPUk5fUkVNT1RFTFkQCRIsCihGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfUkVQTEFDSU5HX0xPQ0FMEAoSMgouRk9MTE9XX09CU0VSVkFUSU9OX1BIQVNFX0xPQ0FMX0NPUFlfVU5SRUFEQUJMRRALKlcKCkxpbmtTdGF0dXMSGwoXTElOS19TVEFUVVNfVU5TUEVDSUZJRUQQABIUChBMSU5LX1NUQVRVU19PUEVOEAESFgoSTElOS19TVEFUVVNfQ0xPU0VEEAIqdgoMVHJhbnNmZXJLaW5kEh0KGVRSQU5TRkVSX0tJTkRfVU5TUEVDSUZJRUQQABIXChNUUkFOU0ZFUl9LSU5EX0RFTFRBEAESFgoSVFJBTlNGRVJfS0lORF9GVUxMEAISFgoSVFJBTlNGRVJfS0lORF9QVVNIEANiBnByb3RvMw", [file_google_protobuf_any2, 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]);
660
+ var file_nomos_runtime_v2_observability_desk = /* @__PURE__ */ fileDesc21("Cilub21vcy9ydW50aW1lL3YyL29ic2VydmFiaWxpdHlfZGVzay5wcm90bxIQbm9tb3MucnVudGltZS52MiJCCgxUcmFjZUNvbnRleHQSEAoIdHJhY2VfaWQYASABKAwSDwoHc3Bhbl9pZBgCIAEoDBIPCgdzYW1wbGVkGAMgASgIIp0CCg5SdW50aW1lRmFpbHVyZRIMCgRjb2RlGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSEQoJY29tcG9uZW50GAMgASgJEhYKCXdvcmtzcGFjZRgEIAEoCUgAiAEBEhMKBmRvbWFpbhgFIAEoCUgBiAEBEhYKCWRpcmVjdGl2ZRgGIAEoCUgCiAEBEjkKCmF0dHJpYnV0ZXMYByADKAsyJS5ub21vcy5ydW50aW1lLnYyLkRpYWdub3N0aWNBdHRyaWJ1dGUSMgoEa2luZBgIIAEoDjIkLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZUZhaWx1cmVLaW5kQgwKCl93b3Jrc3BhY2VCCQoHX2RvbWFpbkIMCgpfZGlyZWN0aXZlIr4BChJSdW50aW1lVW5hdmFpbGFibGUSOgoGcmVhc29uGAEgASgOMioubm9tb3MucnVudGltZS52Mi5SdW50aW1lVW5hdmFpbGFibGVSZWFzb24SEQoJd29ya3NwYWNlGAIgASgJEhEKCXJldHJ5YWJsZRgDIAEoCBIfChJyZXRyeV9hZnRlcl9taWxsaXMYBCABKA1IAIgBARIOCgZkZXRhaWwYBSABKAlCFQoTX3JldHJ5X2FmdGVyX21pbGxpcyJ+Cg5SdW50aW1lUmVmdXNhbBI2CgZyZWFzb24YASABKA4yJi5ub21vcy5ydW50aW1lLnYyLlJ1bnRpbWVSZWZ1c2FsUmVhc29uEhEKCXdvcmtzcGFjZRgCIAEoCRIRCglyZXRyeWFibGUYAyABKAgSDgoGZGV0YWlsGAQgASgJIqUBChNEaWFnbm9zdGljQXR0cmlidXRlEgwKBG5hbWUYASABKAkSFgoMc3RyaW5nX3ZhbHVlGAIgASgJSAASFwoNaW50ZWdlcl92YWx1ZRgDIAEoEkgAEhYKDGRvdWJsZV92YWx1ZRgEIAEoAUgAEhcKDWJvb2xlYW5fdmFsdWUYBSABKAhIABIVCgtieXRlc192YWx1ZRgGIAEoDEgAQgcKBXZhbHVlIvALCgxSdW50aW1lRXZlbnQSEAoIc2VxdWVuY2UYASABKAQSFAoHc2Vzc2lvbhgCIAEoCUgBiAEBEi8KBXJlYWR5GAogASgLMh4ubm9tb3MucnVudGltZS52Mi5SdW50aW1lUmVhZHlIABI3Cg13YXRjaF9jaGFuZ2VkGAsgASgLMh4ubm9tb3MucnVudGltZS52Mi5XYXRjaENoYW5nZWRIABI5Cg5zeW5jX2NvbXBsZXRlZBgMIAEoCzIfLm5vbW9zLnJ1bnRpbWUudjIuU3luY0NvbXBsZXRlZEgAEjUKDGxpbmtfY2hhbmdlZBgNIAEoCzIdLm5vbW9zLnJ1bnRpbWUudjIuTGlua0NoYW5nZWRIABI5Cg5zaWduYWxfY2hhbmdlZBgOIAEoCzIfLm5vbW9zLnJ1bnRpbWUudjIuU2lnbmFsQ2hhbmdlZEgAEjsKD2N1c3RvZHlfY2hhbmdlZBgPIAEoCzIgLm5vbW9zLnJ1bnRpbWUudjIuQ3VzdG9keUNoYW5nZWRIABJCChNsb2NhbF93b3JrX3JlamVjdGVkGBAgASgLMiMubm9tb3MucnVudGltZS52Mi5Mb2NhbFdvcmtSZWplY3RlZEgAEjMKC2xhd19jaGFuZ2VkGBEgASgLMhwubm9tb3MucnVudGltZS52Mi5MYXdDaGFuZ2VkSAASQwoPa2VybmVsX3Byb2dyZXNzGBIgASgLMigubm9tb3MucnVudGltZS52Mi5LZXJuZWxQcm9ncmVzc09ic2VydmVkSAASLQoEc3BhbhgTIAEoCzIdLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZVNwYW5IABI/ChF0cmFuc2Zlcl9wcm9ncmVzcxgUIAEoCzIiLm5vbW9zLnJ1bnRpbWUudjIuVHJhbnNmZXJQcm9ncmVzc0gAEkkKFG1haW50ZW5hbmNlX3Byb2dyZXNzGBUgASgLMikubm9tb3MucnVudGltZS52Mi5SZWFkTWFpbnRlbmFuY2VQcm9ncmVzc0gAEjsKDXNvY2tldF9lZmZlY3QYFiABKAsyIi5ub21vcy5ydW50aW1lLnYyLlBlZXJTb2NrZXRFZmZlY3RIABJUChxjcmVkZW50aWFsX3JlZnJlc2hfcmVxdWVzdGVkGBcgASgLMiwubm9tb3MucnVudGltZS52Mi5DcmVkZW50aWFsUmVmcmVzaFJlcXVlc3RlZEgAElIKG3JlY2VpdmluZ19ncm91cF9jb252ZXJnZW5jZRgYIAEoCzIrLm5vbW9zLnJ1bnRpbWUudjIuUmVjZWl2aW5nR3JvdXBDb252ZXJnZW5jZUgAEkoKF21vZGVsX2Fkb3B0aW9uX3Byb2dyZXNzGBkgASgLMicubm9tb3MucnVudGltZS52Mi5Nb2RlbEFkb3B0aW9uUHJvZ3Jlc3NIABI7Cg9mb2xsb3dzX3N1bW1hcnkYGiABKAsyIC5ub21vcy5ydW50aW1lLnYyLkZvbGxvd3NTdW1tYXJ5SAASRAoUbG9jYWxfY29weV9wcmVzZXJ2ZWQYGyABKAsyJC5ub21vcy5ydW50aW1lLnYyLlByZXNlcnZlZExvY2FsQ29weUgAEk4KGWZvcmVpZ25fcGxhY2VtZW50X2lnbm9yZWQYHCABKAsyKS5ub21vcy5ydW50aW1lLnYyLkZvcmVpZ25QbGFjZW1lbnRJZ25vcmVkSAASQwoTYmluZGluZ19xdWFyYW50aW5lZBgdIAEoCzIkLm5vbW9zLnJ1bnRpbWUudjIuUXVhcmFudGluZWRCaW5kaW5nSAASPwoRd3JpdGVfcHJlcGFyYXRpb24YHiABKAsyIi5ub21vcy5ydW50aW1lLnYyLldyaXRlUHJlcGFyYXRpb25IABJKChdyZWFkX2FjY2Vzc19wcmVwYXJhdGlvbhgfIAEoCzInLm5vbW9zLnJ1bnRpbWUudjIuUmVhZEFjY2Vzc1ByZXBhcmF0aW9uSABCBwoFZXZlbnRCCgoIX3Nlc3Npb24ivAEKDkZvbGxvd3NTdW1tYXJ5EhAKCGZvbGxvd2VkGAEgASgNEg8KB3NldHRsZWQYAiABKA0SDAoEbGl2ZRgDIAEoDRI3Cgp3b3Jrc3BhY2VzGAQgAygLMiMubm9tb3MucnVudGltZS52Mi5Gb2xsb3dPYnNlcnZhdGlvbhIkChdvYnNlcnZlZF9hdF91bml4X21pbGxpcxgFIAEoBEgAiAEBQhoKGF9vYnNlcnZlZF9hdF91bml4X21pbGxpcyL7AwoRRm9sbG93T2JzZXJ2YXRpb24SEQoJd29ya3NwYWNlGAEgASgJEjcKBXBoYXNlGAIgASgOMigubm9tb3MucnVudGltZS52Mi5Gb2xsb3dPYnNlcnZhdGlvblBoYXNlEgwKBGxpdmUYAyABKAgSEwoGZGV0YWlsGAQgASgJSACIAQESIQoUcmV0cnlfYXRfdW5peF9taWxsaXMYBSABKARIAYgBARIfChJkdWVfYXRfdW5peF9taWxsaXMYBiABKARIAogBARIUCgdhdHRlbXB0GAcgASgNSAOIAQESGgoNYWN0aXZlX2VmZmVjdBgIIAEoCUgEiAEBEhMKBnVuc2VudBgJIAEoDUgFiAEBEhsKDnVuYWNrbm93bGVkZ2VkGAogASgNSAaIAQESQgoRY3VzdG9kaWFuX3dhcm1pbmcYCyABKAsyIi5ub21vcy5ydW50aW1lLnYyLkN1c3RvZGlhbldhcm1pbmdIB4gBAUIJCgdfZGV0YWlsQhcKFV9yZXRyeV9hdF91bml4X21pbGxpc0IVChNfZHVlX2F0X3VuaXhfbWlsbGlzQgoKCF9hdHRlbXB0QhAKDl9hY3RpdmVfZWZmZWN0QgkKB191bnNlbnRCEQoPX3VuYWNrbm93bGVkZ2VkQhQKEl9jdXN0b2RpYW5fd2FybWluZyKFAQoQQ3VzdG9kaWFuV2FybWluZxIZChFzaW5jZV91bml4X21pbGxpcxgBIAEoBBIiChpleHBlY3RlZF9yZWFkeV91bml4X21pbGxpcxgCIAEoBBIhChlzdGFsbGVkX2FmdGVyX3VuaXhfbWlsbGlzGAMgASgEEg8KB3N0YWxsZWQYBCABKAgiVgoaQ3JlZGVudGlhbFJlZnJlc2hSZXF1ZXN0ZWQSOAoHcGVuZGluZxgBIAEoCzInLm5vbW9zLnJ1bnRpbWUudjIuQ29ycmVzcG9uZGVuY2VQZW5kaW5nIj4KDFJ1bnRpbWVSZWFkeRIXCg9ydW50aW1lX3ZlcnNpb24YASABKAkSFQoNa2VybmVsX3NoYTI1NhgCIAEoDCKNAwoMV2F0Y2hDaGFuZ2VkEhcKD3N1YnNjcmlwdGlvbl9pZBgBIAEoCRITCgtyZXN1bHRfdXNkYRgCIAEoDBI2CgdmYWlsdXJlGAMgASgLMiAubm9tb3MucnVudGltZS52Mi5SdW50aW1lRmFpbHVyZUgAiAEBEjUKEmFwcGxpY2F0aW9uX3Jlc3VsdBgEIAEoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnlIAYgBARIaCg1pbnRlZ2VyX3ZhbHVlGAUgASgDSAKIAQESRwoRYXBwbGljYXRpb25fZGVsdGEYBiABKAsyJy5ub21vcy5rZXJuZWwudjEuQXBwbGljYXRpb25SZXN1bHREZWx0YUgDiAEBEhwKD3Jlc3VsdF9mcm9udGllchgHIAEoCUgEiAEBQgoKCF9mYWlsdXJlQhUKE19hcHBsaWNhdGlvbl9yZXN1bHRCEAoOX2ludGVnZXJfdmFsdWVCFAoSX2FwcGxpY2F0aW9uX2RlbHRhQhIKEF9yZXN1bHRfZnJvbnRpZXIinAEKDVN5bmNDb21wbGV0ZWQSDgoGcmVhc29uGAEgASgJEjcKBnJlc3VsdBgCIAEoCzInLm5vbW9zLnJ1bnRpbWUudjIuU3luY1dvcmtzcGFjZVJlc3BvbnNlEjYKB2ZhaWx1cmUYAyABKAsyIC5ub21vcy5ydW50aW1lLnYyLlJ1bnRpbWVGYWlsdXJlSACIAQFCCgoIX2ZhaWx1cmUigAEKC0xpbmtDaGFuZ2VkEiwKBnN0YXR1cxgBIAEoDjIcLm5vbW9zLnJ1bnRpbWUudjIuTGlua1N0YXR1cxI3CgdjbG9zdXJlGAIgASgLMiEubm9tb3MucnVudGltZS52Mi5MaXZlTGlua0Nsb3N1cmVIAIgBAUIKCghfY2xvc3VyZSI4Cg1TaWduYWxDaGFuZ2VkEg4KBmRvbWFpbhgBIAEoCRIXCg9wcm9qZWN0aW9uX3VzZGEYAiABKAwiUAoKTGF3Q2hhbmdlZBIOCgZkb21haW4YASABKAkSFgoOcGFja2FnZV9zaGEyNTYYAiABKAkSGgoSY29tcGF0aWJpbGl0eV91c2RhGAMgASgMIt0BCgtSdW50aW1lU3BhbhIQCgh0cmFjZV9pZBgBIAEoDBIPCgdzcGFuX2lkGAIgASgMEhsKDnBhcmVudF9zcGFuX2lkGAMgASgMSACIAQESDAoEbmFtZRgEIAEoCRIaChJzdGFydGVkX3VuaXhfbmFub3MYBSABKAQSFgoOZHVyYXRpb25fbmFub3MYBiABKAQSOQoKYXR0cmlidXRlcxgHIAMoCzIlLm5vbW9zLnJ1bnRpbWUudjIuRGlhZ25vc3RpY0F0dHJpYnV0ZUIRCg9fcGFyZW50X3NwYW5faWQi6gEKFktlcm5lbFByb2dyZXNzT2JzZXJ2ZWQSOQoIc25hcHNob3QYASABKAsyJy5ub21vcy5rZXJuZWwudjEuS2VybmVsUHJvZ3Jlc3NTbmFwc2hvdBIkChxob3N0X29ic2VydmVkX2VsYXBzZWRfbWljcm9zGAIgASgEEioKImhvc3Rfb2JzZXJ2ZWRfcGhhc2VfZWxhcHNlZF9taWNyb3MYAyABKAQSHgoWcHJvY2Vzc19yZXNpZGVudF9ieXRlcxgEIAEoBBIjChtwcm9jZXNzX3BlYWtfcmVzaWRlbnRfYnl0ZXMYBSABKAQiggEKEFRyYW5zZmVyUHJvZ3Jlc3MSFgoOcmVjZWl2ZWRfYnl0ZXMYASABKAQSGAoLdG90YWxfYnl0ZXMYAiABKARIAIgBARIsCgRraW5kGAMgASgOMh4ubm9tb3MucnVudGltZS52Mi5UcmFuc2ZlcktpbmRCDgoMX3RvdGFsX2J5dGVzIjkKEFdyaXRlUHJlcGFyYXRpb24SEgoKcmVxdWVzdF9pZBgBIAEoCRIRCgl3b3Jrc3BhY2UYAiABKAkiPgoVUmVhZEFjY2Vzc1ByZXBhcmF0aW9uEhIKCnJlcXVlc3RfaWQYASABKAkSEQoJd29ya3NwYWNlGAIgASgJKsoBChJSdW50aW1lRmFpbHVyZUtpbmQSJAogUlVOVElNRV9GQUlMVVJFX0tJTkRfVU5TUEVDSUZJRUQQABIhCh1SVU5USU1FX0ZBSUxVUkVfS0lORF9JTlRFUk5BTBABEiEKHVJVTlRJTUVfRkFJTFVSRV9LSU5EX1BST1RPQ09MEAISIgoeUlVOVElNRV9GQUlMVVJFX0tJTkRfSU5URUdSSVRZEAMSJAogUlVOVElNRV9GQUlMVVJFX0tJTkRfVU5TVVBQT1JURUQQBCqnAwoYUnVudGltZVVuYXZhaWxhYmxlUmVhc29uEioKJlJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1VOU1BFQ0lGSUVEEAASMgouUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fUkVNT1RFX09OTFlfT0ZGTElORRABEjEKLVJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1JFTU9URV9VTlJFQUNIQUJMRRACEi0KKVJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1JFTU9URV9USU1FT1VUEAMSNgoyUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fTE9DQUxfUkVQTElDQV9OT1RfUkVBRFkQBBI1CjFSVU5USU1FX1VOQVZBSUxBQkxFX1JFQVNPTl9DUkVERU5USUFMX1VOQVZBSUxBQkxFEAUSMAosUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fV09SS1NQQUNFX09QRU5JTkcQBhIoCiRSVU5USU1FX1VOQVZBSUxBQkxFX1JFQVNPTl9QRUVSX0JVU1kQByrwAQoUUnVudGltZVJlZnVzYWxSZWFzb24SJgoiUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9VTlNQRUNJRklFRBAAEi0KKVJVTlRJTUVfUkVGVVNBTF9SRUFTT05fSU5WQUxJRF9DUkVERU5USUFMEAESKAokUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9BQ0NFU1NfREVOSUVEEAISKwonUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9QTEFDRU1FTlRfUE9MSUNZEAMSKgomUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9TRVNTSU9OX1VOQk9VTkQQBCrCBAoWRm9sbG93T2JzZXJ2YXRpb25QaGFzZRIoCiRGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfVU5TUEVDSUZJRUQQABIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfREVTSVJFRBABEiAKHEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9EVUUQAhIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfUlVOTklORxADEiQKIEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9TRVRUTEVEEAQSMAosRk9MTE9XX09CU0VSVkFUSU9OX1BIQVNFX0FXQUlUSU5HX0RFUEVOREVOQ1kQBRIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfT0ZGTElORRAGEi8KK0ZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9JTlZBTElEX0NSRURFTlRJQUwQBxIkCiBGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfQkFDS09GRhAIEiwKKEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9SRUJPUk5fUkVNT1RFTFkQCRIsCihGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfUkVQTEFDSU5HX0xPQ0FMEAoSMgouRk9MTE9XX09CU0VSVkFUSU9OX1BIQVNFX0xPQ0FMX0NPUFlfVU5SRUFEQUJMRRALEisKJ0ZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9LRVJORUxfUkVGVVNFRBAMKlcKCkxpbmtTdGF0dXMSGwoXTElOS19TVEFUVVNfVU5TUEVDSUZJRUQQABIUChBMSU5LX1NUQVRVU19PUEVOEAESFgoSTElOS19TVEFUVVNfQ0xPU0VEEAIqdgoMVHJhbnNmZXJLaW5kEh0KGVRSQU5TRkVSX0tJTkRfVU5TUEVDSUZJRUQQABIXChNUUkFOU0ZFUl9LSU5EX0RFTFRBEAESFgoSVFJBTlNGRVJfS0lORF9GVUxMEAISFgoSVFJBTlNGRVJfS0lORF9QVVNIEANiBnByb3RvMw", [file_google_protobuf_any2, 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]);
659
661
  var RuntimeFailureSchema = /* @__PURE__ */ messageDesc21(file_nomos_runtime_v2_observability_desk, 1);
660
662
  var RuntimeUnavailableSchema = /* @__PURE__ */ messageDesc21(file_nomos_runtime_v2_observability_desk, 2);
661
663
  var RuntimeRefusalSchema = /* @__PURE__ */ messageDesc21(file_nomos_runtime_v2_observability_desk, 3);
@@ -2036,7 +2038,15 @@ async function replyStream(ports, request) {
2036
2038
  } } })];
2037
2039
  for (const frame2 of frames) {
2038
2040
  const bytes = toBinary3(LiveOfferFrameSchema, frame2);
2039
- if (bytes.byteLength <= LIVE_FRAME_LIMIT) ports.reply(bytes);
2041
+ if (bytes.byteLength <= LIVE_FRAME_LIMIT) {
2042
+ ports.reply(bytes);
2043
+ continue;
2044
+ }
2045
+ ports.reply(toBinary3(LiveOfferFrameSchema, create3(LiveOfferFrameSchema, { message: { case: "refusal", value: {
2046
+ requestId: request.case === "history" || request.case === "ref" ? request.value.requestId : "",
2047
+ code: "nomos.stream.frame_too_large",
2048
+ message: `a ${frame2.message.case ?? "stream"} frame of ${bytes.byteLength} bytes exceeds the live frame limit`
2049
+ } } })));
2040
2050
  }
2041
2051
  }
2042
2052
  var PLACEMENT_REF = "refs/nomos/placement";
@@ -2057,7 +2067,7 @@ function refRing(ref, oid) {
2057
2067
  }
2058
2068
 
2059
2069
  // ../platform-shells/node/local-development/live_sockets.ts
2060
- function relayPorts(office, workspace, next, reply, broadcast) {
2070
+ function relayPorts(office, workspace, next, reply, broadcast, ringMain) {
2061
2071
  const invoke2 = async (request) => {
2062
2072
  const session = `custody-admission:${workspace}`;
2063
2073
  return fromBinary4(RuntimeResponseSchema, await office.invoke({
@@ -2075,7 +2085,9 @@ function relayPorts(office, workspace, next, reply, broadcast) {
2075
2085
  reply,
2076
2086
  admit: async (batch) => {
2077
2087
  const response = await invoke2({ command: { case: "admitCustodyOffers", value: batch } });
2078
- return response.outcome.case === "custodyOffersAdmitted" ? response.outcome.value : void 0;
2088
+ const admission = response.outcome.case === "custodyOffersAdmitted" ? response.outcome.value : void 0;
2089
+ if (admission?.main) ringMain?.(admission.main);
2090
+ return admission;
2079
2091
  },
2080
2092
  serve: async (request) => {
2081
2093
  const response = await invoke2({ command: { case: "serveLiveStream", value: request } });
@@ -2136,6 +2148,10 @@ function openLiveSockets(server, office) {
2136
2148
  const bytes = toBinary4(LiveOfferFrameSchema, create4(LiveOfferFrameSchema, { message: { case: "offers", value: batch } }));
2137
2149
  if (bytes.length <= LIVE_FRAME_LIMIT) broadcast(workspace, bytes);
2138
2150
  },
2151
+ /** Main moved (an admission): ring followers, which take the offers from their streams. */
2152
+ main(workspace, oid) {
2153
+ broadcast(workspace, refRing("main", oid));
2154
+ },
2139
2155
  /** A placement-only change moves no main, so no offer frame tells followers: ring them. */
2140
2156
  placement(workspace, frontier) {
2141
2157
  broadcast(workspace, refRing(PLACEMENT_REF, frontier));
@@ -3587,6 +3603,11 @@ var kernelReadinessPending = (message) => {
3587
3603
  if (!READINESS_DEBT.test(message)) return void 0;
3588
3604
  return new KernelReadinessPending(/source workspace '([^']+)'/.exec(message)?.[1]?.trim(), message);
3589
3605
  };
3606
+ 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/;
3607
+ var kernelReadIndexBuilding = (message) => {
3608
+ const workspace = READ_INDEX_BUILDING.exec(message)?.[1]?.trim();
3609
+ return workspace === void 0 ? void 0 : { workspace };
3610
+ };
3590
3611
  var requiredForeignWorkspace = (message) => {
3591
3612
  const patterns = [
3592
3613
  /workspace '([^']+)' must be resident in the kernel/,
@@ -3610,9 +3631,31 @@ function throwIfKernelControlRequired(failure2) {
3610
3631
  throw new KernelWorkspaceResidencyRequired(workspace, failure2.message);
3611
3632
  }
3612
3633
  }
3634
+ var KernelRefusal = class extends Error {
3635
+ code;
3636
+ failure;
3637
+ constructor(failure2) {
3638
+ super(`${failure2.code}: ${failure2.message}`);
3639
+ this.name = "KernelRefusal";
3640
+ this.code = failure2.code;
3641
+ this.failure = failure2;
3642
+ }
3643
+ };
3613
3644
  function throwKernelFailure(failure2) {
3614
3645
  throwIfKernelControlRequired(failure2);
3615
- throw new Error(`${failure2.code}: ${failure2.message}`);
3646
+ throw new KernelRefusal(failure2);
3647
+ }
3648
+ var KERNEL_FAILURE_TEXT = /^(NMS-[A-Z0-9]+(?:-[A-Z0-9]+)*): ([\s\S]*)$/;
3649
+ 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;
3650
+ function deterministicKernelRefusal(error) {
3651
+ if (error instanceof KernelWorkspaceResidencyRequired || error instanceof KernelHistoryRequired || error instanceof KernelReadinessPending) return void 0;
3652
+ if (error instanceof KernelRefusal && (error.failure.historyRequired !== void 0 || error.failure.identityProviderWitnessRequired !== void 0)) return void 0;
3653
+ const text2 = error instanceof Error ? error.message : typeof error === "string" ? error : "";
3654
+ const match = KERNEL_FAILURE_TEXT.exec(text2);
3655
+ if (!match) return void 0;
3656
+ const [, code, message] = match;
3657
+ if (ENVIRONMENTAL.test(text2) || READINESS_DEBT.test(message) || requiredForeignWorkspace(message) !== void 0) return void 0;
3658
+ return { code, message };
3616
3659
  }
3617
3660
  function rethrowTypedKernelFailure(error) {
3618
3661
  if (error instanceof KernelWorkspaceResidencyRequired || error instanceof KernelHistoryRequired) throw error;
@@ -4640,8 +4683,9 @@ function memoryCheckpointStaging() {
4640
4683
 
4641
4684
  // ../peer-office/src/runtime/live_inbound_stream.ts
4642
4685
  var LEVEL_BATCH = "level:";
4686
+ var HISTORY_REQUIRED = "nomos.stream.history_required";
4687
+ var CONTAINMENT_ASK_SUFFIX = ":contain";
4643
4688
  var STREAM_WINDOW_CHUNKS = 8;
4644
- var ASK_AGAIN_NANOS = 15000000000n;
4645
4689
  var historySlot = (workspace) => `${workspace}#history`;
4646
4690
  var LiveInboundStream = class {
4647
4691
  #ports;
@@ -4659,7 +4703,10 @@ var LiveInboundStream = class {
4659
4703
  }
4660
4704
  return inbound;
4661
4705
  }
4662
- /** When this workspace's stream last delivered anything (a waiting procedure is progressing). */
4706
+ /** When this workspace's stream last delivered data to an ask (a waiting procedure is progressing).
4707
+ * A refusal, a frontier, unrelated traffic on the socket and this copy's own re-asking are not
4708
+ * progress: a procedure whose stream only ever says "ask again" gives up and its round fails over
4709
+ * (CAP-838). */
4663
4710
  lastHeard(workspace) {
4664
4711
  return this.#by.get(workspace)?.lastHeard;
4665
4712
  }
@@ -4682,7 +4729,8 @@ var LiveInboundStream = class {
4682
4729
  inbound.wants.level = {
4683
4730
  effectId: effect.effectId,
4684
4731
  maxOffers: Math.max(1, request.value.maxOffers),
4685
- remountAfterOffers: request.value.remountAfterOffers
4732
+ remountAfterOffers: request.value.remountAfterOffers,
4733
+ contain: effect.effectId.endsWith(CONTAINMENT_ASK_SUFFIX)
4686
4734
  };
4687
4735
  this.#askLevel(effect.workspace, inbound);
4688
4736
  }
@@ -4742,7 +4790,7 @@ var LiveInboundStream = class {
4742
4790
  const batch = inbound.levelBatch;
4743
4791
  if (batch) {
4744
4792
  inbound.levelBatch = void 0;
4745
- if (batch.base === this.#ports.head(effect.workspace)) {
4793
+ if (batch.base === this.#ports.head(effect.workspace) || batch.base === request.value.head) {
4746
4794
  inbound.wants.level = void 0;
4747
4795
  return create11(PeerStreamReceiptSchema, {
4748
4796
  outcome: { case: "pack", value: batch },
@@ -4753,14 +4801,14 @@ var LiveInboundStream = class {
4753
4801
  this.#askLevel(effect.workspace, inbound);
4754
4802
  }
4755
4803
  const head = this.#ports.head(effect.workspace);
4756
- if (head && inbound.announced && head === inbound.announced) {
4804
+ if (inbound.announced && (head === inbound.announced || inbound.askedFrom === inbound.announced)) {
4757
4805
  inbound.wants.level = void 0;
4758
4806
  return create11(PeerStreamReceiptSchema, {
4759
- outcome: { case: "level", value: head },
4807
+ outcome: { case: "level", value: inbound.announced },
4760
4808
  ...inbound.sealed ? { sealed: inbound.sealed } : {}
4761
4809
  });
4762
4810
  }
4763
- return this.#refusalReceipt(inbound);
4811
+ return this.#refusalReceipt(inbound, inbound.wants.level?.effectId === effect.effectId && inbound.wants.level.contain);
4764
4812
  }
4765
4813
  if (request.case === "history" || request.case === "ref") {
4766
4814
  const want = inbound.wants.packs.get(request.value.requestId);
@@ -4775,10 +4823,16 @@ var LiveInboundStream = class {
4775
4823
  return void 0;
4776
4824
  }
4777
4825
  /** A terminal refusal (not one that only says when to ask again) ends the procedure's wait. */
4778
- #refusalReceipt(inbound) {
4826
+ #refusalReceipt(inbound, contain = false) {
4779
4827
  const refused = inbound.refused;
4780
- if (!refused || refused.retryAfterMillis !== void 0) return void 0;
4828
+ if (!refused) return void 0;
4829
+ const answersContainment = contain && refused.code === HISTORY_REQUIRED;
4830
+ if (refused.retryAfterMillis !== void 0 && !answersContainment) return void 0;
4781
4831
  inbound.refused = void 0;
4832
+ if (answersContainment) {
4833
+ inbound.askAgainAt = void 0;
4834
+ inbound.wants.level = void 0;
4835
+ }
4782
4836
  return create11(PeerStreamReceiptSchema, { outcome: { case: "refusal", value: refused } });
4783
4837
  }
4784
4838
  /** The procedure gave up (it timed out, or its work ended). */
@@ -4809,7 +4863,9 @@ var LiveInboundStream = class {
4809
4863
  /** One frame from the peer. True when it was the stream's (the live desk handles the rest). */
4810
4864
  frame(workspace, message) {
4811
4865
  const inbound = this.#of(workspace);
4812
- inbound.lastHeard = this.#ports.monotonicNanoseconds();
4866
+ if (message.case === "checkpointOffer" || message.case === "checkpointChunk" || message.case === "pack") {
4867
+ inbound.lastHeard = this.#ports.monotonicNanoseconds();
4868
+ }
4813
4869
  switch (message.case) {
4814
4870
  case "frontier":
4815
4871
  if (message.value.response && message.value.head) {
@@ -4864,18 +4920,26 @@ var LiveInboundStream = class {
4864
4920
  return false;
4865
4921
  }
4866
4922
  }
4867
- /** Re-ask what is due: a refusal's retry time passed, or an ask heard nothing for too long. */
4923
+ /**
4924
+ * Ask again when a refusal said when to (the peer was opening, or acquiring history). Nothing else
4925
+ * here runs on a timer (CAP-838): the socket is ordered and reliable, every ask is answered on it,
4926
+ * and an ask is re-sent only when its socket re-opens (`opened`) or its refusal's time comes. The
4927
+ * stream used to re-ask whatever had heard nothing for 15 s, and that resend - itself counted as
4928
+ * hearing - hid an ask answered "come back" for ever.
4929
+ */
4868
4930
  drive(workspace) {
4869
4931
  const inbound = this.#by.get(workspace);
4870
- if (!inbound || !this.wanted(workspace)) return void 0;
4932
+ if (!inbound || inbound.askAgainAt === void 0) return void 0;
4933
+ if (!this.wanted(workspace)) {
4934
+ inbound.askAgainAt = void 0;
4935
+ return void 0;
4936
+ }
4871
4937
  const now2 = this.#ports.monotonicNanoseconds();
4872
- const due2 = inbound.askAgainAt ?? inbound.lastHeard + ASK_AGAIN_NANOS;
4873
- if (now2 < due2) return due2 - now2;
4938
+ if (now2 < inbound.askAgainAt) return inbound.askAgainAt - now2;
4874
4939
  inbound.askAgainAt = void 0;
4875
4940
  inbound.refused = void 0;
4876
- inbound.lastHeard = now2;
4877
4941
  this.opened(workspace);
4878
- return ASK_AGAIN_NANOS;
4942
+ return void 0;
4879
4943
  }
4880
4944
  #offered(workspace, inbound, offer) {
4881
4945
  inbound.refused = void 0;
@@ -4918,6 +4982,7 @@ var LiveInboundStream = class {
4918
4982
  const held = !taken ? -1 : "pack" in taken ? taken.pack.byteLength : taken.bytes;
4919
4983
  if (held !== transfer.bytes || transfer.received !== transfer.bytes) {
4920
4984
  if (taken && "stagedPackFile" in taken) this.#staging.clear(workspace);
4985
+ if (inbound.wants.checkpoint) this.#askCheckpoint(workspace, inbound);
4921
4986
  return;
4922
4987
  }
4923
4988
  inbound.complete = {
@@ -5035,8 +5100,12 @@ var LiveInboundStream = class {
5035
5100
  this.#askCheckpoint(workspace, inbound);
5036
5101
  return;
5037
5102
  }
5103
+ inbound.announced = void 0;
5104
+ inbound.sealed = void 0;
5105
+ const head = this.#ports.head(workspace) ?? "";
5106
+ inbound.askedFrom = head;
5038
5107
  this.#ports.send(workspace, { case: "frontier", value: create11(LiveFrontierSchema, {
5039
- head: this.#ports.head(workspace) ?? "",
5108
+ head,
5040
5109
  response: false,
5041
5110
  maxOffers: level.maxOffers,
5042
5111
  remountAfterOffers: level.remountAfterOffers,
@@ -5552,6 +5621,24 @@ function placementMovedBy(request, response) {
5552
5621
  return void 0;
5553
5622
  }
5554
5623
  var PLACEMENT_REFERENCE = "refs/nomos/placement";
5624
+ function readIndexPendingAnswer(request, message) {
5625
+ if (request.operation.case !== "query" || request.operation.value.query.case === "maintenanceQuantum") return void 0;
5626
+ const building = kernelReadIndexBuilding(message);
5627
+ if (building === void 0) return void 0;
5628
+ const target3 = request.operation.value.target;
5629
+ return create15(CallResponseSchema, {
5630
+ protocolVersion: request.protocolVersion,
5631
+ requestId: request.requestId,
5632
+ outcome: { case: "query", value: create15(QueryResponseSchema, {
5633
+ result: { case: "readIndexPending", value: create15(ReadIndexPendingSchema, {
5634
+ workspace: target3?.workspace || building.workspace,
5635
+ branch: target3?.branch ?? "",
5636
+ // The sliced build names no frontier: it restarts at whatever head main holds when it continues.
5637
+ requestedFrontier: ""
5638
+ }) }
5639
+ }) }
5640
+ });
5641
+ }
5555
5642
  var KernelPort = class {
5556
5643
  #kernel;
5557
5644
  #activeOperation;
@@ -6576,6 +6663,8 @@ var KernelPort = class {
6576
6663
  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" : "";
6577
6664
  error.message = `kernel-operation=${top}/${nested}: ${error.message}`;
6578
6665
  }
6666
+ const pending = readIndexPendingAnswer(request, error instanceof Error ? error.message : String(error));
6667
+ if (pending !== void 0) return pending;
6579
6668
  rethrowTypedKernelFailure(error);
6580
6669
  }
6581
6670
  if (response.requestId !== request.requestId) {
@@ -6586,6 +6675,9 @@ var KernelPort = class {
6586
6675
  this.#residency.after(request, response);
6587
6676
  const placementMoved = placementMovedBy(request, response);
6588
6677
  if (placementMoved !== void 0) this.#onPlacementMoved(placementMoved);
6678
+ if (response.outcome.case === "failure") {
6679
+ return readIndexPendingAnswer(request, response.outcome.value.message) ?? response;
6680
+ }
6589
6681
  return response;
6590
6682
  }
6591
6683
  /** [#call] with the opt-in timeline trace: encode, kernel and decode timed separately. */
@@ -13069,6 +13161,7 @@ var ReadMaintenanceDesk = class {
13069
13161
  for (const [key, value] of entries.filter(([key2]) => key2 !== workspace)) this.#pending.set(key, value);
13070
13162
  }
13071
13163
  this.#revision += 1;
13164
+ if (read && (!existing?.read || isReadDemand)) this.#observer.readinessMayChange?.(workspace);
13072
13165
  if (!existing || existing.read?.cause !== read?.cause || existing.background?.cause !== background?.cause) {
13073
13166
  this.#trace.emit(session ?? existing?.session, {
13074
13167
  case: "maintenanceProgress",
@@ -13085,32 +13178,65 @@ var ReadMaintenanceDesk = class {
13085
13178
  * (a waiting read's own turn advances read readiness only).
13086
13179
  */
13087
13180
  tick(request, sessionlessNotBeforeNanoseconds = 0n, backgroundNotBeforeNanoseconds = 0n, durability = true) {
13181
+ const turn = this.#turn(
13182
+ request,
13183
+ sessionlessNotBeforeNanoseconds,
13184
+ { case: "until", atNanoseconds: backgroundNotBeforeNanoseconds },
13185
+ durability
13186
+ );
13187
+ return turn.case === "ran" ? turn.ticked : create45(MaintenanceTickedSchema, {
13188
+ pending: turn.pending,
13189
+ nextTickAfterMillis: turn.nextDelayMillis ?? 0
13190
+ });
13191
+ }
13192
+ /**
13193
+ * A waiting read's turn: advance read readiness only. It never runs a background command, closure
13194
+ * warm, pack import or durability flush on the foreground's turn, and never reports a wake for
13195
+ * that background work: with only background work owed its wake is `none`.
13196
+ */
13197
+ tickReadReadiness() {
13198
+ const turn = this.#turn(void 0, 0n, { case: "readReadinessOnly" }, false);
13199
+ if (turn.case === "ran") {
13200
+ return { ticked: turn.ticked, wake: { case: "after", millis: turn.ticked.nextTickAfterMillis } };
13201
+ }
13202
+ return {
13203
+ ticked: create45(MaintenanceTickedSchema, { pending: turn.pending, nextTickAfterMillis: turn.nextDelayMillis ?? 0 }),
13204
+ wake: turn.nextDelayMillis === void 0 ? { case: "none" } : { case: "after", millis: turn.nextDelayMillis }
13205
+ };
13206
+ }
13207
+ #turn(request, sessionlessNotBeforeNanoseconds, backgroundHold, durability) {
13088
13208
  const now2 = this.#clock.monotonicNanoseconds();
13209
+ const backgroundNotBeforeNanoseconds = backgroundHold.case === "until" ? backgroundHold.atNanoseconds : void 0;
13089
13210
  const custodySlice = (workspace2) => this.#custodyBurstSlice(now2, workspace2);
13090
13211
  const due2 = (demand2) => {
13091
13212
  const held = demand2.session || demand2.awaited || demand2.retryNotBeforeNanoseconds > sessionlessNotBeforeNanoseconds ? demand2.retryNotBeforeNanoseconds : sessionlessNotBeforeNanoseconds;
13092
- const ordinary = demand2.read || demand2.awaited || held > backgroundNotBeforeNanoseconds ? held : backgroundNotBeforeNanoseconds;
13213
+ if (!demand2.read && !demand2.awaited && backgroundNotBeforeNanoseconds === void 0) return void 0;
13214
+ const ordinary = demand2.read || demand2.awaited || backgroundNotBeforeNanoseconds === void 0 || held > backgroundNotBeforeNanoseconds ? held : backgroundNotBeforeNanoseconds;
13093
13215
  const hold = demand2.read || demand2.awaited || !demand2.background?.maintainGitCustody ? void 0 : custodySlice(demand2.workspace);
13094
13216
  if (!hold) return ordinary;
13095
13217
  if (hold.slice && durability) return held > hold.at ? held : hold.at;
13096
13218
  return ordinary > hold.at ? ordinary : hold.at;
13097
13219
  };
13098
- const entry = [...this.#pending.entries()].find(([, demand2]) => due2(demand2) <= now2);
13220
+ const entry = [...this.#pending.entries()].find(([, demand2]) => {
13221
+ const at = due2(demand2);
13222
+ return at !== void 0 && at <= now2;
13223
+ });
13099
13224
  const flush = this.#flush;
13100
13225
  if (durability && flush && this.#flushDueAt(flush) <= now2 && !entry?.[1].read && (flush.local || !entry || flush.owedSinceNanoseconds + DURABILITY_FLUSH_MAX_DELAY_NANOSECONDS <= now2)) {
13101
- return this.#tickFlush(flush, request);
13226
+ return { case: "ran", ticked: this.#tickFlush(flush, request) };
13102
13227
  }
13103
13228
  const pinDue = (pin) => {
13229
+ if (backgroundNotBeforeNanoseconds === void 0) return void 0;
13104
13230
  const held = pin.session ? 0n : sessionlessNotBeforeNanoseconds;
13105
13231
  return [pin.notBeforeNanoseconds, held, backgroundNotBeforeNanoseconds].reduce((latest, at) => at > latest ? at : latest, 0n);
13106
13232
  };
13107
13233
  if (!entry) {
13108
- const pin = [...this.#pins.entries()].find(([, idle]) => pinDue(idle) <= now2);
13109
- if (pin) return this.#tickPin(pin[0], pin[1], request);
13110
- return create45(MaintenanceTickedSchema, {
13111
- pending: this.hasPending(),
13112
- nextTickAfterMillis: this.#nextDelay(now2, due2, pinDue)
13234
+ const pin = [...this.#pins.entries()].find(([, idle]) => {
13235
+ const at = pinDue(idle);
13236
+ return at !== void 0 && at <= now2;
13113
13237
  });
13238
+ if (pin) return { case: "ran", ticked: this.#tickPin(pin[0], pin[1], request) };
13239
+ return { case: "idle", pending: this.hasPending(), nextDelayMillis: this.#nextDelay(now2, due2, pinDue, durability) };
13114
13240
  }
13115
13241
  const [workspace, demand] = entry;
13116
13242
  const mount = demand.session ? this.#sessions.mountForSession(demand.session) : this.#sessions.mountForWorkspace(workspace);
@@ -13159,7 +13285,7 @@ var ReadMaintenanceDesk = class {
13159
13285
  read: read !== void 0,
13160
13286
  awaited: demand.awaited === true,
13161
13287
  session: demand.session !== void 0,
13162
- backgroundHoldMs: Number((backgroundNotBeforeNanoseconds - now2) / 1000000n),
13288
+ backgroundHoldMs: backgroundNotBeforeNanoseconds === void 0 ? "read-readiness-only" : Number((backgroundNotBeforeNanoseconds - now2) / 1000000n),
13163
13289
  sessionlessHoldMs: Number((sessionlessNotBeforeNanoseconds - now2) / 1000000n),
13164
13290
  caller: (new Error().stack ?? "").split("\n").slice(2, 6).map((frame2) => frame2.trim()).join(" < ")
13165
13291
  })}`);
@@ -13208,12 +13334,13 @@ var ReadMaintenanceDesk = class {
13208
13334
  this.#observer.frontierAdvanced?.(workspace);
13209
13335
  }
13210
13336
  }
13211
- return create45(MaintenanceTickedSchema, {
13337
+ this.#observer.readinessMayChange?.(workspace);
13338
+ return { case: "ran", ticked: create45(MaintenanceTickedSchema, {
13212
13339
  pending: this.#pending.size > 0,
13213
13340
  progress: observed,
13214
13341
  // With no debt left, an armed idle pin names when the host should wake next.
13215
- nextTickAfterMillis: progress.maintenancePending ? 20 : this.#pending.size === 0 && this.hasIdleWork() ? this.#nextDelay(this.#clock.monotonicNanoseconds()) : 0
13216
- });
13342
+ nextTickAfterMillis: progress.maintenancePending ? 20 : this.#pending.size === 0 && this.hasIdleWork() ? this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0 : 0
13343
+ }) };
13217
13344
  } catch (error) {
13218
13345
  const format = localCopyFormatRefusal(error);
13219
13346
  if (format !== void 0) {
@@ -13229,10 +13356,10 @@ var ReadMaintenanceDesk = class {
13229
13356
  stopped: true
13230
13357
  })
13231
13358
  });
13232
- return create45(MaintenanceTickedSchema, {
13359
+ return { case: "ran", ticked: create45(MaintenanceTickedSchema, {
13233
13360
  pending: this.#pending.size > 0,
13234
- nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds())
13235
- });
13361
+ nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
13362
+ }) };
13236
13363
  }
13237
13364
  const failures = demand.failures + 1;
13238
13365
  this.#pending.delete(workspace);
@@ -13260,12 +13387,12 @@ var ReadMaintenanceDesk = class {
13260
13387
  retryAfterMillis: retryMillis
13261
13388
  })
13262
13389
  });
13263
- return create45(MaintenanceTickedSchema, {
13390
+ return { case: "ran", ticked: create45(MaintenanceTickedSchema, {
13264
13391
  pending: true,
13265
13392
  // Backoff belongs to the failed workspace. Another workspace's ready
13266
13393
  // index or changed watches must not wait for this retry deadline.
13267
- nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds())
13268
- });
13394
+ nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
13395
+ }) };
13269
13396
  }
13270
13397
  }
13271
13398
  /** Owe the kernel its ordered flush. The first write it covers fixes `owedSince`; the shared
@@ -13330,7 +13457,7 @@ var ReadMaintenanceDesk = class {
13330
13457
  }
13331
13458
  return create45(MaintenanceTickedSchema, {
13332
13459
  pending: this.hasPending(),
13333
- nextTickAfterMillis: progress.maintenancePending ? 20 : this.#nextDelay(this.#clock.monotonicNanoseconds())
13460
+ nextTickAfterMillis: progress.maintenancePending ? 20 : this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
13334
13461
  });
13335
13462
  } catch (error) {
13336
13463
  const failures = flush.failures + 1;
@@ -13354,7 +13481,7 @@ var ReadMaintenanceDesk = class {
13354
13481
  };
13355
13482
  return create45(MaintenanceTickedSchema, {
13356
13483
  pending: this.hasPending(),
13357
- nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds())
13484
+ nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
13358
13485
  });
13359
13486
  }
13360
13487
  }
@@ -13385,7 +13512,7 @@ var ReadMaintenanceDesk = class {
13385
13512
  }
13386
13513
  return create45(MaintenanceTickedSchema, {
13387
13514
  pending: this.hasPending(),
13388
- nextTickAfterMillis: progress.maintenancePending ? 20 : this.#nextDelay(this.#clock.monotonicNanoseconds())
13515
+ nextTickAfterMillis: progress.maintenancePending ? 20 : this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
13389
13516
  });
13390
13517
  } catch (error) {
13391
13518
  slowQuantumObserver?.(`[nomos-kernel-perf] ${JSON.stringify({
@@ -13397,28 +13524,31 @@ var ReadMaintenanceDesk = class {
13397
13524
  })}`);
13398
13525
  return create45(MaintenanceTickedSchema, {
13399
13526
  pending: this.hasPending(),
13400
- nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds())
13527
+ nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
13401
13528
  });
13402
13529
  }
13403
13530
  }
13404
- #nextDelay(now2, due2 = (demand) => demand.retryNotBeforeNanoseconds, pinDue = (pin) => pin.notBeforeNanoseconds) {
13531
+ /** Milliseconds until the earliest owed work this turn serves; `undefined` when none is owed. */
13532
+ #nextDelay(now2, due2 = (demand) => demand.retryNotBeforeNanoseconds, pinDue = (pin) => pin.notBeforeNanoseconds, flushes = true) {
13405
13533
  let earliest;
13406
13534
  for (const demand of this.#pending.values()) {
13407
13535
  const at = due2(demand);
13536
+ if (at === void 0) continue;
13408
13537
  if (at <= now2) return 0;
13409
13538
  if (earliest === void 0 || at < earliest) earliest = at;
13410
13539
  }
13411
13540
  for (const pin of this.#pins.values()) {
13412
13541
  const at = pinDue(pin);
13542
+ if (at === void 0) continue;
13413
13543
  if (at <= now2) return 0;
13414
13544
  if (earliest === void 0 || at < earliest) earliest = at;
13415
13545
  }
13416
- if (this.#flush) {
13546
+ if (flushes && this.#flush) {
13417
13547
  const at = this.#flushDueAt(this.#flush);
13418
13548
  if (at <= now2) return 0;
13419
13549
  if (earliest === void 0 || at < earliest) earliest = at;
13420
13550
  }
13421
- return earliest === void 0 ? 0 : Number((earliest - now2 + 999999n) / 1000000n);
13551
+ return earliest === void 0 ? void 0 : Number((earliest - now2 + 999999n) / 1000000n);
13422
13552
  }
13423
13553
  /** Drop any demand for a workspace no maintenance can serve (an unreadable copy). */
13424
13554
  forget(workspace) {
@@ -13459,15 +13589,19 @@ var ReadMaintenanceDesk = class {
13459
13589
 
13460
13590
  // ../peer-office/src/runtime/read_response_desk.ts
13461
13591
  import { create as create46 } from "@bufbuild/protobuf";
13592
+ var READ_RETENTION_MILLIS = 12e4;
13593
+ var READ_RESUME_MAX_MILLIS = 1e3;
13462
13594
  var ReadResponseDesk = class {
13463
13595
  #waiting = /* @__PURE__ */ new Map();
13464
13596
  #clock;
13465
13597
  #tick;
13598
+ #owe;
13466
13599
  #read;
13467
13600
  #sequence = 0;
13468
- constructor(clock2, tick, read) {
13601
+ constructor(clock2, tick, owe, read) {
13469
13602
  this.#clock = clock2;
13470
13603
  this.#tick = tick;
13604
+ this.#owe = owe;
13471
13605
  this.#read = read;
13472
13606
  }
13473
13607
  #now() {
@@ -13480,18 +13614,27 @@ var ReadResponseDesk = class {
13480
13614
  const now2 = this.#now();
13481
13615
  for (const [id, work] of this.#waiting) if (work.deadline <= now2) this.#waiting.delete(id);
13482
13616
  const workId2 = `local-read-${++this.#sequence}`;
13483
- this.#waiting.set(workId2, { request, dependency, deadline: now2 + 12e4, notBefore: now2 });
13617
+ this.#waiting.set(workId2, {
13618
+ request,
13619
+ dependency,
13620
+ deadline: now2 + READ_RETENTION_MILLIS,
13621
+ notBefore: now2,
13622
+ idle: false,
13623
+ // The office owed this frontier's debt when the kernel first answered pending.
13624
+ owedFor: dependency.requestedFrontier,
13625
+ waiters: /* @__PURE__ */ new Set()
13626
+ });
13484
13627
  return create46(LocalReadPendingSchema, { workId: workId2 });
13485
13628
  }
13486
13629
  resume(workId2, requestId) {
13487
13630
  const work = this.#waiting.get(workId2);
13488
13631
  if (!work || work.request.requestId !== requestId) throw new Error(`unknown local read continuation '${workId2}'`);
13489
13632
  const now2 = this.#now();
13633
+ work.waiters.clear();
13490
13634
  if (now2 >= work.deadline) {
13491
13635
  this.#waiting.delete(workId2);
13492
13636
  throw new Error(`Local read index for '${work.dependency.workspace}' did not catch up to ${work.dependency.requestedFrontier} within its retained maintenance window`);
13493
13637
  }
13494
- if (now2 < work.notBefore) return this.#pending(workId2, work, now2);
13495
13638
  try {
13496
13639
  const response = this.#read(work.request);
13497
13640
  if (response.outcome.case !== "query" || response.outcome.value.result.case !== "readIndexPending") {
@@ -13499,24 +13642,65 @@ var ReadResponseDesk = class {
13499
13642
  return { case: "ready", request: work.request, response };
13500
13643
  }
13501
13644
  work.dependency = response.outcome.value.result.value;
13502
- const tick = this.#tick();
13645
+ if (now2 < work.notBefore) return this.#pending(workId2, work, now2);
13646
+ let { ticked, wake } = this.#tick();
13647
+ if (wake.case === "none" && ticked.progress === void 0 && work.owedFor !== work.dependency.requestedFrontier) {
13648
+ work.owedFor = work.dependency.requestedFrontier;
13649
+ this.#owe(work.request);
13650
+ ({ ticked, wake } = this.#tick());
13651
+ }
13503
13652
  const afterTick = this.#now();
13504
- work.notBefore = afterTick + tick.nextTickAfterMillis;
13505
- work.deadline = afterTick + Math.max(12e4, tick.nextTickAfterMillis + 6e4);
13653
+ work.idle = wake.case === "none";
13654
+ const backoff = wake.case === "after" ? wake.millis : 0;
13655
+ work.notBefore = afterTick + backoff;
13656
+ work.deadline = afterTick + Math.max(READ_RETENTION_MILLIS, backoff + 6e4);
13506
13657
  return this.#pending(workId2, work, afterTick);
13507
13658
  } catch (error) {
13508
13659
  this.#waiting.delete(workId2);
13509
13660
  throw error;
13510
13661
  }
13511
13662
  }
13663
+ /**
13664
+ * Wait in process for a held read to become worth continuing. `notify` is called once, when read
13665
+ * readiness for its workspace changes (a slice or binding finished, a frontier advanced, readiness
13666
+ * newly owed). `afterMillis` is the only timer the shell needs: the read's own scheduled quantum
13667
+ * when it has one, otherwise its deadline. Undefined for an unknown or finished read.
13668
+ */
13669
+ onResumable(workId2, notify) {
13670
+ const work = this.#waiting.get(workId2);
13671
+ if (!work) return void 0;
13672
+ const now2 = this.#now();
13673
+ const due2 = work.idle ? work.deadline : Math.min(work.notBefore, work.deadline);
13674
+ work.waiters.add(notify);
13675
+ return { afterMillis: Math.max(0, due2 - now2), cancel: () => {
13676
+ work.waiters.delete(notify);
13677
+ } };
13678
+ }
13679
+ /** Read readiness for `workspace` changed: every read waiting on it may continue now. */
13680
+ readinessChanged(workspace) {
13681
+ const now2 = this.#now();
13682
+ for (const work of this.#waiting.values()) {
13683
+ if (work.dependency.workspace !== workspace) continue;
13684
+ work.idle = false;
13685
+ if (work.notBefore > now2) work.notBefore = now2;
13686
+ const waiters = [...work.waiters];
13687
+ work.waiters.clear();
13688
+ for (const notify of waiters) notify();
13689
+ }
13690
+ }
13691
+ /** The protocol wake is a bounded re-poll inside the read's retention deadline, never the raw backoff. */
13512
13692
  #pending(workId2, work, now2) {
13693
+ const due2 = work.idle ? READ_RESUME_MAX_MILLIS : work.notBefore - now2;
13694
+ const resumeAfterMillis = Math.max(0, Math.min(due2, work.deadline - now2, READ_RESUME_MAX_MILLIS));
13513
13695
  return { case: "pending", value: create46(LocalReadPendingSchema, {
13514
13696
  workId: workId2,
13515
- resumeAfterMillis: Math.max(0, work.notBefore - now2)
13697
+ resumeAfterMillis: Number.isFinite(resumeAfterMillis) ? Math.ceil(resumeAfterMillis) : READ_RESUME_MAX_MILLIS
13516
13698
  }) };
13517
13699
  }
13518
13700
  clear() {
13701
+ const waiters = [...this.#waiting.values()].flatMap((work) => [...work.waiters]);
13519
13702
  this.#waiting.clear();
13703
+ for (const notify of waiters) notify();
13520
13704
  }
13521
13705
  };
13522
13706
 
@@ -14416,13 +14600,15 @@ var ReplicaFollowEventKind = Object.freeze({
14416
14600
  DependencyAdvanced: "dependency_advanced",
14417
14601
  RebornRemotely: "reborn_remotely",
14418
14602
  LocalCopyDropAuthorized: "local_copy_drop_authorized",
14419
- LocalCopyUnreadable: "local_copy_unreadable"
14603
+ LocalCopyUnreadable: "local_copy_unreadable",
14604
+ RuntimeStarted: "runtime_started"
14420
14605
  });
14421
14606
  var ReplicaFollowEffectKind = Object.freeze({
14422
14607
  ScheduleWake: "schedule_wake",
14423
14608
  RunSync: "run_sync",
14424
14609
  RefreshCredential: "refresh_credential"
14425
14610
  });
14611
+ var KERNEL_REFUSAL_EVENT_FLOOR_MILLIS = 1e4;
14426
14612
  var boundedRetry = (policy, attempt) => Math.min(policy.fallbackMillis, Math.max(250, policy.debounceMillis) * 2 ** Math.min(attempt - 1, 20));
14427
14613
  var attempts = (state) => {
14428
14614
  switch (state.case) {
@@ -14449,13 +14635,14 @@ var due = (atUnixMillis) => ({
14449
14635
  state: { case: ReplicaFollowPhase.Due, dueAtUnixMillis: atUnixMillis },
14450
14636
  effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis }]
14451
14637
  });
14452
- var run = (attempt, replaceLocalHead, warmingSinceUnixMillis) => ({
14638
+ var run = (attempt, replaceLocalHead, warmingSinceUnixMillis, refused) => ({
14453
14639
  state: {
14454
14640
  case: ReplicaFollowPhase.Running,
14455
14641
  attempt,
14456
14642
  observed: false,
14457
14643
  ...replaceLocalHead === void 0 ? {} : { replaceLocalHead },
14458
- ...warmingSinceUnixMillis === void 0 ? {} : { warmingSinceUnixMillis }
14644
+ ...warmingSinceUnixMillis === void 0 ? {} : { warmingSinceUnixMillis },
14645
+ ...refused === void 0 ? {} : { refused }
14459
14646
  },
14460
14647
  effects: [{ case: ReplicaFollowEffectKind.RunSync }]
14461
14648
  });
@@ -14464,6 +14651,16 @@ var replacing = (expectedLocalHead, attempt, atUnixMillis) => ({
14464
14651
  effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis }]
14465
14652
  });
14466
14653
  var quiet = (state) => ({ state, effects: [] });
14654
+ var blockedRefusal = (state) => state.case === ReplicaFollowPhase.Backoff && state.refusal?.blocked ? state.refusal : void 0;
14655
+ var refusedEvent = (state, refusal2, nowUnixMillis) => {
14656
+ const earliest = Math.max(nowUnixMillis, refusal2.atUnixMillis + KERNEL_REFUSAL_EVENT_FLOOR_MILLIS);
14657
+ const rerunAtUnixMillis = refusal2.rerunAtUnixMillis === void 0 ? earliest : Math.min(refusal2.rerunAtUnixMillis, earliest);
14658
+ return {
14659
+ state: { ...state, refusal: { ...refusal2, rerunAtUnixMillis } },
14660
+ effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: rerunAtUnixMillis }]
14661
+ };
14662
+ };
14663
+ var refusedByKernel = (state) => state.case === ReplicaFollowPhase.Backoff && (state.refusal !== void 0 || deterministicKernelRefusal(state.failure) !== void 0);
14467
14664
  function reduceReplicaFollow(state, event, policy) {
14468
14665
  switch (event.case) {
14469
14666
  case ReplicaFollowEventKind.Activate:
@@ -14476,6 +14673,9 @@ function reduceReplicaFollow(state, event, policy) {
14476
14673
  if (state.case === ReplicaFollowPhase.Running) {
14477
14674
  return { state: { ...state, observed: true }, effects: [] };
14478
14675
  }
14676
+ if (state.case === ReplicaFollowPhase.Backoff && state.refusal?.blocked) {
14677
+ return refusedEvent(state, state.refusal, event.nowUnixMillis);
14678
+ }
14479
14679
  if (state.case === ReplicaFollowPhase.RebornRemotely || state.case === ReplicaFollowPhase.LocalCopyUnreadable) return quiet(state);
14480
14680
  if (state.case === ReplicaFollowPhase.InvalidCredential) {
14481
14681
  return {
@@ -14485,6 +14685,9 @@ function reduceReplicaFollow(state, event, policy) {
14485
14685
  }
14486
14686
  return due(event.nowUnixMillis);
14487
14687
  case ReplicaFollowEventKind.Reconnected:
14688
+ if (state.case === ReplicaFollowPhase.Backoff && state.refusal?.blocked) {
14689
+ return refusedEvent(state, state.refusal, event.nowUnixMillis);
14690
+ }
14488
14691
  switch (state.case) {
14489
14692
  case ReplicaFollowPhase.Running:
14490
14693
  return { state: { ...state, observed: true }, effects: [] };
@@ -14530,15 +14733,25 @@ function reduceReplicaFollow(state, event, policy) {
14530
14733
  }
14531
14734
  return run(state.attempt + 1, state.expectedLocalHead);
14532
14735
  case ReplicaFollowPhase.Offline:
14533
- case ReplicaFollowPhase.Backoff:
14736
+ case ReplicaFollowPhase.Backoff: {
14737
+ const blocked = blockedRefusal(state);
14738
+ if (blocked) {
14739
+ if (blocked.rerunAtUnixMillis === void 0) return quiet(state);
14740
+ if (event.nowUnixMillis < blocked.rerunAtUnixMillis) {
14741
+ return { state, effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: blocked.rerunAtUnixMillis }] };
14742
+ }
14743
+ return run(state.attempt + 1, void 0, void 0, state.failure);
14744
+ }
14534
14745
  if (event.nowUnixMillis < state.retryAtUnixMillis) {
14535
14746
  return { state, effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: state.retryAtUnixMillis }] };
14536
14747
  }
14537
14748
  return run(
14538
14749
  state.attempt + 1,
14539
14750
  void 0,
14540
- state.case === ReplicaFollowPhase.Backoff ? state.warming?.sinceUnixMillis : void 0
14751
+ state.case === ReplicaFollowPhase.Backoff ? state.warming?.sinceUnixMillis : void 0,
14752
+ state.case === ReplicaFollowPhase.Backoff && state.refusal ? state.failure : void 0
14541
14753
  );
14754
+ }
14542
14755
  case ReplicaFollowPhase.InvalidCredential:
14543
14756
  if (!state.refreshDue && event.nowUnixMillis < state.retryAtUnixMillis) {
14544
14757
  return { state, effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: state.retryAtUnixMillis }] };
@@ -14615,6 +14828,31 @@ function reduceReplicaFollow(state, event, policy) {
14615
14828
  };
14616
14829
  }
14617
14830
  case ReplicaFollowEventKind.Failed: {
14831
+ if (event.refusal && !(state.case === ReplicaFollowPhase.Running && state.replaceLocalHead !== void 0)) {
14832
+ const attempt2 = Math.max(1, attempts(state));
14833
+ const blocked = state.case === ReplicaFollowPhase.Running && state.refused === event.failure || state.case === ReplicaFollowPhase.Backoff && state.refusal !== void 0 && state.failure === event.failure;
14834
+ const refusal2 = {
14835
+ code: event.refusal.code,
14836
+ blocked,
14837
+ runtime: event.refusal.runtime,
14838
+ atUnixMillis: event.nowUnixMillis
14839
+ };
14840
+ if (!blocked) {
14841
+ const retryAtUnixMillis2 = event.nowUnixMillis + boundedRetry(policy, attempt2);
14842
+ return {
14843
+ state: { case: ReplicaFollowPhase.Backoff, attempt: attempt2, retryAtUnixMillis: retryAtUnixMillis2, failure: event.failure, refusal: refusal2 },
14844
+ effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: retryAtUnixMillis2 }]
14845
+ };
14846
+ }
14847
+ const waiting = {
14848
+ case: ReplicaFollowPhase.Backoff,
14849
+ attempt: attempt2,
14850
+ retryAtUnixMillis: event.nowUnixMillis,
14851
+ failure: event.failure,
14852
+ refusal: refusal2
14853
+ };
14854
+ return state.case === ReplicaFollowPhase.Running && state.observed ? refusedEvent(waiting, refusal2, event.nowUnixMillis) : quiet(waiting);
14855
+ }
14618
14856
  if (state.case === ReplicaFollowPhase.Running && state.observed) {
14619
14857
  return due(event.nowUnixMillis);
14620
14858
  }
@@ -14652,6 +14890,11 @@ function reduceReplicaFollow(state, event, policy) {
14652
14890
  return quiet({ case: ReplicaFollowPhase.RebornRemotely, rebirth: event.rebirth });
14653
14891
  case ReplicaFollowEventKind.LocalCopyUnreadable:
14654
14892
  return quiet({ case: ReplicaFollowPhase.LocalCopyUnreadable, format: event.format });
14893
+ case ReplicaFollowEventKind.RuntimeStarted:
14894
+ if (state.case === ReplicaFollowPhase.Backoff && refusedByKernel(state) && state.refusal?.runtime !== event.runtime) {
14895
+ return due(event.nowUnixMillis);
14896
+ }
14897
+ return quiet(state);
14655
14898
  case ReplicaFollowEventKind.LocalCopyDropAuthorized:
14656
14899
  if (state.case === ReplicaFollowPhase.Running) return invalid(state, event);
14657
14900
  return replacing(event.expectedLocalHead, 0, event.nowUnixMillis);
@@ -14698,11 +14941,15 @@ var ReplicaFollowController = class {
14698
14941
  #replicaId;
14699
14942
  /** Local children whose births custody refused (CAP-804): quarantined, never followed. */
14700
14943
  #birthRefusals;
14701
- constructor(desk, clock2, replicaId2, birthRefusals) {
14944
+ /** The kernel/runtime identity this process runs: a refusal is recorded under it, and a refusal
14945
+ * drawn under another identity is retried once when this process starts. */
14946
+ #runtime;
14947
+ constructor(desk, clock2, replicaId2, birthRefusals, runtime = "unidentified") {
14702
14948
  this.#desk = desk;
14703
14949
  this.#clock = clock2;
14704
14950
  this.#replicaId = replicaId2;
14705
14951
  this.#birthRefusals = birthRefusals ?? new BirthRefusalRegister(new MemoryPeerDeskStore());
14952
+ this.#runtime = runtime;
14706
14953
  }
14707
14954
  /** The durable quarantine of a local child whose birth custody refused; undefined otherwise. */
14708
14955
  birthRefusal(workspace) {
@@ -14801,6 +15048,13 @@ var ReplicaFollowController = class {
14801
15048
  recover() {
14802
15049
  const now2 = this.#now();
14803
15050
  if (!this.#recovered) {
15051
+ for (const follow of this.#desk.all()) {
15052
+ this.#desk.transition(follow.spec.workspace, {
15053
+ case: ReplicaFollowEventKind.RuntimeStarted,
15054
+ nowUnixMillis: now2,
15055
+ runtime: this.#runtime
15056
+ });
15057
+ }
14804
15058
  for (const follow of this.#desk.all()) {
14805
15059
  if (follow.state.case === ReplicaFollowPhase.Settled || follow.state.case === ReplicaFollowPhase.AwaitingDependency) {
14806
15060
  this.#placementRecheck.add(follow.spec.workspace);
@@ -14889,11 +15143,12 @@ var ReplicaFollowController = class {
14889
15143
  placementAnnounced(workspace) {
14890
15144
  if (!this.followForWorkspace(workspace)) return void 0;
14891
15145
  this.#placementRecheck.add(workspace);
14892
- return this.reconnected(workspace);
15146
+ return this.reconnected(workspace, true);
14893
15147
  }
14894
- /** The upstream live link opened or reopened: reconcile once for missed pushes. */
14895
- reconnected(workspace) {
14896
- return this.#event(workspace, ReplicaFollowEventKind.Reconnected);
15148
+ /** The upstream live link opened or reopened: reconcile once for missed pushes. With
15149
+ * `remoteAdvanced`, the upstream announced a new frontier. Either re-runs a blocked refusal. */
15150
+ reconnected(workspace, remoteAdvanced = false) {
15151
+ return this.#event(workspace, ReplicaFollowEventKind.Reconnected, remoteAdvanced);
14897
15152
  }
14898
15153
  /** Another workspace advanced or settled; every held dependency gets one retry. */
14899
15154
  dependencyAdvanced(except) {
@@ -14906,11 +15161,11 @@ var ReplicaFollowController = class {
14906
15161
  }
14907
15162
  return woken;
14908
15163
  }
14909
- #event(workspace, kind) {
15164
+ #event(workspace, kind, remoteAdvanced = false) {
14910
15165
  const follow = this.#recovered ? this.#desk.get(workspace) : void 0;
14911
15166
  if (!follow) return void 0;
14912
15167
  const nowUnixMillis = this.#now();
14913
- this.#desk.transition(workspace, { case: kind, nowUnixMillis });
15168
+ this.#desk.transition(workspace, kind === ReplicaFollowEventKind.Reconnected && remoteAdvanced ? { case: kind, nowUnixMillis, remoteAdvanced } : { case: kind, nowUnixMillis });
14914
15169
  const nextDueAt = dueAt(this.#desk.get(workspace));
14915
15170
  return nextDueAt === void 0 ? void 0 : Math.max(0, nextDueAt - nowUnixMillis);
14916
15171
  }
@@ -15057,7 +15312,9 @@ var ReplicaFollowController = class {
15057
15312
  * still opening the workspace and named when to ask again. */
15058
15313
  failed(workspace, error, custodianRetryAfterMillis) {
15059
15314
  if (!this.#recovered) this.recover();
15060
- custodianRetryAfterMillis ??= warmingFromFailureMessage(error instanceof Error ? error.message : String(error));
15315
+ const refusal2 = deterministicKernelRefusal(error);
15316
+ if (refusal2 !== void 0) custodianRetryAfterMillis = void 0;
15317
+ else custodianRetryAfterMillis ??= warmingFromFailureMessage(error instanceof Error ? error.message : String(error));
15061
15318
  if (!this.#desk.get(workspace)) return;
15062
15319
  const format = localCopyFormatRefusal(error);
15063
15320
  if (format !== void 0) {
@@ -15072,9 +15329,15 @@ var ReplicaFollowController = class {
15072
15329
  case: ReplicaFollowEventKind.Failed,
15073
15330
  nowUnixMillis: this.#now(),
15074
15331
  failure: error instanceof Error ? error.message : String(error),
15075
- ...custodianRetryAfterMillis === void 0 ? {} : { custodianRetryAfterMillis }
15332
+ ...custodianRetryAfterMillis === void 0 ? {} : { custodianRetryAfterMillis },
15333
+ ...refusal2 === void 0 ? {} : { refusal: { code: refusal2.code, runtime: this.#runtime } }
15076
15334
  });
15077
15335
  }
15336
+ /** The kernel refusal behind this follow's backoff (`blocked` once the kernel repeated it). */
15337
+ refusal(workspace) {
15338
+ const state = this.followForWorkspace(workspace)?.state;
15339
+ return state?.case === ReplicaFollowPhase.Backoff ? state.refusal : void 0;
15340
+ }
15078
15341
  /** Closing an interaction realm must not erase a peer-owned follow. */
15079
15342
  closeInteractionRealm() {
15080
15343
  }
@@ -15107,9 +15370,12 @@ function dueAt(follow) {
15107
15370
  case ReplicaFollowPhase.RebornRemotely:
15108
15371
  case ReplicaFollowPhase.LocalCopyUnreadable:
15109
15372
  return void 0;
15373
+ case ReplicaFollowPhase.Backoff: {
15374
+ const blocked = blockedRefusal(follow.state);
15375
+ return blocked ? blocked.rerunAtUnixMillis : follow.state.retryAtUnixMillis;
15376
+ }
15110
15377
  case ReplicaFollowPhase.Offline:
15111
15378
  case ReplicaFollowPhase.InvalidCredential:
15112
- case ReplicaFollowPhase.Backoff:
15113
15379
  return follow.state.retryAtUnixMillis;
15114
15380
  default: {
15115
15381
  const exhaustive = follow.state;
@@ -15125,6 +15391,9 @@ function delayUntilDue(follow, nowUnixMillis) {
15125
15391
  return nextDueAt === void 0 ? void 0 : Math.max(0, nextDueAt - nowUnixMillis);
15126
15392
  }
15127
15393
 
15394
+ // ../peer-office/src/runtime/runtime_identity.ts
15395
+ var PEER_RUNTIME_IDENTITY = typeof __NOMOS_BUNDLE_VERSION__ === "string" && __NOMOS_BUNDLE_VERSION__ ? `@githolon/runtime@${__NOMOS_BUNDLE_VERSION__}` : "@githolon/runtime@unbundled";
15396
+
15128
15397
  // ../peer-office/src/runtime/replica_follow_desk.ts
15129
15398
  var REPLICA_FOLLOW_NAMESPACE = "nomos.peer-desk.replica-follow/v2";
15130
15399
  var textEncoder = new TextEncoder();
@@ -15152,6 +15421,16 @@ var decodeWarming = (value) => {
15152
15421
  ...Number.isFinite(warming.hintMillis) ? { hintMillis: warming.hintMillis } : {}
15153
15422
  } } : {};
15154
15423
  };
15424
+ var decodeRefusal = (value) => {
15425
+ const refusal2 = value;
15426
+ return refusal2 && typeof refusal2.code === "string" && typeof refusal2.runtime === "string" && Number.isFinite(refusal2.atUnixMillis) ? { refusal: {
15427
+ code: refusal2.code,
15428
+ blocked: refusal2.blocked === true,
15429
+ runtime: refusal2.runtime,
15430
+ atUnixMillis: refusal2.atUnixMillis,
15431
+ ...Number.isFinite(refusal2.rerunAtUnixMillis) ? { rerunAtUnixMillis: refusal2.rerunAtUnixMillis } : {}
15432
+ } } : {};
15433
+ };
15155
15434
  var decodeState = (record, value) => {
15156
15435
  if (!value || typeof value !== "object") throw corrupt(record, "state is not an object");
15157
15436
  const state = value;
@@ -15166,7 +15445,8 @@ var decodeState = (record, value) => {
15166
15445
  attempt: state.attempt,
15167
15446
  observed: state.observed === true,
15168
15447
  ...state.replaceLocalHead === void 0 ? {} : { replaceLocalHead: state.replaceLocalHead },
15169
- ...Number.isFinite(state.warmingSinceUnixMillis) ? { warmingSinceUnixMillis: state.warmingSinceUnixMillis } : {}
15448
+ ...Number.isFinite(state.warmingSinceUnixMillis) ? { warmingSinceUnixMillis: state.warmingSinceUnixMillis } : {},
15449
+ ...typeof state.refused === "string" ? { refused: state.refused } : {}
15170
15450
  };
15171
15451
  case ReplicaFollowPhase.Settled:
15172
15452
  return {
@@ -15198,7 +15478,8 @@ var decodeState = (record, value) => {
15198
15478
  attempt: state.attempt,
15199
15479
  retryAtUnixMillis: state.retryAtUnixMillis,
15200
15480
  failure: state.failure,
15201
- ...decodeWarming(state.warming)
15481
+ ...decodeWarming(state.warming),
15482
+ ...decodeRefusal(state.refusal)
15202
15483
  };
15203
15484
  case ReplicaFollowPhase.RebornRemotely: {
15204
15485
  const rebirth = state.rebirth ?? {};
@@ -15388,9 +15669,15 @@ var ReplicaFollowDesk = class {
15388
15669
  break;
15389
15670
  }
15390
15671
  case ReplicaFollowPhase.Offline:
15391
- case ReplicaFollowPhase.Backoff:
15392
- wakes.push({ workspace: follow.spec.workspace, atUnixMillis: follow.state.retryAtUnixMillis });
15672
+ case ReplicaFollowPhase.Backoff: {
15673
+ const blocked = blockedRefusal(follow.state);
15674
+ if (blocked && blocked.rerunAtUnixMillis === void 0) break;
15675
+ wakes.push({
15676
+ workspace: follow.spec.workspace,
15677
+ atUnixMillis: blocked?.rerunAtUnixMillis ?? follow.state.retryAtUnixMillis
15678
+ });
15393
15679
  break;
15680
+ }
15394
15681
  case ReplicaFollowPhase.InvalidCredential:
15395
15682
  wakes.push({
15396
15683
  workspace: follow.spec.workspace,
@@ -16026,6 +16313,8 @@ var refusal = (requestId, code, message, retryAfterMillis) => frame({ case: "ref
16026
16313
  message,
16027
16314
  ...retryAfterMillis === void 0 ? {} : { retryAfterMillis }
16028
16315
  }) });
16316
+ var OFF_MAIN_AFTER_MILLIS = 6e4;
16317
+ var MAX_UNFOUND_HEADS = 1024;
16029
16318
  var LiveStreamServer = class {
16030
16319
  #kernel;
16031
16320
  #now;
@@ -16039,6 +16328,10 @@ var LiveStreamServer = class {
16039
16328
  /** By workspace: the history slices copies are fetching (a few, newest last). */
16040
16329
  #slices = /* @__PURE__ */ new Map();
16041
16330
  #cachedBytes = 0;
16331
+ /** By workspace and asked head: when this peer first answered "acquiring its own history" to a level
16332
+ * ask from a head it could not find. A shallow custody can never prove the head is off its main (its
16333
+ * walk is never `complete`), so after OFF_MAIN_AFTER_MILLIS of the same answer it says so anyway. */
16334
+ #unfound = /* @__PURE__ */ new Map();
16042
16335
  constructor(kernel, now2 = Date.now, historyWanted = () => {
16043
16336
  }, sealed = () => void 0) {
16044
16337
  this.#kernel = kernel;
@@ -16086,9 +16379,12 @@ var LiveStreamServer = class {
16086
16379
  if (!head) return [...answer, ...this.#checkpoint(workspace, requestId, create53(LiveCheckpointRequestSchema))];
16087
16380
  if (head === main) return answer;
16088
16381
  let behind;
16382
+ let offMain = false;
16089
16383
  try {
16090
16384
  const summary = this.#kernel.historySummary(mount, requestId, head, main);
16091
16385
  behind = summary.reachedBase ? summary.commitCount : void 0;
16386
+ offMain = !summary.reachedBase && (summary.complete || !this.#shallow(mount, requestId));
16387
+ if (summary.reachedBase) this.#unfound.delete(`${workspace}\0${head}`);
16092
16388
  } catch {
16093
16389
  behind = void 0;
16094
16390
  }
@@ -16097,6 +16393,22 @@ var LiveStreamServer = class {
16097
16393
  if (remountAfter > 0) {
16098
16394
  return [...answer, ...this.#checkpoint(workspace, requestId, create53(LiveCheckpointRequestSchema), behind ?? 0n)];
16099
16395
  }
16396
+ const key = `${workspace}\0${head}`;
16397
+ const firstUnfound = this.#unfound.get(key);
16398
+ if (!offMain && firstUnfound === void 0) {
16399
+ if (this.#unfound.size >= MAX_UNFOUND_HEADS) this.#unfound.delete(this.#unfound.keys().next().value);
16400
+ this.#unfound.set(key, this.#now());
16401
+ } else if (!offMain && this.#now() - firstUnfound >= OFF_MAIN_AFTER_MILLIS) {
16402
+ offMain = true;
16403
+ }
16404
+ if (offMain) {
16405
+ this.#unfound.delete(key);
16406
+ return [...answer, refusal(
16407
+ "",
16408
+ "nomos.stream.off_main",
16409
+ "the copy's head is not on this peer's main; it must converge its own work, not level from it"
16410
+ )];
16411
+ }
16100
16412
  this.#historyWanted(workspace);
16101
16413
  return [...answer, refusal(
16102
16414
  "",
@@ -16108,6 +16420,17 @@ var LiveStreamServer = class {
16108
16420
  const maxOffers = Math.min(Math.max(1, frontier.maxOffers || MAX_STREAM_BATCH_OFFERS), MAX_STREAM_BATCH_OFFERS);
16109
16421
  return [...answer, this.#batch(workspace, requestId, head, main, maxOffers)];
16110
16422
  }
16423
+ /** Whether this peer's custody of the workspace is shallow. Unknown counts as shallow: it keeps the
16424
+ * existing wait for history rather than calling a head off main. */
16425
+ #shallow(mount, requestId) {
16426
+ const boundaries = this.#kernel.shallowBoundaries;
16427
+ if (!boundaries) return true;
16428
+ try {
16429
+ return boundaries.call(this.#kernel, mount, requestId).length > 0;
16430
+ } catch {
16431
+ return true;
16432
+ }
16433
+ }
16111
16434
  /**
16112
16435
  * The `maxOffers` offers directly above `base`, as the commits this peer admitted them in: one
16113
16436
  * bounded walk and one bounded pack (O(batch)). The copy's kernel adopts exactly these commits on
@@ -16475,7 +16798,6 @@ var OwnOffers = class {
16475
16798
  };
16476
16799
  var LiveCorrespondenceDesk = class {
16477
16800
  #links = /* @__PURE__ */ new Map();
16478
- #pending = /* @__PURE__ */ new Map();
16479
16801
  /** What procedures asked of each workspace's stream, and what it delivered (peer_catchup.md). */
16480
16802
  inbound;
16481
16803
  #own = new OwnOffers();
@@ -16511,13 +16833,6 @@ var LiveCorrespondenceDesk = class {
16511
16833
  * never held. Absent (a custodian, a relay, a test), every write goes out on the next drive.
16512
16834
  */
16513
16835
  writeBurst;
16514
- /**
16515
- * An application peer's receive step (CAP-757; sized by time, CAP-762). A received batch of other
16516
- * senders' offers larger than one step is not admitted on the socket, in one kernel-thread hold:
16517
- * the follow receives it instead, in yielding steps of the policy's current size. Absent (a
16518
- * custodian, a relay, a test), every received batch is admitted as it arrives.
16519
- */
16520
- receiveStep;
16521
16836
  /** The last progress counted per workspace, served while a burst holds recounting back. */
16522
16837
  #progress = /* @__PURE__ */ new Map();
16523
16838
  /** When a held-back progress recount became owed; it reports at the burst's next due point. */
@@ -16607,10 +16922,12 @@ var LiveCorrespondenceDesk = class {
16607
16922
  sent: link.stream?.sent,
16608
16923
  unansweredAgesMs: (link.stream?.unanswered ?? []).map((entry) => Number((now2 - (entry.due - LIVE_ANSWER_WINDOW)) / 1000000n)),
16609
16924
  custodianLocal: link.custodian?.local,
16610
- convergeDue: link.convergeDue !== void 0
16925
+ convergeDue: link.convergeDue !== void 0,
16926
+ resident: false
16611
16927
  };
16612
16928
  try {
16613
16929
  if (this.kernel.isResident(link.binding.workspace) !== false) {
16930
+ state.resident = true;
16614
16931
  const mount = workspaceMount(link.binding.workspace);
16615
16932
  state.head = this.kernel.head(mount, ++this.#requestId);
16616
16933
  state.tracked = this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2);
@@ -16679,7 +16996,7 @@ var LiveCorrespondenceDesk = class {
16679
16996
  }
16680
16997
  #count(link, mount) {
16681
16998
  const head = this.kernel.head(mount, ++this.#requestId);
16682
- const acknowledged = this.#cursor(link, mount)?.local ?? this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2);
16999
+ const acknowledged = this.#cursor(link, mount)?.local ?? this.#heldPeerMain(link, mount, head) ?? this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2);
16683
17000
  if (!head || !acknowledged) return void 0;
16684
17001
  const count = (base, tip) => {
16685
17002
  if (base === tip) return 0;
@@ -16713,6 +17030,14 @@ var LiveCorrespondenceDesk = class {
16713
17030
  #holds(mount, base, tip) {
16714
17031
  return this.#chain(mount, base, tip)?.reachedBase === true;
16715
17032
  }
17033
+ /** The custodian's main as last heard, when this copy holds it on its own head's chain above the
17034
+ * sealed bookmark: the commits up to it came from the stream and are the custodian's (CAP-838). */
17035
+ #heldPeerMain(link, mount, head, tracked = this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2)) {
17036
+ const main = link.peerMain;
17037
+ if (!main || !head || main === tracked) return void 0;
17038
+ if (tracked && !this.#holds(mount, tracked, main)) return void 0;
17039
+ return this.#holds(mount, main, head) ? main : void 0;
17040
+ }
16716
17041
  /** This connection's admission cursor, while it still leads the saved bookmark. A cursor on local
16717
17042
  * history (admitted, not yet sealed) remembers the bookmark it was set above; once anything else
16718
17043
  * moves the bookmark (a follow round adopting the custodian's main) the bookmark rules again, so
@@ -16789,7 +17114,7 @@ var LiveCorrespondenceDesk = class {
16789
17114
  evidencePack: options.carryCommits || intents.some((intent) => intent.transportRequirement === IntentTransportRequirement.COMMIT_TREE) ? this.kernel.packDelta(mount, requestId, batchHead, base) : new Uint8Array()
16790
17115
  });
16791
17116
  }
16792
- receive(request, receipt) {
17117
+ receive(receipt) {
16793
17118
  const link = [...this.#links.values()].find((item) => item.id === receipt.connectionId);
16794
17119
  if (!link) return;
16795
17120
  if (receipt.observation.case === "closed" || receipt.observation.case === "closure") {
@@ -16803,6 +17128,7 @@ var LiveCorrespondenceDesk = class {
16803
17128
  link.ownMains = [];
16804
17129
  delete link.lastAnnounced;
16805
17130
  delete link.lastPlacementAnnounced;
17131
+ link.peerMain = void 0;
16806
17132
  link.dirty = true;
16807
17133
  link.due = this.clock.monotonicNanoseconds() + BigInt(Math.min(3e4, 250 * 2 ** Math.min(link.failures++, 7))) * 1000000n;
16808
17134
  return;
@@ -16812,7 +17138,6 @@ var LiveCorrespondenceDesk = class {
16812
17138
  link.openedAt = this.clock.monotonicNanoseconds();
16813
17139
  link.failures = 0;
16814
17140
  link.unheard = void 0;
16815
- if (!link.publisher) this.#hello(link);
16816
17141
  if (!link.publisher) this.inbound.opened(link.binding.workspace);
16817
17142
  this.linkOpened?.(link.binding.workspace);
16818
17143
  return;
@@ -16846,18 +17171,6 @@ var LiveCorrespondenceDesk = class {
16846
17171
  if (this.inbound.frame(link.binding.workspace, frame2.message)) return;
16847
17172
  if (frame2.message.case === "frontier") {
16848
17173
  this.#announced(link, frame2.message.value.head);
16849
- if (this.kernel.isResident(link.binding.workspace) === false) return;
16850
- if (!frame2.message.value.response) {
16851
- this.#send(link, { case: "frontier", value: {
16852
- head: this.kernel.head(workspaceMount(link.binding.workspace), ++this.#requestId) ?? "",
16853
- response: true
16854
- } });
16855
- }
16856
- try {
16857
- const batch2 = this.export(link.binding, frame2.message.value.head, ++this.#requestId);
16858
- if (batch2.source.case === "inline" && batch2.source.value.offers.length) this.#send(link, { case: "offers", value: batch2 });
16859
- } catch {
16860
- }
16861
17174
  return;
16862
17175
  }
16863
17176
  if (frame2.message.case === "admission") {
@@ -16865,48 +17178,18 @@ var LiveCorrespondenceDesk = class {
16865
17178
  this.progressChanged?.(link.binding.workspace);
16866
17179
  return;
16867
17180
  }
16868
- if (frame2.message.case !== "offers") return;
16869
- const batch = frame2.message.value;
16870
- if (batch.protocolVersion !== 2 || !batch.requestId || batch.source.case !== "inline" || !batch.source.value.offers.length) return;
16871
- const offers = batch.source.value.offers.filter((offer) => !this.#own.hasCommit(link.binding.workspace, offer.commitOid));
16872
- if (!offers.length) return;
16873
- if (this.kernel.isResident(link.binding.workspace) === false && !this.inbound.wanted(link.binding.workspace)) {
16874
- this.remoteAdvanced?.(link.binding.workspace);
16875
- return;
16876
- }
16877
- if (this.receiveStep !== void 0 && offers.length > this.receiveStep.offers) {
16878
- this.remoteAdvanced?.(link.binding.workspace);
16879
- return;
16880
- }
16881
- if ([...this.#pending.values()].some((pending) => pending.link === link && pending.bytes.length === bytes.length && pending.bytes.every((byte, index) => byte === bytes[index]))) return;
16882
- if (this.#pending.size >= 32) return;
16883
- this.#pending.set(request.requestId, { link, bytes });
16884
- return create55(RuntimeRequestSchema, {
16885
- protocolVersion: 2,
16886
- requestId: request.requestId,
16887
- target: { workspace: link.binding.workspace, session: link.binding.replicaId },
16888
- // HTTP sender reconciliation controls are not part of a live proposal.
16889
- // Keeping fastForwardOnly while removing baseHead silently skips every
16890
- // offer against a nonempty local head. The Kernel judges sealed causality;
16891
- // live receivers neither ask for a return archive nor confirm the sender.
16892
- command: { case: "admitCustodyOffers", value: create55(CustodyOfferBatchRequestSchema, {
16893
- ...batch,
16894
- baseHead: void 0,
16895
- observedHead: void 0,
16896
- fastForwardOnly: false,
16897
- ...offers.length === batch.source.value.offers.length ? {} : { source: { case: "inline", value: { ...batch.source.value, offers } } }
16898
- }) }
16899
- });
17181
+ }
17182
+ /** The newest local commit the custodian admitted unchanged over this workspace's open link: its
17183
+ * main holds that commit, sealed or not, so it is no work to offer (CAP-838). */
17184
+ admittedLocal(workspace) {
17185
+ const link = this.#links.get(workspace);
17186
+ const cursor = link?.state === "open" && !link.publisher ? link.custodian : void 0;
17187
+ return cursor && cursor.main === cursor.local ? cursor.local : void 0;
16900
17188
  }
16901
17189
  /** Offers this replica sent another way (the HTTP lane): their echo on the live link is its own. */
16902
17190
  offered(workspace, commitOids) {
16903
17191
  this.#own.commits(workspace, commitOids);
16904
17192
  }
16905
- /** Whether this request is the admission of a batch relayed to this follower over its live link.
16906
- * Such an admission is never answered to a sender, so it keeps no custody receipts (CAP-759). */
16907
- relayed(requestId) {
16908
- return this.#pending.has(requestId);
16909
- }
16910
17193
  /**
16911
17194
  * The custodian judged a live batch. Admission acknowledges the batch at once; its admitted main
16912
17195
  * becomes this connection's cursor when it is already in local verified history. The saved
@@ -16926,9 +17209,10 @@ var LiveCorrespondenceDesk = class {
16926
17209
  ...admission.sealedMain ? { sealed: admission.sealedMain } : {}
16927
17210
  };
16928
17211
  }
16929
- if (!admission?.main || this.kernel.isResident(workspace) === false) return;
17212
+ if (!admission?.main) return;
16930
17213
  const ownBatchHead = this.#own.batchHead(workspace, live.requestId);
16931
17214
  const ours = ownBatchHead !== void 0;
17215
+ if (this.kernel.isResident(workspace) === false) return;
16932
17216
  let stale = false;
16933
17217
  if (ours) link.unheard = void 0;
16934
17218
  if (ours && link.stream) {
@@ -17016,6 +17300,7 @@ var LiveCorrespondenceDesk = class {
17016
17300
  * upstream head it already recorded. Re-announcing a known frontier - which is all an
17017
17301
  * upstream can do while this replica is ahead or held on a dependency - is not an event. */
17018
17302
  #announced(link, head) {
17303
+ if (head) link.peerMain = head;
17019
17304
  if (!head || link.lastAnnounced === head) return;
17020
17305
  link.lastAnnounced = head;
17021
17306
  if (this.kernel.isResident(link.binding.workspace) === false) {
@@ -17040,15 +17325,6 @@ var LiveCorrespondenceDesk = class {
17040
17325
  if (frontier === this.kernel.resolveRef(mount, ++this.#requestId, PLACEMENT_REF4)) return;
17041
17326
  this.placementAdvanced?.(link.binding.workspace);
17042
17327
  }
17043
- settled(request, response) {
17044
- if (response.outcome.case === "correspondencePending" || response.outcome.case === "localReadPending") return;
17045
- this.#pending.delete(request.requestId);
17046
- }
17047
- failed(requestId) {
17048
- const pending = this.#pending.get(requestId);
17049
- this.#pending.delete(requestId);
17050
- if (pending) this.remoteAdvanced?.(pending.link.binding.workspace);
17051
- }
17052
17328
  disconnect(workspace) {
17053
17329
  const link = this.#links.get(workspace);
17054
17330
  if (!link) return;
@@ -17056,7 +17332,6 @@ var LiveCorrespondenceDesk = class {
17056
17332
  if (link.state === "open") this.linkClosed?.(workspace, closure);
17057
17333
  this.#links.delete(workspace);
17058
17334
  this.#progress.delete(workspace);
17059
- for (const [id, pending] of this.#pending) if (pending.link === link) this.#pending.delete(id);
17060
17335
  }
17061
17336
  /** The digest of the settled-letter outcomes this copy holds; empty when it cannot tell. */
17062
17337
  #outcomesDigest(workspace) {
@@ -17094,14 +17369,6 @@ var LiveCorrespondenceDesk = class {
17094
17369
  transfer.retain(create55(PeerGitRefsFetchedSchema, { refs: [...wanted.refs], pack }));
17095
17370
  this.progressChanged?.(link.binding.workspace);
17096
17371
  }
17097
- #hello(link) {
17098
- if (this.kernel.isResident(link.binding.workspace) === false) return;
17099
- const head = this.kernel.head(workspaceMount(link.binding.workspace), ++this.#requestId);
17100
- this.#send(link, { case: "frontier", value: {
17101
- head: head ?? "",
17102
- outcomesDigest: this.#outcomesDigest(link.binding.workspace)
17103
- } });
17104
- }
17105
17372
  drive() {
17106
17373
  const now2 = this.clock.monotonicNanoseconds();
17107
17374
  let wake;
@@ -17150,7 +17417,8 @@ var LiveCorrespondenceDesk = class {
17150
17417
  link.custodian = void 0;
17151
17418
  }
17152
17419
  this.#cursor(link, mount);
17153
- const answered2 = link.publisher ? link.published ??= head ?? "" : link.custodian?.local ?? this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2) ?? "";
17420
+ let answered2 = link.publisher ? link.published ??= head ?? "" : link.custodian?.local ?? this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2) ?? "";
17421
+ if (!link.publisher && !link.custodian) answered2 = this.#heldPeerMain(link, mount, head, answered2) ?? answered2;
17154
17422
  const fence = link.custodian?.main ?? answered2;
17155
17423
  if (link.stream && !(head && this.#holds(mount, link.stream.sent, head))) {
17156
17424
  link.stream = void 0;
@@ -17251,7 +17519,6 @@ var LiveCorrespondenceDesk = class {
17251
17519
  }
17252
17520
  close() {
17253
17521
  for (const workspace of [...this.#links.keys()]) this.disconnect(workspace);
17254
- this.#pending.clear();
17255
17522
  }
17256
17523
  };
17257
17524
 
@@ -18209,6 +18476,7 @@ var PLACEMENT_REF5 = "refs/nomos/placement";
18209
18476
  var RECEIVED_PLACEMENT_REF = "refs/remotes/nomos/placement";
18210
18477
  var STREAM_BATCH_OFFERS = 64;
18211
18478
  var REMOUNT_AFTER_OFFERS = 128;
18479
+ var MAX_REMOUNTS_LOST = 2;
18212
18480
  var HISTORY_SLICES = [8, 64, 256, 256];
18213
18481
  var WorkspaceSyncPhase = Object.freeze({
18214
18482
  Idle: "idle",
@@ -18229,7 +18497,11 @@ var deferredLocal = "refs/nomos/sync-deferred-local";
18229
18497
  var judgedThisLifetime = /* @__PURE__ */ new Map();
18230
18498
  function releaseSyncJudgment(workspace) {
18231
18499
  judgedThisLifetime.delete(workspace);
18500
+ notContainedThisLifetime.delete(workspace);
18232
18501
  }
18502
+ var notContainedThisLifetime = /* @__PURE__ */ new Map();
18503
+ var MAX_NOT_CONTAINED = 1024;
18504
+ var NOT_CONTAINED_REFUSALS = /* @__PURE__ */ new Set(["nomos.stream.off_main", "nomos.stream.history_required"]);
18233
18505
  var MAX_REBASES_PER_ROUND = 2;
18234
18506
  var elapsedMillis = (clock2, started) => {
18235
18507
  const finished = clock2.monotonicNanoseconds();
@@ -18285,6 +18557,7 @@ var WorkspaceSyncWork = class {
18285
18557
  #lastStep;
18286
18558
  #probeOnly;
18287
18559
  #liveConnected;
18560
+ #liveAdmitted;
18288
18561
  /** Set when this round adopted the upstream's own head as its base (see #establishBase). */
18289
18562
  #establishedBase;
18290
18563
  #receiveState;
@@ -18301,6 +18574,11 @@ var WorkspaceSyncWork = class {
18301
18574
  /** The custodian head this round last offered or pulled from. */
18302
18575
  #rebaseFrom;
18303
18576
  #rebases = 0;
18577
+ #remountsLost = 0;
18578
+ /** This round's level ask is a containment question (CAP-870): on a refusal, take this path. */
18579
+ #containment;
18580
+ /** The stale bookmark a contained round replaces: its custodian's main holds the local head. */
18581
+ #containedBookmark;
18304
18582
  /** Local intents this round's rebase refused and parked on the refused-offer desk. */
18305
18583
  #parkedLocal = 0;
18306
18584
  /** An application-authorized drop: replace local custody at exactly this head. */
@@ -18322,6 +18600,7 @@ var WorkspaceSyncWork = class {
18322
18600
  this.#placementFetched = args.placementFetched;
18323
18601
  this.#probeOnly = args.probeOnly ?? false;
18324
18602
  this.#liveConnected = args.liveConnected === true;
18603
+ this.#liveAdmitted = args.liveAdmitted;
18325
18604
  this.#receiveState = args.receiveState;
18326
18605
  this.#completeHistory = args.completeHistory === true;
18327
18606
  this.#repairMissingCommit = args.repairMissingCommit === true;
@@ -18396,9 +18675,15 @@ var WorkspaceSyncWork = class {
18396
18675
  if (this.#receiveState) return this.#acquire("full");
18397
18676
  if (this.#replaceLocalHead !== void 0) return this.#acquire(this.#repairMissingCommit ? "full" : "mount");
18398
18677
  if (!this.#localHead) return this.#acquire(this.#completeHistory ? "full" : "mount");
18399
- if (this.#liveConnected && !this.#probeOnly && this.#holdsLocalWork() && this.#previousHead) {
18400
- return this.#offerOrReconcile();
18678
+ const unadmitted = this.#holdsLocalWork() && this.#localHead !== this.#liveAdmitted;
18679
+ if (this.#liveConnected && unadmitted && this.#previousHead) {
18680
+ if (this.#mayBeContained()) return this.#askContainment("offer");
18681
+ return this.#notContained();
18682
+ }
18683
+ if (this.#liveConnected && this.#probeOnly && this.#previousHead && this.#holdsUnsyncedCommits() && this.#command.admit && this.#localHead === this.#liveAdmitted) {
18684
+ return this.#acquire("level");
18401
18685
  }
18686
+ if (this.#liveConnected && !this.#probeOnly && !unadmitted) return this.#acquire("level");
18402
18687
  const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
18403
18688
  return this.#beginOffer(encodeInlineCustodyOffer({
18404
18689
  session: this.#binding.replicaId,
@@ -18407,6 +18692,60 @@ var WorkspaceSyncWork = class {
18407
18692
  intents: []
18408
18693
  }), { case: "awaiting", requestId }, true);
18409
18694
  }
18695
+ /** Whether the custodian's main may hold this copy's head: not already refused in this lifetime. */
18696
+ #mayBeContained() {
18697
+ return !!this.#localHead && this.#offerHead === void 0 && notContainedThisLifetime.get(this.#mount.workspace) !== this.#localHead;
18698
+ }
18699
+ /** The probe named a custodian main that is not on this copy's own chain, so the copy's head may be
18700
+ * on the custodian's. A main below the local head (the custodian is behind) cannot contain it. A
18701
+ * complete copy answers a main it does not hold after one existence check, and one it holds after
18702
+ * a walk to where the two chains join. A kernel that cannot say keeps the existing path. */
18703
+ #custodianMainOffLocalChain() {
18704
+ if (!this.#kernel.historySummary || !this.#desiredHead || !this.#localHead) return false;
18705
+ try {
18706
+ return !this.#kernel.historySummary(this.#mount, this.#requestId, this.#desiredHead, this.#localHead).reachedBase;
18707
+ } catch (error) {
18708
+ return error instanceof KernelHistoryRequired;
18709
+ }
18710
+ }
18711
+ /** Level from the local head (CAP-870). The stream answers with the custodian's commits above it
18712
+ * (or "level") only when its main holds that head; then this round converges onto them, moves the
18713
+ * bookmark, and offers nothing. One custodian lookup, O(commits behind); no local enumeration. */
18714
+ #askContainment(otherwise) {
18715
+ this.#containment = otherwise;
18716
+ return this.#acquire("level");
18717
+ }
18718
+ /** The stream answered from the local head: it is on the custodian's main. The stale bookmark
18719
+ * stays this round's to replace; the local head is the round's base from here. */
18720
+ #contained() {
18721
+ this.#containment = void 0;
18722
+ this.#containedBookmark = this.#previousHead;
18723
+ this.#previousHead = this.#localHead;
18724
+ }
18725
+ /** The custodian's main does not hold the local head (or the stream could not say): the copy holds
18726
+ * work of its own. Go straight on to the pull/rebase/offer path. A dependency planner's probe hands
18727
+ * the round back to it to plan the outbound suffix. */
18728
+ #notContained(code) {
18729
+ const otherwise = this.#containment ?? "offer";
18730
+ this.#containment = void 0;
18731
+ if (code !== void 0 && NOT_CONTAINED_REFUSALS.has(code) && this.#localHead) {
18732
+ if (notContainedThisLifetime.size >= MAX_NOT_CONTAINED && !notContainedThisLifetime.has(this.#mount.workspace)) {
18733
+ notContainedThisLifetime.delete(notContainedThisLifetime.keys().next().value);
18734
+ }
18735
+ notContainedThisLifetime.set(this.#mount.workspace, this.#localHead);
18736
+ }
18737
+ if (this.#probeOnly) {
18738
+ this.#needsReconciliation = true;
18739
+ return this.#finish(create64(SyncWorkspaceResponseSchema, {
18740
+ workspace: this.#mount.workspace,
18741
+ currentHead: this.#localHead,
18742
+ previousHead: this.#previousHead,
18743
+ stillAhead: true,
18744
+ offerReceipt: this.#offerReceipt
18745
+ }));
18746
+ }
18747
+ return otherwise === "pull" ? this.#pullBeforeOffer() : this.#offerOrReconcile();
18748
+ }
18410
18749
  #offerOrReconcile() {
18411
18750
  if (this.#command.admit && this.#localHead && this.#localHead !== this.#previousHead) {
18412
18751
  const suffix = this.#kernel.transportIntentsAbove(
@@ -18485,7 +18824,14 @@ var WorkspaceSyncWork = class {
18485
18824
  return this.#previousHead === void 0 && this.#localHead !== void 0 && this.#replaceLocalHead === void 0;
18486
18825
  }
18487
18826
  #holdsLocalWork() {
18488
- return this.#command.admit && !!this.#localHead && this.#localHead !== this.#previousHead;
18827
+ return this.#command.admit && this.#holdsUnsyncedCommits();
18828
+ }
18829
+ /** Commits on local main the provider has not been seen to admit, whether or not this round may
18830
+ * offer them. Remount replaces local main, so it asks this, never the admit-gated question: a copy
18831
+ * holding unsynced work is offered and rebased, never remounted. A copy without a bookmark cannot
18832
+ * prove it holds nothing of its own. */
18833
+ #holdsUnsyncedCommits() {
18834
+ return !!this.#localHead && this.#localHead !== this.#previousHead;
18489
18835
  }
18490
18836
  /** Ask only for the custodian's delta; the offer follows once this peer has rebased. */
18491
18837
  #pullBeforeOffer() {
@@ -18523,13 +18869,13 @@ var WorkspaceSyncWork = class {
18523
18869
  }
18524
18870
  if (purpose === "level") {
18525
18871
  this.#state = { phase: WorkspaceSyncPhase.Stream, purpose, startedAt };
18526
- return this.#streamEffect("level", { case: "level", value: create64(LiveFrontierSchema, {
18872
+ return this.#streamEffect(this.#containment ? "contain" : "level", { case: "level", value: create64(LiveFrontierSchema, {
18527
18873
  head: this.#localHead ?? "",
18528
18874
  response: false,
18529
18875
  maxOffers: this.#receiveStep?.offers ?? STREAM_BATCH_OFFERS,
18530
18876
  // Only a copy holding no work above its bookmark may be remounted instead of replaying, and
18531
18877
  // never one whose durable copy must hold the complete history (a head-only mount it cannot keep).
18532
- remountAfterOffers: this.#holdsLocalWork() || this.#completeHistory ? 0 : REMOUNT_AFTER_OFFERS
18878
+ remountAfterOffers: this.#holdsUnsyncedCommits() || this.#completeHistory ? 0 : REMOUNT_AFTER_OFFERS
18533
18879
  }) });
18534
18880
  }
18535
18881
  const outcomes = new EffectOutcomeTransfer(this.#kernel, this.#mount, this.#requestId);
@@ -18606,6 +18952,7 @@ var WorkspaceSyncWork = class {
18606
18952
  }
18607
18953
  if (answer.outcome.case === "refusal") {
18608
18954
  const refusal2 = answer.outcome.value;
18955
+ if (state.purpose === "level" && this.#containment) return this.#notContained(refusal2.code);
18609
18956
  if (state.afterPlacement) return this.#finish(state.afterPlacement);
18610
18957
  return this.#transportFailure(`${refusal2.code}: ${refusal2.message}`, false);
18611
18958
  }
@@ -18642,6 +18989,11 @@ var WorkspaceSyncWork = class {
18642
18989
  state.startedAt
18643
18990
  );
18644
18991
  }
18992
+ if (state.purpose === "level" && this.#containment) {
18993
+ const answeredFromHead = answer.outcome.case === "level" || answer.outcome.case === "pack" && answer.outcome.value.base === this.#localHead;
18994
+ if (!answeredFromHead) return this.#notContained();
18995
+ this.#contained();
18996
+ }
18645
18997
  if (state.purpose === "level" && answer.outcome.case === "pack" && answer.outcome.value.base) {
18646
18998
  const batch = answer.outcome.value;
18647
18999
  if (batch.base !== this.#previousHead && batch.base !== this.#kernel.head(this.#mount, this.#requestId)) {
@@ -18780,13 +19132,19 @@ var WorkspaceSyncWork = class {
18780
19132
  /**
18781
19133
  * A copy holding no work above its bookmark, too far behind to replay the backlog: mount the
18782
19134
  * peer's checkpoint in place of its exact local main (O(state), the same trust as a cold mount).
18783
- * The kernel keeps the replaced head at refs/heads/custody-preserved/<old>; that head was only a
18784
- * bookmark of the provider's own main, so the preservation is released at once.
19135
+ * The kernel keeps the replaced head at refs/heads/custody-preserved/<old>. That ref is custody the
19136
+ * kernel guards (custody may not delete an effectful branch), so it is left where it is: a remount
19137
+ * that deleted it threw after main had already moved, leaving the bookmark behind main and the
19138
+ * round failed for ever (2026-10-08, estate-5b493d6b).
19139
+ *
19140
+ * The copy may have moved while the checkpoint streamed (a live batch, a local write). Then it is
19141
+ * no longer the copy the remount was asked for: take the round up again from its new head. Local
19142
+ * work is offered first; a copy that is still only behind asks to level again.
18785
19143
  */
18786
19144
  #remount(candidateHead, receivedBytes, prefetchMillis) {
18787
19145
  const expected = this.#kernel.head(this.#mount, this.#requestId);
18788
- if (expected === void 0 || expected !== this.#localHead || this.#holdsLocalWork()) {
18789
- return this.#transportFailure("the copy changed while its remount was streaming", false);
19146
+ if (expected === void 0 || expected !== this.#localHead || this.#holdsUnsyncedCommits()) {
19147
+ return this.#remountLost(expected);
18790
19148
  }
18791
19149
  const started = this.#clock.monotonicNanoseconds();
18792
19150
  if (candidateHead !== expected) {
@@ -18794,7 +19152,6 @@ var WorkspaceSyncWork = class {
18794
19152
  if (!restored.accepted || restored.head !== candidateHead) {
18795
19153
  throw new Error(`kernel refused to remount '${this.#mount.workspace}' at ${candidateHead}`);
18796
19154
  }
18797
- this.#kernel.deleteRef?.(this.#mount, this.#requestId, `refs/heads/custody-preserved/${expected}`);
18798
19155
  this.#providerCustodyMounted();
18799
19156
  }
18800
19157
  return this.#converged(create64(SyncResponseSchema, {
@@ -18804,6 +19161,25 @@ var WorkspaceSyncWork = class {
18804
19161
  admittedRemoteHead: candidateHead
18805
19162
  }), candidateHead, receivedBytes, prefetchMillis, started);
18806
19163
  }
19164
+ /** The remount's copy changed under it. Bounded: a copy that keeps moving under live traffic is
19165
+ * levelled by its live link anyway, and the next round starts from wherever it got to. */
19166
+ #remountLost(head) {
19167
+ if (head === void 0 || ++this.#remountsLost > MAX_REMOUNTS_LOST) {
19168
+ return this.#transportFailure("the copy changed while its remount was streaming", false);
19169
+ }
19170
+ this.#localHead = head;
19171
+ this.#previousHead = this.#kernel.resolveRef(this.#mount, this.#requestId, trackedMain);
19172
+ if (this.#desiredHead === this.#localHead) {
19173
+ return this.#converged(create64(SyncResponseSchema, {
19174
+ admitted: true,
19175
+ head,
19176
+ candidateHead: head,
19177
+ admittedRemoteHead: head
19178
+ }), head, 0, 0);
19179
+ }
19180
+ if (this.#holdsLocalWork() && this.#desiredHead !== this.#previousHead) return this.#pullBeforeOffer();
19181
+ return this.#offerOrReconcile();
19182
+ }
18807
19183
  resume(receipt) {
18808
19184
  if (receipt.effectId === this.#lastReceiptEffectId && this.#lastStep) {
18809
19185
  return this.#lastStep;
@@ -18968,6 +19344,10 @@ var WorkspaceSyncWork = class {
18968
19344
  offerReceipt: this.#offerReceipt
18969
19345
  }));
18970
19346
  }
19347
+ const custodianMoved = this.#holdsLocalWork() && this.#desiredHead !== this.#previousHead;
19348
+ if (custodianMoved && this.#mayBeContained() && this.#custodianMainOffLocalChain()) {
19349
+ return this.#askContainment("pull");
19350
+ }
18971
19351
  if (this.#probeOnly) {
18972
19352
  this.#needsReconciliation = true;
18973
19353
  return this.#finish(create64(SyncWorkspaceResponseSchema, {
@@ -18978,9 +19358,7 @@ var WorkspaceSyncWork = class {
18978
19358
  offerReceipt: this.#offerReceipt
18979
19359
  }));
18980
19360
  }
18981
- if (this.#holdsLocalWork() && this.#desiredHead !== this.#previousHead) {
18982
- return this.#pullBeforeOffer();
18983
- }
19361
+ if (custodianMoved) return this.#pullBeforeOffer();
18984
19362
  return this.#offerOrReconcile();
18985
19363
  }
18986
19364
  this.#admissionSummary = summarizeCustodyAdmission(admission);
@@ -19314,7 +19692,8 @@ var WorkspaceSyncWork = class {
19314
19692
  }));
19315
19693
  }
19316
19694
  #converged(verdict, candidateHead, receivedBytes, prefetchMillis, started = this.#clock.monotonicNanoseconds(), rebirth) {
19317
- if (verdict.admitted && this.#candidateDurable && candidateHead !== this.#previousHead && this.#kernel.resolveRef(this.#mount, this.#requestId, trackedMain) === this.#previousHead) {
19695
+ const tracked = verdict.admitted && this.#candidateDurable ? this.#kernel.resolveRef(this.#mount, this.#requestId, trackedMain) : void 0;
19696
+ if (verdict.admitted && this.#candidateDurable && tracked !== candidateHead && (tracked === this.#previousHead || this.#containedBookmark !== void 0 && tracked === this.#containedBookmark)) {
19318
19697
  this.#kernel.writeRef(
19319
19698
  this.#mount,
19320
19699
  this.#requestId,
@@ -19603,10 +19982,16 @@ var WorkspaceDependencySyncWork = class {
19603
19982
  this.#plan = [this.#args.root];
19604
19983
  return this.#advance();
19605
19984
  }
19606
- if (this.#args.liveConnected && this.#args.kernel.resolveRef(this.#args.root.mount, this.#args.requestId, trackedMain2)) {
19985
+ const { kernel, requestId, root } = this.#args;
19986
+ const tracked = this.#args.liveConnected ? kernel.resolveRef(root.mount, requestId, trackedMain2) : void 0;
19987
+ if (tracked && kernel.head(root.mount, requestId) === tracked) {
19607
19988
  this.#plan = this.#planDependencies();
19608
19989
  return this.#advance();
19609
19990
  }
19991
+ if (tracked) {
19992
+ this.#current = this.#work(root, `${this.workId}:contain`, true);
19993
+ return this.#accept(this.#current.start());
19994
+ }
19610
19995
  this.#current = this.#work(this.#args.root, `${this.workId}:frontier`, true);
19611
19996
  return this.#accept(this.#current.start());
19612
19997
  }
@@ -20918,6 +21303,11 @@ var ReplicaFollowLane = class {
20918
21303
  const delay = this.#controller.reconnected(workspace);
20919
21304
  if (delay !== void 0) this.#scheduleAt(workspace, this.#now() + delay);
20920
21305
  }
21306
+ /** The upstream announced a new frontier: news even to a follow the kernel refused. */
21307
+ remoteAdvanced(workspace) {
21308
+ const delay = this.#controller.reconnected(workspace, true);
21309
+ if (delay !== void 0) this.#scheduleAt(workspace, this.#now() + delay);
21310
+ }
20921
21311
  /** The upstream rang for a new placement frontier (see ReplicaFollowController). */
20922
21312
  placementAnnounced(workspace) {
20923
21313
  const delay = this.#controller.placementAnnounced(workspace);
@@ -21232,6 +21622,7 @@ var CorrespondenceDesk = class {
21232
21622
  #onPlacementFetched;
21233
21623
  #onShallowMount;
21234
21624
  #onOffered;
21625
+ #liveAdmitted;
21235
21626
  #onOutboxHistoryRequired;
21236
21627
  #backgroundHistory;
21237
21628
  #receiveStep;
@@ -21288,6 +21679,7 @@ var CorrespondenceDesk = class {
21288
21679
  this.#onPlacementFetched = args.onPlacementFetched;
21289
21680
  this.#onShallowMount = args.onShallowMount;
21290
21681
  this.#onOffered = args.onOffered;
21682
+ this.#liveAdmitted = args.liveAdmitted;
21291
21683
  this.#onOutboxHistoryRequired = args.onOutboxHistoryRequired;
21292
21684
  this.#backgroundHistory = args.backgroundHistory !== false;
21293
21685
  this.#receiveStep = args.receiveStep;
@@ -21614,6 +22006,12 @@ var CorrespondenceDesk = class {
21614
22006
  this.#followLane.reconnected(workspace);
21615
22007
  this.reportFollows();
21616
22008
  }
22009
+ /** The upstream announced a new frontier for this workspace over its live link: an event which
22010
+ * re-runs a round the kernel refused (its inputs changed). */
22011
+ replicaRemoteAdvanced(workspace) {
22012
+ this.#followLane.remoteAdvanced(workspace);
22013
+ this.reportFollows();
22014
+ }
21617
22015
  /** The upstream rang for a new placement frontier: the next round re-checks placement even
21618
22016
  * though main has not moved. */
21619
22017
  replicaPlacementAnnounced(workspace) {
@@ -21650,10 +22048,11 @@ var CorrespondenceDesk = class {
21650
22048
  const state = this.#follows.followForWorkspace(workspace)?.state;
21651
22049
  if (!state) return [];
21652
22050
  const isSettled = state.case === ReplicaFollowPhase.Settled;
22051
+ const refused = state.case === ReplicaFollowPhase.Backoff && state.refusal?.blocked === true;
21653
22052
  const isLive = this.#openLinks.has(workspace);
21654
22053
  if (isSettled) settled += 1;
21655
22054
  if (isLive) live += 1;
21656
- const phase = {
22055
+ const phase = refused ? FollowObservationPhase.KERNEL_REFUSED : {
21657
22056
  [ReplicaFollowPhase.Desired]: FollowObservationPhase.DESIRED,
21658
22057
  [ReplicaFollowPhase.Due]: FollowObservationPhase.DUE,
21659
22058
  [ReplicaFollowPhase.Running]: FollowObservationPhase.RUNNING,
@@ -21667,7 +22066,7 @@ var CorrespondenceDesk = class {
21667
22066
  [ReplicaFollowPhase.LocalCopyUnreadable]: FollowObservationPhase.LOCAL_COPY_UNREADABLE
21668
22067
  }[state.case];
21669
22068
  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;
21670
- const retryAt = state.case === ReplicaFollowPhase.Offline || state.case === ReplicaFollowPhase.InvalidCredential || state.case === ReplicaFollowPhase.Backoff ? state.retryAtUnixMillis : void 0;
22069
+ 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;
21671
22070
  const dueAt2 = state.case === ReplicaFollowPhase.Due || state.case === ReplicaFollowPhase.ReplacingLocal ? state.dueAtUnixMillis : void 0;
21672
22071
  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;
21673
22072
  const activeEffect = state.case === ReplicaFollowPhase.Running ? this.#activeSyncEffect(workspace) : void 0;
@@ -22165,6 +22564,7 @@ var CorrespondenceDesk = class {
22165
22564
  workId: id,
22166
22565
  probeOnly,
22167
22566
  liveConnected: this.#openLinks.has(target3.mount.workspace),
22567
+ ...this.#openLinks.has(target3.mount.workspace) && this.#liveAdmitted?.(target3.mount.workspace) ? { liveAdmitted: this.#liveAdmitted(target3.mount.workspace) } : {},
22168
22568
  ...beforeConverge === void 0 ? {} : { beforeConverge },
22169
22569
  ...target3.receiveState === void 0 ? {} : { receiveState: target3.receiveState },
22170
22570
  ...target3.offerHead === void 0 ? {} : { offerHead: target3.offerHead },
@@ -23788,10 +24188,10 @@ var OfferReadinessDesk = class {
23788
24188
  while (true) {
23789
24189
  this.#ports.owe(owed.workspace);
23790
24190
  while (this.#ports.owes(owed.workspace)) {
23791
- const tick = this.#ports.tick();
24191
+ const { ticked, wake: readiness } = this.#ports.tick();
23792
24192
  const delayMillis = Math.min(LONGEST_WAKE_MILLIS, Math.max(
23793
24193
  FIRST_WAKE_MILLIS,
23794
- tick.progress !== void 0 ? FIRST_WAKE_MILLIS : tick.nextTickAfterMillis
24194
+ ticked.progress !== void 0 ? FIRST_WAKE_MILLIS : readiness.case === "after" ? readiness.millis : LONGEST_WAKE_MILLIS
23795
24195
  ));
23796
24196
  const receipt = yield { case: "wake", value: create80(PeerWakeEffectSchema, {
23797
24197
  effectId: `${workId2}:repay-${++wake}`,
@@ -23921,7 +24321,6 @@ function isAnsweredStateRead(command, response) {
23921
24321
  }
23922
24322
  var INTERACTIVE_PEER_CLASSES = /* @__PURE__ */ new Set(["personal-device", "browser"]);
23923
24323
  var INTERACTION_FIRST_MILLIS = 15e3;
23924
- var READ_READINESS_ONLY = 1n << 62n;
23925
24324
  var PLACEMENT_READ_RETRY_MILLIS = 60000n;
23926
24325
  var STREAM_WAKE_FIRST_MILLIS = 20;
23927
24326
  var HISTORY_STREAM_SLICES = [8, 64, 256];
@@ -23940,7 +24339,6 @@ var APPLICATION_WAITS = /* @__PURE__ */ new Set([
23940
24339
  "continueLocalRead"
23941
24340
  ]);
23942
24341
  var APPLICATION_WAIT_NANOS = 5000000000n;
23943
- var READ_INDEX_BUILDING = /the read index of .+ is being built|read maintenance continues it/;
23944
24342
  var PeerOffice = class {
23945
24343
  #kernel;
23946
24344
  #sessions = new SessionDirectory();
@@ -24135,7 +24533,6 @@ var PeerOffice = class {
24135
24533
  }
24136
24534
  }, (workspace) => this.#residency.lastRetainedHead(workspace));
24137
24535
  if (this.#writeBurst) this.#live.writeBurst = this.#writeBurst;
24138
- if (this.#interactivePeer) this.#live.receiveStep = this.#receiveStepBudget;
24139
24536
  this.#credentials = new CredentialSessions(this.#sessions, credentials, observations);
24140
24537
  this.#readability = new LocalCopyReadability((workspace, format) => {
24141
24538
  this.#follows.markLocalCopyUnreadable(workspace, format);
@@ -24153,7 +24550,8 @@ var PeerOffice = class {
24153
24550
  new ReplicaFollowDesk(seatedStore),
24154
24551
  observations,
24155
24552
  this.#replicaId,
24156
- new BirthRefusalRegister(seatedStore)
24553
+ new BirthRefusalRegister(seatedStore),
24554
+ PEER_RUNTIME_IDENTITY
24157
24555
  );
24158
24556
  this.#compatibility = new CompatibilityDesk(
24159
24557
  this.#queries,
@@ -24172,13 +24570,20 @@ var PeerOffice = class {
24172
24570
  this.#trace,
24173
24571
  observations,
24174
24572
  {
24175
- readReady: (workspace) => this.#subscriptions.readIndexReady(workspace),
24176
- frontierAdvanced: (workspace) => this.#subscriptions.readIndexAdvanced(workspace),
24177
- localCopyUnreadable: (workspace, format) => this.#readability.mark(
24178
- workspace,
24179
- this.#kernel.head(workspaceMount(workspace), 0n),
24180
- format
24181
- ),
24573
+ // A read waiting on this workspace is released by the readiness event itself, not a timer.
24574
+ readReady: (workspace) => {
24575
+ this.#subscriptions.readIndexReady(workspace);
24576
+ this.#readResponses?.readinessChanged(workspace);
24577
+ },
24578
+ frontierAdvanced: (workspace) => {
24579
+ this.#subscriptions.readIndexAdvanced(workspace);
24580
+ this.#readResponses?.readinessChanged(workspace);
24581
+ },
24582
+ readinessMayChange: (workspace) => this.#readResponses?.readinessChanged(workspace),
24583
+ localCopyUnreadable: (workspace, format) => {
24584
+ this.#readability.mark(workspace, this.#kernel.head(workspaceMount(workspace), 0n), format);
24585
+ this.#readResponses?.readinessChanged(workspace);
24586
+ },
24182
24587
  isLocalCopyUnreadable: (workspace) => this.#readability.decide(workspace) !== void 0
24183
24588
  },
24184
24589
  // The kernel owes this peer's writes to an ordered background flush the desk schedules.
@@ -24240,7 +24645,7 @@ var PeerOffice = class {
24240
24645
  aggregateIds: new Set([...admitted.affected, ...admitted.created].map((ref) => ref.id)),
24241
24646
  // What the offer changed, typed as reads resolve it: watches it cannot change are not read.
24242
24647
  stateChange: admitted.stateChange
24243
- }, () => this.#readMaintenance.tick(void 0, 0n, READ_READINESS_ONLY, false).progress !== void 0));
24648
+ }, () => this.#readMaintenance.tickReadReadiness().ticked.progress !== void 0));
24244
24649
  noteTimeline("ownOffer", `${delivery.delivered}/${delivery.watches}`);
24245
24650
  noteTimeline("ownOfferSkipped", delivery.skipped);
24246
24651
  });
@@ -24255,7 +24660,12 @@ var PeerOffice = class {
24255
24660
  observations,
24256
24661
  // A waiting read advances read readiness only: it must never run a background command or
24257
24662
  // closure warm on the foreground's turn.
24258
- () => this.#readMaintenance.tick(void 0, 0n, READ_READINESS_ONLY, false),
24663
+ () => this.#readMaintenance.tickReadReadiness(),
24664
+ // A read the kernel still finds behind, with nothing owing its index, owes it again (as a watch does).
24665
+ (request) => {
24666
+ if (request.command.case !== "kernelCall") throw new Error("local read continuation lost its query");
24667
+ this.#readMaintenance.schedule(request.command.value.session, ReadMaintenanceCause.READ_DEBT);
24668
+ },
24259
24669
  (request) => {
24260
24670
  if (request.command.case !== "kernelCall") throw new Error("local read continuation lost its query");
24261
24671
  return this.#application.call(request, request.command.value);
@@ -24356,6 +24766,7 @@ var PeerOffice = class {
24356
24766
  onShallowMount: (workspace, credentialCapability) => this.#historyAcquisition.materialise(workspace, credentialCapability),
24357
24767
  // The edge echoes an HTTP offer batch back over this replica's own live link (CAP-764).
24358
24768
  onOffered: (workspace, commitOids) => this.#live.offered(workspace, commitOids),
24769
+ liveAdmitted: (workspace) => this.#live.admittedLocal(workspace),
24359
24770
  onOutboxHistoryRequired: (workspace, credentialCapability) => this.#historyAcquisition.requestFromBackground(workspace, credentialCapability),
24360
24771
  backgroundHistory: profile.backgroundHistory !== false,
24361
24772
  onSyncCompleted: (session, event) => {
@@ -24381,7 +24792,7 @@ var PeerOffice = class {
24381
24792
  this.#origins.ignored(workspace, origin, "follow");
24382
24793
  return false;
24383
24794
  };
24384
- this.#live.remoteAdvanced = (workspace) => this.#correspondence.replicaLinkOpened(workspace);
24795
+ this.#live.remoteAdvanced = (workspace) => this.#correspondence.replicaRemoteAdvanced(workspace);
24385
24796
  this.#live.declined = (workspace) => this.#correspondence.liveAdmissionDeclined(workspace);
24386
24797
  this.#live.acknowledged = (workspace, ack) => this.#correspondence.liveAdmissionAcknowledged(workspace, ack);
24387
24798
  this.#live.intentsAdmitted = (workspace, intentIds, local) => this.#correspondence.liveIntentsAdmitted(workspace, intentIds, local);
@@ -24593,7 +25004,7 @@ var PeerOffice = class {
24593
25004
  },
24594
25005
  owes: (workspace) => this.#readMaintenance.owesReadReadiness(workspace),
24595
25006
  // Read readiness only, as a waiting read takes: never a background command or pack import (CAP-806).
24596
- tick: () => this.#readMaintenance.tick(void 0, 0n, READ_READINESS_ONLY, false),
25007
+ tick: () => this.#readMaintenance.tickReadReadiness(),
24597
25008
  emit: (session, event) => this.#trace.emit(session, event)
24598
25009
  });
24599
25010
  this.#modelAdoption = new ModelAdoptionDesk({
@@ -24991,9 +25402,8 @@ var PeerOffice = class {
24991
25402
  let pendingEffectId;
24992
25403
  try {
24993
25404
  if (request.command.case === "socketReceipt") {
24994
- const admission = this.#live.receive(request, request.command.value);
24995
- if (!admission) return this.#response(request, { case: "socketObserved", value: create81(PeerSocketObservedSchema) });
24996
- request = admission;
25405
+ this.#live.receive(request.command.value);
25406
+ return this.#response(request, { case: "socketObserved", value: create81(PeerSocketObservedSchema) });
24997
25407
  }
24998
25408
  const result = timelinePhase("access", () => this.#access.handle(request));
24999
25409
  if (result.outcome.case === "correspondencePending") {
@@ -25002,11 +25412,9 @@ var PeerOffice = class {
25002
25412
  }
25003
25413
  if (result.outcome.case === "watchStarted") this.#subscriptions.retainDependencies(result.outcome.value.subscriptionId, scope);
25004
25414
  this.#subscriptions.recoverySettled(result);
25005
- this.#live.settled(request, result);
25006
25415
  this.#correspondence.observeResponse(result);
25007
25416
  return result;
25008
25417
  } catch (error) {
25009
- this.#live.failed(request.requestId);
25010
25418
  const failure2 = this.#failure(request, "nomos.runtime.workspace_access", error instanceof Error ? error.message : String(error));
25011
25419
  this.#subscriptions.recoverySettled(failure2);
25012
25420
  this.#correspondence.observeResponse(failure2);
@@ -25273,11 +25681,7 @@ var PeerOffice = class {
25273
25681
  try {
25274
25682
  const mount = this.#sessions.mountForWorkspace(request.target.workspace);
25275
25683
  const previousHead = this.#kernel.head(mount, request.requestId);
25276
- const admission = this.#custodyAdmission.admit(
25277
- request,
25278
- request.command.value,
25279
- { journal: !this.#live.relayed(request.requestId) }
25280
- );
25684
+ const admission = this.#custodyAdmission.admit(request, request.command.value);
25281
25685
  admission.sealedMain = this.#residency.retainedHead(request.target.workspace);
25282
25686
  if (custodyAdmissionNeedsReadMaintenance(admission)) {
25283
25687
  admission.localMaintenance = this.#readMaintenance.scheduleWorkspace(
@@ -25394,16 +25798,17 @@ var PeerOffice = class {
25394
25798
  });
25395
25799
  case "historicQuery": {
25396
25800
  const answered2 = this.#historicQueries.execute(request, request.command.value);
25397
- if (answered2.outcome.case === "failure" && READ_INDEX_BUILDING.test(answered2.outcome.value.message)) {
25801
+ if (answered2.outcome.case === "query" && answered2.outcome.value.result.case === "readIndexPending") {
25398
25802
  this.#readMaintenance.schedule(request.command.value.session, ReadMaintenanceCause.READ_DEBT);
25803
+ const workspace = answered2.outcome.value.result.value.workspace || (this.#sessions.bindingIfPresent(request.command.value.session)?.workspace ?? "");
25399
25804
  return this.#response(request, {
25400
25805
  case: "unavailable",
25401
25806
  value: create81(RuntimeUnavailableSchema, {
25402
25807
  reason: RuntimeUnavailableReason.LOCAL_REPLICA_NOT_READY,
25403
- workspace: this.#sessions.bindingIfPresent(request.command.value.session)?.workspace ?? "",
25808
+ workspace,
25404
25809
  retryable: true,
25405
25810
  retryAfterMillis: 250,
25406
- detail: answered2.outcome.value.message
25811
+ detail: `the read index of ${workspace} is being built on this device; read maintenance continues it`
25407
25812
  })
25408
25813
  });
25409
25814
  }
@@ -25823,6 +26228,10 @@ var PeerOffice = class {
25823
26228
  nextEvent() {
25824
26229
  return this.#trace.nextEvent();
25825
26230
  }
26231
+ /** In-process shells wait on a held local read here instead of polling `resumeAfterMillis`. */
26232
+ localReadResumable(workId2, notify) {
26233
+ return this.#readResponses.onResumable(workId2, notify);
26234
+ }
25826
26235
  close() {
25827
26236
  if (this.retentionOutstanding() > 0) {
25828
26237
  throw new Error("custody retention pending; retain the acknowledged frontiers before disposing the peer");
@@ -26174,6 +26583,23 @@ function createPeerOfficeFrameRunner(kernel, credentials, profile, observations,
26174
26583
  lanes?.wake(delayMillis);
26175
26584
  };
26176
26585
  const runner = {
26586
+ localReadResumable(workId2) {
26587
+ let resolve4;
26588
+ const resumable = new Promise((done) => {
26589
+ resolve4 = done;
26590
+ });
26591
+ let timer;
26592
+ const wait = peer.localReadResumable(workId2, () => {
26593
+ if (timer !== void 0) clearTimeout(timer);
26594
+ resolve4();
26595
+ });
26596
+ if (wait === void 0) return void 0;
26597
+ timer = setTimeout(() => {
26598
+ wait.cancel();
26599
+ resolve4();
26600
+ }, wait.afterMillis);
26601
+ return resumable;
26602
+ },
26177
26603
  handleFrame(frame2) {
26178
26604
  const response = peer.invoke(frame2).responseProtobuf;
26179
26605
  drainEvents();
@@ -26402,7 +26828,7 @@ async function drivePeerFrame(runner, initialFrame, fetchImpl = globalThis.fetch
26402
26828
  if (response.outcome.case === "localReadPending") {
26403
26829
  if (yieldLocalReadToCaller) return responseFrame;
26404
26830
  const pending2 = response.outcome.value;
26405
- await new Promise((resolve4) => setTimeout(resolve4, pending2.resumeAfterMillis));
26831
+ await (runner.localReadResumable?.(pending2.workId) ?? new Promise((resolve4) => setTimeout(resolve4, pending2.resumeAfterMillis)));
26406
26832
  responseFrame = await turn(() => runner.handleFrame(toBinary33(RuntimeRequestSchema, create82(RuntimeRequestSchema, {
26407
26833
  protocolVersion: response.protocolVersion,
26408
26834
  requestId: response.requestId,
@@ -27515,8 +27941,23 @@ async function startDevCloud(options = {}) {
27515
27941
  });
27516
27942
  const { bundle, kernelSha, bootstrapSha, dataDir, custody } = peerProcess;
27517
27943
  let ringPlacement;
27944
+ let ringMain;
27945
+ const rungMains = /* @__PURE__ */ new Map();
27518
27946
  const observedInvoke = async (args) => {
27519
27947
  const bytes = await peerProcess.invoke(args);
27948
+ if (ringMain) {
27949
+ try {
27950
+ const response = fromBinary33(RuntimeResponseSchema, bytes);
27951
+ const workspace = fromBinary33(RuntimeRequestSchema, args.requestBytes).target?.workspace;
27952
+ const main = response.outcome.case === "custodyOffersAdmitted" ? response.outcome.value.main : void 0;
27953
+ if (workspace && main && rungMains.get(workspace) !== main) {
27954
+ rungMains.set(workspace, main);
27955
+ ringMain(workspace, main);
27956
+ }
27957
+ } catch (error) {
27958
+ console.error("[local-peer] main ring", error);
27959
+ }
27960
+ }
27520
27961
  if (ringPlacement) {
27521
27962
  try {
27522
27963
  const advanced = placementAdvance(
@@ -27790,6 +28231,7 @@ async function startDevCloud(options = {}) {
27790
28231
  const liveSockets = openLiveSockets(server, { invoke: observedInvoke });
27791
28232
  carriage.onOffers = (workspace, offers) => liveSockets.offer(workspace, offers);
27792
28233
  ringPlacement = (workspace, frontier) => liveSockets.placement(workspace, frontier);
28234
+ ringMain = (workspace, main) => liveSockets.main(workspace, main);
27793
28235
  await new Promise((resolve4, reject) => {
27794
28236
  server.once("error", reject);
27795
28237
  server.listen(port, host, resolve4);