@githolon/runtime 0.110.0 → 0.111.0

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.
@@ -34,6 +34,7 @@
34
34
  1963a804a9cfe7d44a76b2c476817639b939d7e93828da865cab40fe9ba536fa adapter/custody-transport.ts
35
35
  1a5d9fd32360e2cec4adbee9e56221fb26def66bb9d122e0b5745cebc963d92e node_modules/xml-naming/src/index.js
36
36
  1b27a1f4d58d6314cd4887d0f47493d1a98fc474e3364388f321c3aeb94a8ac3 adapter/workspace_effect_outcome.ts
37
+ 1b8eea8acf14374c28330cb21eea0e14f151fffb7c678f8e4a7f34722dc2eb22 peer-office/src/runtime/workspace_sync.ts
37
38
  1c0bba78daf8c28ac51f35d60b2b2fbca9c57bc7bcdb05a05a1f15a2ca657164 peer-office/src/reception/application_readiness_transport.ts
38
39
  1c364712aa61711ce0e654ed81e26fe821e8f7b6dac9c31fe6d49fc184dbacd2 node_modules/@bufbuild/protobuf/dist/esm/wire/size-delimited.js
39
40
  1d1f03bc86ea3788b57b43c7720de2c41a7b133d852262a7615b3b152777cdef node_modules/@bufbuild/protobuf/dist/esm/reflect/nested-types.js
@@ -66,6 +67,7 @@
66
67
  33917d22c20458fce8ef7e3a4fca8f51af8ace4508e6a435870b3ad61ea2eab4 peer-office/src/git_read_lease.ts
67
68
  33e7d6bdd22396057d3f8db92384079f7ec2fda4b3582709de2d43fccacc4a9c node_modules/@bufbuild/protobuf/dist/esm/codegenv2/extension.js
68
69
  34f8712de2bd30a2cb8366d8cfdcde466d979f1a28ac0d78f7547341b01f6c57 adapter/proto/nomos/kernel/v1/progress_pb.js
70
+ 357485877b38fa0a70a2741a46f49f57c784300a53d7301b140cb3aded6e46b5 peer-office/package/package.json
69
71
  3a90933569db7e42ec2ed3b77509c29d1ab75f6eb078f53fe5d1ac6d239d231e peer-office/src/runtime/peer_background_scheduler.ts
70
72
  3c092b8d4185badd23ecf4552434d05aa541b0cd0d534781d687db55260d5da8 adapter/proto/nomos/runtime/v2/sealing_desk_pb.js
71
73
  3c98fa838c05abcfd8dfda1128f2d1fca9b196a371fe9751abbd8f4c3b9d04ec node_modules/@bufbuild/protobuf/dist/esm/wkt/timestamp.js
@@ -93,7 +95,6 @@
93
95
  4de8a60302e6ab22ef5607ee88ab6dd6559221fb8620780fb874a1dcf3000d06 node_modules/is-unsafe/src/contexts/sql.js
94
96
  4f177e43f1ac36dc25b2b6a44970c97918091416bd15722b65ac938256bda687 node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js
95
97
  4f7192626ff16f10e8845dccfce280cfde437dd6faa78d62700e3b21d589ca97 peer-office/src/reception/extremum_read.ts
96
- 4f72a4a85c36309d7d40c387ac6e177ac3f72a7f1227a1a6b92a587dbba1169c peer-office/src/runtime/replica_follow_controller.ts
97
98
  4ff429ac40686adccd2a9ad77e9d12402da95e5396971a9df6e0f3cfa23ff3e7 platform-shells/node/certification_seal.ts
98
99
  501bf6549e9c44a4dbdea0f7a89d567c9b7e7db145b25ec7c8a38e2b4b7a87f2 adapter/custody_retention_refs.ts
99
100
  50e504430270aecdea3794d30f17911099946f38eee258b5837967cb989abd93 node_modules/@bufbuild/protobuf/dist/esm/codegenv2/enum.js
@@ -101,7 +102,6 @@
101
102
  513a0ca639e4d5cbb6ecce90f9668ab63f5e8ce4df2468b1ad439112b903ef0a platform-shells/node/local-development/kernel_work_recovery.ts
102
103
  519afa7759c5cce91b66cd6b1444014ead77df1f691d0eee356b14206d32d59e peer-office/src/runtime/workspace_call_binding.ts
103
104
  5295c7fdcb8d70cadc057dcd7b1efda4535dfae93f1a601b304245fdf8adb5ab peer-office/src/peer_office.ts
104
- 5521fba42530e15bdba2f5a67e7e3c03d0e753c6d70c8834071a6b8832fda007 peer-office/src/runtime/correspondence_desk.ts
105
105
  56e2ac380c2d9be43647d88928727c17df70a3e734834a5be62c8bcb18616738 adapter/proto/nomos/runtime/v2/custody_desk_pb.js
106
106
  57677b7b20768a3bd6eb50fdff229852be7f9978e5988924d2c935ba934366d4 adapter/proto/nomos/discovery/v1/workspace_placement_pb.js
107
107
  587bee5d27b6dbc99d24f472ea93028659610c3496be7d667e72483483c3f3ba node_modules/fast-xml-parser/src/fxp.js
@@ -124,7 +124,6 @@
124
124
  6eb1b52bfa2c7eb3e36b6817973defd7be18dbc7ce4b56ca576b1222dd5df4d7 node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js
125
125
  6ec9654705968f0c75cb0b184d4bb6629a932c05e3d27d603eb42a3cb9447f6f node_modules/@bufbuild/protobuf/dist/esm/reflect/error.js
126
126
  6fc7191c83f8c3318f656463bab0700d9585aa42a7285c364ee73c9829b488d5 peer-office/src/runtime/live_correspondence_desk.ts
127
- 709b5a7e68558438cdf1e4d11ea458b360e6190572c42219c5b9165533d4fb78 peer-office/src/runtime/workspace_sync.ts
128
127
  70f2527a9fde5075b760e0f2b36c5aced16a44d7ba3767f6f00b249fd81e91ec peer-office/src/runtime/kernel_port.ts
129
128
  711039a2d590af0e112a32c7bc50eb77e5fac6336e56e8eb01cc74df23a2cd44 adapter/git_custody_desk.ts
130
129
  71de64c0b205eed7bcbbe11bd937a363c83cb5ab8e9977c4bb4b73b3c5353cf3 peer-office/src/runtime/placement_discovery_desk.ts
@@ -134,7 +133,6 @@
134
133
  72f4dbde9d104ea96276198f8fab8b32e1a296d7ae57b74f8f175472627c2546 peer-office/src/runtime/custody_return_delta.ts
135
134
  73e489001027c703bc0224ae73f78ecefe028e88284bd06952e8603c3d81472c node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/api_pb.js
136
135
  74b1e9405ec5b38e957cf85fb9f73885ab485db853a8b0f95200afa42c5921f8 peer-office/src/runtime/model_adoption_desk.ts
137
- 74f630102656bb2cb326296d4a19343ad5fdfa7949696be26110f318abf7b2ff peer-office/package/package.json
138
136
  75ba818bf766331dc4abe3c488f65562968684934b57eb21e6e777c358c561ae peer-office/package/src/remote_reception.ts
139
137
  77a917d8c6427a9b7d819d4941ec6aeecc079ccb9b1a05c0dc1190680b589f78 platform-shells/node/stdio/entry.ts
140
138
  799c15bd106543d60c5422eeda102396a055397f20866c27504598b68d1d288d node_modules/@bufbuild/protobuf/dist/esm/wire/binary-encoding.js
@@ -172,17 +170,18 @@
172
170
  94a3cef0f355a9a177661748d24faae32206a5cc382c8601a34dcf005340107b node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js
173
171
  95ad7c933403a0c8f7fd3e2df6c4df3008c29911d3d5db063a90460a14144da2 peer-office/src/runtime/records_desk.ts
174
172
  95dbcb2580ed30cb11222c773163c6a906a7e363c5ec4263bd39c1f3a7a16cc2 node_modules/@bufbuild/protobuf/dist/esm/from-json.js
173
+ 9633e84964edf9d8e2f719766c002cabe341e5e805e729ae7ea8fa9ec4c95410 peer-office/src/runtime/correspondence_desk.ts
175
174
  96cb2eb563ccb18dc23fd9f8fb0f65193a1b90f39758a561eed747368ead00b3 node_modules/@bufbuild/protobuf/dist/esm/wkt/index.js
176
175
  96ec5d127a4e8cd77bdc678422f0d57c8ff9e37bcec999983da71a7b72ce9a0e node_modules/@nodable/entities/src/entities.js
177
176
  98f5abf9a7fb522aab513ef3831dd9c5837cebcb38a960cb546ffd084926d746 node_modules/@bufbuild/protobuf/dist/esm/wkt/gen/google/protobuf/empty_pb.js
178
177
  98f70a85fe9d2578c977bbf26927910479cef472100b5ed7bebd4c390e79213c peer-office/src/runtime/workspace_access_desk.ts
179
- 99be7abab3e81c69c2c2919768779742f2ba5ec07befa4abf18a2907fa1c3d0a peer-office/src/runtime/custody_offer.ts
180
178
  99ce0b71dc7acc73e48634ff609eeb3620cf24b524e89835e804d37fb6b51b2c adapter/offer_transport_contract.ts
181
179
  9a3d4c2296b0139778c8f61319349eac6dc0cdb723688f41ebf3c135dca85702 peer-office/src/runtime/history_acquisition_state.ts
182
180
  9b1e46d587a9ad5d1531a5755ba4feccd2878de77749edce8a0086db3eb2217d peer-office/src/runtime/admission_durability_desk.ts
183
181
  9c4c967ea6c149011acb8aabfbadb73651f84d572335c48391d627e5283c0cd0 node_modules/@bufbuild/protobuf/dist/esm/fields.js
184
182
  9e1bf39540fd14df32aa2307c44dd4d93a40a6024199f334ccf3db001f44a7f6 peer-office/src/runtime/local_copy_readability.ts
185
183
  9e82e1fc1bfd3e3573f64349dc42b4b624ed61d24e5c553f2bb4d041444f166c node_modules/@bjorn3/browser_wasi_shim/dist/fd.js
184
+ 9efa0e5824cc0370ea3596b30cd57ea860df0bae95a0caccbbfe97d845a7a09b peer-office/src/runtime/custody_offer.ts
186
185
  9f7a3b2bb0e2a2da849fd9101228bd9c9682b39d667e20900dd172d954b1a548 peer-office/src/runtime/observability_desk.ts
187
186
  a0eca2694871be026546039e99a71291822d01ba81943d44e69a14b2d766fd1a peer-office/src/runtime/custody_desk.ts
188
187
  a0fcc6110f1154fd197a8ce056e2008dbc7d1750f8dd3ba77c3910af928ed3a1 node_modules/uri-js/dist/es5/uri.all.js
@@ -258,6 +257,7 @@ dd9f3f24fb154cfbfbde94e8f2647647c80c8ca050b98e981a407e760a4b9c1e node_modules/@
258
257
  deaa25227d669aa3fbe99174275588dcc175de648ae6623fddf11d6ae69d7f67 platform-shells/node/local-development/peer_process.ts
259
258
  e20a132033f105a29db1cfdb3d85bbadbb7206b9a7e3336bcb030a63d66b4ab2 node_modules/is-unsafe/src/contexts/nosql.js
260
259
  e2133d7e0f0ce5491a3e9bd560e9e47db2243a6a9f762be89c82e027d99d278e peer-office/src/runtime/credential_sessions.ts
260
+ e24433e22af52db25858865dfff3c6ed1e6932f3257ae242a795acbedda70303 peer-office/src/runtime/replica_follow_controller.ts
261
261
  e2d341fc536c47a45d2e45fc1df232094b4afe67281b92eae91ed9b7698c32ff platform-shells/browser/entry.ts
262
262
  e34016b82b6f6e4c4a1cc2dd44ccd14a348e8156a1f6c5aeeb2c7fc36a15b8f9 adapter/proto/nomos/kernel/v1/kernel_pb.js
263
263
  e34016b82b6f6e4c4a1cc2dd44ccd14a348e8156a1f6c5aeeb2c7fc36a15b8f9 peer-office/package/src/protocol/nomos/kernel/v1/kernel_pb.js
@@ -14173,6 +14173,15 @@ var NomosRuntimeComponent = (() => {
14173
14173
  }
14174
14174
  if (result.stillAhead || result.pushFailed || result.directOfferDeferred || result.reconnectRequired) {
14175
14175
  if (result.directOfferDeferred) {
14176
+ if (!result.reconnectRequired) {
14177
+ this.#desk.transition(result.workspace, {
14178
+ case: ReplicaFollowEventKind.Failed,
14179
+ nowUnixMillis,
14180
+ failure: "remote workspace opening; retrying",
14181
+ retryWithinMillis: 5e3
14182
+ });
14183
+ return delayUntilDue(this.#desk.get(result.workspace), nowUnixMillis);
14184
+ }
14176
14185
  this.#desk.transition(result.workspace, {
14177
14186
  case: ReplicaFollowEventKind.DependencyDeferred,
14178
14187
  nowUnixMillis,
@@ -16051,6 +16060,34 @@ var NomosRuntimeComponent = (() => {
16051
16060
  // ../src/runtime/custody_offer.ts
16052
16061
  var CUSTODY_OFFER_MEDIA_TYPE = "application/vnd.nomos.custody-offer-batch+protobuf";
16053
16062
  var CUSTODY_OFFER_RESULT_MEDIA_TYPE = "application/vnd.nomos.custody-offer-result+protobuf";
16063
+ function settleCustodyOfferExchange(awaiting, response) {
16064
+ if (response.status === 202 && response.contentType?.includes("application/json")) {
16065
+ try {
16066
+ const pending = JSON.parse(new TextDecoder().decode(response.body));
16067
+ if (pending?.retryable === true && typeof pending.preparing === "string") {
16068
+ return { case: "maintenance", kind: pending.preparing };
16069
+ }
16070
+ } catch {
16071
+ }
16072
+ }
16073
+ if (!response.contentType?.includes(CUSTODY_OFFER_RESULT_MEDIA_TYPE)) {
16074
+ return {
16075
+ case: "unexpected",
16076
+ status: response.status,
16077
+ ...response.contentType === void 0 ? {} : { contentType: response.contentType }
16078
+ };
16079
+ }
16080
+ const verdict = decodeCustodyOffer(response.body, awaiting.requestId);
16081
+ const receipt = custodyOfferReceipt(awaiting.requestId, verdict);
16082
+ switch (verdict.case) {
16083
+ case "admission":
16084
+ return { case: "admission", value: verdict.value, receipt, status: response.status };
16085
+ case "failure":
16086
+ return { case: "failure", value: verdict.value, receipt, status: response.status };
16087
+ case "blocked":
16088
+ return { case: "blocked", value: verdict.value, receipt, status: response.status };
16089
+ }
16090
+ }
16054
16091
  function encodeInlineCustodyOffer(args) {
16055
16092
  return toBinary(CustodyOfferBatchRequestSchema, create(CustodyOfferBatchRequestSchema, {
16056
16093
  protocolVersion: 2,
@@ -16177,6 +16214,7 @@ var NomosRuntimeComponent = (() => {
16177
16214
  var PLACEMENT_REF3 = "refs/nomos/placement";
16178
16215
  var LAW_PRODUCTS_MEDIA_TYPE = "application/vnd.nomos.export-law-products-response+protobuf";
16179
16216
  var WorkspaceSyncPhase = Object.freeze({
16217
+ Idle: "idle",
16180
16218
  Probe: "probe",
16181
16219
  Offer: "offer",
16182
16220
  Lease: "lease",
@@ -16186,7 +16224,6 @@ var NomosRuntimeComponent = (() => {
16186
16224
  Done: "done"
16187
16225
  });
16188
16226
  var trackedMain = "refs/remotes/nomos/main";
16189
- 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";
16190
16227
  var deferredRemote = "refs/remotes/nomos/deferred";
16191
16228
  var deferredLocal = "refs/nomos/sync-deferred-local";
16192
16229
  var judgedThisLifetime = /* @__PURE__ */ new Map();
@@ -16210,7 +16247,6 @@ var NomosRuntimeComponent = (() => {
16210
16247
  #rediscover;
16211
16248
  /** The route the directory's answer yields, recomputed once that answer is observed. */
16212
16249
  #reroute;
16213
- #placementFetch;
16214
16250
  #discoveredFrontier;
16215
16251
  #observePlacement;
16216
16252
  /** Ask the directory for the provider's current placement frontier this round although a
@@ -16219,19 +16255,14 @@ var NomosRuntimeComponent = (() => {
16219
16255
  #directoryAnswered;
16220
16256
  #placementFetched;
16221
16257
  /** A round which converged without leasing, finishing once placement alone is fetched. */
16222
- #afterPlacement;
16223
16258
  #leased = false;
16224
- #lease;
16225
16259
  #command;
16226
16260
  #requestId;
16227
16261
  #started;
16228
- #phase = WorkspaceSyncPhase.Lease;
16262
+ #state = { phase: WorkspaceSyncPhase.Idle };
16229
16263
  #localHead;
16230
16264
  #offerHead;
16231
16265
  #previousHead;
16232
- #fetchStarted;
16233
- #offerStarted;
16234
- #offerRequestId;
16235
16266
  #pushMillis = 0;
16236
16267
  #pushBytes = 0n;
16237
16268
  #desiredHead;
@@ -16326,7 +16357,7 @@ var NomosRuntimeComponent = (() => {
16326
16357
  throw new Error(`replica '${this.#binding.replicaId}' has no custody remote`);
16327
16358
  }
16328
16359
  if (this.#rediscover || this.#recheckPlacement || !this.#route?.placementObserved && !this.#route?.placementFrontier && !this.#kernel.resolveRef(this.#mount, this.#requestId, PLACEMENT_REF3)) {
16329
- this.#phase = WorkspaceSyncPhase.Discover;
16360
+ this.#state = { phase: WorkspaceSyncPhase.Discover };
16330
16361
  return this.#remember({
16331
16362
  case: "pending",
16332
16363
  value: create(CorrespondencePendingSchema, {
@@ -16346,13 +16377,13 @@ var NomosRuntimeComponent = (() => {
16346
16377
  #openRound() {
16347
16378
  if (this.#receiveState || this.#replaceLocalHead !== void 0) return this.#leaseEffect();
16348
16379
  if (!this.#localHead) return this.#leaseEffect();
16349
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
16380
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
16350
16381
  return this.#beginOffer(encodeInlineCustodyOffer({
16351
16382
  session: this.#binding.replicaId,
16352
- requestId: this.#offerRequestId,
16383
+ requestId,
16353
16384
  observedHead: this.#localHead,
16354
16385
  intents: []
16355
- }), true);
16386
+ }), { case: "awaiting", requestId }, true);
16356
16387
  }
16357
16388
  #offerOrReconcile() {
16358
16389
  if (this.#command.admit && this.#localHead && this.#localHead !== this.#previousHead) {
@@ -16373,13 +16404,13 @@ var NomosRuntimeComponent = (() => {
16373
16404
  throw new Error(`kernel did not classify transport for intent '${unspecified.intentId}'`);
16374
16405
  }
16375
16406
  if (suffix.length > 0) {
16376
- this.#offerStarted = this.#clock.monotonicNanoseconds();
16377
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}`;
16407
+ const requestId2 = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}`;
16408
+ const startedAt = this.#clock.monotonicNanoseconds();
16378
16409
  this.#offerAfterConverge = true;
16379
16410
  this.#rebaseFrom = this.#previousHead;
16380
16411
  return this.#beginOffer(encodeInlineCustodyOffer({
16381
16412
  session: this.#binding.replicaId,
16382
- requestId: this.#offerRequestId,
16413
+ requestId: requestId2,
16383
16414
  ...this.#previousHead === void 0 ? {} : { baseHead: this.#previousHead },
16384
16415
  observedHead: this.#localHead,
16385
16416
  intents: suffix,
@@ -16390,51 +16421,26 @@ var NomosRuntimeComponent = (() => {
16390
16421
  this.#previousHead
16391
16422
  ) : void 0,
16392
16423
  fastForwardOnly: true
16393
- }));
16424
+ }), { case: "awaiting", requestId: requestId2, startedAt });
16394
16425
  }
16395
16426
  }
16396
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:reconcile`;
16427
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:reconcile`;
16397
16428
  return this.#beginOffer(encodeInlineCustodyOffer({
16398
16429
  session: this.#binding.replicaId,
16399
- requestId: this.#offerRequestId,
16430
+ requestId,
16400
16431
  baseHead: this.#previousHead,
16401
16432
  observedHead: this.#localHead,
16402
16433
  intents: []
16403
- }));
16434
+ }), { case: "awaiting", requestId });
16404
16435
  }
16405
16436
  /**
16406
- * NO COMMON BASE — a round that cannot converge, and must not pay for history to find out.
16407
- *
16408
- * This replica holds a non-empty ledger but has never recorded a frontier its upstream
16409
- * confirmed (`refs/remotes/nomos/main` is absent). The kernel refuses convergence in that
16410
- * state ("a non-empty live ledger requires a common admitted base"), so every step after the
16411
- * O(1) frontier probe is wasted work — and it is not cheap waste: the fetch negotiates with
16412
- * no `have` (a full-history pack), and the dependency planner decodes EVERY intent from
16413
- * genesis and inspects every change, once per round. That is O(history) per follow round,
16414
- * repeated at every retry, for a round that can only end in a refusal.
16415
- *
16416
- * The one base this round can establish costs nothing and is established before this is
16417
- * asked: an upstream holding exactly this replica's head (the probe's answer) converges it
16418
- * and records the tracking frontier. Anything else needs the local copy to be dropped and
16419
- * refetched (an application decision, which preserves the copy), or a re-discovery that
16420
- * names a provider holding this lineage. Both are reported, at O(1), as this failure.
16421
- */
16422
- /**
16423
- * Establish this round's base when none is tracked, without walking any history it can avoid.
16424
- *
16425
- * The upstream just named its own frontier. If that commit is in THIS replica's lineage, it is
16426
- * a common admitted base by definition — both sides hold it — and adopting it turns the round
16427
- * into an ordinary fast-forward: the offer carries only the suffix above it, the fetch can name
16428
- * it as a truthful `have`, and convergence has the base the kernel requires. One commit walk
16429
- * (no change decoding, no pack, no network) decides it.
16430
- *
16431
- * If it is not in this replica's lineage, no base exists to establish and the round is refused
16432
- * (#noCommonBase) before it leases, fetches or plans anything.
16433
- *
16434
- * A kernel without the commit walk cannot be asked, so it keeps the previous behaviour.
16437
+ * Establish a cheap base when the provider's current tip is in our local chain.
16438
+ * A negative answer means the base is unknown: both sides may have advanced from
16439
+ * an earlier shared commit. Acquire the candidate and let the kernel discover
16440
+ * and judge that history. A tracking bookmark is not an admission prerequisite.
16435
16441
  */
16436
16442
  #establishBase(upstreamHead) {
16437
- if (!this.#noCommonBase() || !this.#kernel.historySummary) return true;
16443
+ if (!this.#missingTrackedBase() || !this.#kernel.historySummary) return true;
16438
16444
  const summary = this.#kernel.historySummary(this.#mount, this.#requestId, upstreamHead, this.#localHead);
16439
16445
  if (!summary.reachedBase) return false;
16440
16446
  this.#previousHead = upstreamHead;
@@ -16449,26 +16455,9 @@ var NomosRuntimeComponent = (() => {
16449
16455
  get establishedBase() {
16450
16456
  return this.#establishedBase;
16451
16457
  }
16452
- #noCommonBase() {
16458
+ #missingTrackedBase() {
16453
16459
  return this.#previousHead === void 0 && this.#localHead !== void 0 && this.#replaceLocalHead === void 0;
16454
16460
  }
16455
- #noCommonBaseResult() {
16456
- return this.#finish(create(SyncWorkspaceResponseSchema, {
16457
- workspace: this.#mount.workspace,
16458
- ...this.#localHead === void 0 ? {} : { currentHead: this.#localHead },
16459
- stillAhead: true,
16460
- ...this.#offerReceipt === void 0 ? {} : { offerReceipt: this.#offerReceipt },
16461
- pushError: create(RuntimeTransportFailureSchema, {
16462
- endpoint: this.#offerEndpoint(),
16463
- status: 409,
16464
- refused: true,
16465
- message: NO_COMMON_BASE
16466
- }),
16467
- timings: create(SyncPhaseTimingsSchema, {
16468
- convergeMillis: elapsedMillis(this.#clock, this.#started)
16469
- })
16470
- }));
16471
- }
16472
16461
  #holdsLocalWork() {
16473
16462
  return this.#command.admit && !!this.#localHead && this.#localHead !== this.#previousHead;
16474
16463
  }
@@ -16476,18 +16465,18 @@ var NomosRuntimeComponent = (() => {
16476
16465
  #pullBeforeOffer() {
16477
16466
  this.#offerAfterConverge = true;
16478
16467
  this.#rebaseFrom = this.#previousHead;
16479
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:pull-${this.#rebases}`;
16468
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:pull-${this.#rebases}`;
16480
16469
  return this.#beginOffer(encodeInlineCustodyOffer({
16481
16470
  session: this.#binding.replicaId,
16482
- requestId: this.#offerRequestId,
16471
+ requestId,
16483
16472
  ...this.#previousHead === void 0 ? {} : { baseHead: this.#previousHead },
16484
16473
  observedHead: this.#localHead,
16485
16474
  intents: []
16486
- }));
16475
+ }), { case: "awaiting", requestId });
16487
16476
  }
16488
- #leaseEffect() {
16477
+ #leaseEffect(afterPlacement) {
16489
16478
  const token = this.#authToken();
16490
- this.#phase = WorkspaceSyncPhase.Lease;
16479
+ this.#state = { phase: WorkspaceSyncPhase.Lease, ...afterPlacement ? { afterPlacement } : {} };
16491
16480
  return this.#remember({
16492
16481
  case: "pending",
16493
16482
  value: create(CorrespondencePendingSchema, {
@@ -16516,35 +16505,38 @@ var NomosRuntimeComponent = (() => {
16516
16505
  `workspace sync '${this.workId}' expected effect '${expected}', received '${receipt.effectId}'`
16517
16506
  );
16518
16507
  }
16508
+ const state = this.#state;
16519
16509
  const previousReceipt = this.#lastReceiptEffectId;
16520
16510
  this.#lastReceiptEffectId = receipt.effectId;
16521
16511
  try {
16522
16512
  if (receipt.outcome.case === "failure") {
16523
- if (this.#phase === WorkspaceSyncPhase.Discover) return this.#openRound();
16513
+ if (state.phase === WorkspaceSyncPhase.Discover) return this.#openRound();
16524
16514
  return this.#transportFailure(
16525
16515
  receipt.outcome.value.message,
16526
16516
  receipt.outcome.value.reason === PeerEffectFailureReason.OFFLINE
16527
16517
  );
16528
16518
  }
16529
- if (this.#phase === WorkspaceSyncPhase.Offer || this.#phase === WorkspaceSyncPhase.Probe) return this.#acceptOffer(receipt);
16530
- if (this.#phase === WorkspaceSyncPhase.Lease) return this.#acceptLease(receipt);
16531
- if (this.#phase === WorkspaceSyncPhase.Discover) return this.#acceptDiscovery(receipt);
16532
- if (this.#phase === WorkspaceSyncPhase.Placement) {
16533
- if (!this.#placementFetch || !this.#lease) throw new Error("placement transfer lost its lease");
16534
- this.#placementFetch.accept(receipt);
16519
+ if (state.phase === WorkspaceSyncPhase.Offer || state.phase === WorkspaceSyncPhase.Probe) {
16520
+ return this.#acceptOffer(receipt, state);
16521
+ }
16522
+ if (state.phase === WorkspaceSyncPhase.Lease) return this.#acceptLease(receipt, state);
16523
+ if (state.phase === WorkspaceSyncPhase.Discover) return this.#acceptDiscovery(receipt);
16524
+ if (state.phase === WorkspaceSyncPhase.Placement) {
16525
+ state.transfer.accept(receipt);
16535
16526
  this.#placementFetched?.();
16536
- if (this.#afterPlacement) return this.#finish(this.#afterPlacement);
16537
- return this.#beginMainFetch(this.#lease);
16527
+ if (state.afterPlacement) return this.#finish(state.afterPlacement);
16528
+ return this.#beginMainFetch(state.lease);
16538
16529
  }
16539
- if (this.#phase === WorkspaceSyncPhase.Fetch) return this.#acceptFetch(receipt);
16530
+ if (state.phase === WorkspaceSyncPhase.Fetch) return this.#acceptFetch(receipt, state);
16540
16531
  throw new Error(`workspace sync '${this.workId}' is already complete`);
16541
16532
  } catch (error) {
16542
16533
  this.#lastReceiptEffectId = previousReceipt;
16543
16534
  throw error;
16544
16535
  }
16545
16536
  }
16546
- #beginOffer(body, probe = false) {
16547
- this.#phase = probe ? WorkspaceSyncPhase.Probe : WorkspaceSyncPhase.Offer;
16537
+ #beginOffer(body, exchange, probe = false) {
16538
+ const phase = probe ? WorkspaceSyncPhase.Probe : WorkspaceSyncPhase.Offer;
16539
+ this.#state = { phase, exchange };
16548
16540
  const token = this.#authToken();
16549
16541
  this.#pushBytes += BigInt(body.byteLength);
16550
16542
  return this.#remember({
@@ -16554,7 +16546,7 @@ var NomosRuntimeComponent = (() => {
16554
16546
  effect: {
16555
16547
  case: "http",
16556
16548
  value: create(PeerHttpEffectSchema, {
16557
- effectId: `${this.workId}:${this.#phase}`,
16549
+ effectId: `${this.workId}:${phase}`,
16558
16550
  method: PeerHttpMethod.POST,
16559
16551
  url: this.#offerEndpoint(),
16560
16552
  contentType: CUSTODY_OFFER_MEDIA_TYPE,
@@ -16571,28 +16563,30 @@ var NomosRuntimeComponent = (() => {
16571
16563
  })
16572
16564
  });
16573
16565
  }
16574
- #acceptOffer(receipt) {
16575
- this.#pushMillis = this.#offerStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#offerStarted);
16566
+ #acceptOffer(receipt, state) {
16567
+ const exchange = state.exchange;
16568
+ this.#pushMillis = exchange.startedAt === void 0 ? 0 : elapsedMillis(this.#clock, exchange.startedAt);
16576
16569
  if (receipt.outcome.case !== "response") {
16577
16570
  throw new Error("platform returned the wrong receipt for a custody offer");
16578
16571
  }
16579
- const response = receipt.outcome.value;
16580
- if (!response.contentType?.includes(CUSTODY_OFFER_RESULT_MEDIA_TYPE)) {
16572
+ const outcome = settleCustodyOfferExchange(exchange, receipt.outcome.value);
16573
+ if (outcome.case === "maintenance") {
16574
+ return this.#finishOfferOutcome(true, false);
16575
+ }
16576
+ if (outcome.case === "unexpected") {
16581
16577
  this.#pushError = create(RuntimeTransportFailureSchema, {
16582
16578
  endpoint: this.#offerEndpoint(),
16583
- status: response.status,
16579
+ status: outcome.status,
16584
16580
  refused: false,
16585
- message: `Sync received an unexpected server response (HTTP ${response.status}; ${response.contentType || "no content type"}). No custody receipt was returned.`
16581
+ message: `Sync received an unexpected server response (HTTP ${outcome.status}; ${outcome.contentType || "no content type"}). No custody receipt was returned.`
16586
16582
  });
16587
16583
  return this.#finishOfferOutcome(false);
16588
16584
  }
16589
- if (!this.#offerRequestId) throw new Error("custody offer has no request identity");
16590
- const outcome = decodeCustodyOffer(response.body, this.#offerRequestId);
16591
- this.#offerReceipt = custodyOfferReceipt(this.#offerRequestId, outcome);
16585
+ this.#offerReceipt = outcome.receipt;
16592
16586
  if (outcome.case === "failure") {
16593
16587
  this.#pushError = create(RuntimeTransportFailureSchema, {
16594
16588
  endpoint: this.#offerEndpoint(),
16595
- status: response.status,
16589
+ status: outcome.status,
16596
16590
  refused: false,
16597
16591
  message: `${outcome.value.code}: ${outcome.value.message}`
16598
16592
  });
@@ -16601,12 +16595,12 @@ var NomosRuntimeComponent = (() => {
16601
16595
  if (outcome.case === "blocked") {
16602
16596
  return this.#finishOfferOutcome(true);
16603
16597
  }
16604
- if (response.status < 200 || response.status >= 300) {
16598
+ if (outcome.status < 200 || outcome.status >= 300) {
16605
16599
  this.#pushError = create(RuntimeTransportFailureSchema, {
16606
16600
  endpoint: this.#offerEndpoint(),
16607
- status: response.status,
16608
- refused: response.status === 422,
16609
- message: `custody offer returned an admission verdict with HTTP ${response.status}`
16601
+ status: outcome.status,
16602
+ refused: outcome.status === 422,
16603
+ message: `custody offer returned an admission verdict with HTTP ${outcome.status}`
16610
16604
  });
16611
16605
  return this.#finishOfferOutcome(false);
16612
16606
  }
@@ -16614,8 +16608,7 @@ var NomosRuntimeComponent = (() => {
16614
16608
  this.#desiredHead = admission.main || void 0;
16615
16609
  if (!this.#desiredHead) return this.#transportFailure("resident peer returned no admitted frontier", false);
16616
16610
  this.#candidateDurable = admission.sealedMain === this.#desiredHead;
16617
- if (this.#phase === WorkspaceSyncPhase.Probe && this.#desiredHead !== this.#localHead) {
16618
- if (!this.#establishBase(this.#desiredHead)) return this.#noCommonBaseResult();
16611
+ if (state.phase === WorkspaceSyncPhase.Probe && this.#desiredHead !== this.#localHead) {
16619
16612
  if (this.#alreadyJudged(this.#desiredHead)) {
16620
16613
  return this.#finish(create(SyncWorkspaceResponseSchema, {
16621
16614
  workspace: this.#mount.workspace,
@@ -16627,6 +16620,22 @@ var NomosRuntimeComponent = (() => {
16627
16620
  offerReceipt: this.#offerReceipt
16628
16621
  }));
16629
16622
  }
16623
+ if (!this.#establishBase(this.#desiredHead)) {
16624
+ this.#offerAfterConverge = this.#command.admit;
16625
+ this.#rebaseFrom = void 0;
16626
+ return this.#leaseEffect();
16627
+ }
16628
+ if (this.#establishedBase && !this.#candidateDurable && this.#kernel.resolveRef(this.#mount, this.#requestId, trackedMain) === void 0) {
16629
+ return this.#finish(create(SyncWorkspaceResponseSchema, {
16630
+ workspace: this.#mount.workspace,
16631
+ currentHead: this.#localHead,
16632
+ previousHead: this.#previousHead,
16633
+ stillAhead: true,
16634
+ directOfferDeferred: true,
16635
+ reconnectRequired: false,
16636
+ offerReceipt: this.#offerReceipt
16637
+ }));
16638
+ }
16630
16639
  if (this.#probeOnly) {
16631
16640
  this.#needsReconciliation = true;
16632
16641
  return this.#finish(create(SyncWorkspaceResponseSchema, {
@@ -16672,11 +16681,11 @@ var NomosRuntimeComponent = (() => {
16672
16681
  return this.#converge(this.#desiredHead, admission.resultPack.byteLength, 0);
16673
16682
  }
16674
16683
  if (this.#desiredHead === this.#previousHead) return this.#converge(this.#desiredHead, 0, 0);
16675
- if (!this.#establishBase(this.#desiredHead)) return this.#noCommonBaseResult();
16684
+ this.#establishBase(this.#desiredHead);
16676
16685
  if (admission.recoveryRequired !== false) return this.#leaseEffect();
16677
16686
  return this.#transportFailure("resident peer supplied neither the missing delta nor a history gap", false);
16678
16687
  }
16679
- #acceptLease(receipt) {
16688
+ #acceptLease(receipt, state) {
16680
16689
  if (receipt.outcome.case !== "response") {
16681
16690
  throw new Error("platform returned the wrong receipt for a Git read lease");
16682
16691
  }
@@ -16692,21 +16701,25 @@ var NomosRuntimeComponent = (() => {
16692
16701
  this.#leased = true;
16693
16702
  const frontier = this.#placementFrontier();
16694
16703
  if (frontier) {
16695
- this.#placementFetch = new PlacementFetch(
16704
+ const transfer = new PlacementFetch(
16696
16705
  this.#kernel,
16697
16706
  this.#mount,
16698
16707
  this.#requestId,
16699
16708
  this.workId,
16700
16709
  frontier
16701
16710
  );
16702
- const pending = this.#placementFetch.start(lease);
16711
+ const pending = transfer.start(lease);
16703
16712
  if (pending) {
16704
- this.#phase = WorkspaceSyncPhase.Placement;
16705
- this.#lease = lease;
16713
+ this.#state = {
16714
+ phase: WorkspaceSyncPhase.Placement,
16715
+ transfer,
16716
+ lease,
16717
+ ...state.afterPlacement ? { afterPlacement: state.afterPlacement } : {}
16718
+ };
16706
16719
  return this.#remember({ case: "pending", value: pending });
16707
16720
  }
16708
16721
  }
16709
- if (this.#afterPlacement) return this.#finish(this.#afterPlacement);
16722
+ if (state.afterPlacement) return this.#finish(state.afterPlacement);
16710
16723
  return this.#beginMainFetch(lease);
16711
16724
  }
16712
16725
  /** The provider's placement frontier as this round knows it: what the directory named in this
@@ -16726,8 +16739,7 @@ var NomosRuntimeComponent = (() => {
16726
16739
  if (!new PlacementFetch(this.#kernel, this.#mount, this.#requestId, this.workId, frontier).wanted()) {
16727
16740
  return void 0;
16728
16741
  }
16729
- this.#afterPlacement = presented;
16730
- return this.#leaseEffect();
16742
+ return this.#leaseEffect(presented);
16731
16743
  }
16732
16744
  #acceptDiscovery(receipt) {
16733
16745
  this.#directoryAnswered?.();
@@ -16751,9 +16763,11 @@ var NomosRuntimeComponent = (() => {
16751
16763
  return this.#replaceLocalHead !== void 0 || this.#localHead === void 0 && this.#previousHead === void 0;
16752
16764
  }
16753
16765
  #beginMainFetch(lease) {
16754
- this.#phase = WorkspaceSyncPhase.Fetch;
16755
16766
  const lawProducts = this.#lawProductsAlongside();
16756
- this.#fetchStarted = this.#clock.monotonicNanoseconds();
16767
+ this.#state = {
16768
+ phase: WorkspaceSyncPhase.Fetch,
16769
+ startedAt: this.#clock.monotonicNanoseconds()
16770
+ };
16757
16771
  const haves = this.#replaceLocalHead !== void 0 ? this.#repairMissingCommit ? [] : [this.#kernel.resolveRef(this.#mount, this.#requestId, deferredRemote)].filter(
16758
16772
  (head) => !!head
16759
16773
  ) : [...new Set([
@@ -16784,7 +16798,7 @@ var NomosRuntimeComponent = (() => {
16784
16798
  })
16785
16799
  });
16786
16800
  }
16787
- #acceptFetch(receipt) {
16801
+ #acceptFetch(receipt, state) {
16788
16802
  if (receipt.outcome.case !== "gitFetch") {
16789
16803
  throw new Error("platform returned the wrong receipt for a Git object fetch");
16790
16804
  }
@@ -16794,7 +16808,7 @@ var NomosRuntimeComponent = (() => {
16794
16808
  if (fetched.pack.byteLength > 0) {
16795
16809
  this.#kernel.applyPack(this.#mount, this.#requestId, fetched.pack, fetched.head, fetched.shallow);
16796
16810
  }
16797
- const prefetchMillis = this.#fetchStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#fetchStarted);
16811
+ const prefetchMillis = elapsedMillis(this.#clock, state.startedAt);
16798
16812
  const candidateHead = this.#receiveState ? this.#kernel.resolveStatePosition?.(this.#mount, this.#requestId, fetched.head, this.#receiveState) : fetched.head;
16799
16813
  if (!candidateHead) {
16800
16814
  return this.#finish(create(SyncWorkspaceResponseSchema, {
@@ -16890,7 +16904,7 @@ var NomosRuntimeComponent = (() => {
16890
16904
  }
16891
16905
  }
16892
16906
  #converge(candidateHead, receivedBytes, prefetchMillis) {
16893
- if (!this.#establishBase(candidateHead)) return this.#noCommonBaseResult();
16907
+ this.#establishBase(candidateHead);
16894
16908
  this.#beforeConverge?.(candidateHead, this.#previousHead);
16895
16909
  const convergeStarted = this.#clock.monotonicNanoseconds();
16896
16910
  let judged;
@@ -17145,11 +17159,11 @@ var NomosRuntimeComponent = (() => {
17145
17159
  pushBytes: this.#pushBytes,
17146
17160
  pullBytes: BigInt(receivedBytes),
17147
17161
  serverMillis: this.#admissionSummary?.serverMillis ?? 0,
17148
- offerInPush: this.#offerRequestId !== void 0
17162
+ offerInPush: this.#pushBytes > 0n
17149
17163
  })
17150
17164
  });
17151
17165
  }
17152
- #finishOfferOutcome(blocked) {
17166
+ #finishOfferOutcome(blocked, reconnectRequired = true) {
17153
17167
  return this.#finish(create(SyncWorkspaceResponseSchema, {
17154
17168
  workspace: this.#mount.workspace,
17155
17169
  previousHead: this.#previousHead,
@@ -17157,7 +17171,7 @@ var NomosRuntimeComponent = (() => {
17157
17171
  admitted: BigInt(this.#admissionSummary?.admittedIntentIds.length ?? 0),
17158
17172
  refused: BigInt((this.#admissionSummary?.refusedMessages.length ?? 0) + this.#parkedLocal),
17159
17173
  deferred: BigInt(this.#admissionSummary ? this.#admissionSummary.blockedMessages.length + this.#admissionSummary.deadLetteredMessages.length + this.#admissionSummary.quarantinedMessages.length + this.#admissionSummary.deferredMessages.length : blocked ? 1 : 0),
17160
- reconnectRequired: true,
17174
+ reconnectRequired,
17161
17175
  stillAhead: this.#localHead !== this.#previousHead,
17162
17176
  directOfferDeferred: blocked,
17163
17177
  offerReceipt: this.#offerReceipt,
@@ -17171,15 +17185,16 @@ var NomosRuntimeComponent = (() => {
17171
17185
  }));
17172
17186
  }
17173
17187
  #transportFailure(message, offline, status = -1) {
17174
- const pushFailed = this.#phase === WorkspaceSyncPhase.Offer;
17188
+ const state = this.#state;
17189
+ const pushFailed = state.phase === WorkspaceSyncPhase.Offer;
17175
17190
  const failedEndpoint = this.#offerEndpoint();
17176
17191
  const failure = create(RuntimeTransportFailureSchema, {
17177
17192
  endpoint: pushFailed ? failedEndpoint : this.#binding.cloud ?? "",
17178
17193
  status,
17179
17194
  message
17180
17195
  });
17181
- if (pushFailed) {
17182
- this.#pushMillis = this.#offerStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#offerStarted);
17196
+ if (state.phase === WorkspaceSyncPhase.Offer) {
17197
+ this.#pushMillis = state.exchange.startedAt === void 0 ? 0 : elapsedMillis(this.#clock, state.exchange.startedAt);
17183
17198
  this.#pushError = failure;
17184
17199
  }
17185
17200
  return this.#finish(create(SyncWorkspaceResponseSchema, {
@@ -17196,7 +17211,7 @@ var NomosRuntimeComponent = (() => {
17196
17211
  pushMillis: this.#pushMillis,
17197
17212
  pushBytes: this.#pushBytes,
17198
17213
  prefetchMillis: elapsedMillis(this.#clock, this.#started),
17199
- offerInPush: this.#offerRequestId !== void 0
17214
+ offerInPush: this.#pushBytes > 0n
17200
17215
  })
17201
17216
  }));
17202
17217
  }
@@ -17206,7 +17221,7 @@ var NomosRuntimeComponent = (() => {
17206
17221
  return step;
17207
17222
  }
17208
17223
  #finish(value) {
17209
- this.#phase = WorkspaceSyncPhase.Done;
17224
+ this.#state = { phase: WorkspaceSyncPhase.Done };
17210
17225
  this.#current = void 0;
17211
17226
  return this.#remember({ case: "synced", value });
17212
17227
  }
@@ -19335,13 +19350,21 @@ var NomosRuntimeComponent = (() => {
19335
19350
  }
19336
19351
  #observeSyncResult(requestId, workId2, result) {
19337
19352
  const timings = result.timings;
19353
+ const receipt = result.offerReceipt?.outcome;
19354
+ const admission = receipt?.case === "admission" ? receipt.value : void 0;
19338
19355
  this.#events.instant("peer.follow.sync-result", {
19339
19356
  request: create(RuntimeRequestSchema, { protocolVersion: 2, requestId }),
19340
19357
  workspace: result.workspace
19341
19358
  }, {
19342
19359
  "sync.workId": workId2,
19343
19360
  ...result.currentHead ? { "sync.head": result.currentHead } : {},
19361
+ ...result.previousHead ? { "sync.previousHead": result.previousHead } : {},
19362
+ ...admission?.main ? { "sync.providerHead": admission.main } : {},
19363
+ ...admission?.sealedMain ? { "sync.sealedHead": admission.sealedMain } : {},
19344
19364
  "sync.stillAhead": result.stillAhead,
19365
+ "sync.reconnectRequired": result.reconnectRequired,
19366
+ "sync.refused": result.refused,
19367
+ "sync.deferred": result.deferred,
19345
19368
  "sync.directOfferDeferred": result.directOfferDeferred,
19346
19369
  "sync.offline": result.offline,
19347
19370
  ...timings ? {