githolon 0.115.0 → 0.116.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
@@ -774,11 +774,106 @@ var init_contract = __esm({
|
|
|
774
774
|
}
|
|
775
775
|
});
|
|
776
776
|
|
|
777
|
+
// ../dsl/src/value_identity.ts
|
|
778
|
+
function canonicalString(value, at) {
|
|
779
|
+
if (PLAIN_STRING.test(value)) return `"${value}"`;
|
|
780
|
+
let out4 = '"';
|
|
781
|
+
for (let i = 0; i < value.length; i++) {
|
|
782
|
+
const c = value.charCodeAt(i);
|
|
783
|
+
if (c >= 55296 && c <= 56319) {
|
|
784
|
+
const next = i + 1 < value.length ? value.charCodeAt(i + 1) : -1;
|
|
785
|
+
if (next < 56320 || next > 57343) throw new VoCanonicalError(at, "is not well-formed UTF-16 (a lone high surrogate)");
|
|
786
|
+
out4 += value[i] + value[i + 1];
|
|
787
|
+
i++;
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
if (c >= 56320 && c <= 57343) throw new VoCanonicalError(at, "is not well-formed UTF-16 (a lone low surrogate)");
|
|
791
|
+
switch (c) {
|
|
792
|
+
case 34:
|
|
793
|
+
out4 += '\\"';
|
|
794
|
+
break;
|
|
795
|
+
case 92:
|
|
796
|
+
out4 += "\\\\";
|
|
797
|
+
break;
|
|
798
|
+
case 8:
|
|
799
|
+
out4 += "\\b";
|
|
800
|
+
break;
|
|
801
|
+
case 12:
|
|
802
|
+
out4 += "\\f";
|
|
803
|
+
break;
|
|
804
|
+
case 10:
|
|
805
|
+
out4 += "\\n";
|
|
806
|
+
break;
|
|
807
|
+
case 13:
|
|
808
|
+
out4 += "\\r";
|
|
809
|
+
break;
|
|
810
|
+
case 9:
|
|
811
|
+
out4 += "\\t";
|
|
812
|
+
break;
|
|
813
|
+
default:
|
|
814
|
+
out4 += c < 32 ? `\\u00${c < 16 ? "0" : ""}${c.toString(16)}` : value[i];
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
return `${out4}"`;
|
|
818
|
+
}
|
|
819
|
+
function canonicalNumber(value, at) {
|
|
820
|
+
if (!Number.isFinite(value)) throw new VoCanonicalError(at, "is not a finite number (NaN and Infinity have no canonical form)");
|
|
821
|
+
return String(value);
|
|
822
|
+
}
|
|
823
|
+
function isPlainObject(value) {
|
|
824
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
825
|
+
const proto = Object.getPrototypeOf(value);
|
|
826
|
+
return proto === Object.prototype || proto === null;
|
|
827
|
+
}
|
|
828
|
+
function members(entries) {
|
|
829
|
+
const sorted = [...entries].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
830
|
+
return `{${sorted.map(([k, v]) => `${canonicalString(k, "member name")}:${v}`).join(",")}}`;
|
|
831
|
+
}
|
|
832
|
+
function canonicalJsonValue(value, at = "value") {
|
|
833
|
+
if (value === null) return "null";
|
|
834
|
+
switch (typeof value) {
|
|
835
|
+
case "string":
|
|
836
|
+
return canonicalString(value, at);
|
|
837
|
+
case "number":
|
|
838
|
+
return canonicalNumber(value, at);
|
|
839
|
+
case "boolean":
|
|
840
|
+
return value ? "true" : "false";
|
|
841
|
+
case "object": {
|
|
842
|
+
if (Array.isArray(value)) {
|
|
843
|
+
const out4 = [];
|
|
844
|
+
for (let i = 0; i < value.length; i++) {
|
|
845
|
+
if (value[i] === void 0) throw new VoCanonicalError(`${at}[${i}]`, "is undefined (a list has no absent elements)");
|
|
846
|
+
out4.push(canonicalJsonValue(value[i], `${at}[${i}]`));
|
|
847
|
+
}
|
|
848
|
+
return `[${out4.join(",")}]`;
|
|
849
|
+
}
|
|
850
|
+
if (!isPlainObject(value)) throw new VoCanonicalError(at, "is not a plain json object");
|
|
851
|
+
return members(Object.keys(value).filter((k) => value[k] !== void 0).map((k) => [k, canonicalJsonValue(value[k], `${at}.${k}`)]));
|
|
852
|
+
}
|
|
853
|
+
default:
|
|
854
|
+
throw new VoCanonicalError(at, `is a ${typeof value}, which json cannot carry`);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
var VO_CANONICAL_ENCODING, VoCanonicalError, PLAIN_STRING;
|
|
858
|
+
var init_value_identity = __esm({
|
|
859
|
+
"../dsl/src/value_identity.ts"() {
|
|
860
|
+
"use strict";
|
|
861
|
+
VO_CANONICAL_ENCODING = "nomos.vo-canonical.v1";
|
|
862
|
+
VoCanonicalError = class extends TypeError {
|
|
863
|
+
constructor(at, problem) {
|
|
864
|
+
super(`${VO_CANONICAL_ENCODING}: ${at} ${problem}`);
|
|
865
|
+
this.name = "VoCanonicalError";
|
|
866
|
+
}
|
|
867
|
+
};
|
|
868
|
+
PLAIN_STRING = /^[^"\\\u0000-\u001f\ud800-\udfff]*$/;
|
|
869
|
+
}
|
|
870
|
+
});
|
|
871
|
+
|
|
777
872
|
// ../dsl/src/aggregate.ts
|
|
778
873
|
function sameKeyValue(a, b) {
|
|
779
874
|
if (a === b) return true;
|
|
780
875
|
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
|
|
781
|
-
return
|
|
876
|
+
return canonicalJsonValue(a) === canonicalJsonValue(b);
|
|
782
877
|
}
|
|
783
878
|
function judgeBirthKeyWriteOnce(aggregateId, fields, snapshot, previous) {
|
|
784
879
|
if (previous === void 0 || previous === null) return { accept: true };
|
|
@@ -1116,6 +1211,7 @@ var init_aggregate = __esm({
|
|
|
1116
1211
|
init_fields();
|
|
1117
1212
|
init_contract();
|
|
1118
1213
|
init_drivers();
|
|
1214
|
+
init_value_identity();
|
|
1119
1215
|
BIRTH_KEY_WRITE_ONCE_CODE = "birth-key-write-once";
|
|
1120
1216
|
BIRTH_KEY_FIELDS = Symbol.for("nomos.birthKeyWriteOnceFields");
|
|
1121
1217
|
READ_CAP_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$/;
|
|
@@ -1728,7 +1824,7 @@ function evaluatePointGuard(predicate, row, payload) {
|
|
|
1728
1824
|
const left = valueAt(row, predicate.left.path);
|
|
1729
1825
|
const right = predicate.right.source === "literal" ? predicate.right.value : valueAt(predicate.right.source === "row" ? row : payload, predicate.right.path);
|
|
1730
1826
|
if (left === void 0 || right === void 0) return predicate.operator === "ne";
|
|
1731
|
-
const equal =
|
|
1827
|
+
const equal = canonicalJsonValue(left) === canonicalJsonValue(right);
|
|
1732
1828
|
return predicate.operator === "eq" ? equal : !equal;
|
|
1733
1829
|
}
|
|
1734
1830
|
}
|
|
@@ -1736,6 +1832,7 @@ function evaluatePointGuard(predicate, row, payload) {
|
|
|
1736
1832
|
var init_point_guard = __esm({
|
|
1737
1833
|
"../dsl/src/point_guard.ts"() {
|
|
1738
1834
|
"use strict";
|
|
1835
|
+
init_value_identity();
|
|
1739
1836
|
}
|
|
1740
1837
|
});
|
|
1741
1838
|
|
|
@@ -2907,7 +3004,7 @@ var init_law_status = __esm({
|
|
|
2907
3004
|
// ../adapter/proto/nomos/kernel/v1/kernel_pb.js
|
|
2908
3005
|
import { enumDesc, fileDesc, messageDesc, serviceDesc, tsEnum } from "@bufbuild/protobuf/codegenv2";
|
|
2909
3006
|
import { file_google_protobuf_any } from "@bufbuild/protobuf/wkt";
|
|
2910
|
-
var file_nomos_kernel_v1_kernel, CallRequestSchema, CallResponseSchema, OfferResponseSchema, WorkspaceEffectStatusRequestSchema, WorkspaceEffectStatusResponseSchema, RecordWorkspaceEffectOutcomeRequestSchema, BirthOutcomeSchema, SignPreparedOfferRequestSchema, PrepareRemoteOfferRequestSchema, PrepareRemoteOfferResponseSchema, SignOfferPreparationRequestSchema, SigningIdentityRequestSchema, GenerateSigningKeyPairSchema, KernelRefusalSchema, ApplicationResultDeltaSchema, InterfaceCompatibilityQuerySchema, MaintenanceQuantumQuerySchema, CarriedWorkspaceOfferSchema, PrepareOutboundOfferSchema, SyncResponseSchema, CustodyDisagreementSchema, WorkspaceTargetSchema, DirectiveCallSchema, AuthoringOptionsSchema, CapturedClockSchema, BirthCertificateSchema, SignBirthCertificateRequestSchema, ModelLifecycleIntentSchema, IdentityProviderWitnessAdoptionSchema, OfferRequestSchema, QueryRequestSchema, IdentityProviderWitnessQuerySchema, ChildWorkspaceQuerySchema, InstalledLawDeclarationsQuerySchema, DirectiveAuthoringRequirementsQuerySchema, AuthenticationPostureQuerySchema, QueryAuthoritySchema, NomosRefSchema, ReferenceVersionsQuerySchema, NamedQuerySchema, FrontierTransitionRequestSchema, AuthorizationCheckRequestSchema, OutboxRequestSchema, SyncRequestSchema, KernelConfigurationRequestSchema, CustodyRequestSchema, AggregateCensusRequestSchema, ResidentFootprintRequestSchema, PackDeltaRequestSchema, ApplyPackRequestSchema, RepoStatsRequestSchema, IntentsAboveRequestSchema, HistorySummaryRequestSchema, InspectChangeRequestSchema, InspectRefusalVerdictRequestSchema, ReadBlobRequestSchema, ResolveRefRequestSchema, PhysicalRefFileSchema, ListRefsRequestSchema, WriteRefRequestSchema, DeleteRefRequestSchema, LawClosureInfoRequestSchema, RestoreMainRequestSchema, LawProductsSchema, ExportLawProductsRequestSchema, ExportLawProductsResponseSchema, ImportLawProductsRequestSchema, AttachLocalFrontierRequestSchema, CustodyRemoteSchema, CustodyPlacementPolicySchema, CustodyPlacementExpectationSchema, ReadCustodyPlacementRequestSchema, InspectCustodyPlacementRequestSchema, PlacementOfferSchema, ResolveStatePositionRequestSchema, ReleaseWorkspaceStateRequestSchema, NomosValueSchema, NullSchema, NomosListSchema, NomosStructSchema, BirthOutcomeStatusSchema, BirthOutcomeStatus, KernelRefusalCodeSchema, KernelRefusalCode, InterfaceCompatibilityStatusSchema, InterfaceCompatibilityStatus, EffectExecutionPlacementSchema, EffectExecutionPlacement, EffectExecutionCardinalitySchema, EffectExecutionCardinality, ModelLifecycleOperationSchema, ModelLifecycleOperation, ChildWorkspaceLifecycleStatusSchema, ChildWorkspaceLifecycleStatus, ProviderTokenVerificationStatusSchema, ProviderTokenVerificationStatus, DeviceSignerStatusSchema, DeviceSignerStatus, BirthEvidenceStatusSchema, BirthEvidenceStatus, QueryResultFormatSchema, QueryResultFormat, QueryOperationSchema, QueryOperation, KernelLawCapabilitySchema, KernelLawCapability, KernelResidencyIntentSchema, KernelResidencyIntent, CustodyRetentionIntentSchema, CustodyRetentionIntent, IntentTransportRequirementSchema, IntentTransportRequirement;
|
|
3007
|
+
var file_nomos_kernel_v1_kernel, CallRequestSchema, CallResponseSchema, OfferResponseSchema, WorkspaceEffectStatusRequestSchema, WorkspaceEffectStatusResponseSchema, RecordWorkspaceEffectOutcomeRequestSchema, BirthOutcomeSchema, SignPreparedOfferRequestSchema, PrepareRemoteOfferRequestSchema, PrepareRemoteOfferResponseSchema, SignOfferPreparationRequestSchema, SigningIdentityRequestSchema, GenerateSigningKeyPairSchema, KernelRefusalSchema, QueryResponseSchema, ApplicationResultDeltaSchema, InterfaceCompatibilityQuerySchema, ReadIndexPendingSchema, MaintenanceQuantumQuerySchema, CarriedWorkspaceOfferSchema, PrepareOutboundOfferSchema, SyncResponseSchema, CustodyDisagreementSchema, WorkspaceTargetSchema, DirectiveCallSchema, AuthoringOptionsSchema, CapturedClockSchema, BirthCertificateSchema, SignBirthCertificateRequestSchema, ModelLifecycleIntentSchema, IdentityProviderWitnessAdoptionSchema, OfferRequestSchema, QueryRequestSchema, IdentityProviderWitnessQuerySchema, ChildWorkspaceQuerySchema, InstalledLawDeclarationsQuerySchema, DirectiveAuthoringRequirementsQuerySchema, AuthenticationPostureQuerySchema, QueryAuthoritySchema, NomosRefSchema, ReferenceVersionsQuerySchema, NamedQuerySchema, FrontierTransitionRequestSchema, AuthorizationCheckRequestSchema, OutboxRequestSchema, SyncRequestSchema, KernelConfigurationRequestSchema, CustodyRequestSchema, AggregateCensusRequestSchema, ResidentFootprintRequestSchema, PackDeltaRequestSchema, ApplyPackRequestSchema, RepoStatsRequestSchema, IntentsAboveRequestSchema, HistorySummaryRequestSchema, InspectChangeRequestSchema, InspectRefusalVerdictRequestSchema, ReadBlobRequestSchema, ResolveRefRequestSchema, PhysicalRefFileSchema, ListRefsRequestSchema, WriteRefRequestSchema, DeleteRefRequestSchema, LawClosureInfoRequestSchema, RestoreMainRequestSchema, LawProductsSchema, ExportLawProductsRequestSchema, ExportLawProductsResponseSchema, ImportLawProductsRequestSchema, AttachLocalFrontierRequestSchema, CustodyRemoteSchema, CustodyPlacementPolicySchema, CustodyPlacementExpectationSchema, ReadCustodyPlacementRequestSchema, InspectCustodyPlacementRequestSchema, PlacementOfferSchema, ResolveStatePositionRequestSchema, ReleaseWorkspaceStateRequestSchema, NomosValueSchema, NullSchema, NomosListSchema, NomosStructSchema, BirthOutcomeStatusSchema, BirthOutcomeStatus, KernelRefusalCodeSchema, KernelRefusalCode, InterfaceCompatibilityStatusSchema, InterfaceCompatibilityStatus, EffectExecutionPlacementSchema, EffectExecutionPlacement, EffectExecutionCardinalitySchema, EffectExecutionCardinality, ModelLifecycleOperationSchema, ModelLifecycleOperation, ChildWorkspaceLifecycleStatusSchema, ChildWorkspaceLifecycleStatus, ProviderTokenVerificationStatusSchema, ProviderTokenVerificationStatus, DeviceSignerStatusSchema, DeviceSignerStatus, BirthEvidenceStatusSchema, BirthEvidenceStatus, QueryResultFormatSchema, QueryResultFormat, QueryOperationSchema, QueryOperation, KernelLawCapabilitySchema, KernelLawCapability, KernelResidencyIntentSchema, KernelResidencyIntent, CustodyRetentionIntentSchema, CustodyRetentionIntent, IntentTransportRequirementSchema, IntentTransportRequirement;
|
|
2911
3008
|
var init_kernel_pb = __esm({
|
|
2912
3009
|
"../adapter/proto/nomos/kernel/v1/kernel_pb.js"() {
|
|
2913
3010
|
"use strict";
|
|
@@ -2926,8 +3023,10 @@ var init_kernel_pb = __esm({
|
|
|
2926
3023
|
SigningIdentityRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 39);
|
|
2927
3024
|
GenerateSigningKeyPairSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 40);
|
|
2928
3025
|
KernelRefusalSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 55);
|
|
3026
|
+
QueryResponseSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 56);
|
|
2929
3027
|
ApplicationResultDeltaSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 58);
|
|
2930
3028
|
InterfaceCompatibilityQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 60);
|
|
3029
|
+
ReadIndexPendingSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 64);
|
|
2931
3030
|
MaintenanceQuantumQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 65);
|
|
2932
3031
|
CarriedWorkspaceOfferSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 80);
|
|
2933
3032
|
PrepareOutboundOfferSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 84);
|
|
@@ -3457,7 +3556,7 @@ var init_observability_desk_pb = __esm({
|
|
|
3457
3556
|
init_model_adoption_desk_pb();
|
|
3458
3557
|
init_receiving_group_desk_pb();
|
|
3459
3558
|
init_recovery_desk_pb();
|
|
3460
|
-
file_nomos_runtime_v2_observability_desk = /* @__PURE__ */ fileDesc22("Cilub21vcy9ydW50aW1lL3YyL29ic2VydmFiaWxpdHlfZGVzay5wcm90bxIQbm9tb3MucnVudGltZS52MiJCCgxUcmFjZUNvbnRleHQSEAoIdHJhY2VfaWQYASABKAwSDwoHc3Bhbl9pZBgCIAEoDBIPCgdzYW1wbGVkGAMgASgIIp0CCg5SdW50aW1lRmFpbHVyZRIMCgRjb2RlGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSEQoJY29tcG9uZW50GAMgASgJEhYKCXdvcmtzcGFjZRgEIAEoCUgAiAEBEhMKBmRvbWFpbhgFIAEoCUgBiAEBEhYKCWRpcmVjdGl2ZRgGIAEoCUgCiAEBEjkKCmF0dHJpYnV0ZXMYByADKAsyJS5ub21vcy5ydW50aW1lLnYyLkRpYWdub3N0aWNBdHRyaWJ1dGUSMgoEa2luZBgIIAEoDjIkLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZUZhaWx1cmVLaW5kQgwKCl93b3Jrc3BhY2VCCQoHX2RvbWFpbkIMCgpfZGlyZWN0aXZlIr4BChJSdW50aW1lVW5hdmFpbGFibGUSOgoGcmVhc29uGAEgASgOMioubm9tb3MucnVudGltZS52Mi5SdW50aW1lVW5hdmFpbGFibGVSZWFzb24SEQoJd29ya3NwYWNlGAIgASgJEhEKCXJldHJ5YWJsZRgDIAEoCBIfChJyZXRyeV9hZnRlcl9taWxsaXMYBCABKA1IAIgBARIOCgZkZXRhaWwYBSABKAlCFQoTX3JldHJ5X2FmdGVyX21pbGxpcyJ+Cg5SdW50aW1lUmVmdXNhbBI2CgZyZWFzb24YASABKA4yJi5ub21vcy5ydW50aW1lLnYyLlJ1bnRpbWVSZWZ1c2FsUmVhc29uEhEKCXdvcmtzcGFjZRgCIAEoCRIRCglyZXRyeWFibGUYAyABKAgSDgoGZGV0YWlsGAQgASgJIqUBChNEaWFnbm9zdGljQXR0cmlidXRlEgwKBG5hbWUYASABKAkSFgoMc3RyaW5nX3ZhbHVlGAIgASgJSAASFwoNaW50ZWdlcl92YWx1ZRgDIAEoEkgAEhYKDGRvdWJsZV92YWx1ZRgEIAEoAUgAEhcKDWJvb2xlYW5fdmFsdWUYBSABKAhIABIVCgtieXRlc192YWx1ZRgGIAEoDEgAQgcKBXZhbHVlIvALCgxSdW50aW1lRXZlbnQSEAoIc2VxdWVuY2UYASABKAQSFAoHc2Vzc2lvbhgCIAEoCUgBiAEBEi8KBXJlYWR5GAogASgLMh4ubm9tb3MucnVudGltZS52Mi5SdW50aW1lUmVhZHlIABI3Cg13YXRjaF9jaGFuZ2VkGAsgASgLMh4ubm9tb3MucnVudGltZS52Mi5XYXRjaENoYW5nZWRIABI5Cg5zeW5jX2NvbXBsZXRlZBgMIAEoCzIfLm5vbW9zLnJ1bnRpbWUudjIuU3luY0NvbXBsZXRlZEgAEjUKDGxpbmtfY2hhbmdlZBgNIAEoCzIdLm5vbW9zLnJ1bnRpbWUudjIuTGlua0NoYW5nZWRIABI5Cg5zaWduYWxfY2hhbmdlZBgOIAEoCzIfLm5vbW9zLnJ1bnRpbWUudjIuU2lnbmFsQ2hhbmdlZEgAEjsKD2N1c3RvZHlfY2hhbmdlZBgPIAEoCzIgLm5vbW9zLnJ1bnRpbWUudjIuQ3VzdG9keUNoYW5nZWRIABJCChNsb2NhbF93b3JrX3JlamVjdGVkGBAgASgLMiMubm9tb3MucnVudGltZS52Mi5Mb2NhbFdvcmtSZWplY3RlZEgAEjMKC2xhd19jaGFuZ2VkGBEgASgLMhwubm9tb3MucnVudGltZS52Mi5MYXdDaGFuZ2VkSAASQwoPa2VybmVsX3Byb2dyZXNzGBIgASgLMigubm9tb3MucnVudGltZS52Mi5LZXJuZWxQcm9ncmVzc09ic2VydmVkSAASLQoEc3BhbhgTIAEoCzIdLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZVNwYW5IABI/
|
|
3559
|
+
file_nomos_runtime_v2_observability_desk = /* @__PURE__ */ fileDesc22("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]);
|
|
3461
3560
|
RuntimeFailureSchema = /* @__PURE__ */ messageDesc22(file_nomos_runtime_v2_observability_desk, 1);
|
|
3462
3561
|
RuntimeUnavailableSchema = /* @__PURE__ */ messageDesc22(file_nomos_runtime_v2_observability_desk, 2);
|
|
3463
3562
|
RuntimeRefusalSchema = /* @__PURE__ */ messageDesc22(file_nomos_runtime_v2_observability_desk, 3);
|
|
@@ -5145,7 +5244,17 @@ function throwIfKernelControlRequired(failure) {
|
|
|
5145
5244
|
}
|
|
5146
5245
|
function throwKernelFailure(failure) {
|
|
5147
5246
|
throwIfKernelControlRequired(failure);
|
|
5148
|
-
throw new
|
|
5247
|
+
throw new KernelRefusal(failure);
|
|
5248
|
+
}
|
|
5249
|
+
function deterministicKernelRefusal(error) {
|
|
5250
|
+
if (error instanceof KernelWorkspaceResidencyRequired || error instanceof KernelHistoryRequired || error instanceof KernelReadinessPending) return void 0;
|
|
5251
|
+
if (error instanceof KernelRefusal && (error.failure.historyRequired !== void 0 || error.failure.identityProviderWitnessRequired !== void 0)) return void 0;
|
|
5252
|
+
const text = error instanceof Error ? error.message : typeof error === "string" ? error : "";
|
|
5253
|
+
const match = KERNEL_FAILURE_TEXT.exec(text);
|
|
5254
|
+
if (!match) return void 0;
|
|
5255
|
+
const [, code, message] = match;
|
|
5256
|
+
if (ENVIRONMENTAL.test(text) || READINESS_DEBT.test(message) || requiredForeignWorkspace(message) !== void 0) return void 0;
|
|
5257
|
+
return { code, message };
|
|
5149
5258
|
}
|
|
5150
5259
|
function rethrowTypedKernelFailure(error) {
|
|
5151
5260
|
if (error instanceof KernelWorkspaceResidencyRequired || error instanceof KernelHistoryRequired) throw error;
|
|
@@ -5154,7 +5263,7 @@ function rethrowTypedKernelFailure(error) {
|
|
|
5154
5263
|
if (workspace !== void 0) throw new KernelWorkspaceResidencyRequired(workspace, message);
|
|
5155
5264
|
throw error;
|
|
5156
5265
|
}
|
|
5157
|
-
var KernelWorkspaceResidencyRequired, KernelHistoryRequired, KernelReadinessPending, READINESS_DEBT, kernelReadinessPending, requiredForeignWorkspace;
|
|
5266
|
+
var KernelWorkspaceResidencyRequired, KernelHistoryRequired, KernelReadinessPending, READINESS_DEBT, kernelReadinessPending, READ_INDEX_BUILDING, kernelReadIndexBuilding, requiredForeignWorkspace, KernelRefusal, KERNEL_FAILURE_TEXT, ENVIRONMENTAL;
|
|
5158
5267
|
var init_kernel_failure = __esm({
|
|
5159
5268
|
"../adapter/kernel_failure.ts"() {
|
|
5160
5269
|
"use strict";
|
|
@@ -5193,6 +5302,11 @@ var init_kernel_failure = __esm({
|
|
|
5193
5302
|
if (!READINESS_DEBT.test(message)) return void 0;
|
|
5194
5303
|
return new KernelReadinessPending(/source workspace '([^']+)'/.exec(message)?.[1]?.trim(), message);
|
|
5195
5304
|
};
|
|
5305
|
+
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/;
|
|
5306
|
+
kernelReadIndexBuilding = (message) => {
|
|
5307
|
+
const workspace = READ_INDEX_BUILDING.exec(message)?.[1]?.trim();
|
|
5308
|
+
return workspace === void 0 ? void 0 : { workspace };
|
|
5309
|
+
};
|
|
5196
5310
|
requiredForeignWorkspace = (message) => {
|
|
5197
5311
|
const patterns = [
|
|
5198
5312
|
/workspace '([^']+)' must be resident in the kernel/,
|
|
@@ -5207,6 +5321,18 @@ var init_kernel_failure = __esm({
|
|
|
5207
5321
|
}
|
|
5208
5322
|
return void 0;
|
|
5209
5323
|
};
|
|
5324
|
+
KernelRefusal = class extends Error {
|
|
5325
|
+
code;
|
|
5326
|
+
failure;
|
|
5327
|
+
constructor(failure) {
|
|
5328
|
+
super(`${failure.code}: ${failure.message}`);
|
|
5329
|
+
this.name = "KernelRefusal";
|
|
5330
|
+
this.code = failure.code;
|
|
5331
|
+
this.failure = failure;
|
|
5332
|
+
}
|
|
5333
|
+
};
|
|
5334
|
+
KERNEL_FAILURE_TEXT = /^(NMS-[A-Z0-9]+(?:-[A-Z0-9]+)*): ([\s\S]*)$/;
|
|
5335
|
+
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;
|
|
5210
5336
|
}
|
|
5211
5337
|
});
|
|
5212
5338
|
|
|
@@ -6638,15 +6764,16 @@ function streamRefused(code, message) {
|
|
|
6638
6764
|
value: create6(LiveStreamRefusalSchema, { code, message })
|
|
6639
6765
|
} });
|
|
6640
6766
|
}
|
|
6641
|
-
var LEVEL_BATCH,
|
|
6767
|
+
var LEVEL_BATCH, HISTORY_REQUIRED, CONTAINMENT_ASK_SUFFIX, STREAM_WINDOW_CHUNKS, historySlot, LiveInboundStream;
|
|
6642
6768
|
var init_live_inbound_stream = __esm({
|
|
6643
6769
|
"../peer-office/src/runtime/live_inbound_stream.ts"() {
|
|
6644
6770
|
"use strict";
|
|
6645
6771
|
init_correspondence_desk_pb();
|
|
6646
6772
|
init_checkpoint_staging();
|
|
6647
6773
|
LEVEL_BATCH = "level:";
|
|
6774
|
+
HISTORY_REQUIRED = "nomos.stream.history_required";
|
|
6775
|
+
CONTAINMENT_ASK_SUFFIX = ":contain";
|
|
6648
6776
|
STREAM_WINDOW_CHUNKS = 8;
|
|
6649
|
-
ASK_AGAIN_NANOS = 15000000000n;
|
|
6650
6777
|
historySlot = (workspace) => `${workspace}#history`;
|
|
6651
6778
|
LiveInboundStream = class {
|
|
6652
6779
|
#ports;
|
|
@@ -6664,7 +6791,10 @@ var init_live_inbound_stream = __esm({
|
|
|
6664
6791
|
}
|
|
6665
6792
|
return inbound;
|
|
6666
6793
|
}
|
|
6667
|
-
/** When this workspace's stream last delivered
|
|
6794
|
+
/** When this workspace's stream last delivered data to an ask (a waiting procedure is progressing).
|
|
6795
|
+
* A refusal, a frontier, unrelated traffic on the socket and this copy's own re-asking are not
|
|
6796
|
+
* progress: a procedure whose stream only ever says "ask again" gives up and its round fails over
|
|
6797
|
+
* (CAP-838). */
|
|
6668
6798
|
lastHeard(workspace) {
|
|
6669
6799
|
return this.#by.get(workspace)?.lastHeard;
|
|
6670
6800
|
}
|
|
@@ -6687,7 +6817,8 @@ var init_live_inbound_stream = __esm({
|
|
|
6687
6817
|
inbound.wants.level = {
|
|
6688
6818
|
effectId: effect.effectId,
|
|
6689
6819
|
maxOffers: Math.max(1, request.value.maxOffers),
|
|
6690
|
-
remountAfterOffers: request.value.remountAfterOffers
|
|
6820
|
+
remountAfterOffers: request.value.remountAfterOffers,
|
|
6821
|
+
contain: effect.effectId.endsWith(CONTAINMENT_ASK_SUFFIX)
|
|
6691
6822
|
};
|
|
6692
6823
|
this.#askLevel(effect.workspace, inbound);
|
|
6693
6824
|
}
|
|
@@ -6747,7 +6878,7 @@ var init_live_inbound_stream = __esm({
|
|
|
6747
6878
|
const batch = inbound.levelBatch;
|
|
6748
6879
|
if (batch) {
|
|
6749
6880
|
inbound.levelBatch = void 0;
|
|
6750
|
-
if (batch.base === this.#ports.head(effect.workspace)) {
|
|
6881
|
+
if (batch.base === this.#ports.head(effect.workspace) || batch.base === request.value.head) {
|
|
6751
6882
|
inbound.wants.level = void 0;
|
|
6752
6883
|
return create6(PeerStreamReceiptSchema, {
|
|
6753
6884
|
outcome: { case: "pack", value: batch },
|
|
@@ -6758,14 +6889,14 @@ var init_live_inbound_stream = __esm({
|
|
|
6758
6889
|
this.#askLevel(effect.workspace, inbound);
|
|
6759
6890
|
}
|
|
6760
6891
|
const head = this.#ports.head(effect.workspace);
|
|
6761
|
-
if (
|
|
6892
|
+
if (inbound.announced && (head === inbound.announced || inbound.askedFrom === inbound.announced)) {
|
|
6762
6893
|
inbound.wants.level = void 0;
|
|
6763
6894
|
return create6(PeerStreamReceiptSchema, {
|
|
6764
|
-
outcome: { case: "level", value:
|
|
6895
|
+
outcome: { case: "level", value: inbound.announced },
|
|
6765
6896
|
...inbound.sealed ? { sealed: inbound.sealed } : {}
|
|
6766
6897
|
});
|
|
6767
6898
|
}
|
|
6768
|
-
return this.#refusalReceipt(inbound);
|
|
6899
|
+
return this.#refusalReceipt(inbound, inbound.wants.level?.effectId === effect.effectId && inbound.wants.level.contain);
|
|
6769
6900
|
}
|
|
6770
6901
|
if (request.case === "history" || request.case === "ref") {
|
|
6771
6902
|
const want = inbound.wants.packs.get(request.value.requestId);
|
|
@@ -6780,10 +6911,16 @@ var init_live_inbound_stream = __esm({
|
|
|
6780
6911
|
return void 0;
|
|
6781
6912
|
}
|
|
6782
6913
|
/** A terminal refusal (not one that only says when to ask again) ends the procedure's wait. */
|
|
6783
|
-
#refusalReceipt(inbound) {
|
|
6914
|
+
#refusalReceipt(inbound, contain = false) {
|
|
6784
6915
|
const refused = inbound.refused;
|
|
6785
|
-
if (!refused
|
|
6916
|
+
if (!refused) return void 0;
|
|
6917
|
+
const answersContainment = contain && refused.code === HISTORY_REQUIRED;
|
|
6918
|
+
if (refused.retryAfterMillis !== void 0 && !answersContainment) return void 0;
|
|
6786
6919
|
inbound.refused = void 0;
|
|
6920
|
+
if (answersContainment) {
|
|
6921
|
+
inbound.askAgainAt = void 0;
|
|
6922
|
+
inbound.wants.level = void 0;
|
|
6923
|
+
}
|
|
6787
6924
|
return create6(PeerStreamReceiptSchema, { outcome: { case: "refusal", value: refused } });
|
|
6788
6925
|
}
|
|
6789
6926
|
/** The procedure gave up (it timed out, or its work ended). */
|
|
@@ -6814,7 +6951,9 @@ var init_live_inbound_stream = __esm({
|
|
|
6814
6951
|
/** One frame from the peer. True when it was the stream's (the live desk handles the rest). */
|
|
6815
6952
|
frame(workspace, message) {
|
|
6816
6953
|
const inbound = this.#of(workspace);
|
|
6817
|
-
|
|
6954
|
+
if (message.case === "checkpointOffer" || message.case === "checkpointChunk" || message.case === "pack") {
|
|
6955
|
+
inbound.lastHeard = this.#ports.monotonicNanoseconds();
|
|
6956
|
+
}
|
|
6818
6957
|
switch (message.case) {
|
|
6819
6958
|
case "frontier":
|
|
6820
6959
|
if (message.value.response && message.value.head) {
|
|
@@ -6869,18 +7008,26 @@ var init_live_inbound_stream = __esm({
|
|
|
6869
7008
|
return false;
|
|
6870
7009
|
}
|
|
6871
7010
|
}
|
|
6872
|
-
/**
|
|
7011
|
+
/**
|
|
7012
|
+
* Ask again when a refusal said when to (the peer was opening, or acquiring history). Nothing else
|
|
7013
|
+
* here runs on a timer (CAP-838): the socket is ordered and reliable, every ask is answered on it,
|
|
7014
|
+
* and an ask is re-sent only when its socket re-opens (`opened`) or its refusal's time comes. The
|
|
7015
|
+
* stream used to re-ask whatever had heard nothing for 15 s, and that resend - itself counted as
|
|
7016
|
+
* hearing - hid an ask answered "come back" for ever.
|
|
7017
|
+
*/
|
|
6873
7018
|
drive(workspace) {
|
|
6874
7019
|
const inbound = this.#by.get(workspace);
|
|
6875
|
-
if (!inbound ||
|
|
7020
|
+
if (!inbound || inbound.askAgainAt === void 0) return void 0;
|
|
7021
|
+
if (!this.wanted(workspace)) {
|
|
7022
|
+
inbound.askAgainAt = void 0;
|
|
7023
|
+
return void 0;
|
|
7024
|
+
}
|
|
6876
7025
|
const now2 = this.#ports.monotonicNanoseconds();
|
|
6877
|
-
|
|
6878
|
-
if (now2 < due2) return due2 - now2;
|
|
7026
|
+
if (now2 < inbound.askAgainAt) return inbound.askAgainAt - now2;
|
|
6879
7027
|
inbound.askAgainAt = void 0;
|
|
6880
7028
|
inbound.refused = void 0;
|
|
6881
|
-
inbound.lastHeard = now2;
|
|
6882
7029
|
this.opened(workspace);
|
|
6883
|
-
return
|
|
7030
|
+
return void 0;
|
|
6884
7031
|
}
|
|
6885
7032
|
#offered(workspace, inbound, offer) {
|
|
6886
7033
|
inbound.refused = void 0;
|
|
@@ -6923,6 +7070,7 @@ var init_live_inbound_stream = __esm({
|
|
|
6923
7070
|
const held = !taken ? -1 : "pack" in taken ? taken.pack.byteLength : taken.bytes;
|
|
6924
7071
|
if (held !== transfer.bytes || transfer.received !== transfer.bytes) {
|
|
6925
7072
|
if (taken && "stagedPackFile" in taken) this.#staging.clear(workspace);
|
|
7073
|
+
if (inbound.wants.checkpoint) this.#askCheckpoint(workspace, inbound);
|
|
6926
7074
|
return;
|
|
6927
7075
|
}
|
|
6928
7076
|
inbound.complete = {
|
|
@@ -7040,8 +7188,12 @@ var init_live_inbound_stream = __esm({
|
|
|
7040
7188
|
this.#askCheckpoint(workspace, inbound);
|
|
7041
7189
|
return;
|
|
7042
7190
|
}
|
|
7191
|
+
inbound.announced = void 0;
|
|
7192
|
+
inbound.sealed = void 0;
|
|
7193
|
+
const head = this.#ports.head(workspace) ?? "";
|
|
7194
|
+
inbound.askedFrom = head;
|
|
7043
7195
|
this.#ports.send(workspace, { case: "frontier", value: create6(LiveFrontierSchema, {
|
|
7044
|
-
head
|
|
7196
|
+
head,
|
|
7045
7197
|
response: false,
|
|
7046
7198
|
maxOffers: level.maxOffers,
|
|
7047
7199
|
remountAfterOffers: level.remountAfterOffers,
|
|
@@ -7584,6 +7736,24 @@ function placementMovedBy(request, response) {
|
|
|
7584
7736
|
}
|
|
7585
7737
|
return void 0;
|
|
7586
7738
|
}
|
|
7739
|
+
function readIndexPendingAnswer(request, message) {
|
|
7740
|
+
if (request.operation.case !== "query" || request.operation.value.query.case === "maintenanceQuantum") return void 0;
|
|
7741
|
+
const building = kernelReadIndexBuilding(message);
|
|
7742
|
+
if (building === void 0) return void 0;
|
|
7743
|
+
const target3 = request.operation.value.target;
|
|
7744
|
+
return create10(CallResponseSchema, {
|
|
7745
|
+
protocolVersion: request.protocolVersion,
|
|
7746
|
+
requestId: request.requestId,
|
|
7747
|
+
outcome: { case: "query", value: create10(QueryResponseSchema, {
|
|
7748
|
+
result: { case: "readIndexPending", value: create10(ReadIndexPendingSchema, {
|
|
7749
|
+
workspace: target3?.workspace || building.workspace,
|
|
7750
|
+
branch: target3?.branch ?? "",
|
|
7751
|
+
// The sliced build names no frontier: it restarts at whatever head main holds when it continues.
|
|
7752
|
+
requestedFrontier: ""
|
|
7753
|
+
}) }
|
|
7754
|
+
}) }
|
|
7755
|
+
});
|
|
7756
|
+
}
|
|
7587
7757
|
var STAGED_PACK_BYTES, PLACEMENT_REFERENCE, KernelPort;
|
|
7588
7758
|
var init_kernel_port = __esm({
|
|
7589
7759
|
"../peer-office/src/runtime/kernel_port.ts"() {
|
|
@@ -8621,6 +8791,8 @@ var init_kernel_port = __esm({
|
|
|
8621
8791
|
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" : "";
|
|
8622
8792
|
error.message = `kernel-operation=${top}/${nested}: ${error.message}`;
|
|
8623
8793
|
}
|
|
8794
|
+
const pending = readIndexPendingAnswer(request, error instanceof Error ? error.message : String(error));
|
|
8795
|
+
if (pending !== void 0) return pending;
|
|
8624
8796
|
rethrowTypedKernelFailure(error);
|
|
8625
8797
|
}
|
|
8626
8798
|
if (response.requestId !== request.requestId) {
|
|
@@ -8631,6 +8803,9 @@ var init_kernel_port = __esm({
|
|
|
8631
8803
|
this.#residency.after(request, response);
|
|
8632
8804
|
const placementMoved = placementMovedBy(request, response);
|
|
8633
8805
|
if (placementMoved !== void 0) this.#onPlacementMoved(placementMoved);
|
|
8806
|
+
if (response.outcome.case === "failure") {
|
|
8807
|
+
return readIndexPendingAnswer(request, response.outcome.value.message) ?? response;
|
|
8808
|
+
}
|
|
8634
8809
|
return response;
|
|
8635
8810
|
}
|
|
8636
8811
|
/** [#call] with the opt-in timeline trace: encode, kernel and decode timed separately. */
|
|
@@ -15632,6 +15807,7 @@ var init_read_maintenance_desk = __esm({
|
|
|
15632
15807
|
for (const [key2, value] of entries.filter(([key3]) => key3 !== workspace)) this.#pending.set(key2, value);
|
|
15633
15808
|
}
|
|
15634
15809
|
this.#revision += 1;
|
|
15810
|
+
if (read && (!existing?.read || isReadDemand)) this.#observer.readinessMayChange?.(workspace);
|
|
15635
15811
|
if (!existing || existing.read?.cause !== read?.cause || existing.background?.cause !== background?.cause) {
|
|
15636
15812
|
this.#trace.emit(session ?? existing?.session, {
|
|
15637
15813
|
case: "maintenanceProgress",
|
|
@@ -15648,32 +15824,65 @@ var init_read_maintenance_desk = __esm({
|
|
|
15648
15824
|
* (a waiting read's own turn advances read readiness only).
|
|
15649
15825
|
*/
|
|
15650
15826
|
tick(request, sessionlessNotBeforeNanoseconds = 0n, backgroundNotBeforeNanoseconds = 0n, durability = true) {
|
|
15827
|
+
const turn = this.#turn(
|
|
15828
|
+
request,
|
|
15829
|
+
sessionlessNotBeforeNanoseconds,
|
|
15830
|
+
{ case: "until", atNanoseconds: backgroundNotBeforeNanoseconds },
|
|
15831
|
+
durability
|
|
15832
|
+
);
|
|
15833
|
+
return turn.case === "ran" ? turn.ticked : create40(MaintenanceTickedSchema, {
|
|
15834
|
+
pending: turn.pending,
|
|
15835
|
+
nextTickAfterMillis: turn.nextDelayMillis ?? 0
|
|
15836
|
+
});
|
|
15837
|
+
}
|
|
15838
|
+
/**
|
|
15839
|
+
* A waiting read's turn: advance read readiness only. It never runs a background command, closure
|
|
15840
|
+
* warm, pack import or durability flush on the foreground's turn, and never reports a wake for
|
|
15841
|
+
* that background work: with only background work owed its wake is `none`.
|
|
15842
|
+
*/
|
|
15843
|
+
tickReadReadiness() {
|
|
15844
|
+
const turn = this.#turn(void 0, 0n, { case: "readReadinessOnly" }, false);
|
|
15845
|
+
if (turn.case === "ran") {
|
|
15846
|
+
return { ticked: turn.ticked, wake: { case: "after", millis: turn.ticked.nextTickAfterMillis } };
|
|
15847
|
+
}
|
|
15848
|
+
return {
|
|
15849
|
+
ticked: create40(MaintenanceTickedSchema, { pending: turn.pending, nextTickAfterMillis: turn.nextDelayMillis ?? 0 }),
|
|
15850
|
+
wake: turn.nextDelayMillis === void 0 ? { case: "none" } : { case: "after", millis: turn.nextDelayMillis }
|
|
15851
|
+
};
|
|
15852
|
+
}
|
|
15853
|
+
#turn(request, sessionlessNotBeforeNanoseconds, backgroundHold, durability) {
|
|
15651
15854
|
const now2 = this.#clock.monotonicNanoseconds();
|
|
15855
|
+
const backgroundNotBeforeNanoseconds = backgroundHold.case === "until" ? backgroundHold.atNanoseconds : void 0;
|
|
15652
15856
|
const custodySlice = (workspace2) => this.#custodyBurstSlice(now2, workspace2);
|
|
15653
15857
|
const due2 = (demand2) => {
|
|
15654
15858
|
const held = demand2.session || demand2.awaited || demand2.retryNotBeforeNanoseconds > sessionlessNotBeforeNanoseconds ? demand2.retryNotBeforeNanoseconds : sessionlessNotBeforeNanoseconds;
|
|
15655
|
-
|
|
15859
|
+
if (!demand2.read && !demand2.awaited && backgroundNotBeforeNanoseconds === void 0) return void 0;
|
|
15860
|
+
const ordinary = demand2.read || demand2.awaited || backgroundNotBeforeNanoseconds === void 0 || held > backgroundNotBeforeNanoseconds ? held : backgroundNotBeforeNanoseconds;
|
|
15656
15861
|
const hold = demand2.read || demand2.awaited || !demand2.background?.maintainGitCustody ? void 0 : custodySlice(demand2.workspace);
|
|
15657
15862
|
if (!hold) return ordinary;
|
|
15658
15863
|
if (hold.slice && durability) return held > hold.at ? held : hold.at;
|
|
15659
15864
|
return ordinary > hold.at ? ordinary : hold.at;
|
|
15660
15865
|
};
|
|
15661
|
-
const entry = [...this.#pending.entries()].find(([, demand2]) =>
|
|
15866
|
+
const entry = [...this.#pending.entries()].find(([, demand2]) => {
|
|
15867
|
+
const at = due2(demand2);
|
|
15868
|
+
return at !== void 0 && at <= now2;
|
|
15869
|
+
});
|
|
15662
15870
|
const flush = this.#flush;
|
|
15663
15871
|
if (durability && flush && this.#flushDueAt(flush) <= now2 && !entry?.[1].read && (flush.local || !entry || flush.owedSinceNanoseconds + DURABILITY_FLUSH_MAX_DELAY_NANOSECONDS <= now2)) {
|
|
15664
|
-
return this.#tickFlush(flush, request);
|
|
15872
|
+
return { case: "ran", ticked: this.#tickFlush(flush, request) };
|
|
15665
15873
|
}
|
|
15666
15874
|
const pinDue = (pin) => {
|
|
15875
|
+
if (backgroundNotBeforeNanoseconds === void 0) return void 0;
|
|
15667
15876
|
const held = pin.session ? 0n : sessionlessNotBeforeNanoseconds;
|
|
15668
15877
|
return [pin.notBeforeNanoseconds, held, backgroundNotBeforeNanoseconds].reduce((latest, at) => at > latest ? at : latest, 0n);
|
|
15669
15878
|
};
|
|
15670
15879
|
if (!entry) {
|
|
15671
|
-
const pin = [...this.#pins.entries()].find(([, idle]) =>
|
|
15672
|
-
|
|
15673
|
-
|
|
15674
|
-
pending: this.hasPending(),
|
|
15675
|
-
nextTickAfterMillis: this.#nextDelay(now2, due2, pinDue)
|
|
15880
|
+
const pin = [...this.#pins.entries()].find(([, idle]) => {
|
|
15881
|
+
const at = pinDue(idle);
|
|
15882
|
+
return at !== void 0 && at <= now2;
|
|
15676
15883
|
});
|
|
15884
|
+
if (pin) return { case: "ran", ticked: this.#tickPin(pin[0], pin[1], request) };
|
|
15885
|
+
return { case: "idle", pending: this.hasPending(), nextDelayMillis: this.#nextDelay(now2, due2, pinDue, durability) };
|
|
15677
15886
|
}
|
|
15678
15887
|
const [workspace, demand] = entry;
|
|
15679
15888
|
const mount = demand.session ? this.#sessions.mountForSession(demand.session) : this.#sessions.mountForWorkspace(workspace);
|
|
@@ -15722,7 +15931,7 @@ var init_read_maintenance_desk = __esm({
|
|
|
15722
15931
|
read: read !== void 0,
|
|
15723
15932
|
awaited: demand.awaited === true,
|
|
15724
15933
|
session: demand.session !== void 0,
|
|
15725
|
-
backgroundHoldMs: Number((backgroundNotBeforeNanoseconds - now2) / 1000000n),
|
|
15934
|
+
backgroundHoldMs: backgroundNotBeforeNanoseconds === void 0 ? "read-readiness-only" : Number((backgroundNotBeforeNanoseconds - now2) / 1000000n),
|
|
15726
15935
|
sessionlessHoldMs: Number((sessionlessNotBeforeNanoseconds - now2) / 1000000n),
|
|
15727
15936
|
caller: (new Error().stack ?? "").split("\n").slice(2, 6).map((frame2) => frame2.trim()).join(" < ")
|
|
15728
15937
|
})}`);
|
|
@@ -15771,12 +15980,13 @@ var init_read_maintenance_desk = __esm({
|
|
|
15771
15980
|
this.#observer.frontierAdvanced?.(workspace);
|
|
15772
15981
|
}
|
|
15773
15982
|
}
|
|
15774
|
-
|
|
15983
|
+
this.#observer.readinessMayChange?.(workspace);
|
|
15984
|
+
return { case: "ran", ticked: create40(MaintenanceTickedSchema, {
|
|
15775
15985
|
pending: this.#pending.size > 0,
|
|
15776
15986
|
progress: observed,
|
|
15777
15987
|
// With no debt left, an armed idle pin names when the host should wake next.
|
|
15778
|
-
nextTickAfterMillis: progress.maintenancePending ? 20 : this.#pending.size === 0 && this.hasIdleWork() ? this.#nextDelay(this.#clock.monotonicNanoseconds()) : 0
|
|
15779
|
-
});
|
|
15988
|
+
nextTickAfterMillis: progress.maintenancePending ? 20 : this.#pending.size === 0 && this.hasIdleWork() ? this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0 : 0
|
|
15989
|
+
}) };
|
|
15780
15990
|
} catch (error) {
|
|
15781
15991
|
const format = localCopyFormatRefusal(error);
|
|
15782
15992
|
if (format !== void 0) {
|
|
@@ -15792,10 +16002,10 @@ var init_read_maintenance_desk = __esm({
|
|
|
15792
16002
|
stopped: true
|
|
15793
16003
|
})
|
|
15794
16004
|
});
|
|
15795
|
-
return create40(MaintenanceTickedSchema, {
|
|
16005
|
+
return { case: "ran", ticked: create40(MaintenanceTickedSchema, {
|
|
15796
16006
|
pending: this.#pending.size > 0,
|
|
15797
|
-
nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds())
|
|
15798
|
-
});
|
|
16007
|
+
nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
|
|
16008
|
+
}) };
|
|
15799
16009
|
}
|
|
15800
16010
|
const failures = demand.failures + 1;
|
|
15801
16011
|
this.#pending.delete(workspace);
|
|
@@ -15823,12 +16033,12 @@ var init_read_maintenance_desk = __esm({
|
|
|
15823
16033
|
retryAfterMillis: retryMillis
|
|
15824
16034
|
})
|
|
15825
16035
|
});
|
|
15826
|
-
return create40(MaintenanceTickedSchema, {
|
|
16036
|
+
return { case: "ran", ticked: create40(MaintenanceTickedSchema, {
|
|
15827
16037
|
pending: true,
|
|
15828
16038
|
// Backoff belongs to the failed workspace. Another workspace's ready
|
|
15829
16039
|
// index or changed watches must not wait for this retry deadline.
|
|
15830
|
-
nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds())
|
|
15831
|
-
});
|
|
16040
|
+
nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
|
|
16041
|
+
}) };
|
|
15832
16042
|
}
|
|
15833
16043
|
}
|
|
15834
16044
|
/** Owe the kernel its ordered flush. The first write it covers fixes `owedSince`; the shared
|
|
@@ -15893,7 +16103,7 @@ var init_read_maintenance_desk = __esm({
|
|
|
15893
16103
|
}
|
|
15894
16104
|
return create40(MaintenanceTickedSchema, {
|
|
15895
16105
|
pending: this.hasPending(),
|
|
15896
|
-
nextTickAfterMillis: progress.maintenancePending ? 20 : this.#nextDelay(this.#clock.monotonicNanoseconds())
|
|
16106
|
+
nextTickAfterMillis: progress.maintenancePending ? 20 : this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
|
|
15897
16107
|
});
|
|
15898
16108
|
} catch (error) {
|
|
15899
16109
|
const failures = flush.failures + 1;
|
|
@@ -15917,7 +16127,7 @@ var init_read_maintenance_desk = __esm({
|
|
|
15917
16127
|
};
|
|
15918
16128
|
return create40(MaintenanceTickedSchema, {
|
|
15919
16129
|
pending: this.hasPending(),
|
|
15920
|
-
nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds())
|
|
16130
|
+
nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
|
|
15921
16131
|
});
|
|
15922
16132
|
}
|
|
15923
16133
|
}
|
|
@@ -15948,7 +16158,7 @@ var init_read_maintenance_desk = __esm({
|
|
|
15948
16158
|
}
|
|
15949
16159
|
return create40(MaintenanceTickedSchema, {
|
|
15950
16160
|
pending: this.hasPending(),
|
|
15951
|
-
nextTickAfterMillis: progress.maintenancePending ? 20 : this.#nextDelay(this.#clock.monotonicNanoseconds())
|
|
16161
|
+
nextTickAfterMillis: progress.maintenancePending ? 20 : this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
|
|
15952
16162
|
});
|
|
15953
16163
|
} catch (error) {
|
|
15954
16164
|
slowQuantumObserver?.(`[nomos-kernel-perf] ${JSON.stringify({
|
|
@@ -15960,28 +16170,31 @@ var init_read_maintenance_desk = __esm({
|
|
|
15960
16170
|
})}`);
|
|
15961
16171
|
return create40(MaintenanceTickedSchema, {
|
|
15962
16172
|
pending: this.hasPending(),
|
|
15963
|
-
nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds())
|
|
16173
|
+
nextTickAfterMillis: this.#nextDelay(this.#clock.monotonicNanoseconds()) ?? 0
|
|
15964
16174
|
});
|
|
15965
16175
|
}
|
|
15966
16176
|
}
|
|
15967
|
-
|
|
16177
|
+
/** Milliseconds until the earliest owed work this turn serves; `undefined` when none is owed. */
|
|
16178
|
+
#nextDelay(now2, due2 = (demand) => demand.retryNotBeforeNanoseconds, pinDue = (pin) => pin.notBeforeNanoseconds, flushes = true) {
|
|
15968
16179
|
let earliest;
|
|
15969
16180
|
for (const demand of this.#pending.values()) {
|
|
15970
16181
|
const at = due2(demand);
|
|
16182
|
+
if (at === void 0) continue;
|
|
15971
16183
|
if (at <= now2) return 0;
|
|
15972
16184
|
if (earliest === void 0 || at < earliest) earliest = at;
|
|
15973
16185
|
}
|
|
15974
16186
|
for (const pin of this.#pins.values()) {
|
|
15975
16187
|
const at = pinDue(pin);
|
|
16188
|
+
if (at === void 0) continue;
|
|
15976
16189
|
if (at <= now2) return 0;
|
|
15977
16190
|
if (earliest === void 0 || at < earliest) earliest = at;
|
|
15978
16191
|
}
|
|
15979
|
-
if (this.#flush) {
|
|
16192
|
+
if (flushes && this.#flush) {
|
|
15980
16193
|
const at = this.#flushDueAt(this.#flush);
|
|
15981
16194
|
if (at <= now2) return 0;
|
|
15982
16195
|
if (earliest === void 0 || at < earliest) earliest = at;
|
|
15983
16196
|
}
|
|
15984
|
-
return earliest === void 0 ? 0 : Number((earliest - now2 + 999999n) / 1000000n);
|
|
16197
|
+
return earliest === void 0 ? void 0 : Number((earliest - now2 + 999999n) / 1000000n);
|
|
15985
16198
|
}
|
|
15986
16199
|
/** Drop any demand for a workspace no maintenance can serve (an unreadable copy). */
|
|
15987
16200
|
forget(workspace) {
|
|
@@ -16024,20 +16237,24 @@ var init_read_maintenance_desk = __esm({
|
|
|
16024
16237
|
|
|
16025
16238
|
// ../peer-office/src/runtime/read_response_desk.ts
|
|
16026
16239
|
import { create as create41 } from "@bufbuild/protobuf";
|
|
16027
|
-
var ReadResponseDesk;
|
|
16240
|
+
var READ_RETENTION_MILLIS, READ_RESUME_MAX_MILLIS, ReadResponseDesk;
|
|
16028
16241
|
var init_read_response_desk = __esm({
|
|
16029
16242
|
"../peer-office/src/runtime/read_response_desk.ts"() {
|
|
16030
16243
|
"use strict";
|
|
16031
16244
|
init_maintenance_desk_pb();
|
|
16245
|
+
READ_RETENTION_MILLIS = 12e4;
|
|
16246
|
+
READ_RESUME_MAX_MILLIS = 1e3;
|
|
16032
16247
|
ReadResponseDesk = class {
|
|
16033
16248
|
#waiting = /* @__PURE__ */ new Map();
|
|
16034
16249
|
#clock;
|
|
16035
16250
|
#tick;
|
|
16251
|
+
#owe;
|
|
16036
16252
|
#read;
|
|
16037
16253
|
#sequence = 0;
|
|
16038
|
-
constructor(clock2, tick, read) {
|
|
16254
|
+
constructor(clock2, tick, owe, read) {
|
|
16039
16255
|
this.#clock = clock2;
|
|
16040
16256
|
this.#tick = tick;
|
|
16257
|
+
this.#owe = owe;
|
|
16041
16258
|
this.#read = read;
|
|
16042
16259
|
}
|
|
16043
16260
|
#now() {
|
|
@@ -16050,18 +16267,27 @@ var init_read_response_desk = __esm({
|
|
|
16050
16267
|
const now2 = this.#now();
|
|
16051
16268
|
for (const [id, work] of this.#waiting) if (work.deadline <= now2) this.#waiting.delete(id);
|
|
16052
16269
|
const workId2 = `local-read-${++this.#sequence}`;
|
|
16053
|
-
this.#waiting.set(workId2, {
|
|
16270
|
+
this.#waiting.set(workId2, {
|
|
16271
|
+
request,
|
|
16272
|
+
dependency,
|
|
16273
|
+
deadline: now2 + READ_RETENTION_MILLIS,
|
|
16274
|
+
notBefore: now2,
|
|
16275
|
+
idle: false,
|
|
16276
|
+
// The office owed this frontier's debt when the kernel first answered pending.
|
|
16277
|
+
owedFor: dependency.requestedFrontier,
|
|
16278
|
+
waiters: /* @__PURE__ */ new Set()
|
|
16279
|
+
});
|
|
16054
16280
|
return create41(LocalReadPendingSchema, { workId: workId2 });
|
|
16055
16281
|
}
|
|
16056
16282
|
resume(workId2, requestId) {
|
|
16057
16283
|
const work = this.#waiting.get(workId2);
|
|
16058
16284
|
if (!work || work.request.requestId !== requestId) throw new Error(`unknown local read continuation '${workId2}'`);
|
|
16059
16285
|
const now2 = this.#now();
|
|
16286
|
+
work.waiters.clear();
|
|
16060
16287
|
if (now2 >= work.deadline) {
|
|
16061
16288
|
this.#waiting.delete(workId2);
|
|
16062
16289
|
throw new Error(`Local read index for '${work.dependency.workspace}' did not catch up to ${work.dependency.requestedFrontier} within its retained maintenance window`);
|
|
16063
16290
|
}
|
|
16064
|
-
if (now2 < work.notBefore) return this.#pending(workId2, work, now2);
|
|
16065
16291
|
try {
|
|
16066
16292
|
const response = this.#read(work.request);
|
|
16067
16293
|
if (response.outcome.case !== "query" || response.outcome.value.result.case !== "readIndexPending") {
|
|
@@ -16069,24 +16295,65 @@ var init_read_response_desk = __esm({
|
|
|
16069
16295
|
return { case: "ready", request: work.request, response };
|
|
16070
16296
|
}
|
|
16071
16297
|
work.dependency = response.outcome.value.result.value;
|
|
16072
|
-
|
|
16298
|
+
if (now2 < work.notBefore) return this.#pending(workId2, work, now2);
|
|
16299
|
+
let { ticked, wake } = this.#tick();
|
|
16300
|
+
if (wake.case === "none" && ticked.progress === void 0 && work.owedFor !== work.dependency.requestedFrontier) {
|
|
16301
|
+
work.owedFor = work.dependency.requestedFrontier;
|
|
16302
|
+
this.#owe(work.request);
|
|
16303
|
+
({ ticked, wake } = this.#tick());
|
|
16304
|
+
}
|
|
16073
16305
|
const afterTick = this.#now();
|
|
16074
|
-
work.
|
|
16075
|
-
|
|
16306
|
+
work.idle = wake.case === "none";
|
|
16307
|
+
const backoff = wake.case === "after" ? wake.millis : 0;
|
|
16308
|
+
work.notBefore = afterTick + backoff;
|
|
16309
|
+
work.deadline = afterTick + Math.max(READ_RETENTION_MILLIS, backoff + 6e4);
|
|
16076
16310
|
return this.#pending(workId2, work, afterTick);
|
|
16077
16311
|
} catch (error) {
|
|
16078
16312
|
this.#waiting.delete(workId2);
|
|
16079
16313
|
throw error;
|
|
16080
16314
|
}
|
|
16081
16315
|
}
|
|
16316
|
+
/**
|
|
16317
|
+
* Wait in process for a held read to become worth continuing. `notify` is called once, when read
|
|
16318
|
+
* readiness for its workspace changes (a slice or binding finished, a frontier advanced, readiness
|
|
16319
|
+
* newly owed). `afterMillis` is the only timer the shell needs: the read's own scheduled quantum
|
|
16320
|
+
* when it has one, otherwise its deadline. Undefined for an unknown or finished read.
|
|
16321
|
+
*/
|
|
16322
|
+
onResumable(workId2, notify) {
|
|
16323
|
+
const work = this.#waiting.get(workId2);
|
|
16324
|
+
if (!work) return void 0;
|
|
16325
|
+
const now2 = this.#now();
|
|
16326
|
+
const due2 = work.idle ? work.deadline : Math.min(work.notBefore, work.deadline);
|
|
16327
|
+
work.waiters.add(notify);
|
|
16328
|
+
return { afterMillis: Math.max(0, due2 - now2), cancel: () => {
|
|
16329
|
+
work.waiters.delete(notify);
|
|
16330
|
+
} };
|
|
16331
|
+
}
|
|
16332
|
+
/** Read readiness for `workspace` changed: every read waiting on it may continue now. */
|
|
16333
|
+
readinessChanged(workspace) {
|
|
16334
|
+
const now2 = this.#now();
|
|
16335
|
+
for (const work of this.#waiting.values()) {
|
|
16336
|
+
if (work.dependency.workspace !== workspace) continue;
|
|
16337
|
+
work.idle = false;
|
|
16338
|
+
if (work.notBefore > now2) work.notBefore = now2;
|
|
16339
|
+
const waiters = [...work.waiters];
|
|
16340
|
+
work.waiters.clear();
|
|
16341
|
+
for (const notify of waiters) notify();
|
|
16342
|
+
}
|
|
16343
|
+
}
|
|
16344
|
+
/** The protocol wake is a bounded re-poll inside the read's retention deadline, never the raw backoff. */
|
|
16082
16345
|
#pending(workId2, work, now2) {
|
|
16346
|
+
const due2 = work.idle ? READ_RESUME_MAX_MILLIS : work.notBefore - now2;
|
|
16347
|
+
const resumeAfterMillis = Math.max(0, Math.min(due2, work.deadline - now2, READ_RESUME_MAX_MILLIS));
|
|
16083
16348
|
return { case: "pending", value: create41(LocalReadPendingSchema, {
|
|
16084
16349
|
workId: workId2,
|
|
16085
|
-
resumeAfterMillis:
|
|
16350
|
+
resumeAfterMillis: Number.isFinite(resumeAfterMillis) ? Math.ceil(resumeAfterMillis) : READ_RESUME_MAX_MILLIS
|
|
16086
16351
|
}) };
|
|
16087
16352
|
}
|
|
16088
16353
|
clear() {
|
|
16354
|
+
const waiters = [...this.#waiting.values()].flatMap((work) => [...work.waiters]);
|
|
16089
16355
|
this.#waiting.clear();
|
|
16356
|
+
for (const notify of waiters) notify();
|
|
16090
16357
|
}
|
|
16091
16358
|
};
|
|
16092
16359
|
}
|
|
@@ -17000,6 +17267,9 @@ function reduceReplicaFollow(state, event, policy) {
|
|
|
17000
17267
|
if (state.case === ReplicaFollowPhase.Running) {
|
|
17001
17268
|
return { state: { ...state, observed: true }, effects: [] };
|
|
17002
17269
|
}
|
|
17270
|
+
if (state.case === ReplicaFollowPhase.Backoff && state.refusal?.blocked) {
|
|
17271
|
+
return refusedEvent(state, state.refusal, event.nowUnixMillis);
|
|
17272
|
+
}
|
|
17003
17273
|
if (state.case === ReplicaFollowPhase.RebornRemotely || state.case === ReplicaFollowPhase.LocalCopyUnreadable) return quiet(state);
|
|
17004
17274
|
if (state.case === ReplicaFollowPhase.InvalidCredential) {
|
|
17005
17275
|
return {
|
|
@@ -17009,6 +17279,9 @@ function reduceReplicaFollow(state, event, policy) {
|
|
|
17009
17279
|
}
|
|
17010
17280
|
return due(event.nowUnixMillis);
|
|
17011
17281
|
case ReplicaFollowEventKind.Reconnected:
|
|
17282
|
+
if (state.case === ReplicaFollowPhase.Backoff && state.refusal?.blocked) {
|
|
17283
|
+
return refusedEvent(state, state.refusal, event.nowUnixMillis);
|
|
17284
|
+
}
|
|
17012
17285
|
switch (state.case) {
|
|
17013
17286
|
case ReplicaFollowPhase.Running:
|
|
17014
17287
|
return { state: { ...state, observed: true }, effects: [] };
|
|
@@ -17054,15 +17327,25 @@ function reduceReplicaFollow(state, event, policy) {
|
|
|
17054
17327
|
}
|
|
17055
17328
|
return run(state.attempt + 1, state.expectedLocalHead);
|
|
17056
17329
|
case ReplicaFollowPhase.Offline:
|
|
17057
|
-
case ReplicaFollowPhase.Backoff:
|
|
17330
|
+
case ReplicaFollowPhase.Backoff: {
|
|
17331
|
+
const blocked = blockedRefusal(state);
|
|
17332
|
+
if (blocked) {
|
|
17333
|
+
if (blocked.rerunAtUnixMillis === void 0) return quiet(state);
|
|
17334
|
+
if (event.nowUnixMillis < blocked.rerunAtUnixMillis) {
|
|
17335
|
+
return { state, effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: blocked.rerunAtUnixMillis }] };
|
|
17336
|
+
}
|
|
17337
|
+
return run(state.attempt + 1, void 0, void 0, state.failure);
|
|
17338
|
+
}
|
|
17058
17339
|
if (event.nowUnixMillis < state.retryAtUnixMillis) {
|
|
17059
17340
|
return { state, effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: state.retryAtUnixMillis }] };
|
|
17060
17341
|
}
|
|
17061
17342
|
return run(
|
|
17062
17343
|
state.attempt + 1,
|
|
17063
17344
|
void 0,
|
|
17064
|
-
state.case === ReplicaFollowPhase.Backoff ? state.warming?.sinceUnixMillis : void 0
|
|
17345
|
+
state.case === ReplicaFollowPhase.Backoff ? state.warming?.sinceUnixMillis : void 0,
|
|
17346
|
+
state.case === ReplicaFollowPhase.Backoff && state.refusal ? state.failure : void 0
|
|
17065
17347
|
);
|
|
17348
|
+
}
|
|
17066
17349
|
case ReplicaFollowPhase.InvalidCredential:
|
|
17067
17350
|
if (!state.refreshDue && event.nowUnixMillis < state.retryAtUnixMillis) {
|
|
17068
17351
|
return { state, effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: state.retryAtUnixMillis }] };
|
|
@@ -17139,6 +17422,31 @@ function reduceReplicaFollow(state, event, policy) {
|
|
|
17139
17422
|
};
|
|
17140
17423
|
}
|
|
17141
17424
|
case ReplicaFollowEventKind.Failed: {
|
|
17425
|
+
if (event.refusal && !(state.case === ReplicaFollowPhase.Running && state.replaceLocalHead !== void 0)) {
|
|
17426
|
+
const attempt2 = Math.max(1, attempts(state));
|
|
17427
|
+
const blocked = state.case === ReplicaFollowPhase.Running && state.refused === event.failure || state.case === ReplicaFollowPhase.Backoff && state.refusal !== void 0 && state.failure === event.failure;
|
|
17428
|
+
const refusal2 = {
|
|
17429
|
+
code: event.refusal.code,
|
|
17430
|
+
blocked,
|
|
17431
|
+
runtime: event.refusal.runtime,
|
|
17432
|
+
atUnixMillis: event.nowUnixMillis
|
|
17433
|
+
};
|
|
17434
|
+
if (!blocked) {
|
|
17435
|
+
const retryAtUnixMillis2 = event.nowUnixMillis + boundedRetry(policy, attempt2);
|
|
17436
|
+
return {
|
|
17437
|
+
state: { case: ReplicaFollowPhase.Backoff, attempt: attempt2, retryAtUnixMillis: retryAtUnixMillis2, failure: event.failure, refusal: refusal2 },
|
|
17438
|
+
effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: retryAtUnixMillis2 }]
|
|
17439
|
+
};
|
|
17440
|
+
}
|
|
17441
|
+
const waiting = {
|
|
17442
|
+
case: ReplicaFollowPhase.Backoff,
|
|
17443
|
+
attempt: attempt2,
|
|
17444
|
+
retryAtUnixMillis: event.nowUnixMillis,
|
|
17445
|
+
failure: event.failure,
|
|
17446
|
+
refusal: refusal2
|
|
17447
|
+
};
|
|
17448
|
+
return state.case === ReplicaFollowPhase.Running && state.observed ? refusedEvent(waiting, refusal2, event.nowUnixMillis) : quiet(waiting);
|
|
17449
|
+
}
|
|
17142
17450
|
if (state.case === ReplicaFollowPhase.Running && state.observed) {
|
|
17143
17451
|
return due(event.nowUnixMillis);
|
|
17144
17452
|
}
|
|
@@ -17176,6 +17484,11 @@ function reduceReplicaFollow(state, event, policy) {
|
|
|
17176
17484
|
return quiet({ case: ReplicaFollowPhase.RebornRemotely, rebirth: event.rebirth });
|
|
17177
17485
|
case ReplicaFollowEventKind.LocalCopyUnreadable:
|
|
17178
17486
|
return quiet({ case: ReplicaFollowPhase.LocalCopyUnreadable, format: event.format });
|
|
17487
|
+
case ReplicaFollowEventKind.RuntimeStarted:
|
|
17488
|
+
if (state.case === ReplicaFollowPhase.Backoff && refusedByKernel(state) && state.refusal?.runtime !== event.runtime) {
|
|
17489
|
+
return due(event.nowUnixMillis);
|
|
17490
|
+
}
|
|
17491
|
+
return quiet(state);
|
|
17179
17492
|
case ReplicaFollowEventKind.LocalCopyDropAuthorized:
|
|
17180
17493
|
if (state.case === ReplicaFollowPhase.Running) return invalid(state, event);
|
|
17181
17494
|
return replacing(event.expectedLocalHead, 0, event.nowUnixMillis);
|
|
@@ -17188,10 +17501,11 @@ function reduceReplicaFollow(state, event, policy) {
|
|
|
17188
17501
|
function invalid(state, event) {
|
|
17189
17502
|
throw new Error(`replica follow cannot apply '${event.case}' while '${state.case}'`);
|
|
17190
17503
|
}
|
|
17191
|
-
var ReplicaFollowPhase, ReplicaFollowEventKind, ReplicaFollowEffectKind, boundedRetry, attempts, due, run, replacing, quiet;
|
|
17504
|
+
var ReplicaFollowPhase, ReplicaFollowEventKind, ReplicaFollowEffectKind, KERNEL_REFUSAL_EVENT_FLOOR_MILLIS, boundedRetry, attempts, due, run, replacing, quiet, blockedRefusal, refusedEvent, refusedByKernel;
|
|
17192
17505
|
var init_replica_follow_state = __esm({
|
|
17193
17506
|
"../peer-office/src/runtime/replica_follow_state.ts"() {
|
|
17194
17507
|
"use strict";
|
|
17508
|
+
init_kernel_failure();
|
|
17195
17509
|
ReplicaFollowPhase = Object.freeze({
|
|
17196
17510
|
Desired: "desired",
|
|
17197
17511
|
Due: "due",
|
|
@@ -17226,13 +17540,15 @@ var init_replica_follow_state = __esm({
|
|
|
17226
17540
|
DependencyAdvanced: "dependency_advanced",
|
|
17227
17541
|
RebornRemotely: "reborn_remotely",
|
|
17228
17542
|
LocalCopyDropAuthorized: "local_copy_drop_authorized",
|
|
17229
|
-
LocalCopyUnreadable: "local_copy_unreadable"
|
|
17543
|
+
LocalCopyUnreadable: "local_copy_unreadable",
|
|
17544
|
+
RuntimeStarted: "runtime_started"
|
|
17230
17545
|
});
|
|
17231
17546
|
ReplicaFollowEffectKind = Object.freeze({
|
|
17232
17547
|
ScheduleWake: "schedule_wake",
|
|
17233
17548
|
RunSync: "run_sync",
|
|
17234
17549
|
RefreshCredential: "refresh_credential"
|
|
17235
17550
|
});
|
|
17551
|
+
KERNEL_REFUSAL_EVENT_FLOOR_MILLIS = 1e4;
|
|
17236
17552
|
boundedRetry = (policy, attempt) => Math.min(policy.fallbackMillis, Math.max(250, policy.debounceMillis) * 2 ** Math.min(attempt - 1, 20));
|
|
17237
17553
|
attempts = (state) => {
|
|
17238
17554
|
switch (state.case) {
|
|
@@ -17259,13 +17575,14 @@ var init_replica_follow_state = __esm({
|
|
|
17259
17575
|
state: { case: ReplicaFollowPhase.Due, dueAtUnixMillis: atUnixMillis },
|
|
17260
17576
|
effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis }]
|
|
17261
17577
|
});
|
|
17262
|
-
run = (attempt, replaceLocalHead, warmingSinceUnixMillis) => ({
|
|
17578
|
+
run = (attempt, replaceLocalHead, warmingSinceUnixMillis, refused) => ({
|
|
17263
17579
|
state: {
|
|
17264
17580
|
case: ReplicaFollowPhase.Running,
|
|
17265
17581
|
attempt,
|
|
17266
17582
|
observed: false,
|
|
17267
17583
|
...replaceLocalHead === void 0 ? {} : { replaceLocalHead },
|
|
17268
|
-
...warmingSinceUnixMillis === void 0 ? {} : { warmingSinceUnixMillis }
|
|
17584
|
+
...warmingSinceUnixMillis === void 0 ? {} : { warmingSinceUnixMillis },
|
|
17585
|
+
...refused === void 0 ? {} : { refused }
|
|
17269
17586
|
},
|
|
17270
17587
|
effects: [{ case: ReplicaFollowEffectKind.RunSync }]
|
|
17271
17588
|
});
|
|
@@ -17274,6 +17591,16 @@ var init_replica_follow_state = __esm({
|
|
|
17274
17591
|
effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis }]
|
|
17275
17592
|
});
|
|
17276
17593
|
quiet = (state) => ({ state, effects: [] });
|
|
17594
|
+
blockedRefusal = (state) => state.case === ReplicaFollowPhase.Backoff && state.refusal?.blocked ? state.refusal : void 0;
|
|
17595
|
+
refusedEvent = (state, refusal2, nowUnixMillis) => {
|
|
17596
|
+
const earliest = Math.max(nowUnixMillis, refusal2.atUnixMillis + KERNEL_REFUSAL_EVENT_FLOOR_MILLIS);
|
|
17597
|
+
const rerunAtUnixMillis = refusal2.rerunAtUnixMillis === void 0 ? earliest : Math.min(refusal2.rerunAtUnixMillis, earliest);
|
|
17598
|
+
return {
|
|
17599
|
+
state: { ...state, refusal: { ...refusal2, rerunAtUnixMillis } },
|
|
17600
|
+
effects: [{ case: ReplicaFollowEffectKind.ScheduleWake, atUnixMillis: rerunAtUnixMillis }]
|
|
17601
|
+
};
|
|
17602
|
+
};
|
|
17603
|
+
refusedByKernel = (state) => state.case === ReplicaFollowPhase.Backoff && (state.refusal !== void 0 || deterministicKernelRefusal(state.failure) !== void 0);
|
|
17277
17604
|
}
|
|
17278
17605
|
});
|
|
17279
17606
|
|
|
@@ -17293,9 +17620,12 @@ function dueAt(follow) {
|
|
|
17293
17620
|
case ReplicaFollowPhase.RebornRemotely:
|
|
17294
17621
|
case ReplicaFollowPhase.LocalCopyUnreadable:
|
|
17295
17622
|
return void 0;
|
|
17623
|
+
case ReplicaFollowPhase.Backoff: {
|
|
17624
|
+
const blocked = blockedRefusal(follow.state);
|
|
17625
|
+
return blocked ? blocked.rerunAtUnixMillis : follow.state.retryAtUnixMillis;
|
|
17626
|
+
}
|
|
17296
17627
|
case ReplicaFollowPhase.Offline:
|
|
17297
17628
|
case ReplicaFollowPhase.InvalidCredential:
|
|
17298
|
-
case ReplicaFollowPhase.Backoff:
|
|
17299
17629
|
return follow.state.retryAtUnixMillis;
|
|
17300
17630
|
default: {
|
|
17301
17631
|
const exhaustive = follow.state;
|
|
@@ -17321,6 +17651,7 @@ var init_replica_follow_controller = __esm({
|
|
|
17321
17651
|
init_custodian_warming();
|
|
17322
17652
|
init_birth_refusal();
|
|
17323
17653
|
init_peer_desk_store();
|
|
17654
|
+
init_kernel_failure();
|
|
17324
17655
|
ReplicaFollowReconciliationKind = Object.freeze({
|
|
17325
17656
|
Following: "following",
|
|
17326
17657
|
NotFollowing: "not_following"
|
|
@@ -17353,11 +17684,15 @@ var init_replica_follow_controller = __esm({
|
|
|
17353
17684
|
#replicaId;
|
|
17354
17685
|
/** Local children whose births custody refused (CAP-804): quarantined, never followed. */
|
|
17355
17686
|
#birthRefusals;
|
|
17356
|
-
|
|
17687
|
+
/** The kernel/runtime identity this process runs: a refusal is recorded under it, and a refusal
|
|
17688
|
+
* drawn under another identity is retried once when this process starts. */
|
|
17689
|
+
#runtime;
|
|
17690
|
+
constructor(desk, clock2, replicaId2, birthRefusals, runtime = "unidentified") {
|
|
17357
17691
|
this.#desk = desk;
|
|
17358
17692
|
this.#clock = clock2;
|
|
17359
17693
|
this.#replicaId = replicaId2;
|
|
17360
17694
|
this.#birthRefusals = birthRefusals ?? new BirthRefusalRegister(new MemoryPeerDeskStore());
|
|
17695
|
+
this.#runtime = runtime;
|
|
17361
17696
|
}
|
|
17362
17697
|
/** The durable quarantine of a local child whose birth custody refused; undefined otherwise. */
|
|
17363
17698
|
birthRefusal(workspace) {
|
|
@@ -17456,6 +17791,13 @@ var init_replica_follow_controller = __esm({
|
|
|
17456
17791
|
recover() {
|
|
17457
17792
|
const now2 = this.#now();
|
|
17458
17793
|
if (!this.#recovered) {
|
|
17794
|
+
for (const follow of this.#desk.all()) {
|
|
17795
|
+
this.#desk.transition(follow.spec.workspace, {
|
|
17796
|
+
case: ReplicaFollowEventKind.RuntimeStarted,
|
|
17797
|
+
nowUnixMillis: now2,
|
|
17798
|
+
runtime: this.#runtime
|
|
17799
|
+
});
|
|
17800
|
+
}
|
|
17459
17801
|
for (const follow of this.#desk.all()) {
|
|
17460
17802
|
if (follow.state.case === ReplicaFollowPhase.Settled || follow.state.case === ReplicaFollowPhase.AwaitingDependency) {
|
|
17461
17803
|
this.#placementRecheck.add(follow.spec.workspace);
|
|
@@ -17544,11 +17886,12 @@ var init_replica_follow_controller = __esm({
|
|
|
17544
17886
|
placementAnnounced(workspace) {
|
|
17545
17887
|
if (!this.followForWorkspace(workspace)) return void 0;
|
|
17546
17888
|
this.#placementRecheck.add(workspace);
|
|
17547
|
-
return this.reconnected(workspace);
|
|
17889
|
+
return this.reconnected(workspace, true);
|
|
17548
17890
|
}
|
|
17549
|
-
/** The upstream live link opened or reopened: reconcile once for missed pushes.
|
|
17550
|
-
|
|
17551
|
-
|
|
17891
|
+
/** The upstream live link opened or reopened: reconcile once for missed pushes. With
|
|
17892
|
+
* `remoteAdvanced`, the upstream announced a new frontier. Either re-runs a blocked refusal. */
|
|
17893
|
+
reconnected(workspace, remoteAdvanced = false) {
|
|
17894
|
+
return this.#event(workspace, ReplicaFollowEventKind.Reconnected, remoteAdvanced);
|
|
17552
17895
|
}
|
|
17553
17896
|
/** Another workspace advanced or settled; every held dependency gets one retry. */
|
|
17554
17897
|
dependencyAdvanced(except) {
|
|
@@ -17561,11 +17904,11 @@ var init_replica_follow_controller = __esm({
|
|
|
17561
17904
|
}
|
|
17562
17905
|
return woken;
|
|
17563
17906
|
}
|
|
17564
|
-
#event(workspace, kind) {
|
|
17907
|
+
#event(workspace, kind, remoteAdvanced = false) {
|
|
17565
17908
|
const follow = this.#recovered ? this.#desk.get(workspace) : void 0;
|
|
17566
17909
|
if (!follow) return void 0;
|
|
17567
17910
|
const nowUnixMillis = this.#now();
|
|
17568
|
-
this.#desk.transition(workspace, { case: kind, nowUnixMillis });
|
|
17911
|
+
this.#desk.transition(workspace, kind === ReplicaFollowEventKind.Reconnected && remoteAdvanced ? { case: kind, nowUnixMillis, remoteAdvanced } : { case: kind, nowUnixMillis });
|
|
17569
17912
|
const nextDueAt = dueAt(this.#desk.get(workspace));
|
|
17570
17913
|
return nextDueAt === void 0 ? void 0 : Math.max(0, nextDueAt - nowUnixMillis);
|
|
17571
17914
|
}
|
|
@@ -17712,7 +18055,9 @@ var init_replica_follow_controller = __esm({
|
|
|
17712
18055
|
* still opening the workspace and named when to ask again. */
|
|
17713
18056
|
failed(workspace, error, custodianRetryAfterMillis) {
|
|
17714
18057
|
if (!this.#recovered) this.recover();
|
|
17715
|
-
|
|
18058
|
+
const refusal2 = deterministicKernelRefusal(error);
|
|
18059
|
+
if (refusal2 !== void 0) custodianRetryAfterMillis = void 0;
|
|
18060
|
+
else custodianRetryAfterMillis ??= warmingFromFailureMessage(error instanceof Error ? error.message : String(error));
|
|
17716
18061
|
if (!this.#desk.get(workspace)) return;
|
|
17717
18062
|
const format = localCopyFormatRefusal(error);
|
|
17718
18063
|
if (format !== void 0) {
|
|
@@ -17727,9 +18072,15 @@ var init_replica_follow_controller = __esm({
|
|
|
17727
18072
|
case: ReplicaFollowEventKind.Failed,
|
|
17728
18073
|
nowUnixMillis: this.#now(),
|
|
17729
18074
|
failure: error instanceof Error ? error.message : String(error),
|
|
17730
|
-
...custodianRetryAfterMillis === void 0 ? {} : { custodianRetryAfterMillis }
|
|
18075
|
+
...custodianRetryAfterMillis === void 0 ? {} : { custodianRetryAfterMillis },
|
|
18076
|
+
...refusal2 === void 0 ? {} : { refusal: { code: refusal2.code, runtime: this.#runtime } }
|
|
17731
18077
|
});
|
|
17732
18078
|
}
|
|
18079
|
+
/** The kernel refusal behind this follow's backoff (`blocked` once the kernel repeated it). */
|
|
18080
|
+
refusal(workspace) {
|
|
18081
|
+
const state = this.followForWorkspace(workspace)?.state;
|
|
18082
|
+
return state?.case === ReplicaFollowPhase.Backoff ? state.refusal : void 0;
|
|
18083
|
+
}
|
|
17733
18084
|
/** Closing an interaction realm must not erase a peer-owned follow. */
|
|
17734
18085
|
closeInteractionRealm() {
|
|
17735
18086
|
}
|
|
@@ -17750,6 +18101,15 @@ var init_replica_follow_controller = __esm({
|
|
|
17750
18101
|
}
|
|
17751
18102
|
});
|
|
17752
18103
|
|
|
18104
|
+
// ../peer-office/src/runtime/runtime_identity.ts
|
|
18105
|
+
var PEER_RUNTIME_IDENTITY;
|
|
18106
|
+
var init_runtime_identity = __esm({
|
|
18107
|
+
"../peer-office/src/runtime/runtime_identity.ts"() {
|
|
18108
|
+
"use strict";
|
|
18109
|
+
PEER_RUNTIME_IDENTITY = typeof __NOMOS_BUNDLE_VERSION__ === "string" && __NOMOS_BUNDLE_VERSION__ ? `@githolon/runtime@${__NOMOS_BUNDLE_VERSION__}` : "@githolon/runtime@unbundled";
|
|
18110
|
+
}
|
|
18111
|
+
});
|
|
18112
|
+
|
|
17753
18113
|
// ../peer-office/src/runtime/replica_follow_desk.ts
|
|
17754
18114
|
function assertSpec(record, spec) {
|
|
17755
18115
|
if (!spec.workspace || !spec.credentialCapability || typeof spec.cloudBound !== "boolean" || !Number.isFinite(spec.policy?.debounceMillis) || !Number.isFinite(spec.policy?.fallbackMillis) || spec.policy.debounceMillis < 0 || spec.policy.fallbackMillis <= 0) {
|
|
@@ -17803,7 +18163,7 @@ function assertState(record, state) {
|
|
|
17803
18163
|
}
|
|
17804
18164
|
throw corrupt(record, `invalid '${state.case}' state`);
|
|
17805
18165
|
}
|
|
17806
|
-
var REPLICA_FOLLOW_NAMESPACE, textEncoder, textDecoder, encode, decode, decodeWarming, decodeState, corrupt, samePolicy, sameSpec, ReplicaFollowDesk;
|
|
18166
|
+
var REPLICA_FOLLOW_NAMESPACE, textEncoder, textDecoder, encode, decode, decodeWarming, decodeRefusal, decodeState, corrupt, samePolicy, sameSpec, ReplicaFollowDesk;
|
|
17807
18167
|
var init_replica_follow_desk = __esm({
|
|
17808
18168
|
"../peer-office/src/runtime/replica_follow_desk.ts"() {
|
|
17809
18169
|
"use strict";
|
|
@@ -17834,6 +18194,16 @@ var init_replica_follow_desk = __esm({
|
|
|
17834
18194
|
...Number.isFinite(warming.hintMillis) ? { hintMillis: warming.hintMillis } : {}
|
|
17835
18195
|
} } : {};
|
|
17836
18196
|
};
|
|
18197
|
+
decodeRefusal = (value) => {
|
|
18198
|
+
const refusal2 = value;
|
|
18199
|
+
return refusal2 && typeof refusal2.code === "string" && typeof refusal2.runtime === "string" && Number.isFinite(refusal2.atUnixMillis) ? { refusal: {
|
|
18200
|
+
code: refusal2.code,
|
|
18201
|
+
blocked: refusal2.blocked === true,
|
|
18202
|
+
runtime: refusal2.runtime,
|
|
18203
|
+
atUnixMillis: refusal2.atUnixMillis,
|
|
18204
|
+
...Number.isFinite(refusal2.rerunAtUnixMillis) ? { rerunAtUnixMillis: refusal2.rerunAtUnixMillis } : {}
|
|
18205
|
+
} } : {};
|
|
18206
|
+
};
|
|
17837
18207
|
decodeState = (record, value) => {
|
|
17838
18208
|
if (!value || typeof value !== "object") throw corrupt(record, "state is not an object");
|
|
17839
18209
|
const state = value;
|
|
@@ -17848,7 +18218,8 @@ var init_replica_follow_desk = __esm({
|
|
|
17848
18218
|
attempt: state.attempt,
|
|
17849
18219
|
observed: state.observed === true,
|
|
17850
18220
|
...state.replaceLocalHead === void 0 ? {} : { replaceLocalHead: state.replaceLocalHead },
|
|
17851
|
-
...Number.isFinite(state.warmingSinceUnixMillis) ? { warmingSinceUnixMillis: state.warmingSinceUnixMillis } : {}
|
|
18221
|
+
...Number.isFinite(state.warmingSinceUnixMillis) ? { warmingSinceUnixMillis: state.warmingSinceUnixMillis } : {},
|
|
18222
|
+
...typeof state.refused === "string" ? { refused: state.refused } : {}
|
|
17852
18223
|
};
|
|
17853
18224
|
case ReplicaFollowPhase.Settled:
|
|
17854
18225
|
return {
|
|
@@ -17880,7 +18251,8 @@ var init_replica_follow_desk = __esm({
|
|
|
17880
18251
|
attempt: state.attempt,
|
|
17881
18252
|
retryAtUnixMillis: state.retryAtUnixMillis,
|
|
17882
18253
|
failure: state.failure,
|
|
17883
|
-
...decodeWarming(state.warming)
|
|
18254
|
+
...decodeWarming(state.warming),
|
|
18255
|
+
...decodeRefusal(state.refusal)
|
|
17884
18256
|
};
|
|
17885
18257
|
case ReplicaFollowPhase.RebornRemotely: {
|
|
17886
18258
|
const rebirth = state.rebirth ?? {};
|
|
@@ -18018,9 +18390,15 @@ var init_replica_follow_desk = __esm({
|
|
|
18018
18390
|
break;
|
|
18019
18391
|
}
|
|
18020
18392
|
case ReplicaFollowPhase.Offline:
|
|
18021
|
-
case ReplicaFollowPhase.Backoff:
|
|
18022
|
-
|
|
18393
|
+
case ReplicaFollowPhase.Backoff: {
|
|
18394
|
+
const blocked = blockedRefusal(follow.state);
|
|
18395
|
+
if (blocked && blocked.rerunAtUnixMillis === void 0) break;
|
|
18396
|
+
wakes.push({
|
|
18397
|
+
workspace: follow.spec.workspace,
|
|
18398
|
+
atUnixMillis: blocked?.rerunAtUnixMillis ?? follow.state.retryAtUnixMillis
|
|
18399
|
+
});
|
|
18023
18400
|
break;
|
|
18401
|
+
}
|
|
18024
18402
|
case ReplicaFollowPhase.InvalidCredential:
|
|
18025
18403
|
wakes.push({
|
|
18026
18404
|
workspace: follow.spec.workspace,
|
|
@@ -18690,7 +19068,7 @@ import { create as create48 } from "@bufbuild/protobuf";
|
|
|
18690
19068
|
function outcomesDigest(oids) {
|
|
18691
19069
|
return sha256Hex(new TextEncoder().encode([...new Set(oids)].sort().join("\n")));
|
|
18692
19070
|
}
|
|
18693
|
-
var CHECKPOINT_CHUNK_BYTES, CHECKPOINT_WINDOW_CHUNKS, MAX_CHECKPOINT_WINDOW_CHUNKS, CHECKPOINT_STALE_OFFERS, MAX_STREAM_BATCH_OFFERS, MAX_HISTORY_SLICE, MAX_HELD_SLICES, CHECKPOINT_CACHE_BYTES, MAX_CHECKPOINT_OUTCOMES, PLACEMENT_REF2, LEVEL_BATCH2, hex, frame, refusal, LiveStreamServer;
|
|
19071
|
+
var CHECKPOINT_CHUNK_BYTES, CHECKPOINT_WINDOW_CHUNKS, MAX_CHECKPOINT_WINDOW_CHUNKS, CHECKPOINT_STALE_OFFERS, MAX_STREAM_BATCH_OFFERS, MAX_HISTORY_SLICE, MAX_HELD_SLICES, CHECKPOINT_CACHE_BYTES, MAX_CHECKPOINT_OUTCOMES, PLACEMENT_REF2, LEVEL_BATCH2, hex, frame, refusal, OFF_MAIN_AFTER_MILLIS, MAX_UNFOUND_HEADS, LiveStreamServer;
|
|
18694
19072
|
var init_live_stream_server = __esm({
|
|
18695
19073
|
"../peer-office/src/runtime/live_stream_server.ts"() {
|
|
18696
19074
|
"use strict";
|
|
@@ -18717,6 +19095,8 @@ var init_live_stream_server = __esm({
|
|
|
18717
19095
|
message,
|
|
18718
19096
|
...retryAfterMillis === void 0 ? {} : { retryAfterMillis }
|
|
18719
19097
|
}) });
|
|
19098
|
+
OFF_MAIN_AFTER_MILLIS = 6e4;
|
|
19099
|
+
MAX_UNFOUND_HEADS = 1024;
|
|
18720
19100
|
LiveStreamServer = class {
|
|
18721
19101
|
#kernel;
|
|
18722
19102
|
#now;
|
|
@@ -18730,6 +19110,10 @@ var init_live_stream_server = __esm({
|
|
|
18730
19110
|
/** By workspace: the history slices copies are fetching (a few, newest last). */
|
|
18731
19111
|
#slices = /* @__PURE__ */ new Map();
|
|
18732
19112
|
#cachedBytes = 0;
|
|
19113
|
+
/** By workspace and asked head: when this peer first answered "acquiring its own history" to a level
|
|
19114
|
+
* ask from a head it could not find. A shallow custody can never prove the head is off its main (its
|
|
19115
|
+
* walk is never `complete`), so after OFF_MAIN_AFTER_MILLIS of the same answer it says so anyway. */
|
|
19116
|
+
#unfound = /* @__PURE__ */ new Map();
|
|
18733
19117
|
constructor(kernel, now2 = Date.now, historyWanted = () => {
|
|
18734
19118
|
}, sealed = () => void 0) {
|
|
18735
19119
|
this.#kernel = kernel;
|
|
@@ -18777,9 +19161,12 @@ var init_live_stream_server = __esm({
|
|
|
18777
19161
|
if (!head) return [...answer, ...this.#checkpoint(workspace, requestId, create48(LiveCheckpointRequestSchema))];
|
|
18778
19162
|
if (head === main) return answer;
|
|
18779
19163
|
let behind;
|
|
19164
|
+
let offMain = false;
|
|
18780
19165
|
try {
|
|
18781
19166
|
const summary = this.#kernel.historySummary(mount, requestId, head, main);
|
|
18782
19167
|
behind = summary.reachedBase ? summary.commitCount : void 0;
|
|
19168
|
+
offMain = !summary.reachedBase && (summary.complete || !this.#shallow(mount, requestId));
|
|
19169
|
+
if (summary.reachedBase) this.#unfound.delete(`${workspace}\0${head}`);
|
|
18783
19170
|
} catch {
|
|
18784
19171
|
behind = void 0;
|
|
18785
19172
|
}
|
|
@@ -18788,6 +19175,22 @@ var init_live_stream_server = __esm({
|
|
|
18788
19175
|
if (remountAfter > 0) {
|
|
18789
19176
|
return [...answer, ...this.#checkpoint(workspace, requestId, create48(LiveCheckpointRequestSchema), behind ?? 0n)];
|
|
18790
19177
|
}
|
|
19178
|
+
const key2 = `${workspace}\0${head}`;
|
|
19179
|
+
const firstUnfound = this.#unfound.get(key2);
|
|
19180
|
+
if (!offMain && firstUnfound === void 0) {
|
|
19181
|
+
if (this.#unfound.size >= MAX_UNFOUND_HEADS) this.#unfound.delete(this.#unfound.keys().next().value);
|
|
19182
|
+
this.#unfound.set(key2, this.#now());
|
|
19183
|
+
} else if (!offMain && this.#now() - firstUnfound >= OFF_MAIN_AFTER_MILLIS) {
|
|
19184
|
+
offMain = true;
|
|
19185
|
+
}
|
|
19186
|
+
if (offMain) {
|
|
19187
|
+
this.#unfound.delete(key2);
|
|
19188
|
+
return [...answer, refusal(
|
|
19189
|
+
"",
|
|
19190
|
+
"nomos.stream.off_main",
|
|
19191
|
+
"the copy's head is not on this peer's main; it must converge its own work, not level from it"
|
|
19192
|
+
)];
|
|
19193
|
+
}
|
|
18791
19194
|
this.#historyWanted(workspace);
|
|
18792
19195
|
return [...answer, refusal(
|
|
18793
19196
|
"",
|
|
@@ -18799,6 +19202,17 @@ var init_live_stream_server = __esm({
|
|
|
18799
19202
|
const maxOffers = Math.min(Math.max(1, frontier.maxOffers || MAX_STREAM_BATCH_OFFERS), MAX_STREAM_BATCH_OFFERS);
|
|
18800
19203
|
return [...answer, this.#batch(workspace, requestId, head, main, maxOffers)];
|
|
18801
19204
|
}
|
|
19205
|
+
/** Whether this peer's custody of the workspace is shallow. Unknown counts as shallow: it keeps the
|
|
19206
|
+
* existing wait for history rather than calling a head off main. */
|
|
19207
|
+
#shallow(mount, requestId) {
|
|
19208
|
+
const boundaries = this.#kernel.shallowBoundaries;
|
|
19209
|
+
if (!boundaries) return true;
|
|
19210
|
+
try {
|
|
19211
|
+
return boundaries.call(this.#kernel, mount, requestId).length > 0;
|
|
19212
|
+
} catch {
|
|
19213
|
+
return true;
|
|
19214
|
+
}
|
|
19215
|
+
}
|
|
18802
19216
|
/**
|
|
18803
19217
|
* The `maxOffers` offers directly above `base`, as the commits this peer admitted them in: one
|
|
18804
19218
|
* bounded walk and one bounded pack (O(batch)). The copy's kernel adopts exactly these commits on
|
|
@@ -19128,7 +19542,6 @@ var init_live_correspondence_desk = __esm({
|
|
|
19128
19542
|
"use strict";
|
|
19129
19543
|
init_kernel_pb();
|
|
19130
19544
|
init_correspondence_desk_pb();
|
|
19131
|
-
init_runtime_pb();
|
|
19132
19545
|
init_kernel_failure();
|
|
19133
19546
|
init_local_write_burst();
|
|
19134
19547
|
init_session_directory();
|
|
@@ -19189,7 +19602,6 @@ var init_live_correspondence_desk = __esm({
|
|
|
19189
19602
|
};
|
|
19190
19603
|
LiveCorrespondenceDesk = class {
|
|
19191
19604
|
#links = /* @__PURE__ */ new Map();
|
|
19192
|
-
#pending = /* @__PURE__ */ new Map();
|
|
19193
19605
|
/** What procedures asked of each workspace's stream, and what it delivered (peer_catchup.md). */
|
|
19194
19606
|
inbound;
|
|
19195
19607
|
#own = new OwnOffers();
|
|
@@ -19225,13 +19637,6 @@ var init_live_correspondence_desk = __esm({
|
|
|
19225
19637
|
* never held. Absent (a custodian, a relay, a test), every write goes out on the next drive.
|
|
19226
19638
|
*/
|
|
19227
19639
|
writeBurst;
|
|
19228
|
-
/**
|
|
19229
|
-
* An application peer's receive step (CAP-757; sized by time, CAP-762). A received batch of other
|
|
19230
|
-
* senders' offers larger than one step is not admitted on the socket, in one kernel-thread hold:
|
|
19231
|
-
* the follow receives it instead, in yielding steps of the policy's current size. Absent (a
|
|
19232
|
-
* custodian, a relay, a test), every received batch is admitted as it arrives.
|
|
19233
|
-
*/
|
|
19234
|
-
receiveStep;
|
|
19235
19640
|
/** The last progress counted per workspace, served while a burst holds recounting back. */
|
|
19236
19641
|
#progress = /* @__PURE__ */ new Map();
|
|
19237
19642
|
/** When a held-back progress recount became owed; it reports at the burst's next due point. */
|
|
@@ -19321,10 +19726,12 @@ var init_live_correspondence_desk = __esm({
|
|
|
19321
19726
|
sent: link.stream?.sent,
|
|
19322
19727
|
unansweredAgesMs: (link.stream?.unanswered ?? []).map((entry) => Number((now2 - (entry.due - LIVE_ANSWER_WINDOW)) / 1000000n)),
|
|
19323
19728
|
custodianLocal: link.custodian?.local,
|
|
19324
|
-
convergeDue: link.convergeDue !== void 0
|
|
19729
|
+
convergeDue: link.convergeDue !== void 0,
|
|
19730
|
+
resident: false
|
|
19325
19731
|
};
|
|
19326
19732
|
try {
|
|
19327
19733
|
if (this.kernel.isResident(link.binding.workspace) !== false) {
|
|
19734
|
+
state.resident = true;
|
|
19328
19735
|
const mount = workspaceMount(link.binding.workspace);
|
|
19329
19736
|
state.head = this.kernel.head(mount, ++this.#requestId);
|
|
19330
19737
|
state.tracked = this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2);
|
|
@@ -19393,7 +19800,7 @@ var init_live_correspondence_desk = __esm({
|
|
|
19393
19800
|
}
|
|
19394
19801
|
#count(link, mount) {
|
|
19395
19802
|
const head = this.kernel.head(mount, ++this.#requestId);
|
|
19396
|
-
const acknowledged = this.#cursor(link, mount)?.local ?? this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2);
|
|
19803
|
+
const acknowledged = this.#cursor(link, mount)?.local ?? this.#heldPeerMain(link, mount, head) ?? this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2);
|
|
19397
19804
|
if (!head || !acknowledged) return void 0;
|
|
19398
19805
|
const count = (base, tip) => {
|
|
19399
19806
|
if (base === tip) return 0;
|
|
@@ -19427,6 +19834,14 @@ var init_live_correspondence_desk = __esm({
|
|
|
19427
19834
|
#holds(mount, base, tip) {
|
|
19428
19835
|
return this.#chain(mount, base, tip)?.reachedBase === true;
|
|
19429
19836
|
}
|
|
19837
|
+
/** The custodian's main as last heard, when this copy holds it on its own head's chain above the
|
|
19838
|
+
* sealed bookmark: the commits up to it came from the stream and are the custodian's (CAP-838). */
|
|
19839
|
+
#heldPeerMain(link, mount, head, tracked = this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2)) {
|
|
19840
|
+
const main = link.peerMain;
|
|
19841
|
+
if (!main || !head || main === tracked) return void 0;
|
|
19842
|
+
if (tracked && !this.#holds(mount, tracked, main)) return void 0;
|
|
19843
|
+
return this.#holds(mount, main, head) ? main : void 0;
|
|
19844
|
+
}
|
|
19430
19845
|
/** This connection's admission cursor, while it still leads the saved bookmark. A cursor on local
|
|
19431
19846
|
* history (admitted, not yet sealed) remembers the bookmark it was set above; once anything else
|
|
19432
19847
|
* moves the bookmark (a follow round adopting the custodian's main) the bookmark rules again, so
|
|
@@ -19503,7 +19918,7 @@ var init_live_correspondence_desk = __esm({
|
|
|
19503
19918
|
evidencePack: options.carryCommits || intents.some((intent) => intent.transportRequirement === IntentTransportRequirement.COMMIT_TREE) ? this.kernel.packDelta(mount, requestId, batchHead, base) : new Uint8Array()
|
|
19504
19919
|
});
|
|
19505
19920
|
}
|
|
19506
|
-
receive(
|
|
19921
|
+
receive(receipt) {
|
|
19507
19922
|
const link = [...this.#links.values()].find((item) => item.id === receipt.connectionId);
|
|
19508
19923
|
if (!link) return;
|
|
19509
19924
|
if (receipt.observation.case === "closed" || receipt.observation.case === "closure") {
|
|
@@ -19517,6 +19932,7 @@ var init_live_correspondence_desk = __esm({
|
|
|
19517
19932
|
link.ownMains = [];
|
|
19518
19933
|
delete link.lastAnnounced;
|
|
19519
19934
|
delete link.lastPlacementAnnounced;
|
|
19935
|
+
link.peerMain = void 0;
|
|
19520
19936
|
link.dirty = true;
|
|
19521
19937
|
link.due = this.clock.monotonicNanoseconds() + BigInt(Math.min(3e4, 250 * 2 ** Math.min(link.failures++, 7))) * 1000000n;
|
|
19522
19938
|
return;
|
|
@@ -19526,7 +19942,6 @@ var init_live_correspondence_desk = __esm({
|
|
|
19526
19942
|
link.openedAt = this.clock.monotonicNanoseconds();
|
|
19527
19943
|
link.failures = 0;
|
|
19528
19944
|
link.unheard = void 0;
|
|
19529
|
-
if (!link.publisher) this.#hello(link);
|
|
19530
19945
|
if (!link.publisher) this.inbound.opened(link.binding.workspace);
|
|
19531
19946
|
this.linkOpened?.(link.binding.workspace);
|
|
19532
19947
|
return;
|
|
@@ -19560,18 +19975,6 @@ var init_live_correspondence_desk = __esm({
|
|
|
19560
19975
|
if (this.inbound.frame(link.binding.workspace, frame2.message)) return;
|
|
19561
19976
|
if (frame2.message.case === "frontier") {
|
|
19562
19977
|
this.#announced(link, frame2.message.value.head);
|
|
19563
|
-
if (this.kernel.isResident(link.binding.workspace) === false) return;
|
|
19564
|
-
if (!frame2.message.value.response) {
|
|
19565
|
-
this.#send(link, { case: "frontier", value: {
|
|
19566
|
-
head: this.kernel.head(workspaceMount(link.binding.workspace), ++this.#requestId) ?? "",
|
|
19567
|
-
response: true
|
|
19568
|
-
} });
|
|
19569
|
-
}
|
|
19570
|
-
try {
|
|
19571
|
-
const batch2 = this.export(link.binding, frame2.message.value.head, ++this.#requestId);
|
|
19572
|
-
if (batch2.source.case === "inline" && batch2.source.value.offers.length) this.#send(link, { case: "offers", value: batch2 });
|
|
19573
|
-
} catch {
|
|
19574
|
-
}
|
|
19575
19978
|
return;
|
|
19576
19979
|
}
|
|
19577
19980
|
if (frame2.message.case === "admission") {
|
|
@@ -19579,48 +19982,18 @@ var init_live_correspondence_desk = __esm({
|
|
|
19579
19982
|
this.progressChanged?.(link.binding.workspace);
|
|
19580
19983
|
return;
|
|
19581
19984
|
}
|
|
19582
|
-
|
|
19583
|
-
|
|
19584
|
-
|
|
19585
|
-
|
|
19586
|
-
|
|
19587
|
-
|
|
19588
|
-
|
|
19589
|
-
return;
|
|
19590
|
-
}
|
|
19591
|
-
if (this.receiveStep !== void 0 && offers.length > this.receiveStep.offers) {
|
|
19592
|
-
this.remoteAdvanced?.(link.binding.workspace);
|
|
19593
|
-
return;
|
|
19594
|
-
}
|
|
19595
|
-
if ([...this.#pending.values()].some((pending) => pending.link === link && pending.bytes.length === bytes.length && pending.bytes.every((byte, index) => byte === bytes[index]))) return;
|
|
19596
|
-
if (this.#pending.size >= 32) return;
|
|
19597
|
-
this.#pending.set(request.requestId, { link, bytes });
|
|
19598
|
-
return create50(RuntimeRequestSchema, {
|
|
19599
|
-
protocolVersion: 2,
|
|
19600
|
-
requestId: request.requestId,
|
|
19601
|
-
target: { workspace: link.binding.workspace, session: link.binding.replicaId },
|
|
19602
|
-
// HTTP sender reconciliation controls are not part of a live proposal.
|
|
19603
|
-
// Keeping fastForwardOnly while removing baseHead silently skips every
|
|
19604
|
-
// offer against a nonempty local head. The Kernel judges sealed causality;
|
|
19605
|
-
// live receivers neither ask for a return archive nor confirm the sender.
|
|
19606
|
-
command: { case: "admitCustodyOffers", value: create50(CustodyOfferBatchRequestSchema, {
|
|
19607
|
-
...batch,
|
|
19608
|
-
baseHead: void 0,
|
|
19609
|
-
observedHead: void 0,
|
|
19610
|
-
fastForwardOnly: false,
|
|
19611
|
-
...offers.length === batch.source.value.offers.length ? {} : { source: { case: "inline", value: { ...batch.source.value, offers } } }
|
|
19612
|
-
}) }
|
|
19613
|
-
});
|
|
19985
|
+
}
|
|
19986
|
+
/** The newest local commit the custodian admitted unchanged over this workspace's open link: its
|
|
19987
|
+
* main holds that commit, sealed or not, so it is no work to offer (CAP-838). */
|
|
19988
|
+
admittedLocal(workspace) {
|
|
19989
|
+
const link = this.#links.get(workspace);
|
|
19990
|
+
const cursor = link?.state === "open" && !link.publisher ? link.custodian : void 0;
|
|
19991
|
+
return cursor && cursor.main === cursor.local ? cursor.local : void 0;
|
|
19614
19992
|
}
|
|
19615
19993
|
/** Offers this replica sent another way (the HTTP lane): their echo on the live link is its own. */
|
|
19616
19994
|
offered(workspace, commitOids) {
|
|
19617
19995
|
this.#own.commits(workspace, commitOids);
|
|
19618
19996
|
}
|
|
19619
|
-
/** Whether this request is the admission of a batch relayed to this follower over its live link.
|
|
19620
|
-
* Such an admission is never answered to a sender, so it keeps no custody receipts (CAP-759). */
|
|
19621
|
-
relayed(requestId) {
|
|
19622
|
-
return this.#pending.has(requestId);
|
|
19623
|
-
}
|
|
19624
19997
|
/**
|
|
19625
19998
|
* The custodian judged a live batch. Admission acknowledges the batch at once; its admitted main
|
|
19626
19999
|
* becomes this connection's cursor when it is already in local verified history. The saved
|
|
@@ -19640,9 +20013,10 @@ var init_live_correspondence_desk = __esm({
|
|
|
19640
20013
|
...admission.sealedMain ? { sealed: admission.sealedMain } : {}
|
|
19641
20014
|
};
|
|
19642
20015
|
}
|
|
19643
|
-
if (!admission?.main
|
|
20016
|
+
if (!admission?.main) return;
|
|
19644
20017
|
const ownBatchHead = this.#own.batchHead(workspace, live.requestId);
|
|
19645
20018
|
const ours = ownBatchHead !== void 0;
|
|
20019
|
+
if (this.kernel.isResident(workspace) === false) return;
|
|
19646
20020
|
let stale = false;
|
|
19647
20021
|
if (ours) link.unheard = void 0;
|
|
19648
20022
|
if (ours && link.stream) {
|
|
@@ -19730,6 +20104,7 @@ var init_live_correspondence_desk = __esm({
|
|
|
19730
20104
|
* upstream head it already recorded. Re-announcing a known frontier - which is all an
|
|
19731
20105
|
* upstream can do while this replica is ahead or held on a dependency - is not an event. */
|
|
19732
20106
|
#announced(link, head) {
|
|
20107
|
+
if (head) link.peerMain = head;
|
|
19733
20108
|
if (!head || link.lastAnnounced === head) return;
|
|
19734
20109
|
link.lastAnnounced = head;
|
|
19735
20110
|
if (this.kernel.isResident(link.binding.workspace) === false) {
|
|
@@ -19754,15 +20129,6 @@ var init_live_correspondence_desk = __esm({
|
|
|
19754
20129
|
if (frontier === this.kernel.resolveRef(mount, ++this.#requestId, PLACEMENT_REF3)) return;
|
|
19755
20130
|
this.placementAdvanced?.(link.binding.workspace);
|
|
19756
20131
|
}
|
|
19757
|
-
settled(request, response) {
|
|
19758
|
-
if (response.outcome.case === "correspondencePending" || response.outcome.case === "localReadPending") return;
|
|
19759
|
-
this.#pending.delete(request.requestId);
|
|
19760
|
-
}
|
|
19761
|
-
failed(requestId) {
|
|
19762
|
-
const pending = this.#pending.get(requestId);
|
|
19763
|
-
this.#pending.delete(requestId);
|
|
19764
|
-
if (pending) this.remoteAdvanced?.(pending.link.binding.workspace);
|
|
19765
|
-
}
|
|
19766
20132
|
disconnect(workspace) {
|
|
19767
20133
|
const link = this.#links.get(workspace);
|
|
19768
20134
|
if (!link) return;
|
|
@@ -19770,7 +20136,6 @@ var init_live_correspondence_desk = __esm({
|
|
|
19770
20136
|
if (link.state === "open") this.linkClosed?.(workspace, closure);
|
|
19771
20137
|
this.#links.delete(workspace);
|
|
19772
20138
|
this.#progress.delete(workspace);
|
|
19773
|
-
for (const [id, pending] of this.#pending) if (pending.link === link) this.#pending.delete(id);
|
|
19774
20139
|
}
|
|
19775
20140
|
/** The digest of the settled-letter outcomes this copy holds; empty when it cannot tell. */
|
|
19776
20141
|
#outcomesDigest(workspace) {
|
|
@@ -19808,14 +20173,6 @@ var init_live_correspondence_desk = __esm({
|
|
|
19808
20173
|
transfer.retain(create50(PeerGitRefsFetchedSchema, { refs: [...wanted.refs], pack }));
|
|
19809
20174
|
this.progressChanged?.(link.binding.workspace);
|
|
19810
20175
|
}
|
|
19811
|
-
#hello(link) {
|
|
19812
|
-
if (this.kernel.isResident(link.binding.workspace) === false) return;
|
|
19813
|
-
const head = this.kernel.head(workspaceMount(link.binding.workspace), ++this.#requestId);
|
|
19814
|
-
this.#send(link, { case: "frontier", value: {
|
|
19815
|
-
head: head ?? "",
|
|
19816
|
-
outcomesDigest: this.#outcomesDigest(link.binding.workspace)
|
|
19817
|
-
} });
|
|
19818
|
-
}
|
|
19819
20176
|
drive() {
|
|
19820
20177
|
const now2 = this.clock.monotonicNanoseconds();
|
|
19821
20178
|
let wake;
|
|
@@ -19864,7 +20221,8 @@ var init_live_correspondence_desk = __esm({
|
|
|
19864
20221
|
link.custodian = void 0;
|
|
19865
20222
|
}
|
|
19866
20223
|
this.#cursor(link, mount);
|
|
19867
|
-
|
|
20224
|
+
let answered2 = link.publisher ? link.published ??= head ?? "" : link.custodian?.local ?? this.kernel.resolveRef(mount, ++this.#requestId, TRACKED_MAIN2) ?? "";
|
|
20225
|
+
if (!link.publisher && !link.custodian) answered2 = this.#heldPeerMain(link, mount, head, answered2) ?? answered2;
|
|
19868
20226
|
const fence = link.custodian?.main ?? answered2;
|
|
19869
20227
|
if (link.stream && !(head && this.#holds(mount, link.stream.sent, head))) {
|
|
19870
20228
|
link.stream = void 0;
|
|
@@ -19965,7 +20323,6 @@ var init_live_correspondence_desk = __esm({
|
|
|
19965
20323
|
}
|
|
19966
20324
|
close() {
|
|
19967
20325
|
for (const workspace of [...this.#links.keys()]) this.disconnect(workspace);
|
|
19968
|
-
this.#pending.clear();
|
|
19969
20326
|
}
|
|
19970
20327
|
};
|
|
19971
20328
|
}
|
|
@@ -21007,12 +21364,14 @@ var init_custody_offer = __esm({
|
|
|
21007
21364
|
import { create as create59 } from "@bufbuild/protobuf";
|
|
21008
21365
|
function releaseSyncJudgment(workspace) {
|
|
21009
21366
|
judgedThisLifetime.delete(workspace);
|
|
21367
|
+
notContainedThisLifetime.delete(workspace);
|
|
21010
21368
|
}
|
|
21011
|
-
var PLACEMENT_REF4, RECEIVED_PLACEMENT_REF, STREAM_BATCH_OFFERS, REMOUNT_AFTER_OFFERS, HISTORY_SLICES, WorkspaceSyncPhase, trackedMain, deferredRemote, deferredLocal, judgedThisLifetime, MAX_REBASES_PER_ROUND, elapsedMillis, WorkspaceSyncWork;
|
|
21369
|
+
var PLACEMENT_REF4, RECEIVED_PLACEMENT_REF, STREAM_BATCH_OFFERS, REMOUNT_AFTER_OFFERS, MAX_REMOUNTS_LOST, HISTORY_SLICES, WorkspaceSyncPhase, trackedMain, deferredRemote, deferredLocal, judgedThisLifetime, notContainedThisLifetime, MAX_NOT_CONTAINED, NOT_CONTAINED_REFUSALS, MAX_REBASES_PER_ROUND, elapsedMillis, WorkspaceSyncWork;
|
|
21012
21370
|
var init_workspace_sync = __esm({
|
|
21013
21371
|
"../peer-office/src/runtime/workspace_sync.ts"() {
|
|
21014
21372
|
"use strict";
|
|
21015
21373
|
init_placement_fetch();
|
|
21374
|
+
init_kernel_failure();
|
|
21016
21375
|
init_effect_outcome_refs();
|
|
21017
21376
|
init_law_products_digest();
|
|
21018
21377
|
init_law_products_digest();
|
|
@@ -21029,6 +21388,7 @@ var init_workspace_sync = __esm({
|
|
|
21029
21388
|
RECEIVED_PLACEMENT_REF = "refs/remotes/nomos/placement";
|
|
21030
21389
|
STREAM_BATCH_OFFERS = 64;
|
|
21031
21390
|
REMOUNT_AFTER_OFFERS = 128;
|
|
21391
|
+
MAX_REMOUNTS_LOST = 2;
|
|
21032
21392
|
HISTORY_SLICES = [8, 64, 256, 256];
|
|
21033
21393
|
WorkspaceSyncPhase = Object.freeze({
|
|
21034
21394
|
Idle: "idle",
|
|
@@ -21047,6 +21407,9 @@ var init_workspace_sync = __esm({
|
|
|
21047
21407
|
deferredRemote = "refs/remotes/nomos/deferred";
|
|
21048
21408
|
deferredLocal = "refs/nomos/sync-deferred-local";
|
|
21049
21409
|
judgedThisLifetime = /* @__PURE__ */ new Map();
|
|
21410
|
+
notContainedThisLifetime = /* @__PURE__ */ new Map();
|
|
21411
|
+
MAX_NOT_CONTAINED = 1024;
|
|
21412
|
+
NOT_CONTAINED_REFUSALS = /* @__PURE__ */ new Set(["nomos.stream.off_main", "nomos.stream.history_required"]);
|
|
21050
21413
|
MAX_REBASES_PER_ROUND = 2;
|
|
21051
21414
|
elapsedMillis = (clock2, started) => {
|
|
21052
21415
|
const finished = clock2.monotonicNanoseconds();
|
|
@@ -21102,6 +21465,7 @@ var init_workspace_sync = __esm({
|
|
|
21102
21465
|
#lastStep;
|
|
21103
21466
|
#probeOnly;
|
|
21104
21467
|
#liveConnected;
|
|
21468
|
+
#liveAdmitted;
|
|
21105
21469
|
/** Set when this round adopted the upstream's own head as its base (see #establishBase). */
|
|
21106
21470
|
#establishedBase;
|
|
21107
21471
|
#receiveState;
|
|
@@ -21118,6 +21482,11 @@ var init_workspace_sync = __esm({
|
|
|
21118
21482
|
/** The custodian head this round last offered or pulled from. */
|
|
21119
21483
|
#rebaseFrom;
|
|
21120
21484
|
#rebases = 0;
|
|
21485
|
+
#remountsLost = 0;
|
|
21486
|
+
/** This round's level ask is a containment question (CAP-870): on a refusal, take this path. */
|
|
21487
|
+
#containment;
|
|
21488
|
+
/** The stale bookmark a contained round replaces: its custodian's main holds the local head. */
|
|
21489
|
+
#containedBookmark;
|
|
21121
21490
|
/** Local intents this round's rebase refused and parked on the refused-offer desk. */
|
|
21122
21491
|
#parkedLocal = 0;
|
|
21123
21492
|
/** An application-authorized drop: replace local custody at exactly this head. */
|
|
@@ -21139,6 +21508,7 @@ var init_workspace_sync = __esm({
|
|
|
21139
21508
|
this.#placementFetched = args.placementFetched;
|
|
21140
21509
|
this.#probeOnly = args.probeOnly ?? false;
|
|
21141
21510
|
this.#liveConnected = args.liveConnected === true;
|
|
21511
|
+
this.#liveAdmitted = args.liveAdmitted;
|
|
21142
21512
|
this.#receiveState = args.receiveState;
|
|
21143
21513
|
this.#completeHistory = args.completeHistory === true;
|
|
21144
21514
|
this.#repairMissingCommit = args.repairMissingCommit === true;
|
|
@@ -21213,9 +21583,15 @@ var init_workspace_sync = __esm({
|
|
|
21213
21583
|
if (this.#receiveState) return this.#acquire("full");
|
|
21214
21584
|
if (this.#replaceLocalHead !== void 0) return this.#acquire(this.#repairMissingCommit ? "full" : "mount");
|
|
21215
21585
|
if (!this.#localHead) return this.#acquire(this.#completeHistory ? "full" : "mount");
|
|
21216
|
-
|
|
21217
|
-
|
|
21586
|
+
const unadmitted = this.#holdsLocalWork() && this.#localHead !== this.#liveAdmitted;
|
|
21587
|
+
if (this.#liveConnected && unadmitted && this.#previousHead) {
|
|
21588
|
+
if (this.#mayBeContained()) return this.#askContainment("offer");
|
|
21589
|
+
return this.#notContained();
|
|
21218
21590
|
}
|
|
21591
|
+
if (this.#liveConnected && this.#probeOnly && this.#previousHead && this.#holdsUnsyncedCommits() && this.#command.admit && this.#localHead === this.#liveAdmitted) {
|
|
21592
|
+
return this.#acquire("level");
|
|
21593
|
+
}
|
|
21594
|
+
if (this.#liveConnected && !this.#probeOnly && !unadmitted) return this.#acquire("level");
|
|
21219
21595
|
const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
|
|
21220
21596
|
return this.#beginOffer(encodeInlineCustodyOffer({
|
|
21221
21597
|
session: this.#binding.replicaId,
|
|
@@ -21224,6 +21600,60 @@ var init_workspace_sync = __esm({
|
|
|
21224
21600
|
intents: []
|
|
21225
21601
|
}), { case: "awaiting", requestId }, true);
|
|
21226
21602
|
}
|
|
21603
|
+
/** Whether the custodian's main may hold this copy's head: not already refused in this lifetime. */
|
|
21604
|
+
#mayBeContained() {
|
|
21605
|
+
return !!this.#localHead && this.#offerHead === void 0 && notContainedThisLifetime.get(this.#mount.workspace) !== this.#localHead;
|
|
21606
|
+
}
|
|
21607
|
+
/** The probe named a custodian main that is not on this copy's own chain, so the copy's head may be
|
|
21608
|
+
* on the custodian's. A main below the local head (the custodian is behind) cannot contain it. A
|
|
21609
|
+
* complete copy answers a main it does not hold after one existence check, and one it holds after
|
|
21610
|
+
* a walk to where the two chains join. A kernel that cannot say keeps the existing path. */
|
|
21611
|
+
#custodianMainOffLocalChain() {
|
|
21612
|
+
if (!this.#kernel.historySummary || !this.#desiredHead || !this.#localHead) return false;
|
|
21613
|
+
try {
|
|
21614
|
+
return !this.#kernel.historySummary(this.#mount, this.#requestId, this.#desiredHead, this.#localHead).reachedBase;
|
|
21615
|
+
} catch (error) {
|
|
21616
|
+
return error instanceof KernelHistoryRequired;
|
|
21617
|
+
}
|
|
21618
|
+
}
|
|
21619
|
+
/** Level from the local head (CAP-870). The stream answers with the custodian's commits above it
|
|
21620
|
+
* (or "level") only when its main holds that head; then this round converges onto them, moves the
|
|
21621
|
+
* bookmark, and offers nothing. One custodian lookup, O(commits behind); no local enumeration. */
|
|
21622
|
+
#askContainment(otherwise) {
|
|
21623
|
+
this.#containment = otherwise;
|
|
21624
|
+
return this.#acquire("level");
|
|
21625
|
+
}
|
|
21626
|
+
/** The stream answered from the local head: it is on the custodian's main. The stale bookmark
|
|
21627
|
+
* stays this round's to replace; the local head is the round's base from here. */
|
|
21628
|
+
#contained() {
|
|
21629
|
+
this.#containment = void 0;
|
|
21630
|
+
this.#containedBookmark = this.#previousHead;
|
|
21631
|
+
this.#previousHead = this.#localHead;
|
|
21632
|
+
}
|
|
21633
|
+
/** The custodian's main does not hold the local head (or the stream could not say): the copy holds
|
|
21634
|
+
* work of its own. Go straight on to the pull/rebase/offer path. A dependency planner's probe hands
|
|
21635
|
+
* the round back to it to plan the outbound suffix. */
|
|
21636
|
+
#notContained(code) {
|
|
21637
|
+
const otherwise = this.#containment ?? "offer";
|
|
21638
|
+
this.#containment = void 0;
|
|
21639
|
+
if (code !== void 0 && NOT_CONTAINED_REFUSALS.has(code) && this.#localHead) {
|
|
21640
|
+
if (notContainedThisLifetime.size >= MAX_NOT_CONTAINED && !notContainedThisLifetime.has(this.#mount.workspace)) {
|
|
21641
|
+
notContainedThisLifetime.delete(notContainedThisLifetime.keys().next().value);
|
|
21642
|
+
}
|
|
21643
|
+
notContainedThisLifetime.set(this.#mount.workspace, this.#localHead);
|
|
21644
|
+
}
|
|
21645
|
+
if (this.#probeOnly) {
|
|
21646
|
+
this.#needsReconciliation = true;
|
|
21647
|
+
return this.#finish(create59(SyncWorkspaceResponseSchema, {
|
|
21648
|
+
workspace: this.#mount.workspace,
|
|
21649
|
+
currentHead: this.#localHead,
|
|
21650
|
+
previousHead: this.#previousHead,
|
|
21651
|
+
stillAhead: true,
|
|
21652
|
+
offerReceipt: this.#offerReceipt
|
|
21653
|
+
}));
|
|
21654
|
+
}
|
|
21655
|
+
return otherwise === "pull" ? this.#pullBeforeOffer() : this.#offerOrReconcile();
|
|
21656
|
+
}
|
|
21227
21657
|
#offerOrReconcile() {
|
|
21228
21658
|
if (this.#command.admit && this.#localHead && this.#localHead !== this.#previousHead) {
|
|
21229
21659
|
const suffix = this.#kernel.transportIntentsAbove(
|
|
@@ -21302,7 +21732,14 @@ var init_workspace_sync = __esm({
|
|
|
21302
21732
|
return this.#previousHead === void 0 && this.#localHead !== void 0 && this.#replaceLocalHead === void 0;
|
|
21303
21733
|
}
|
|
21304
21734
|
#holdsLocalWork() {
|
|
21305
|
-
return this.#command.admit &&
|
|
21735
|
+
return this.#command.admit && this.#holdsUnsyncedCommits();
|
|
21736
|
+
}
|
|
21737
|
+
/** Commits on local main the provider has not been seen to admit, whether or not this round may
|
|
21738
|
+
* offer them. Remount replaces local main, so it asks this, never the admit-gated question: a copy
|
|
21739
|
+
* holding unsynced work is offered and rebased, never remounted. A copy without a bookmark cannot
|
|
21740
|
+
* prove it holds nothing of its own. */
|
|
21741
|
+
#holdsUnsyncedCommits() {
|
|
21742
|
+
return !!this.#localHead && this.#localHead !== this.#previousHead;
|
|
21306
21743
|
}
|
|
21307
21744
|
/** Ask only for the custodian's delta; the offer follows once this peer has rebased. */
|
|
21308
21745
|
#pullBeforeOffer() {
|
|
@@ -21340,13 +21777,13 @@ var init_workspace_sync = __esm({
|
|
|
21340
21777
|
}
|
|
21341
21778
|
if (purpose === "level") {
|
|
21342
21779
|
this.#state = { phase: WorkspaceSyncPhase.Stream, purpose, startedAt };
|
|
21343
|
-
return this.#streamEffect("level", { case: "level", value: create59(LiveFrontierSchema, {
|
|
21780
|
+
return this.#streamEffect(this.#containment ? "contain" : "level", { case: "level", value: create59(LiveFrontierSchema, {
|
|
21344
21781
|
head: this.#localHead ?? "",
|
|
21345
21782
|
response: false,
|
|
21346
21783
|
maxOffers: this.#receiveStep?.offers ?? STREAM_BATCH_OFFERS,
|
|
21347
21784
|
// Only a copy holding no work above its bookmark may be remounted instead of replaying, and
|
|
21348
21785
|
// never one whose durable copy must hold the complete history (a head-only mount it cannot keep).
|
|
21349
|
-
remountAfterOffers: this.#
|
|
21786
|
+
remountAfterOffers: this.#holdsUnsyncedCommits() || this.#completeHistory ? 0 : REMOUNT_AFTER_OFFERS
|
|
21350
21787
|
}) });
|
|
21351
21788
|
}
|
|
21352
21789
|
const outcomes = new EffectOutcomeTransfer(this.#kernel, this.#mount, this.#requestId);
|
|
@@ -21423,6 +21860,7 @@ var init_workspace_sync = __esm({
|
|
|
21423
21860
|
}
|
|
21424
21861
|
if (answer.outcome.case === "refusal") {
|
|
21425
21862
|
const refusal2 = answer.outcome.value;
|
|
21863
|
+
if (state.purpose === "level" && this.#containment) return this.#notContained(refusal2.code);
|
|
21426
21864
|
if (state.afterPlacement) return this.#finish(state.afterPlacement);
|
|
21427
21865
|
return this.#transportFailure(`${refusal2.code}: ${refusal2.message}`, false);
|
|
21428
21866
|
}
|
|
@@ -21459,6 +21897,11 @@ var init_workspace_sync = __esm({
|
|
|
21459
21897
|
state.startedAt
|
|
21460
21898
|
);
|
|
21461
21899
|
}
|
|
21900
|
+
if (state.purpose === "level" && this.#containment) {
|
|
21901
|
+
const answeredFromHead = answer.outcome.case === "level" || answer.outcome.case === "pack" && answer.outcome.value.base === this.#localHead;
|
|
21902
|
+
if (!answeredFromHead) return this.#notContained();
|
|
21903
|
+
this.#contained();
|
|
21904
|
+
}
|
|
21462
21905
|
if (state.purpose === "level" && answer.outcome.case === "pack" && answer.outcome.value.base) {
|
|
21463
21906
|
const batch = answer.outcome.value;
|
|
21464
21907
|
if (batch.base !== this.#previousHead && batch.base !== this.#kernel.head(this.#mount, this.#requestId)) {
|
|
@@ -21597,13 +22040,19 @@ var init_workspace_sync = __esm({
|
|
|
21597
22040
|
/**
|
|
21598
22041
|
* A copy holding no work above its bookmark, too far behind to replay the backlog: mount the
|
|
21599
22042
|
* peer's checkpoint in place of its exact local main (O(state), the same trust as a cold mount).
|
|
21600
|
-
* The kernel keeps the replaced head at refs/heads/custody-preserved/<old
|
|
21601
|
-
*
|
|
22043
|
+
* The kernel keeps the replaced head at refs/heads/custody-preserved/<old>. That ref is custody the
|
|
22044
|
+
* kernel guards (custody may not delete an effectful branch), so it is left where it is: a remount
|
|
22045
|
+
* that deleted it threw after main had already moved, leaving the bookmark behind main and the
|
|
22046
|
+
* round failed for ever (2026-10-08, estate-5b493d6b).
|
|
22047
|
+
*
|
|
22048
|
+
* The copy may have moved while the checkpoint streamed (a live batch, a local write). Then it is
|
|
22049
|
+
* no longer the copy the remount was asked for: take the round up again from its new head. Local
|
|
22050
|
+
* work is offered first; a copy that is still only behind asks to level again.
|
|
21602
22051
|
*/
|
|
21603
22052
|
#remount(candidateHead, receivedBytes, prefetchMillis) {
|
|
21604
22053
|
const expected = this.#kernel.head(this.#mount, this.#requestId);
|
|
21605
|
-
if (expected === void 0 || expected !== this.#localHead || this.#
|
|
21606
|
-
return this.#
|
|
22054
|
+
if (expected === void 0 || expected !== this.#localHead || this.#holdsUnsyncedCommits()) {
|
|
22055
|
+
return this.#remountLost(expected);
|
|
21607
22056
|
}
|
|
21608
22057
|
const started = this.#clock.monotonicNanoseconds();
|
|
21609
22058
|
if (candidateHead !== expected) {
|
|
@@ -21611,7 +22060,6 @@ var init_workspace_sync = __esm({
|
|
|
21611
22060
|
if (!restored.accepted || restored.head !== candidateHead) {
|
|
21612
22061
|
throw new Error(`kernel refused to remount '${this.#mount.workspace}' at ${candidateHead}`);
|
|
21613
22062
|
}
|
|
21614
|
-
this.#kernel.deleteRef?.(this.#mount, this.#requestId, `refs/heads/custody-preserved/${expected}`);
|
|
21615
22063
|
this.#providerCustodyMounted();
|
|
21616
22064
|
}
|
|
21617
22065
|
return this.#converged(create59(SyncResponseSchema, {
|
|
@@ -21621,6 +22069,25 @@ var init_workspace_sync = __esm({
|
|
|
21621
22069
|
admittedRemoteHead: candidateHead
|
|
21622
22070
|
}), candidateHead, receivedBytes, prefetchMillis, started);
|
|
21623
22071
|
}
|
|
22072
|
+
/** The remount's copy changed under it. Bounded: a copy that keeps moving under live traffic is
|
|
22073
|
+
* levelled by its live link anyway, and the next round starts from wherever it got to. */
|
|
22074
|
+
#remountLost(head) {
|
|
22075
|
+
if (head === void 0 || ++this.#remountsLost > MAX_REMOUNTS_LOST) {
|
|
22076
|
+
return this.#transportFailure("the copy changed while its remount was streaming", false);
|
|
22077
|
+
}
|
|
22078
|
+
this.#localHead = head;
|
|
22079
|
+
this.#previousHead = this.#kernel.resolveRef(this.#mount, this.#requestId, trackedMain);
|
|
22080
|
+
if (this.#desiredHead === this.#localHead) {
|
|
22081
|
+
return this.#converged(create59(SyncResponseSchema, {
|
|
22082
|
+
admitted: true,
|
|
22083
|
+
head,
|
|
22084
|
+
candidateHead: head,
|
|
22085
|
+
admittedRemoteHead: head
|
|
22086
|
+
}), head, 0, 0);
|
|
22087
|
+
}
|
|
22088
|
+
if (this.#holdsLocalWork() && this.#desiredHead !== this.#previousHead) return this.#pullBeforeOffer();
|
|
22089
|
+
return this.#offerOrReconcile();
|
|
22090
|
+
}
|
|
21624
22091
|
resume(receipt) {
|
|
21625
22092
|
if (receipt.effectId === this.#lastReceiptEffectId && this.#lastStep) {
|
|
21626
22093
|
return this.#lastStep;
|
|
@@ -21785,6 +22252,10 @@ var init_workspace_sync = __esm({
|
|
|
21785
22252
|
offerReceipt: this.#offerReceipt
|
|
21786
22253
|
}));
|
|
21787
22254
|
}
|
|
22255
|
+
const custodianMoved = this.#holdsLocalWork() && this.#desiredHead !== this.#previousHead;
|
|
22256
|
+
if (custodianMoved && this.#mayBeContained() && this.#custodianMainOffLocalChain()) {
|
|
22257
|
+
return this.#askContainment("pull");
|
|
22258
|
+
}
|
|
21788
22259
|
if (this.#probeOnly) {
|
|
21789
22260
|
this.#needsReconciliation = true;
|
|
21790
22261
|
return this.#finish(create59(SyncWorkspaceResponseSchema, {
|
|
@@ -21795,9 +22266,7 @@ var init_workspace_sync = __esm({
|
|
|
21795
22266
|
offerReceipt: this.#offerReceipt
|
|
21796
22267
|
}));
|
|
21797
22268
|
}
|
|
21798
|
-
if (
|
|
21799
|
-
return this.#pullBeforeOffer();
|
|
21800
|
-
}
|
|
22269
|
+
if (custodianMoved) return this.#pullBeforeOffer();
|
|
21801
22270
|
return this.#offerOrReconcile();
|
|
21802
22271
|
}
|
|
21803
22272
|
this.#admissionSummary = summarizeCustodyAdmission(admission);
|
|
@@ -22131,7 +22600,8 @@ var init_workspace_sync = __esm({
|
|
|
22131
22600
|
}));
|
|
22132
22601
|
}
|
|
22133
22602
|
#converged(verdict, candidateHead, receivedBytes, prefetchMillis, started = this.#clock.monotonicNanoseconds(), rebirth) {
|
|
22134
|
-
|
|
22603
|
+
const tracked = verdict.admitted && this.#candidateDurable ? this.#kernel.resolveRef(this.#mount, this.#requestId, trackedMain) : void 0;
|
|
22604
|
+
if (verdict.admitted && this.#candidateDurable && tracked !== candidateHead && (tracked === this.#previousHead || this.#containedBookmark !== void 0 && tracked === this.#containedBookmark)) {
|
|
22135
22605
|
this.#kernel.writeRef(
|
|
22136
22606
|
this.#mount,
|
|
22137
22607
|
this.#requestId,
|
|
@@ -22428,10 +22898,16 @@ var init_workspace_sync_dependencies = __esm({
|
|
|
22428
22898
|
this.#plan = [this.#args.root];
|
|
22429
22899
|
return this.#advance();
|
|
22430
22900
|
}
|
|
22431
|
-
|
|
22901
|
+
const { kernel, requestId, root } = this.#args;
|
|
22902
|
+
const tracked = this.#args.liveConnected ? kernel.resolveRef(root.mount, requestId, trackedMain2) : void 0;
|
|
22903
|
+
if (tracked && kernel.head(root.mount, requestId) === tracked) {
|
|
22432
22904
|
this.#plan = this.#planDependencies();
|
|
22433
22905
|
return this.#advance();
|
|
22434
22906
|
}
|
|
22907
|
+
if (tracked) {
|
|
22908
|
+
this.#current = this.#work(root, `${this.workId}:contain`, true);
|
|
22909
|
+
return this.#accept(this.#current.start());
|
|
22910
|
+
}
|
|
22435
22911
|
this.#current = this.#work(this.#args.root, `${this.workId}:frontier`, true);
|
|
22436
22912
|
return this.#accept(this.#current.start());
|
|
22437
22913
|
}
|
|
@@ -23804,6 +24280,11 @@ var init_replica_follow_lane = __esm({
|
|
|
23804
24280
|
const delay = this.#controller.reconnected(workspace);
|
|
23805
24281
|
if (delay !== void 0) this.#scheduleAt(workspace, this.#now() + delay);
|
|
23806
24282
|
}
|
|
24283
|
+
/** The upstream announced a new frontier: news even to a follow the kernel refused. */
|
|
24284
|
+
remoteAdvanced(workspace) {
|
|
24285
|
+
const delay = this.#controller.reconnected(workspace, true);
|
|
24286
|
+
if (delay !== void 0) this.#scheduleAt(workspace, this.#now() + delay);
|
|
24287
|
+
}
|
|
23807
24288
|
/** The upstream rang for a new placement frontier (see ReplicaFollowController). */
|
|
23808
24289
|
placementAnnounced(workspace) {
|
|
23809
24290
|
const delay = this.#controller.placementAnnounced(workspace);
|
|
@@ -24158,6 +24639,7 @@ var init_correspondence_desk = __esm({
|
|
|
24158
24639
|
#onPlacementFetched;
|
|
24159
24640
|
#onShallowMount;
|
|
24160
24641
|
#onOffered;
|
|
24642
|
+
#liveAdmitted;
|
|
24161
24643
|
#onOutboxHistoryRequired;
|
|
24162
24644
|
#backgroundHistory;
|
|
24163
24645
|
#receiveStep;
|
|
@@ -24214,6 +24696,7 @@ var init_correspondence_desk = __esm({
|
|
|
24214
24696
|
this.#onPlacementFetched = args.onPlacementFetched;
|
|
24215
24697
|
this.#onShallowMount = args.onShallowMount;
|
|
24216
24698
|
this.#onOffered = args.onOffered;
|
|
24699
|
+
this.#liveAdmitted = args.liveAdmitted;
|
|
24217
24700
|
this.#onOutboxHistoryRequired = args.onOutboxHistoryRequired;
|
|
24218
24701
|
this.#backgroundHistory = args.backgroundHistory !== false;
|
|
24219
24702
|
this.#receiveStep = args.receiveStep;
|
|
@@ -24540,6 +25023,12 @@ var init_correspondence_desk = __esm({
|
|
|
24540
25023
|
this.#followLane.reconnected(workspace);
|
|
24541
25024
|
this.reportFollows();
|
|
24542
25025
|
}
|
|
25026
|
+
/** The upstream announced a new frontier for this workspace over its live link: an event which
|
|
25027
|
+
* re-runs a round the kernel refused (its inputs changed). */
|
|
25028
|
+
replicaRemoteAdvanced(workspace) {
|
|
25029
|
+
this.#followLane.remoteAdvanced(workspace);
|
|
25030
|
+
this.reportFollows();
|
|
25031
|
+
}
|
|
24543
25032
|
/** The upstream rang for a new placement frontier: the next round re-checks placement even
|
|
24544
25033
|
* though main has not moved. */
|
|
24545
25034
|
replicaPlacementAnnounced(workspace) {
|
|
@@ -24576,10 +25065,11 @@ var init_correspondence_desk = __esm({
|
|
|
24576
25065
|
const state = this.#follows.followForWorkspace(workspace)?.state;
|
|
24577
25066
|
if (!state) return [];
|
|
24578
25067
|
const isSettled = state.case === ReplicaFollowPhase.Settled;
|
|
25068
|
+
const refused = state.case === ReplicaFollowPhase.Backoff && state.refusal?.blocked === true;
|
|
24579
25069
|
const isLive = this.#openLinks.has(workspace);
|
|
24580
25070
|
if (isSettled) settled += 1;
|
|
24581
25071
|
if (isLive) live += 1;
|
|
24582
|
-
const phase = {
|
|
25072
|
+
const phase = refused ? FollowObservationPhase.KERNEL_REFUSED : {
|
|
24583
25073
|
[ReplicaFollowPhase.Desired]: FollowObservationPhase.DESIRED,
|
|
24584
25074
|
[ReplicaFollowPhase.Due]: FollowObservationPhase.DUE,
|
|
24585
25075
|
[ReplicaFollowPhase.Running]: FollowObservationPhase.RUNNING,
|
|
@@ -24593,7 +25083,7 @@ var init_correspondence_desk = __esm({
|
|
|
24593
25083
|
[ReplicaFollowPhase.LocalCopyUnreadable]: FollowObservationPhase.LOCAL_COPY_UNREADABLE
|
|
24594
25084
|
}[state.case];
|
|
24595
25085
|
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;
|
|
24596
|
-
const retryAt = state.case === ReplicaFollowPhase.Offline || state.case === ReplicaFollowPhase.InvalidCredential || state.case === ReplicaFollowPhase.Backoff ? state.retryAtUnixMillis : void 0;
|
|
25086
|
+
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;
|
|
24597
25087
|
const dueAt2 = state.case === ReplicaFollowPhase.Due || state.case === ReplicaFollowPhase.ReplacingLocal ? state.dueAtUnixMillis : void 0;
|
|
24598
25088
|
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;
|
|
24599
25089
|
const activeEffect = state.case === ReplicaFollowPhase.Running ? this.#activeSyncEffect(workspace) : void 0;
|
|
@@ -25091,6 +25581,7 @@ var init_correspondence_desk = __esm({
|
|
|
25091
25581
|
workId: id,
|
|
25092
25582
|
probeOnly,
|
|
25093
25583
|
liveConnected: this.#openLinks.has(target3.mount.workspace),
|
|
25584
|
+
...this.#openLinks.has(target3.mount.workspace) && this.#liveAdmitted?.(target3.mount.workspace) ? { liveAdmitted: this.#liveAdmitted(target3.mount.workspace) } : {},
|
|
25094
25585
|
...beforeConverge === void 0 ? {} : { beforeConverge },
|
|
25095
25586
|
...target3.receiveState === void 0 ? {} : { receiveState: target3.receiveState },
|
|
25096
25587
|
...target3.offerHead === void 0 ? {} : { offerHead: target3.offerHead },
|
|
@@ -26824,10 +27315,10 @@ var init_offer_readiness_desk = __esm({
|
|
|
26824
27315
|
while (true) {
|
|
26825
27316
|
this.#ports.owe(owed.workspace);
|
|
26826
27317
|
while (this.#ports.owes(owed.workspace)) {
|
|
26827
|
-
const
|
|
27318
|
+
const { ticked, wake: readiness } = this.#ports.tick();
|
|
26828
27319
|
const delayMillis = Math.min(LONGEST_WAKE_MILLIS, Math.max(
|
|
26829
27320
|
FIRST_WAKE_MILLIS,
|
|
26830
|
-
|
|
27321
|
+
ticked.progress !== void 0 ? FIRST_WAKE_MILLIS : readiness.case === "after" ? readiness.millis : LONGEST_WAKE_MILLIS
|
|
26831
27322
|
));
|
|
26832
27323
|
const receipt = yield { case: "wake", value: create75(PeerWakeEffectSchema, {
|
|
26833
27324
|
effectId: `${workId2}:repay-${++wake}`,
|
|
@@ -26979,7 +27470,7 @@ function driveOfficeTurn(subscriptions, maintenance, followUp) {
|
|
|
26979
27470
|
const wake = maintenance.drive();
|
|
26980
27471
|
return subscriptions.owesRefresh ? 0n : wake;
|
|
26981
27472
|
}
|
|
26982
|
-
var INTERACTIVE_PEER_CLASSES, INTERACTION_FIRST_MILLIS,
|
|
27473
|
+
var INTERACTIVE_PEER_CLASSES, INTERACTION_FIRST_MILLIS, PLACEMENT_READ_RETRY_MILLIS, STREAM_WAKE_FIRST_MILLIS, HISTORY_STREAM_SLICES, STREAM_WAKE_MAX_MILLIS, CHECKPOINT_WAIT_LIMIT_NANOS, STREAM_WAIT_LIMIT_NANOS, BACKGROUND_YIELD_MILLIS, BACKGROUND_YIELD_LIMIT, BACKGROUND_YIELD_PREFIX, APPLICATION_WAITS, APPLICATION_WAIT_NANOS, PeerOffice, peerOffice;
|
|
26983
27474
|
var init_peer_office = __esm({
|
|
26984
27475
|
"../peer-office/src/peer_office.ts"() {
|
|
26985
27476
|
"use strict";
|
|
@@ -27027,6 +27518,7 @@ var init_peer_office = __esm({
|
|
|
27027
27518
|
init_shell_contract();
|
|
27028
27519
|
init_birth_refusal();
|
|
27029
27520
|
init_replica_follow_controller();
|
|
27521
|
+
init_runtime_identity();
|
|
27030
27522
|
init_replica_follow_desk();
|
|
27031
27523
|
init_local_copy_drop();
|
|
27032
27524
|
init_preserved_copies_desk();
|
|
@@ -27067,7 +27559,6 @@ var init_peer_office = __esm({
|
|
|
27067
27559
|
init_pack_import_steps();
|
|
27068
27560
|
INTERACTIVE_PEER_CLASSES = /* @__PURE__ */ new Set(["personal-device", "browser"]);
|
|
27069
27561
|
INTERACTION_FIRST_MILLIS = 15e3;
|
|
27070
|
-
READ_READINESS_ONLY = 1n << 62n;
|
|
27071
27562
|
PLACEMENT_READ_RETRY_MILLIS = 60000n;
|
|
27072
27563
|
STREAM_WAKE_FIRST_MILLIS = 20;
|
|
27073
27564
|
HISTORY_STREAM_SLICES = [8, 64, 256];
|
|
@@ -27086,7 +27577,6 @@ var init_peer_office = __esm({
|
|
|
27086
27577
|
"continueLocalRead"
|
|
27087
27578
|
]);
|
|
27088
27579
|
APPLICATION_WAIT_NANOS = 5000000000n;
|
|
27089
|
-
READ_INDEX_BUILDING = /the read index of .+ is being built|read maintenance continues it/;
|
|
27090
27580
|
PeerOffice = class {
|
|
27091
27581
|
#kernel;
|
|
27092
27582
|
#sessions = new SessionDirectory();
|
|
@@ -27281,7 +27771,6 @@ var init_peer_office = __esm({
|
|
|
27281
27771
|
}
|
|
27282
27772
|
}, (workspace) => this.#residency.lastRetainedHead(workspace));
|
|
27283
27773
|
if (this.#writeBurst) this.#live.writeBurst = this.#writeBurst;
|
|
27284
|
-
if (this.#interactivePeer) this.#live.receiveStep = this.#receiveStepBudget;
|
|
27285
27774
|
this.#credentials = new CredentialSessions(this.#sessions, credentials, observations);
|
|
27286
27775
|
this.#readability = new LocalCopyReadability((workspace, format) => {
|
|
27287
27776
|
this.#follows.markLocalCopyUnreadable(workspace, format);
|
|
@@ -27299,7 +27788,8 @@ var init_peer_office = __esm({
|
|
|
27299
27788
|
new ReplicaFollowDesk(seatedStore),
|
|
27300
27789
|
observations,
|
|
27301
27790
|
this.#replicaId,
|
|
27302
|
-
new BirthRefusalRegister(seatedStore)
|
|
27791
|
+
new BirthRefusalRegister(seatedStore),
|
|
27792
|
+
PEER_RUNTIME_IDENTITY
|
|
27303
27793
|
);
|
|
27304
27794
|
this.#compatibility = new CompatibilityDesk(
|
|
27305
27795
|
this.#queries,
|
|
@@ -27318,13 +27808,20 @@ var init_peer_office = __esm({
|
|
|
27318
27808
|
this.#trace,
|
|
27319
27809
|
observations,
|
|
27320
27810
|
{
|
|
27321
|
-
|
|
27322
|
-
|
|
27323
|
-
|
|
27324
|
-
workspace
|
|
27325
|
-
|
|
27326
|
-
|
|
27327
|
-
|
|
27811
|
+
// A read waiting on this workspace is released by the readiness event itself, not a timer.
|
|
27812
|
+
readReady: (workspace) => {
|
|
27813
|
+
this.#subscriptions.readIndexReady(workspace);
|
|
27814
|
+
this.#readResponses?.readinessChanged(workspace);
|
|
27815
|
+
},
|
|
27816
|
+
frontierAdvanced: (workspace) => {
|
|
27817
|
+
this.#subscriptions.readIndexAdvanced(workspace);
|
|
27818
|
+
this.#readResponses?.readinessChanged(workspace);
|
|
27819
|
+
},
|
|
27820
|
+
readinessMayChange: (workspace) => this.#readResponses?.readinessChanged(workspace),
|
|
27821
|
+
localCopyUnreadable: (workspace, format) => {
|
|
27822
|
+
this.#readability.mark(workspace, this.#kernel.head(workspaceMount(workspace), 0n), format);
|
|
27823
|
+
this.#readResponses?.readinessChanged(workspace);
|
|
27824
|
+
},
|
|
27328
27825
|
isLocalCopyUnreadable: (workspace) => this.#readability.decide(workspace) !== void 0
|
|
27329
27826
|
},
|
|
27330
27827
|
// The kernel owes this peer's writes to an ordered background flush the desk schedules.
|
|
@@ -27386,7 +27883,7 @@ var init_peer_office = __esm({
|
|
|
27386
27883
|
aggregateIds: new Set([...admitted.affected, ...admitted.created].map((ref) => ref.id)),
|
|
27387
27884
|
// What the offer changed, typed as reads resolve it: watches it cannot change are not read.
|
|
27388
27885
|
stateChange: admitted.stateChange
|
|
27389
|
-
}, () => this.#readMaintenance.
|
|
27886
|
+
}, () => this.#readMaintenance.tickReadReadiness().ticked.progress !== void 0));
|
|
27390
27887
|
noteTimeline("ownOffer", `${delivery.delivered}/${delivery.watches}`);
|
|
27391
27888
|
noteTimeline("ownOfferSkipped", delivery.skipped);
|
|
27392
27889
|
});
|
|
@@ -27401,7 +27898,12 @@ var init_peer_office = __esm({
|
|
|
27401
27898
|
observations,
|
|
27402
27899
|
// A waiting read advances read readiness only: it must never run a background command or
|
|
27403
27900
|
// closure warm on the foreground's turn.
|
|
27404
|
-
() => this.#readMaintenance.
|
|
27901
|
+
() => this.#readMaintenance.tickReadReadiness(),
|
|
27902
|
+
// A read the kernel still finds behind, with nothing owing its index, owes it again (as a watch does).
|
|
27903
|
+
(request) => {
|
|
27904
|
+
if (request.command.case !== "kernelCall") throw new Error("local read continuation lost its query");
|
|
27905
|
+
this.#readMaintenance.schedule(request.command.value.session, ReadMaintenanceCause.READ_DEBT);
|
|
27906
|
+
},
|
|
27405
27907
|
(request) => {
|
|
27406
27908
|
if (request.command.case !== "kernelCall") throw new Error("local read continuation lost its query");
|
|
27407
27909
|
return this.#application.call(request, request.command.value);
|
|
@@ -27502,6 +28004,7 @@ var init_peer_office = __esm({
|
|
|
27502
28004
|
onShallowMount: (workspace, credentialCapability) => this.#historyAcquisition.materialise(workspace, credentialCapability),
|
|
27503
28005
|
// The edge echoes an HTTP offer batch back over this replica's own live link (CAP-764).
|
|
27504
28006
|
onOffered: (workspace, commitOids) => this.#live.offered(workspace, commitOids),
|
|
28007
|
+
liveAdmitted: (workspace) => this.#live.admittedLocal(workspace),
|
|
27505
28008
|
onOutboxHistoryRequired: (workspace, credentialCapability) => this.#historyAcquisition.requestFromBackground(workspace, credentialCapability),
|
|
27506
28009
|
backgroundHistory: profile.backgroundHistory !== false,
|
|
27507
28010
|
onSyncCompleted: (session, event) => {
|
|
@@ -27527,7 +28030,7 @@ var init_peer_office = __esm({
|
|
|
27527
28030
|
this.#origins.ignored(workspace, origin, "follow");
|
|
27528
28031
|
return false;
|
|
27529
28032
|
};
|
|
27530
|
-
this.#live.remoteAdvanced = (workspace) => this.#correspondence.
|
|
28033
|
+
this.#live.remoteAdvanced = (workspace) => this.#correspondence.replicaRemoteAdvanced(workspace);
|
|
27531
28034
|
this.#live.declined = (workspace) => this.#correspondence.liveAdmissionDeclined(workspace);
|
|
27532
28035
|
this.#live.acknowledged = (workspace, ack) => this.#correspondence.liveAdmissionAcknowledged(workspace, ack);
|
|
27533
28036
|
this.#live.intentsAdmitted = (workspace, intentIds, local) => this.#correspondence.liveIntentsAdmitted(workspace, intentIds, local);
|
|
@@ -27739,7 +28242,7 @@ var init_peer_office = __esm({
|
|
|
27739
28242
|
},
|
|
27740
28243
|
owes: (workspace) => this.#readMaintenance.owesReadReadiness(workspace),
|
|
27741
28244
|
// Read readiness only, as a waiting read takes: never a background command or pack import (CAP-806).
|
|
27742
|
-
tick: () => this.#readMaintenance.
|
|
28245
|
+
tick: () => this.#readMaintenance.tickReadReadiness(),
|
|
27743
28246
|
emit: (session, event) => this.#trace.emit(session, event)
|
|
27744
28247
|
});
|
|
27745
28248
|
this.#modelAdoption = new ModelAdoptionDesk({
|
|
@@ -28137,9 +28640,8 @@ var init_peer_office = __esm({
|
|
|
28137
28640
|
let pendingEffectId;
|
|
28138
28641
|
try {
|
|
28139
28642
|
if (request.command.case === "socketReceipt") {
|
|
28140
|
-
|
|
28141
|
-
|
|
28142
|
-
request = admission;
|
|
28643
|
+
this.#live.receive(request.command.value);
|
|
28644
|
+
return this.#response(request, { case: "socketObserved", value: create76(PeerSocketObservedSchema) });
|
|
28143
28645
|
}
|
|
28144
28646
|
const result = timelinePhase("access", () => this.#access.handle(request));
|
|
28145
28647
|
if (result.outcome.case === "correspondencePending") {
|
|
@@ -28148,11 +28650,9 @@ var init_peer_office = __esm({
|
|
|
28148
28650
|
}
|
|
28149
28651
|
if (result.outcome.case === "watchStarted") this.#subscriptions.retainDependencies(result.outcome.value.subscriptionId, scope);
|
|
28150
28652
|
this.#subscriptions.recoverySettled(result);
|
|
28151
|
-
this.#live.settled(request, result);
|
|
28152
28653
|
this.#correspondence.observeResponse(result);
|
|
28153
28654
|
return result;
|
|
28154
28655
|
} catch (error) {
|
|
28155
|
-
this.#live.failed(request.requestId);
|
|
28156
28656
|
const failure = this.#failure(request, "nomos.runtime.workspace_access", error instanceof Error ? error.message : String(error));
|
|
28157
28657
|
this.#subscriptions.recoverySettled(failure);
|
|
28158
28658
|
this.#correspondence.observeResponse(failure);
|
|
@@ -28419,11 +28919,7 @@ var init_peer_office = __esm({
|
|
|
28419
28919
|
try {
|
|
28420
28920
|
const mount = this.#sessions.mountForWorkspace(request.target.workspace);
|
|
28421
28921
|
const previousHead = this.#kernel.head(mount, request.requestId);
|
|
28422
|
-
const admission = this.#custodyAdmission.admit(
|
|
28423
|
-
request,
|
|
28424
|
-
request.command.value,
|
|
28425
|
-
{ journal: !this.#live.relayed(request.requestId) }
|
|
28426
|
-
);
|
|
28922
|
+
const admission = this.#custodyAdmission.admit(request, request.command.value);
|
|
28427
28923
|
admission.sealedMain = this.#residency.retainedHead(request.target.workspace);
|
|
28428
28924
|
if (custodyAdmissionNeedsReadMaintenance(admission)) {
|
|
28429
28925
|
admission.localMaintenance = this.#readMaintenance.scheduleWorkspace(
|
|
@@ -28540,16 +29036,17 @@ var init_peer_office = __esm({
|
|
|
28540
29036
|
});
|
|
28541
29037
|
case "historicQuery": {
|
|
28542
29038
|
const answered2 = this.#historicQueries.execute(request, request.command.value);
|
|
28543
|
-
if (answered2.outcome.case === "
|
|
29039
|
+
if (answered2.outcome.case === "query" && answered2.outcome.value.result.case === "readIndexPending") {
|
|
28544
29040
|
this.#readMaintenance.schedule(request.command.value.session, ReadMaintenanceCause.READ_DEBT);
|
|
29041
|
+
const workspace = answered2.outcome.value.result.value.workspace || (this.#sessions.bindingIfPresent(request.command.value.session)?.workspace ?? "");
|
|
28545
29042
|
return this.#response(request, {
|
|
28546
29043
|
case: "unavailable",
|
|
28547
29044
|
value: create76(RuntimeUnavailableSchema, {
|
|
28548
29045
|
reason: RuntimeUnavailableReason.LOCAL_REPLICA_NOT_READY,
|
|
28549
|
-
workspace
|
|
29046
|
+
workspace,
|
|
28550
29047
|
retryable: true,
|
|
28551
29048
|
retryAfterMillis: 250,
|
|
28552
|
-
detail:
|
|
29049
|
+
detail: `the read index of ${workspace} is being built on this device; read maintenance continues it`
|
|
28553
29050
|
})
|
|
28554
29051
|
});
|
|
28555
29052
|
}
|
|
@@ -28969,6 +29466,10 @@ var init_peer_office = __esm({
|
|
|
28969
29466
|
nextEvent() {
|
|
28970
29467
|
return this.#trace.nextEvent();
|
|
28971
29468
|
}
|
|
29469
|
+
/** In-process shells wait on a held local read here instead of polling `resumeAfterMillis`. */
|
|
29470
|
+
localReadResumable(workId2, notify) {
|
|
29471
|
+
return this.#readResponses.onResumable(workId2, notify);
|
|
29472
|
+
}
|
|
28972
29473
|
close() {
|
|
28973
29474
|
if (this.retentionOutstanding() > 0) {
|
|
28974
29475
|
throw new Error("custody retention pending; retain the acknowledged frontiers before disposing the peer");
|
|
@@ -29319,6 +29820,23 @@ function createPeerOfficeFrameRunner(kernel, credentials, profile, observations,
|
|
|
29319
29820
|
lanes?.wake(delayMillis);
|
|
29320
29821
|
};
|
|
29321
29822
|
const runner = {
|
|
29823
|
+
localReadResumable(workId2) {
|
|
29824
|
+
let resolve4;
|
|
29825
|
+
const resumable = new Promise((done) => {
|
|
29826
|
+
resolve4 = done;
|
|
29827
|
+
});
|
|
29828
|
+
let timer;
|
|
29829
|
+
const wait = peer2.localReadResumable(workId2, () => {
|
|
29830
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
29831
|
+
resolve4();
|
|
29832
|
+
});
|
|
29833
|
+
if (wait === void 0) return void 0;
|
|
29834
|
+
timer = setTimeout(() => {
|
|
29835
|
+
wait.cancel();
|
|
29836
|
+
resolve4();
|
|
29837
|
+
}, wait.afterMillis);
|
|
29838
|
+
return resumable;
|
|
29839
|
+
},
|
|
29322
29840
|
handleFrame(frame2) {
|
|
29323
29841
|
const response = peer2.invoke(frame2).responseProtobuf;
|
|
29324
29842
|
drainEvents();
|
|
@@ -29409,7 +29927,7 @@ async function drivePeerFrame(runner, initialFrame, fetchImpl = globalThis.fetch
|
|
|
29409
29927
|
if (response.outcome.case === "localReadPending") {
|
|
29410
29928
|
if (yieldLocalReadToCaller) return responseFrame;
|
|
29411
29929
|
const pending2 = response.outcome.value;
|
|
29412
|
-
await new Promise((resolve4) => setTimeout(resolve4, pending2.resumeAfterMillis));
|
|
29930
|
+
await (runner.localReadResumable?.(pending2.workId) ?? new Promise((resolve4) => setTimeout(resolve4, pending2.resumeAfterMillis)));
|
|
29413
29931
|
responseFrame = await turn(() => runner.handleFrame(toBinary28(RuntimeRequestSchema, create77(RuntimeRequestSchema, {
|
|
29414
29932
|
protocolVersion: response.protocolVersion,
|
|
29415
29933
|
requestId: response.requestId,
|
|
@@ -31459,12 +31977,10 @@ __export(governance_exports, {
|
|
|
31459
31977
|
relaySealedOfferViaStage: () => relaySealedOfferViaStage,
|
|
31460
31978
|
remoteOfferAuthority: () => remoteOfferAuthority,
|
|
31461
31979
|
resolveGovernancePrincipal: () => resolveGovernancePrincipal,
|
|
31462
|
-
signAndPostChildLifecycle: () => signAndPostChildLifecycle,
|
|
31463
31980
|
signAndPostGovernance: () => signAndPostGovernance,
|
|
31464
31981
|
signAndPostModelLifecycleOffer: () => signAndPostModelLifecycleOffer,
|
|
31465
31982
|
signAndPostOffer: () => signAndPostOffer,
|
|
31466
|
-
signAndPostWorkspaceBirth: () => signAndPostWorkspaceBirth
|
|
31467
|
-
signAndPostWorkspaceRetirement: () => signAndPostWorkspaceRetirement
|
|
31983
|
+
signAndPostWorkspaceBirth: () => signAndPostWorkspaceBirth
|
|
31468
31984
|
});
|
|
31469
31985
|
import { createHash as createHash4, createPrivateKey, createPublicKey } from "node:crypto";
|
|
31470
31986
|
import { create as create83 } from "@bufbuild/protobuf";
|
|
@@ -32370,38 +32886,6 @@ async function ensureApplicationWorkspace(application, opts = {}) {
|
|
|
32370
32886
|
deployPrincipal: home.principal
|
|
32371
32887
|
};
|
|
32372
32888
|
}
|
|
32373
|
-
async function signAndPostWorkspaceRetirement(parent, workspaceId, creator, opts) {
|
|
32374
|
-
return signAndPostPreparedOffer(
|
|
32375
|
-
parent,
|
|
32376
|
-
"workspaces",
|
|
32377
|
-
(actor) => ({
|
|
32378
|
-
directiveId: creator !== "" && sameIdentity(creator, actor) ? "retireOwnWorkspace" : "retireWorkspace",
|
|
32379
|
-
payload: { workspaceId, retiredBy: lineageIdentity(actor), retiredAt: Date.now() }
|
|
32380
|
-
}),
|
|
32381
|
-
opts,
|
|
32382
|
-
"self-if-unenrolled",
|
|
32383
|
-
creator
|
|
32384
|
-
);
|
|
32385
|
-
}
|
|
32386
|
-
async function signAndPostChildLifecycle(parent, child, creator, action, opts) {
|
|
32387
|
-
return signAndPostPreparedOffer(
|
|
32388
|
-
parent,
|
|
32389
|
-
void 0,
|
|
32390
|
-
(actor) => {
|
|
32391
|
-
const creatorActing = creator !== "" && sameIdentity(creator, actor);
|
|
32392
|
-
return action === "retire" ? {
|
|
32393
|
-
directiveId: creatorActing ? "retireChild" : "retireChildAsAdmin",
|
|
32394
|
-
payload: { child, principal: creator, retiredBy: lineageIdentity(actor), retiredAt: Date.now() }
|
|
32395
|
-
} : {
|
|
32396
|
-
directiveId: creatorActing ? "reclaimChild" : "reclaimChildAsAdmin",
|
|
32397
|
-
payload: { child, reclaimedBy: lineageIdentity(actor), reclaimedAt: Date.now() }
|
|
32398
|
-
};
|
|
32399
|
-
},
|
|
32400
|
-
opts,
|
|
32401
|
-
"self-if-unenrolled",
|
|
32402
|
-
creator
|
|
32403
|
-
);
|
|
32404
|
-
}
|
|
32405
32889
|
async function relaySealedOfferViaStage(cloud, ws, directiveId, intentBytesB64, fetchImpl) {
|
|
32406
32890
|
const raw = Buffer.from(intentBytesB64, "base64");
|
|
32407
32891
|
const sha2562 = createHash4("sha256").update(raw).digest("hex");
|
|
@@ -33086,8 +33570,6 @@ __export(cloud_exports, {
|
|
|
33086
33570
|
waitForDurableMainAdvance: () => waitForDurableMainAdvance,
|
|
33087
33571
|
whoami: () => whoami,
|
|
33088
33572
|
wsCreate: () => wsCreate,
|
|
33089
|
-
wsReclaim: () => wsReclaim,
|
|
33090
|
-
wsRetire: () => wsRetire,
|
|
33091
33573
|
wsStatus: () => wsStatus
|
|
33092
33574
|
});
|
|
33093
33575
|
import { chmodSync as chmodSync2, existsSync as existsSync6, mkdirSync as mkdirSync7, readdirSync as readdirSync3, readFileSync as readFileSync6, writeFileSync as writeFileSync7 } from "node:fs";
|
|
@@ -33387,117 +33869,6 @@ async function wsStatus(name, opts) {
|
|
|
33387
33869
|
out3(text);
|
|
33388
33870
|
return 0;
|
|
33389
33871
|
}
|
|
33390
|
-
async function childBirthRecord(cloud, parent, child) {
|
|
33391
|
-
try {
|
|
33392
|
-
const id = `nomos-birth-record:${child}`;
|
|
33393
|
-
const r = await fetch(`${cloud}/v2/workspaces/${encodeURIComponent(parent)}/aggregates/${encodeURIComponent(id)}`);
|
|
33394
|
-
const body = await r.json().catch(() => void 0);
|
|
33395
|
-
return body?.ok === true ? body.rows?.find((row) => row.data?.child === child) : void 0;
|
|
33396
|
-
} catch {
|
|
33397
|
-
return void 0;
|
|
33398
|
-
}
|
|
33399
|
-
}
|
|
33400
|
-
async function wsRetire(ws, opts) {
|
|
33401
|
-
const cloud = cloudBase(opts.cloud);
|
|
33402
|
-
const { signAndPostChildLifecycle: signAndPostChildLifecycle2, signAndPostWorkspaceRetirement: signAndPostWorkspaceRetirement2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
33403
|
-
const parent = opts.parent ?? "root";
|
|
33404
|
-
let record;
|
|
33405
|
-
try {
|
|
33406
|
-
const q = await fetch(`${cloud}/v2/workspaces/${parent}/workspaceByName?name=${encodeURIComponent(ws)}`);
|
|
33407
|
-
const qd = await q.json().catch(() => void 0);
|
|
33408
|
-
const rows = qd?.ok === true ? qd.rows ?? [] : [];
|
|
33409
|
-
record = rows.find((r) => r.data?.status !== "retired" && r.data?.status !== "reclaimed") ?? rows[0];
|
|
33410
|
-
} catch {
|
|
33411
|
-
}
|
|
33412
|
-
const recordId2 = record?.id;
|
|
33413
|
-
if (recordId2 === void 0) {
|
|
33414
|
-
const childRecord = await childBirthRecord(cloud, parent, ws);
|
|
33415
|
-
if (childRecord === void 0) {
|
|
33416
|
-
err3(
|
|
33417
|
-
`retire '${ws}': no CloudWorkspace or NomosBirthRecord named '${ws}' in ${parent}'s registry \u2014 nothing lawful to retire.
|
|
33418
|
-
An out-of-band custody repo has no parent lifecycle fact and needs a custodian investigation.`
|
|
33419
|
-
);
|
|
33420
|
-
return 1;
|
|
33421
|
-
}
|
|
33422
|
-
const creator = childRecord.data?.principal ?? "";
|
|
33423
|
-
let childVerdict;
|
|
33424
|
-
try {
|
|
33425
|
-
childVerdict = await signAndPostChildLifecycle2(parent, ws, creator, "retire", opts);
|
|
33426
|
-
} catch (e) {
|
|
33427
|
-
err3(e.message);
|
|
33428
|
-
return 1;
|
|
33429
|
-
}
|
|
33430
|
-
if (!childVerdict.ok) {
|
|
33431
|
-
err3(`retire '${ws}' refused (${childVerdict.status}): ${typeof childVerdict.body === "string" ? childVerdict.body : JSON.stringify(childVerdict.body)}`);
|
|
33432
|
-
return 1;
|
|
33433
|
-
}
|
|
33434
|
-
out3(`\u2713 child ${ws} retired via signed lifecycle offer to ${parent} on ${cloud}`);
|
|
33435
|
-
out3(" custody is retained; reclaim is a separate, law-gated terminal step");
|
|
33436
|
-
return 0;
|
|
33437
|
-
}
|
|
33438
|
-
let v;
|
|
33439
|
-
try {
|
|
33440
|
-
const creator = record?.data?.createdBy ?? record?.data?.principal ?? "";
|
|
33441
|
-
v = await signAndPostWorkspaceRetirement2(parent, recordId2, creator, opts);
|
|
33442
|
-
} catch (e) {
|
|
33443
|
-
err3(e.message);
|
|
33444
|
-
return 1;
|
|
33445
|
-
}
|
|
33446
|
-
if (!v.ok) {
|
|
33447
|
-
err3(`retire '${ws}' refused (${v.status}): ${typeof v.body === "string" ? v.body : JSON.stringify(v.body)}`);
|
|
33448
|
-
if (JSON.stringify(v.body ?? "").includes("retire-own-only")) {
|
|
33449
|
-
err3(
|
|
33450
|
-
`note: you appear to BE '${ws}'s creator \u2014 the parent's deployed governance law may predate the
|
|
33451
|
-
0.34.1 retireOwnWorkspace creator-normalization fix (the 'user:' subject prefix vs the bare uid).
|
|
33452
|
-
A governance re-deploy to ${parent} fixes the self-service lane; meanwhile an ADMIN can retire it:
|
|
33453
|
-
githolon ws retire ${ws} --as <admin-uid>`
|
|
33454
|
-
);
|
|
33455
|
-
}
|
|
33456
|
-
return 1;
|
|
33457
|
-
}
|
|
33458
|
-
out3(`\u2713 workspace ${ws} retired via signed governance offer to ${parent} on ${cloud}`);
|
|
33459
|
-
out3(" nothing was deleted \u2014 the ledger and its data are retained per the Nomos Pre-Release License");
|
|
33460
|
-
out3(" it no longer counts toward your workspace allowance; reads keep serving, deploys/pushes refuse");
|
|
33461
|
-
return 0;
|
|
33462
|
-
}
|
|
33463
|
-
async function wsReclaim(ws, opts) {
|
|
33464
|
-
const cloud = cloudBase(opts.cloud);
|
|
33465
|
-
const { signAndPostChildLifecycle: signAndPostChildLifecycle2, signAndPostGovernance: signAndPostGovernance2, resolveGovernancePrincipal: resolveGovernancePrincipal2 } = await Promise.resolve().then(() => (init_governance(), governance_exports));
|
|
33466
|
-
const parent = opts.parent ?? "root";
|
|
33467
|
-
let v;
|
|
33468
|
-
try {
|
|
33469
|
-
const principal = resolveGovernancePrincipal2(opts);
|
|
33470
|
-
const q = await fetch(`${cloud}/v2/workspaces/${parent}/workspaceByName?name=${encodeURIComponent(ws)}`);
|
|
33471
|
-
const qd = await q.json().catch(() => void 0);
|
|
33472
|
-
const rows = qd?.ok === true ? qd.rows ?? [] : [];
|
|
33473
|
-
const workspace = rows.find((r) => r.data?.status === "retired") ?? rows[0];
|
|
33474
|
-
if (workspace?.id !== void 0) {
|
|
33475
|
-
v = await signAndPostGovernance2(
|
|
33476
|
-
parent,
|
|
33477
|
-
"reclaimWorkspace",
|
|
33478
|
-
{ workspaceId: workspace.id, reclaimedBy: principal, reclaimedAt: Date.now() },
|
|
33479
|
-
opts
|
|
33480
|
-
);
|
|
33481
|
-
} else {
|
|
33482
|
-
const child = await childBirthRecord(cloud, parent, ws);
|
|
33483
|
-
if (child === void 0) {
|
|
33484
|
-
err3(`reclaim '${ws}': no CloudWorkspace or NomosBirthRecord named '${ws}' in ${parent}'s registry`);
|
|
33485
|
-
return 1;
|
|
33486
|
-
}
|
|
33487
|
-
v = await signAndPostChildLifecycle2(parent, ws, child.data?.principal ?? "", "reclaim", opts);
|
|
33488
|
-
}
|
|
33489
|
-
} catch (e) {
|
|
33490
|
-
err3(e.message);
|
|
33491
|
-
return 1;
|
|
33492
|
-
}
|
|
33493
|
-
if (!v.ok) {
|
|
33494
|
-
err3(`reclaim '${ws}' refused (${v.status}): ${typeof v.body === "string" ? v.body : JSON.stringify(v.body)}`);
|
|
33495
|
-
return 1;
|
|
33496
|
-
}
|
|
33497
|
-
out3(`\u2713 workspace ${ws} reclaimed via signed lifecycle offer to ${parent} on ${cloud}`);
|
|
33498
|
-
out3(" the custodian drops the ledger bytes on seeing this fact folded; the reclaimed FACT is append-only");
|
|
33499
|
-
return 0;
|
|
33500
|
-
}
|
|
33501
33872
|
function advertisedMainHead(text) {
|
|
33502
33873
|
return /([0-9a-f]{40}) refs\/heads\/main\b/.exec(text)?.[1];
|
|
33503
33874
|
}
|