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.
- package/dist/compile_mountability_entry.js +731 -360
- package/dist/dev-server.mjs +645 -203
- package/dist/framework/bootstrap.law.usdz +0 -0
- package/dist/framework/nomos.law.usdz +0 -0
- package/dist/framework/nomos.reception.mjs +16 -9
- package/dist/full-cli.mjs +5671 -4963
- package/package.json +2 -2
package/dist/dev-server.mjs
CHANGED
|
@@ -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/
|
|
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)
|
|
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
|
-
|
|
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
|
|
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
|
|
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 (
|
|
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:
|
|
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
|
|
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
|
-
|
|
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
|
-
/**
|
|
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 ||
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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]) =>
|
|
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]) =>
|
|
13109
|
-
|
|
13110
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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, {
|
|
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
|
-
|
|
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.
|
|
13505
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
14896
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
16869
|
-
|
|
16870
|
-
|
|
16871
|
-
|
|
16872
|
-
|
|
16873
|
-
|
|
16874
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
18400
|
-
|
|
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 &&
|
|
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.#
|
|
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
|
|
18784
|
-
*
|
|
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.#
|
|
18789
|
-
return this.#
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
24176
|
-
|
|
24177
|
-
|
|
24178
|
-
workspace
|
|
24179
|
-
|
|
24180
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
24995
|
-
|
|
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 === "
|
|
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
|
|
25808
|
+
workspace,
|
|
25404
25809
|
retryable: true,
|
|
25405
25810
|
retryAfterMillis: 250,
|
|
25406
|
-
detail:
|
|
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);
|