githolon 0.110.1 → 0.111.1
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/README.md +43 -0
- package/dist/compile_mountability_entry.js +188 -76
- package/dist/conformance-fixture/domains/booking.ts +72 -0
- package/dist/conformance-fixture/nomos.project.ts +1 -0
- package/dist/conformance-probe.mjs +69 -0
- package/dist/dev-server.mjs +165 -71
- package/dist/full-cli.mjs +497 -139
- package/package.json +2 -2
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// src/conformance_probe.ts
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { writeFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
var [testingEntry, fixture, resultFile, runtime, offline] = process.argv.slice(2);
|
|
7
|
+
var report = { passed: false, packages: [], checks: [] };
|
|
8
|
+
var keepAlive = setInterval(() => {
|
|
9
|
+
}, 1e3);
|
|
10
|
+
var stage = "load generated application";
|
|
11
|
+
try {
|
|
12
|
+
const { testHolon, Refusal, kernelContractRequirements } = await import(pathToFileURL(testingEntry).href);
|
|
13
|
+
const { seatsClient } = await import(pathToFileURL(join(fixture, "build/seats.reception.mjs")).href);
|
|
14
|
+
stage = "runtime acquisition";
|
|
15
|
+
const h = await testHolon({
|
|
16
|
+
law: join(fixture, "build/seats.law.usdz"),
|
|
17
|
+
deterministic: true,
|
|
18
|
+
...runtime ? { runtimeDir: runtime } : {},
|
|
19
|
+
offline: offline === "true"
|
|
20
|
+
});
|
|
21
|
+
report.runtime = { kernelSha256: h.kernelSha256, contracts: kernelContractRequirements };
|
|
22
|
+
report.checks.push({ name: stage, passed: true });
|
|
23
|
+
const app = h.app(seatsClient, { actor: "person:conformance" });
|
|
24
|
+
stage = "generated write and read";
|
|
25
|
+
const { booking } = await app.openBooking({ label: "conformance", capacity: 1 });
|
|
26
|
+
await app.takeSeat({ bookingId: booking, attendee: "alice", takenAt: "2026-01-01T00:00:00.000Z" });
|
|
27
|
+
const before = await app.bookings.find(booking);
|
|
28
|
+
assert.equal(before.label, "conformance");
|
|
29
|
+
assert.equal(before.seats.alice.status, "active");
|
|
30
|
+
assert.equal((await app.bookingsByLabel({ label: "conformance" })).length, 1);
|
|
31
|
+
report.checks.push({ name: stage, passed: true });
|
|
32
|
+
stage = "expected refusal has no effect";
|
|
33
|
+
const history = h.intents();
|
|
34
|
+
await assert.rejects(
|
|
35
|
+
app.takeSeat({ bookingId: booking, attendee: "bob", takenAt: "2026-01-01T00:00:01.000Z" }),
|
|
36
|
+
(error) => error instanceof Refusal && error.refusal.includes("seats-exceed-capacity")
|
|
37
|
+
);
|
|
38
|
+
assert.deepEqual(await app.bookings.find(booking), before);
|
|
39
|
+
assert.deepEqual(h.intents(), history);
|
|
40
|
+
report.checks.push({ name: stage, passed: true });
|
|
41
|
+
stage = "persisted history verifies";
|
|
42
|
+
const persisted = await h.verify();
|
|
43
|
+
assert.equal(persisted.valid, true, JSON.stringify(persisted));
|
|
44
|
+
assert.ok(history.length >= 3, "admitted application writes must be present in physical custody");
|
|
45
|
+
report.checks.push({ name: stage, passed: true });
|
|
46
|
+
stage = "cold restore preserves data and history";
|
|
47
|
+
const restored = await h.restart();
|
|
48
|
+
const restoredApp = restored.app(seatsClient, { actor: "person:conformance" });
|
|
49
|
+
assert.deepEqual(await restoredApp.bookings.find(booking), before);
|
|
50
|
+
assert.deepEqual(restored.intents(), history);
|
|
51
|
+
const verified = await restored.verify();
|
|
52
|
+
const materialising = verified.walk === "present" && verified.history?.state === "materialising";
|
|
53
|
+
assert.ok(verified.valid || materialising, JSON.stringify(verified));
|
|
54
|
+
assert.equal(restored.kernelSha256, h.kernelSha256);
|
|
55
|
+
const next = await restoredApp.openBooking({ label: "after-restore", capacity: 1 });
|
|
56
|
+
assert.equal((await restoredApp.bookings.find(next.booking)).label, "after-restore");
|
|
57
|
+
report.checks.push({ name: stage, passed: true, ...materialising ? { detail: "Restored data and persisted history match; historical verification is still materialising." } : {} });
|
|
58
|
+
report.passed = true;
|
|
59
|
+
} catch (error) {
|
|
60
|
+
report.checks.push({ name: stage, passed: false });
|
|
61
|
+
report.failure = {
|
|
62
|
+
stage,
|
|
63
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
64
|
+
action: stage === "runtime acquisition" ? "Use a compatible verified runtime directory with --runtime, or run online once to populate the runtime cache. Check the reported package versions before retrying." : "Reinstall the project's locked Nomos packages and retry. If the same check fails, report this diagnostic and the package/kernel versions to Nomos; this isolated fixture should pass."
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
clearInterval(keepAlive);
|
|
68
|
+
writeFileSync(resultFile, JSON.stringify(report));
|
|
69
|
+
process.exit(report.passed ? 0 : 1);
|
package/dist/dev-server.mjs
CHANGED
|
@@ -631,7 +631,7 @@ var CustodyBreakPolicySchema = /* @__PURE__ */ enumDesc13(file_nomos_runtime_v2_
|
|
|
631
631
|
var CustodyBreakPolicy = /* @__PURE__ */ tsEnum13(CustodyBreakPolicySchema);
|
|
632
632
|
|
|
633
633
|
// ../adapter/proto/nomos/runtime/v2/observability_desk_pb.js
|
|
634
|
-
var file_nomos_runtime_v2_observability_desk = /* @__PURE__ */ fileDesc21("Cilub21vcy9ydW50aW1lL3YyL29ic2VydmFiaWxpdHlfZGVzay5wcm90bxIQbm9tb3MucnVudGltZS52MiJCCgxUcmFjZUNvbnRleHQSEAoIdHJhY2VfaWQYASABKAwSDwoHc3Bhbl9pZBgCIAEoDBIPCgdzYW1wbGVkGAMgASgIIp0CCg5SdW50aW1lRmFpbHVyZRIMCgRjb2RlGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSEQoJY29tcG9uZW50GAMgASgJEhYKCXdvcmtzcGFjZRgEIAEoCUgAiAEBEhMKBmRvbWFpbhgFIAEoCUgBiAEBEhYKCWRpcmVjdGl2ZRgGIAEoCUgCiAEBEjkKCmF0dHJpYnV0ZXMYByADKAsyJS5ub21vcy5ydW50aW1lLnYyLkRpYWdub3N0aWNBdHRyaWJ1dGUSMgoEa2luZBgIIAEoDjIkLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZUZhaWx1cmVLaW5kQgwKCl93b3Jrc3BhY2VCCQoHX2RvbWFpbkIMCgpfZGlyZWN0aXZlIr4BChJSdW50aW1lVW5hdmFpbGFibGUSOgoGcmVhc29uGAEgASgOMioubm9tb3MucnVudGltZS52Mi5SdW50aW1lVW5hdmFpbGFibGVSZWFzb24SEQoJd29ya3NwYWNlGAIgASgJEhEKCXJldHJ5YWJsZRgDIAEoCBIfChJyZXRyeV9hZnRlcl9taWxsaXMYBCABKA1IAIgBARIOCgZkZXRhaWwYBSABKAlCFQoTX3JldHJ5X2FmdGVyX21pbGxpcyJ+
|
|
634
|
+
var file_nomos_runtime_v2_observability_desk = /* @__PURE__ */ fileDesc21("Cilub21vcy9ydW50aW1lL3YyL29ic2VydmFiaWxpdHlfZGVzay5wcm90bxIQbm9tb3MucnVudGltZS52MiJCCgxUcmFjZUNvbnRleHQSEAoIdHJhY2VfaWQYASABKAwSDwoHc3Bhbl9pZBgCIAEoDBIPCgdzYW1wbGVkGAMgASgIIp0CCg5SdW50aW1lRmFpbHVyZRIMCgRjb2RlGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSEQoJY29tcG9uZW50GAMgASgJEhYKCXdvcmtzcGFjZRgEIAEoCUgAiAEBEhMKBmRvbWFpbhgFIAEoCUgBiAEBEhYKCWRpcmVjdGl2ZRgGIAEoCUgCiAEBEjkKCmF0dHJpYnV0ZXMYByADKAsyJS5ub21vcy5ydW50aW1lLnYyLkRpYWdub3N0aWNBdHRyaWJ1dGUSMgoEa2luZBgIIAEoDjIkLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZUZhaWx1cmVLaW5kQgwKCl93b3Jrc3BhY2VCCQoHX2RvbWFpbkIMCgpfZGlyZWN0aXZlIr4BChJSdW50aW1lVW5hdmFpbGFibGUSOgoGcmVhc29uGAEgASgOMioubm9tb3MucnVudGltZS52Mi5SdW50aW1lVW5hdmFpbGFibGVSZWFzb24SEQoJd29ya3NwYWNlGAIgASgJEhEKCXJldHJ5YWJsZRgDIAEoCBIfChJyZXRyeV9hZnRlcl9taWxsaXMYBCABKA1IAIgBARIOCgZkZXRhaWwYBSABKAlCFQoTX3JldHJ5X2FmdGVyX21pbGxpcyJ+Cg5SdW50aW1lUmVmdXNhbBI2CgZyZWFzb24YASABKA4yJi5ub21vcy5ydW50aW1lLnYyLlJ1bnRpbWVSZWZ1c2FsUmVhc29uEhEKCXdvcmtzcGFjZRgCIAEoCRIRCglyZXRyeWFibGUYAyABKAgSDgoGZGV0YWlsGAQgASgJIqUBChNEaWFnbm9zdGljQXR0cmlidXRlEgwKBG5hbWUYASABKAkSFgoMc3RyaW5nX3ZhbHVlGAIgASgJSAASFwoNaW50ZWdlcl92YWx1ZRgDIAEoEkgAEhYKDGRvdWJsZV92YWx1ZRgEIAEoAUgAEhcKDWJvb2xlYW5fdmFsdWUYBSABKAhIABIVCgtieXRlc192YWx1ZRgGIAEoDEgAQgcKBXZhbHVlIqQLCgxSdW50aW1lRXZlbnQSEAoIc2VxdWVuY2UYASABKAQSFAoHc2Vzc2lvbhgCIAEoCUgBiAEBEi8KBXJlYWR5GAogASgLMh4ubm9tb3MucnVudGltZS52Mi5SdW50aW1lUmVhZHlIABI3Cg13YXRjaF9jaGFuZ2VkGAsgASgLMh4ubm9tb3MucnVudGltZS52Mi5XYXRjaENoYW5nZWRIABI5Cg5zeW5jX2NvbXBsZXRlZBgMIAEoCzIfLm5vbW9zLnJ1bnRpbWUudjIuU3luY0NvbXBsZXRlZEgAEjUKDGxpbmtfY2hhbmdlZBgNIAEoCzIdLm5vbW9zLnJ1bnRpbWUudjIuTGlua0NoYW5nZWRIABI5Cg5zaWduYWxfY2hhbmdlZBgOIAEoCzIfLm5vbW9zLnJ1bnRpbWUudjIuU2lnbmFsQ2hhbmdlZEgAEjsKD2N1c3RvZHlfY2hhbmdlZBgPIAEoCzIgLm5vbW9zLnJ1bnRpbWUudjIuQ3VzdG9keUNoYW5nZWRIABJCChNsb2NhbF93b3JrX3JlamVjdGVkGBAgASgLMiMubm9tb3MucnVudGltZS52Mi5Mb2NhbFdvcmtSZWplY3RlZEgAEjMKC2xhd19jaGFuZ2VkGBEgASgLMhwubm9tb3MucnVudGltZS52Mi5MYXdDaGFuZ2VkSAASQwoPa2VybmVsX3Byb2dyZXNzGBIgASgLMigubm9tb3MucnVudGltZS52Mi5LZXJuZWxQcm9ncmVzc09ic2VydmVkSAASLQoEc3BhbhgTIAEoCzIdLm5vbW9zLnJ1bnRpbWUudjIuUnVudGltZVNwYW5IABI/ChF0cmFuc2Zlcl9wcm9ncmVzcxgUIAEoCzIiLm5vbW9zLnJ1bnRpbWUudjIuVHJhbnNmZXJQcm9ncmVzc0gAEkkKFG1haW50ZW5hbmNlX3Byb2dyZXNzGBUgASgLMikubm9tb3MucnVudGltZS52Mi5SZWFkTWFpbnRlbmFuY2VQcm9ncmVzc0gAEjsKDXNvY2tldF9lZmZlY3QYFiABKAsyIi5ub21vcy5ydW50aW1lLnYyLlBlZXJTb2NrZXRFZmZlY3RIABJUChxjcmVkZW50aWFsX3JlZnJlc2hfcmVxdWVzdGVkGBcgASgLMiwubm9tb3MucnVudGltZS52Mi5DcmVkZW50aWFsUmVmcmVzaFJlcXVlc3RlZEgAElIKG3JlY2VpdmluZ19ncm91cF9jb252ZXJnZW5jZRgYIAEoCzIrLm5vbW9zLnJ1bnRpbWUudjIuUmVjZWl2aW5nR3JvdXBDb252ZXJnZW5jZUgAEkoKF21vZGVsX2Fkb3B0aW9uX3Byb2dyZXNzGBkgASgLMicubm9tb3MucnVudGltZS52Mi5Nb2RlbEFkb3B0aW9uUHJvZ3Jlc3NIABI7Cg9mb2xsb3dzX3N1bW1hcnkYGiABKAsyIC5ub21vcy5ydW50aW1lLnYyLkZvbGxvd3NTdW1tYXJ5SAASRAoUbG9jYWxfY29weV9wcmVzZXJ2ZWQYGyABKAsyJC5ub21vcy5ydW50aW1lLnYyLlByZXNlcnZlZExvY2FsQ29weUgAEk4KGWZvcmVpZ25fcGxhY2VtZW50X2lnbm9yZWQYHCABKAsyKS5ub21vcy5ydW50aW1lLnYyLkZvcmVpZ25QbGFjZW1lbnRJZ25vcmVkSAASQwoTYmluZGluZ19xdWFyYW50aW5lZBgdIAEoCzIkLm5vbW9zLnJ1bnRpbWUudjIuUXVhcmFudGluZWRCaW5kaW5nSAASPwoRd3JpdGVfcHJlcGFyYXRpb24YHiABKAsyIi5ub21vcy5ydW50aW1lLnYyLldyaXRlUHJlcGFyYXRpb25IAEIHCgVldmVudEIKCghfc2Vzc2lvbiK8AQoORm9sbG93c1N1bW1hcnkSEAoIZm9sbG93ZWQYASABKA0SDwoHc2V0dGxlZBgCIAEoDRIMCgRsaXZlGAMgASgNEjcKCndvcmtzcGFjZXMYBCADKAsyIy5ub21vcy5ydW50aW1lLnYyLkZvbGxvd09ic2VydmF0aW9uEiQKF29ic2VydmVkX2F0X3VuaXhfbWlsbGlzGAUgASgESACIAQFCGgoYX29ic2VydmVkX2F0X3VuaXhfbWlsbGlzItECChFGb2xsb3dPYnNlcnZhdGlvbhIRCgl3b3Jrc3BhY2UYASABKAkSNwoFcGhhc2UYAiABKA4yKC5ub21vcy5ydW50aW1lLnYyLkZvbGxvd09ic2VydmF0aW9uUGhhc2USDAoEbGl2ZRgDIAEoCBITCgZkZXRhaWwYBCABKAlIAIgBARIhChRyZXRyeV9hdF91bml4X21pbGxpcxgFIAEoBEgBiAEBEh8KEmR1ZV9hdF91bml4X21pbGxpcxgGIAEoBEgCiAEBEhQKB2F0dGVtcHQYByABKA1IA4gBARIaCg1hY3RpdmVfZWZmZWN0GAggASgJSASIAQFCCQoHX2RldGFpbEIXChVfcmV0cnlfYXRfdW5peF9taWxsaXNCFQoTX2R1ZV9hdF91bml4X21pbGxpc0IKCghfYXR0ZW1wdEIQCg5fYWN0aXZlX2VmZmVjdCJWChpDcmVkZW50aWFsUmVmcmVzaFJlcXVlc3RlZBI4CgdwZW5kaW5nGAEgASgLMicubm9tb3MucnVudGltZS52Mi5Db3JyZXNwb25kZW5jZVBlbmRpbmciPgoMUnVudGltZVJlYWR5EhcKD3J1bnRpbWVfdmVyc2lvbhgBIAEoCRIVCg1rZXJuZWxfc2hhMjU2GAIgASgMIvwBCgxXYXRjaENoYW5nZWQSFwoPc3Vic2NyaXB0aW9uX2lkGAEgASgJEhMKC3Jlc3VsdF91c2RhGAIgASgMEjYKB2ZhaWx1cmUYAyABKAsyIC5ub21vcy5ydW50aW1lLnYyLlJ1bnRpbWVGYWlsdXJlSACIAQESNQoSYXBwbGljYXRpb25fcmVzdWx0GAQgASgLMhQuZ29vZ2xlLnByb3RvYnVmLkFueUgBiAEBEhoKDWludGVnZXJfdmFsdWUYBSABKANIAogBAUIKCghfZmFpbHVyZUIVChNfYXBwbGljYXRpb25fcmVzdWx0QhAKDl9pbnRlZ2VyX3ZhbHVlIpwBCg1TeW5jQ29tcGxldGVkEg4KBnJlYXNvbhgBIAEoCRI3CgZyZXN1bHQYAiABKAsyJy5ub21vcy5ydW50aW1lLnYyLlN5bmNXb3Jrc3BhY2VSZXNwb25zZRI2CgdmYWlsdXJlGAMgASgLMiAubm9tb3MucnVudGltZS52Mi5SdW50aW1lRmFpbHVyZUgAiAEBQgoKCF9mYWlsdXJlIjsKC0xpbmtDaGFuZ2VkEiwKBnN0YXR1cxgBIAEoDjIcLm5vbW9zLnJ1bnRpbWUudjIuTGlua1N0YXR1cyI4Cg1TaWduYWxDaGFuZ2VkEg4KBmRvbWFpbhgBIAEoCRIXCg9wcm9qZWN0aW9uX3VzZGEYAiABKAwiUAoKTGF3Q2hhbmdlZBIOCgZkb21haW4YASABKAkSFgoOcGFja2FnZV9zaGEyNTYYAiABKAkSGgoSY29tcGF0aWJpbGl0eV91c2RhGAMgASgMIt0BCgtSdW50aW1lU3BhbhIQCgh0cmFjZV9pZBgBIAEoDBIPCgdzcGFuX2lkGAIgASgMEhsKDnBhcmVudF9zcGFuX2lkGAMgASgMSACIAQESDAoEbmFtZRgEIAEoCRIaChJzdGFydGVkX3VuaXhfbmFub3MYBSABKAQSFgoOZHVyYXRpb25fbmFub3MYBiABKAQSOQoKYXR0cmlidXRlcxgHIAMoCzIlLm5vbW9zLnJ1bnRpbWUudjIuRGlhZ25vc3RpY0F0dHJpYnV0ZUIRCg9fcGFyZW50X3NwYW5faWQi6gEKFktlcm5lbFByb2dyZXNzT2JzZXJ2ZWQSOQoIc25hcHNob3QYASABKAsyJy5ub21vcy5rZXJuZWwudjEuS2VybmVsUHJvZ3Jlc3NTbmFwc2hvdBIkChxob3N0X29ic2VydmVkX2VsYXBzZWRfbWljcm9zGAIgASgEEioKImhvc3Rfb2JzZXJ2ZWRfcGhhc2VfZWxhcHNlZF9taWNyb3MYAyABKAQSHgoWcHJvY2Vzc19yZXNpZGVudF9ieXRlcxgEIAEoBBIjChtwcm9jZXNzX3BlYWtfcmVzaWRlbnRfYnl0ZXMYBSABKAQiggEKEFRyYW5zZmVyUHJvZ3Jlc3MSFgoOcmVjZWl2ZWRfYnl0ZXMYASABKAQSGAoLdG90YWxfYnl0ZXMYAiABKARIAIgBARIsCgRraW5kGAMgASgOMh4ubm9tb3MucnVudGltZS52Mi5UcmFuc2ZlcktpbmRCDgoMX3RvdGFsX2J5dGVzIjkKEFdyaXRlUHJlcGFyYXRpb24SEgoKcmVxdWVzdF9pZBgBIAEoCRIRCgl3b3Jrc3BhY2UYAiABKAkqygEKElJ1bnRpbWVGYWlsdXJlS2luZBIkCiBSVU5USU1FX0ZBSUxVUkVfS0lORF9VTlNQRUNJRklFRBAAEiEKHVJVTlRJTUVfRkFJTFVSRV9LSU5EX0lOVEVSTkFMEAESIQodUlVOVElNRV9GQUlMVVJFX0tJTkRfUFJPVE9DT0wQAhIiCh5SVU5USU1FX0ZBSUxVUkVfS0lORF9JTlRFR1JJVFkQAxIkCiBSVU5USU1FX0ZBSUxVUkVfS0lORF9VTlNVUFBPUlRFRBAEKqcDChhSdW50aW1lVW5hdmFpbGFibGVSZWFzb24SKgomUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fVU5TUEVDSUZJRUQQABIyCi5SVU5USU1FX1VOQVZBSUxBQkxFX1JFQVNPTl9SRU1PVEVfT05MWV9PRkZMSU5FEAESMQotUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fUkVNT1RFX1VOUkVBQ0hBQkxFEAISLQopUlVOVElNRV9VTkFWQUlMQUJMRV9SRUFTT05fUkVNT1RFX1RJTUVPVVQQAxI2CjJSVU5USU1FX1VOQVZBSUxBQkxFX1JFQVNPTl9MT0NBTF9SRVBMSUNBX05PVF9SRUFEWRAEEjUKMVJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX0NSRURFTlRJQUxfVU5BVkFJTEFCTEUQBRIwCixSVU5USU1FX1VOQVZBSUxBQkxFX1JFQVNPTl9XT1JLU1BBQ0VfT1BFTklORxAGEigKJFJVTlRJTUVfVU5BVkFJTEFCTEVfUkVBU09OX1BFRVJfQlVTWRAHKvABChRSdW50aW1lUmVmdXNhbFJlYXNvbhImCiJSVU5USU1FX1JFRlVTQUxfUkVBU09OX1VOU1BFQ0lGSUVEEAASLQopUlVOVElNRV9SRUZVU0FMX1JFQVNPTl9JTlZBTElEX0NSRURFTlRJQUwQARIoCiRSVU5USU1FX1JFRlVTQUxfUkVBU09OX0FDQ0VTU19ERU5JRUQQAhIrCidSVU5USU1FX1JFRlVTQUxfUkVBU09OX1BMQUNFTUVOVF9QT0xJQ1kQAxIqCiZSVU5USU1FX1JFRlVTQUxfUkVBU09OX1NFU1NJT05fVU5CT1VORBAEKpUEChZGb2xsb3dPYnNlcnZhdGlvblBoYXNlEigKJEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9VTlNQRUNJRklFRBAAEiQKIEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9ERVNJUkVEEAESIAocRk9MTE9XX09CU0VSVkFUSU9OX1BIQVNFX0RVRRACEiQKIEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9SVU5OSU5HEAMSJAogRk9MTE9XX09CU0VSVkFUSU9OX1BIQVNFX1NFVFRMRUQQBBIwCixGT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfQVdBSVRJTkdfREVQRU5ERU5DWRAFEiQKIEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9PRkZMSU5FEAYSLworRk9MTE9XX09CU0VSVkFUSU9OX1BIQVNFX0lOVkFMSURfQ1JFREVOVElBTBAHEiQKIEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9CQUNLT0ZGEAgSLAooRk9MTE9XX09CU0VSVkFUSU9OX1BIQVNFX1JFQk9STl9SRU1PVEVMWRAJEiwKKEZPTExPV19PQlNFUlZBVElPTl9QSEFTRV9SRVBMQUNJTkdfTE9DQUwQChIyCi5GT0xMT1dfT0JTRVJWQVRJT05fUEhBU0VfTE9DQUxfQ09QWV9VTlJFQURBQkxFEAsqVwoKTGlua1N0YXR1cxIbChdMSU5LX1NUQVRVU19VTlNQRUNJRklFRBAAEhQKEExJTktfU1RBVFVTX09QRU4QARIWChJMSU5LX1NUQVRVU19DTE9TRUQQAip2CgxUcmFuc2ZlcktpbmQSHQoZVFJBTlNGRVJfS0lORF9VTlNQRUNJRklFRBAAEhcKE1RSQU5TRkVSX0tJTkRfREVMVEEQARIWChJUUkFOU0ZFUl9LSU5EX0ZVTEwQAhIWChJUUkFOU0ZFUl9LSU5EX1BVU0gQA2IGcHJvdG8z", [file_google_protobuf_any2, 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]);
|
|
635
635
|
var RuntimeFailureSchema = /* @__PURE__ */ messageDesc21(file_nomos_runtime_v2_observability_desk, 1);
|
|
636
636
|
var RuntimeUnavailableSchema = /* @__PURE__ */ messageDesc21(file_nomos_runtime_v2_observability_desk, 2);
|
|
637
637
|
var RuntimeRefusalSchema = /* @__PURE__ */ messageDesc21(file_nomos_runtime_v2_observability_desk, 3);
|
|
@@ -645,6 +645,7 @@ var WatchChangedSchema = /* @__PURE__ */ messageDesc21(file_nomos_runtime_v2_obs
|
|
|
645
645
|
var SyncCompletedSchema = /* @__PURE__ */ messageDesc21(file_nomos_runtime_v2_observability_desk, 11);
|
|
646
646
|
var LinkChangedSchema = /* @__PURE__ */ messageDesc21(file_nomos_runtime_v2_observability_desk, 12);
|
|
647
647
|
var RuntimeSpanSchema = /* @__PURE__ */ messageDesc21(file_nomos_runtime_v2_observability_desk, 15);
|
|
648
|
+
var WritePreparationSchema = /* @__PURE__ */ messageDesc21(file_nomos_runtime_v2_observability_desk, 18);
|
|
648
649
|
var RuntimeFailureKindSchema = /* @__PURE__ */ enumDesc14(file_nomos_runtime_v2_observability_desk, 0);
|
|
649
650
|
var RuntimeFailureKind = /* @__PURE__ */ tsEnum14(RuntimeFailureKindSchema);
|
|
650
651
|
var RuntimeUnavailableReasonSchema = /* @__PURE__ */ enumDesc14(file_nomos_runtime_v2_observability_desk, 1);
|
|
@@ -6707,6 +6708,17 @@ var CredentialSessions = class {
|
|
|
6707
6708
|
// ../peer-office/src/runtime/credential_recovery_desk.ts
|
|
6708
6709
|
import { create as create21, fromBinary as fromBinary13, toBinary as toBinary13 } from "@bufbuild/protobuf";
|
|
6709
6710
|
|
|
6711
|
+
// ../peer-office/src/runtime/credential_failure.ts
|
|
6712
|
+
function recoverableCredential(failure2) {
|
|
6713
|
+
return failure2.code === "nomos.auth.token_expired" || failure2.code === "nomos.auth.token_missing";
|
|
6714
|
+
}
|
|
6715
|
+
function syncNeedsCredentialRefresh(result, failure2) {
|
|
6716
|
+
if (failure2 !== void 0 && recoverableCredential(failure2)) return true;
|
|
6717
|
+
const offer = result?.offerReceipt?.outcome;
|
|
6718
|
+
const pushNeedsRefresh = offer?.case === "failure" ? recoverableCredential(offer.value) : result?.pushError?.status === 401;
|
|
6719
|
+
return pushNeedsRefresh || result?.discoveryError?.status === 401;
|
|
6720
|
+
}
|
|
6721
|
+
|
|
6710
6722
|
// ../peer-office/src/runtime/credential_renewal.ts
|
|
6711
6723
|
var RENEW_BEFORE_MILLIS = 5 * 6e4;
|
|
6712
6724
|
var BASE64URL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
@@ -6970,7 +6982,7 @@ var CredentialRecoveryDesk = class {
|
|
|
6970
6982
|
return false;
|
|
6971
6983
|
}
|
|
6972
6984
|
observeSync(session, event) {
|
|
6973
|
-
if (!syncNeedsCredentialRefresh(event) || this.#tokenless(session)) return;
|
|
6985
|
+
if (!syncNeedsCredentialRefresh(event.result, event.failure) || this.#tokenless(session)) return;
|
|
6974
6986
|
this.#prune();
|
|
6975
6987
|
const capability = this.#ports.capabilityFor(session);
|
|
6976
6988
|
const existing = this.#active.get(capability);
|
|
@@ -7172,15 +7184,6 @@ var CredentialRecoveryDesk = class {
|
|
|
7172
7184
|
this.#completed.clear();
|
|
7173
7185
|
}
|
|
7174
7186
|
};
|
|
7175
|
-
function recoverableCredential(failure2) {
|
|
7176
|
-
return failure2.code === "nomos.auth.token_expired" || failure2.code === "nomos.auth.token_missing";
|
|
7177
|
-
}
|
|
7178
|
-
function syncNeedsCredentialRefresh(event) {
|
|
7179
|
-
const failures = [event.result?.pushError, event.result?.discoveryError];
|
|
7180
|
-
if (failures.some((failure2) => failure2?.status === 401 || failure2?.status === 403)) return true;
|
|
7181
|
-
const text2 = `${event.failure?.message ?? ""} ${failures.map((failure2) => failure2?.message ?? "").join(" ")}`.toLowerCase();
|
|
7182
|
-
return text2.includes("unauthenticated") || text2.includes("token expired") || text2.includes("invalid token");
|
|
7183
|
-
}
|
|
7184
7187
|
|
|
7185
7188
|
// ../peer-office/src/runtime/device_identity_desk.ts
|
|
7186
7189
|
import { create as create22 } from "@bufbuild/protobuf";
|
|
@@ -8098,6 +8101,7 @@ var ReceivingGroupDesk = class {
|
|
|
8098
8101
|
#accounts = /* @__PURE__ */ new Map();
|
|
8099
8102
|
/** D22: device key hash → the workspaces the console reported this key enrolled in (this process's memory, not truth). */
|
|
8100
8103
|
#consoleEnrolments = /* @__PURE__ */ new Map();
|
|
8104
|
+
#preparingWrites = /* @__PURE__ */ new Map();
|
|
8101
8105
|
#sequence = 0;
|
|
8102
8106
|
#internalRequestId = 30000000000n;
|
|
8103
8107
|
constructor(ports) {
|
|
@@ -8137,16 +8141,124 @@ var ReceivingGroupDesk = class {
|
|
|
8137
8141
|
if (head === account.observedHead) return;
|
|
8138
8142
|
this.#tails.set(workspace, { ...account, inFlight: false, attempts: 0, notBefore: 0n });
|
|
8139
8143
|
}
|
|
8140
|
-
/**
|
|
8141
|
-
*
|
|
8144
|
+
/** Only a proven non-admission can enter recovery. Console-enrolled children
|
|
8145
|
+
* share the owning application's route, selected by credential capability and
|
|
8146
|
+
* principal, never by workspace-name guessing or an unverified payload. */
|
|
8142
8147
|
recoverOffer(request, response) {
|
|
8143
|
-
if (!this.#ports.call || request.command.case !== "kernelCall" || request.command.value.credentialUse !== CredentialUse.SESSION || request.command.value.request?.operation.case !== "offer" || request.command.value.request.operation.value.intent.case !== "call"
|
|
8148
|
+
if (!this.#ports.call || request.command.case !== "kernelCall" || request.command.value.credentialUse !== CredentialUse.SESSION || request.command.value.request?.operation.case !== "offer" || request.command.value.request.operation.value.intent.case !== "call") return;
|
|
8149
|
+
const missing = response.outcome.case === "failure" ? response.outcome.value.code === "nomos.authz.signer_enrollment_missing" : response.outcome.case === "offer" && response.outcome.value.outcome.case === "refused" && response.outcome.value.outcome.value.refusal?.code === KernelRefusalCode.FORGED_PRINCIPAL && response.outcome.value.outcome.value.refusal.details?.fields.actor?.kind.case === "text" && response.outcome.value.outcome.value.refusal.details.fields.actor.kind.value === "unenrolled-signer-key";
|
|
8150
|
+
const revoked = response.outcome.case === "failure" && response.outcome.value.code === "nomos.authz.device_key_revoked";
|
|
8151
|
+
if (!missing && !revoked) return;
|
|
8144
8152
|
const binding = this.#ports.binding(request.command.value.session);
|
|
8145
|
-
|
|
8146
|
-
|
|
8153
|
+
if (!binding) return;
|
|
8154
|
+
const enrolled = [...this.#accounts.values()].find((account2) => {
|
|
8155
|
+
const owner = this.#ports.binding(account2.session);
|
|
8156
|
+
return account2.enrolment && owner?.credentialCapability === binding.credentialCapability && owner.principal === binding.principal;
|
|
8157
|
+
});
|
|
8147
8158
|
const copy3 = fromBinary18(RuntimeRequestSchema, toBinary16(RuntimeRequestSchema, request));
|
|
8159
|
+
if (enrolled?.enrolment) {
|
|
8160
|
+
if (revoked) return this.#writeRefused(binding.workspace, "This device's access has been revoked.");
|
|
8161
|
+
return this.#begin(request, `enrolled-write-${++this.#sequence}`, (workId2) => this.#prepareEnrolledWrite(copy3, binding, enrolled.application, enrolled.enrolment, workId2));
|
|
8162
|
+
}
|
|
8163
|
+
const account = this.#accounts.get(binding.workspace);
|
|
8164
|
+
if (!account) return;
|
|
8148
8165
|
return this.#begin(request, `receiving-group-authoring-${++this.#sequence}`, (workId2) => this.#recoverOffer(copy3, response, account, workId2));
|
|
8149
8166
|
}
|
|
8167
|
+
#writeRefused(workspace, detail, reason = RuntimeRefusalReason.ACCESS_DENIED) {
|
|
8168
|
+
return { case: "refused", value: create28(RuntimeRefusalSchema, {
|
|
8169
|
+
reason,
|
|
8170
|
+
workspace,
|
|
8171
|
+
retryable: false,
|
|
8172
|
+
detail
|
|
8173
|
+
}) };
|
|
8174
|
+
}
|
|
8175
|
+
#writeWaiting(workspace, detail) {
|
|
8176
|
+
return { case: "unavailable", value: create28(RuntimeUnavailableSchema, {
|
|
8177
|
+
reason: RuntimeUnavailableReason.CREDENTIAL_UNAVAILABLE,
|
|
8178
|
+
workspace,
|
|
8179
|
+
retryable: true,
|
|
8180
|
+
retryAfterMillis: 1e3,
|
|
8181
|
+
detail
|
|
8182
|
+
}) };
|
|
8183
|
+
}
|
|
8184
|
+
*#prepareEnrolledWrite(request, binding, application, route, workId2) {
|
|
8185
|
+
if (request.command.case !== "kernelCall") throw new Error("write preparation lost its call");
|
|
8186
|
+
const command = request.command.value;
|
|
8187
|
+
const principal = binding.principal;
|
|
8188
|
+
const unavailable = () => this.#writeWaiting(
|
|
8189
|
+
binding.workspace,
|
|
8190
|
+
"This device is still being prepared to save changes. Your change has not been saved. Try again when connected."
|
|
8191
|
+
);
|
|
8192
|
+
this.#ports.emit(binding.session, { case: "writePreparation", value: create28(WritePreparationSchema, {
|
|
8193
|
+
requestId: command.request.requestId,
|
|
8194
|
+
workspace: binding.workspace
|
|
8195
|
+
}) });
|
|
8196
|
+
const key = JSON.stringify([binding.credentialCapability, principal, binding.workspace]);
|
|
8197
|
+
const shared = this.#preparingWrites.get(key);
|
|
8198
|
+
const deadline = this.#ports.clock.monotonicNanoseconds() + 30000000000n;
|
|
8199
|
+
let wake = 0;
|
|
8200
|
+
if (shared) {
|
|
8201
|
+
while (!shared.settled) {
|
|
8202
|
+
if (this.#ports.clock.monotonicNanoseconds() >= deadline) return unavailable();
|
|
8203
|
+
const receipt = yield { case: "wake", value: create28(PeerWakeEffectSchema, {
|
|
8204
|
+
effectId: `${workId2}:join-${++wake}`,
|
|
8205
|
+
delayMillis: 250
|
|
8206
|
+
}) };
|
|
8207
|
+
if (receipt.outcome.case !== "woken") return unavailable();
|
|
8208
|
+
}
|
|
8209
|
+
if (shared.result) return shared.result;
|
|
8210
|
+
} else {
|
|
8211
|
+
const preparation = { settled: false };
|
|
8212
|
+
this.#preparingWrites.set(key, preparation);
|
|
8213
|
+
try {
|
|
8214
|
+
const secret = this.#ports.authorSecretIfPresent(binding.session);
|
|
8215
|
+
if (!secret) return preparation.result = this.#writeRefused(binding.workspace, "Sign in again to set up this device.", RuntimeRefusalReason.INVALID_CREDENTIAL);
|
|
8216
|
+
const keyHash = sha256Hex(this.#ports.deriveSigningPublicKey(secret));
|
|
8217
|
+
let posture = this.#ports.posture(request, binding.session, principal, secret, false);
|
|
8218
|
+
if (posture.deviceSignerStatus === DeviceSignerStatus.REVOKED) {
|
|
8219
|
+
return preparation.result = this.#writeRefused(binding.workspace, "This device's access has been revoked.");
|
|
8220
|
+
}
|
|
8221
|
+
if (!posture.enrolledDevice || posture.deviceSignerStatus !== DeviceSignerStatus.ACTIVE) {
|
|
8222
|
+
const enrolled = yield* this.#enrolAtConsole(
|
|
8223
|
+
route,
|
|
8224
|
+
binding,
|
|
8225
|
+
`${application}|${principal}`,
|
|
8226
|
+
principal,
|
|
8227
|
+
keyHash,
|
|
8228
|
+
[binding.workspace],
|
|
8229
|
+
`${workId2}:console`
|
|
8230
|
+
);
|
|
8231
|
+
if (enrolled.case === "deferred") return preparation.result = enrolled.credentialRefused ? this.#writeRefused(binding.workspace, "Sign in again to set up this device.", RuntimeRefusalReason.INVALID_CREDENTIAL) : unavailable();
|
|
8232
|
+
if (!(binding.workspace in enrolled.value.heads)) {
|
|
8233
|
+
return preparation.result = this.#writeRefused(binding.workspace, "This device could not obtain access to save changes in this workspace.");
|
|
8234
|
+
}
|
|
8235
|
+
while (true) {
|
|
8236
|
+
posture = this.#ports.posture(request, binding.session, principal, secret, false);
|
|
8237
|
+
if (posture.deviceSignerStatus === DeviceSignerStatus.REVOKED) {
|
|
8238
|
+
return preparation.result = this.#writeRefused(binding.workspace, "This device's access has been revoked.");
|
|
8239
|
+
}
|
|
8240
|
+
if (posture.enrolledDevice && posture.deviceSignerStatus === DeviceSignerStatus.ACTIVE) break;
|
|
8241
|
+
if (this.#ports.clock.monotonicNanoseconds() >= deadline) return preparation.result = unavailable();
|
|
8242
|
+
const receipt = yield { case: "wake", value: create28(PeerWakeEffectSchema, {
|
|
8243
|
+
effectId: `${workId2}:observe-${++wake}`,
|
|
8244
|
+
delayMillis: 500
|
|
8245
|
+
}) };
|
|
8246
|
+
if (receipt.outcome.case !== "woken") return preparation.result = unavailable();
|
|
8247
|
+
}
|
|
8248
|
+
}
|
|
8249
|
+
} catch (error) {
|
|
8250
|
+
if (error instanceof ReceivingGroupRefusal) {
|
|
8251
|
+
return preparation.result = this.#writeRefused(binding.workspace, "This device could not obtain access to save changes in this workspace.");
|
|
8252
|
+
}
|
|
8253
|
+
preparation.result = unavailable();
|
|
8254
|
+
throw error;
|
|
8255
|
+
} finally {
|
|
8256
|
+
preparation.settled = true;
|
|
8257
|
+
this.#preparingWrites.delete(key);
|
|
8258
|
+
}
|
|
8259
|
+
}
|
|
8260
|
+
return { case: "retried", request, response: this.#ports.call(request, command) };
|
|
8261
|
+
}
|
|
8150
8262
|
*#recoverOffer(request, response, account, workId2) {
|
|
8151
8263
|
const workspace = this.#ports.binding(account.session).workspace;
|
|
8152
8264
|
const deadline = this.#ports.clock.monotonicNanoseconds() + 60000000000n;
|
|
@@ -8214,6 +8326,7 @@ var ReceivingGroupDesk = class {
|
|
|
8214
8326
|
this.#opening.clear();
|
|
8215
8327
|
this.#accounts.clear();
|
|
8216
8328
|
this.#consoleEnrolments.clear();
|
|
8329
|
+
this.#preparingWrites.clear();
|
|
8217
8330
|
}
|
|
8218
8331
|
#begin(request, workId2, procedure) {
|
|
8219
8332
|
const held = {
|
|
@@ -12161,12 +12274,12 @@ var ReplicaFollowController = class {
|
|
|
12161
12274
|
this.#desk.transition(result.workspace, { case: ReplicaFollowEventKind.WentOffline, nowUnixMillis });
|
|
12162
12275
|
return delayUntilDue(this.#desk.get(result.workspace), nowUnixMillis);
|
|
12163
12276
|
}
|
|
12164
|
-
|
|
12165
|
-
|
|
12277
|
+
if (syncNeedsCredentialRefresh(result)) {
|
|
12278
|
+
const offer = result.offerReceipt?.outcome;
|
|
12166
12279
|
const transition = this.#desk.transition(result.workspace, {
|
|
12167
12280
|
case: ReplicaFollowEventKind.CredentialRejected,
|
|
12168
12281
|
nowUnixMillis,
|
|
12169
|
-
failure:
|
|
12282
|
+
failure: (offer?.case === "failure" ? offer.value.message : void 0) || result.pushError?.message || result.discoveryError?.message || "remote requires a refreshed credential"
|
|
12170
12283
|
});
|
|
12171
12284
|
if (transition.effects.some((effect) => effect.case === ReplicaFollowEffectKind.RefreshCredential)) {
|
|
12172
12285
|
return 0;
|
|
@@ -14249,7 +14362,6 @@ var WorkspaceSyncPhase = Object.freeze({
|
|
|
14249
14362
|
Done: "done"
|
|
14250
14363
|
});
|
|
14251
14364
|
var trackedMain = "refs/remotes/nomos/main";
|
|
14252
|
-
var NO_COMMON_BASE = "this replica holds local history with no frontier its upstream ever confirmed; convergence needs a common admitted base \u2014 drop the local copy to refetch it, or re-discover a provider holding this lineage";
|
|
14253
14365
|
var deferredRemote = "refs/remotes/nomos/deferred";
|
|
14254
14366
|
var deferredLocal = "refs/nomos/sync-deferred-local";
|
|
14255
14367
|
var judgedThisLifetime = /* @__PURE__ */ new Map();
|
|
@@ -14460,38 +14572,13 @@ var WorkspaceSyncWork = class {
|
|
|
14460
14572
|
}), { case: "awaiting", requestId });
|
|
14461
14573
|
}
|
|
14462
14574
|
/**
|
|
14463
|
-
*
|
|
14464
|
-
*
|
|
14465
|
-
*
|
|
14466
|
-
*
|
|
14467
|
-
* state ("a non-empty live ledger requires a common admitted base"), so every step after the
|
|
14468
|
-
* O(1) frontier probe is wasted work — and it is not cheap waste: the fetch negotiates with
|
|
14469
|
-
* no `have` (a full-history pack), and the dependency planner decodes EVERY intent from
|
|
14470
|
-
* genesis and inspects every change, once per round. That is O(history) per follow round,
|
|
14471
|
-
* repeated at every retry, for a round that can only end in a refusal.
|
|
14472
|
-
*
|
|
14473
|
-
* The one base this round can establish costs nothing and is established before this is
|
|
14474
|
-
* asked: an upstream holding exactly this replica's head (the probe's answer) converges it
|
|
14475
|
-
* and records the tracking frontier. Anything else needs the local copy to be dropped and
|
|
14476
|
-
* refetched (an application decision, which preserves the copy), or a re-discovery that
|
|
14477
|
-
* names a provider holding this lineage. Both are reported, at O(1), as this failure.
|
|
14478
|
-
*/
|
|
14479
|
-
/**
|
|
14480
|
-
* Establish this round's base when none is tracked, without walking any history it can avoid.
|
|
14481
|
-
*
|
|
14482
|
-
* The upstream just named its own frontier. If that commit is in THIS replica's lineage, it is
|
|
14483
|
-
* a common admitted base by definition — both sides hold it — and adopting it turns the round
|
|
14484
|
-
* into an ordinary fast-forward: the offer carries only the suffix above it, the fetch can name
|
|
14485
|
-
* it as a truthful `have`, and convergence has the base the kernel requires. One commit walk
|
|
14486
|
-
* (no change decoding, no pack, no network) decides it.
|
|
14487
|
-
*
|
|
14488
|
-
* If it is not in this replica's lineage, no base exists to establish and the round is refused
|
|
14489
|
-
* (#noCommonBase) before it leases, fetches or plans anything.
|
|
14490
|
-
*
|
|
14491
|
-
* A kernel without the commit walk cannot be asked, so it keeps the previous behaviour.
|
|
14575
|
+
* Establish a cheap base when the provider's current tip is in our local chain.
|
|
14576
|
+
* A negative answer means the base is unknown: both sides may have advanced from
|
|
14577
|
+
* an earlier shared commit. Acquire the candidate and let the kernel discover
|
|
14578
|
+
* and judge that history. A tracking bookmark is not an admission prerequisite.
|
|
14492
14579
|
*/
|
|
14493
14580
|
#establishBase(upstreamHead) {
|
|
14494
|
-
if (!this.#
|
|
14581
|
+
if (!this.#missingTrackedBase() || !this.#kernel.historySummary) return true;
|
|
14495
14582
|
const summary = this.#kernel.historySummary(this.#mount, this.#requestId, upstreamHead, this.#localHead);
|
|
14496
14583
|
if (!summary.reachedBase) return false;
|
|
14497
14584
|
this.#previousHead = upstreamHead;
|
|
@@ -14506,26 +14593,9 @@ var WorkspaceSyncWork = class {
|
|
|
14506
14593
|
get establishedBase() {
|
|
14507
14594
|
return this.#establishedBase;
|
|
14508
14595
|
}
|
|
14509
|
-
#
|
|
14596
|
+
#missingTrackedBase() {
|
|
14510
14597
|
return this.#previousHead === void 0 && this.#localHead !== void 0 && this.#replaceLocalHead === void 0;
|
|
14511
14598
|
}
|
|
14512
|
-
#noCommonBaseResult() {
|
|
14513
|
-
return this.#finish(create59(SyncWorkspaceResponseSchema, {
|
|
14514
|
-
workspace: this.#mount.workspace,
|
|
14515
|
-
...this.#localHead === void 0 ? {} : { currentHead: this.#localHead },
|
|
14516
|
-
stillAhead: true,
|
|
14517
|
-
...this.#offerReceipt === void 0 ? {} : { offerReceipt: this.#offerReceipt },
|
|
14518
|
-
pushError: create59(RuntimeTransportFailureSchema, {
|
|
14519
|
-
endpoint: this.#offerEndpoint(),
|
|
14520
|
-
status: 409,
|
|
14521
|
-
refused: true,
|
|
14522
|
-
message: NO_COMMON_BASE
|
|
14523
|
-
}),
|
|
14524
|
-
timings: create59(SyncPhaseTimingsSchema, {
|
|
14525
|
-
convergeMillis: elapsedMillis(this.#clock, this.#started)
|
|
14526
|
-
})
|
|
14527
|
-
}));
|
|
14528
|
-
}
|
|
14529
14599
|
#holdsLocalWork() {
|
|
14530
14600
|
return this.#command.admit && !!this.#localHead && this.#localHead !== this.#previousHead;
|
|
14531
14601
|
}
|
|
@@ -14677,7 +14747,6 @@ var WorkspaceSyncWork = class {
|
|
|
14677
14747
|
if (!this.#desiredHead) return this.#transportFailure("resident peer returned no admitted frontier", false);
|
|
14678
14748
|
this.#candidateDurable = admission.sealedMain === this.#desiredHead;
|
|
14679
14749
|
if (state.phase === WorkspaceSyncPhase.Probe && this.#desiredHead !== this.#localHead) {
|
|
14680
|
-
if (!this.#establishBase(this.#desiredHead)) return this.#noCommonBaseResult();
|
|
14681
14750
|
if (this.#alreadyJudged(this.#desiredHead)) {
|
|
14682
14751
|
return this.#finish(create59(SyncWorkspaceResponseSchema, {
|
|
14683
14752
|
workspace: this.#mount.workspace,
|
|
@@ -14689,6 +14758,22 @@ var WorkspaceSyncWork = class {
|
|
|
14689
14758
|
offerReceipt: this.#offerReceipt
|
|
14690
14759
|
}));
|
|
14691
14760
|
}
|
|
14761
|
+
if (!this.#establishBase(this.#desiredHead)) {
|
|
14762
|
+
this.#offerAfterConverge = this.#command.admit;
|
|
14763
|
+
this.#rebaseFrom = void 0;
|
|
14764
|
+
return this.#leaseEffect();
|
|
14765
|
+
}
|
|
14766
|
+
if (this.#establishedBase && !this.#candidateDurable && this.#kernel.resolveRef(this.#mount, this.#requestId, trackedMain) === void 0) {
|
|
14767
|
+
return this.#finish(create59(SyncWorkspaceResponseSchema, {
|
|
14768
|
+
workspace: this.#mount.workspace,
|
|
14769
|
+
currentHead: this.#localHead,
|
|
14770
|
+
previousHead: this.#previousHead,
|
|
14771
|
+
stillAhead: true,
|
|
14772
|
+
directOfferDeferred: true,
|
|
14773
|
+
reconnectRequired: false,
|
|
14774
|
+
offerReceipt: this.#offerReceipt
|
|
14775
|
+
}));
|
|
14776
|
+
}
|
|
14692
14777
|
if (this.#probeOnly) {
|
|
14693
14778
|
this.#needsReconciliation = true;
|
|
14694
14779
|
return this.#finish(create59(SyncWorkspaceResponseSchema, {
|
|
@@ -14734,7 +14819,7 @@ var WorkspaceSyncWork = class {
|
|
|
14734
14819
|
return this.#converge(this.#desiredHead, admission.resultPack.byteLength, 0);
|
|
14735
14820
|
}
|
|
14736
14821
|
if (this.#desiredHead === this.#previousHead) return this.#converge(this.#desiredHead, 0, 0);
|
|
14737
|
-
|
|
14822
|
+
this.#establishBase(this.#desiredHead);
|
|
14738
14823
|
if (admission.recoveryRequired !== false) return this.#leaseEffect();
|
|
14739
14824
|
return this.#transportFailure("resident peer supplied neither the missing delta nor a history gap", false);
|
|
14740
14825
|
}
|
|
@@ -14957,7 +15042,7 @@ var WorkspaceSyncWork = class {
|
|
|
14957
15042
|
}
|
|
14958
15043
|
}
|
|
14959
15044
|
#converge(candidateHead, receivedBytes, prefetchMillis) {
|
|
14960
|
-
|
|
15045
|
+
this.#establishBase(candidateHead);
|
|
14961
15046
|
this.#beforeConverge?.(candidateHead, this.#previousHead);
|
|
14962
15047
|
const convergeStarted = this.#clock.monotonicNanoseconds();
|
|
14963
15048
|
let judged;
|
|
@@ -17402,13 +17487,21 @@ var CorrespondenceDesk = class {
|
|
|
17402
17487
|
}
|
|
17403
17488
|
#observeSyncResult(requestId, workId2, result) {
|
|
17404
17489
|
const timings = result.timings;
|
|
17490
|
+
const receipt = result.offerReceipt?.outcome;
|
|
17491
|
+
const admission = receipt?.case === "admission" ? receipt.value : void 0;
|
|
17405
17492
|
this.#events.instant("peer.follow.sync-result", {
|
|
17406
17493
|
request: create64(RuntimeRequestSchema, { protocolVersion: 2, requestId }),
|
|
17407
17494
|
workspace: result.workspace
|
|
17408
17495
|
}, {
|
|
17409
17496
|
"sync.workId": workId2,
|
|
17410
17497
|
...result.currentHead ? { "sync.head": result.currentHead } : {},
|
|
17498
|
+
...result.previousHead ? { "sync.previousHead": result.previousHead } : {},
|
|
17499
|
+
...admission?.main ? { "sync.providerHead": admission.main } : {},
|
|
17500
|
+
...admission?.sealedMain ? { "sync.sealedHead": admission.sealedMain } : {},
|
|
17411
17501
|
"sync.stillAhead": result.stillAhead,
|
|
17502
|
+
"sync.reconnectRequired": result.reconnectRequired,
|
|
17503
|
+
"sync.refused": result.refused,
|
|
17504
|
+
"sync.deferred": result.deferred,
|
|
17412
17505
|
"sync.directOfferDeferred": result.directOfferDeferred,
|
|
17413
17506
|
"sync.offline": result.offline,
|
|
17414
17507
|
...timings ? {
|
|
@@ -20494,6 +20587,7 @@ var PeerOffice = class {
|
|
|
20494
20587
|
return this.#responses.modelAdoption(request, step);
|
|
20495
20588
|
}
|
|
20496
20589
|
#receivingGroupResponse(request, step) {
|
|
20590
|
+
if (step.case === "refused") return this.#response(request, { case: "refused", value: step.value });
|
|
20497
20591
|
if (step.case === "retried") return this.#birthCustodyResponse(step.request, this.#birthCustody.afterKernelCall(step.request, step.response));
|
|
20498
20592
|
if (step.case === "pending") return this.#response(request, { case: "correspondencePending", value: step.value });
|
|
20499
20593
|
if (step.case === "failure") return this.#failure(request, step.code, step.message);
|