githolon 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.
@@ -14705,6 +14705,15 @@ var init_replica_follow_controller = __esm({
14705
14705
  }
14706
14706
  if (result.stillAhead || result.pushFailed || result.directOfferDeferred || result.reconnectRequired) {
14707
14707
  if (result.directOfferDeferred) {
14708
+ if (!result.reconnectRequired) {
14709
+ this.#desk.transition(result.workspace, {
14710
+ case: ReplicaFollowEventKind.Failed,
14711
+ nowUnixMillis,
14712
+ failure: "remote workspace opening; retrying",
14713
+ retryWithinMillis: 5e3
14714
+ });
14715
+ return delayUntilDue(this.#desk.get(result.workspace), nowUnixMillis);
14716
+ }
14708
14717
  this.#desk.transition(result.workspace, {
14709
14718
  case: ReplicaFollowEventKind.DependencyDeferred,
14710
14719
  nowUnixMillis,
@@ -16709,6 +16718,34 @@ var init_custody_replacement = __esm({
16709
16718
 
16710
16719
  // ../peer-office/src/runtime/custody_offer.ts
16711
16720
  import { create as create53, fromBinary as fromBinary19, toBinary as toBinary17 } from "@bufbuild/protobuf";
16721
+ function settleCustodyOfferExchange(awaiting, response) {
16722
+ if (response.status === 202 && response.contentType?.includes("application/json")) {
16723
+ try {
16724
+ const pending = JSON.parse(new TextDecoder().decode(response.body));
16725
+ if (pending?.retryable === true && typeof pending.preparing === "string") {
16726
+ return { case: "maintenance", kind: pending.preparing };
16727
+ }
16728
+ } catch {
16729
+ }
16730
+ }
16731
+ if (!response.contentType?.includes(CUSTODY_OFFER_RESULT_MEDIA_TYPE)) {
16732
+ return {
16733
+ case: "unexpected",
16734
+ status: response.status,
16735
+ ...response.contentType === void 0 ? {} : { contentType: response.contentType }
16736
+ };
16737
+ }
16738
+ const verdict = decodeCustodyOffer(response.body, awaiting.requestId);
16739
+ const receipt = custodyOfferReceipt(awaiting.requestId, verdict);
16740
+ switch (verdict.case) {
16741
+ case "admission":
16742
+ return { case: "admission", value: verdict.value, receipt, status: response.status };
16743
+ case "failure":
16744
+ return { case: "failure", value: verdict.value, receipt, status: response.status };
16745
+ case "blocked":
16746
+ return { case: "blocked", value: verdict.value, receipt, status: response.status };
16747
+ }
16748
+ }
16712
16749
  function encodeInlineCustodyOffer(args) {
16713
16750
  return toBinary17(CustodyOfferBatchRequestSchema, create53(CustodyOfferBatchRequestSchema, {
16714
16751
  protocolVersion: 2,
@@ -16846,7 +16883,7 @@ import { create as create54, fromBinary as fromBinary20 } from "@bufbuild/protob
16846
16883
  function releaseSyncJudgment(workspace) {
16847
16884
  judgedThisLifetime.delete(workspace);
16848
16885
  }
16849
- var PLACEMENT_REF3, LAW_PRODUCTS_MEDIA_TYPE, WorkspaceSyncPhase, trackedMain, NO_COMMON_BASE, deferredRemote, deferredLocal, judgedThisLifetime, MAX_REBASES_PER_ROUND, elapsedMillis, WorkspaceSyncWork;
16886
+ var PLACEMENT_REF3, LAW_PRODUCTS_MEDIA_TYPE, WorkspaceSyncPhase, trackedMain, deferredRemote, deferredLocal, judgedThisLifetime, MAX_REBASES_PER_ROUND, elapsedMillis, WorkspaceSyncWork;
16850
16887
  var init_workspace_sync = __esm({
16851
16888
  "../peer-office/src/runtime/workspace_sync.ts"() {
16852
16889
  "use strict";
@@ -16862,6 +16899,7 @@ var init_workspace_sync = __esm({
16862
16899
  PLACEMENT_REF3 = "refs/nomos/placement";
16863
16900
  LAW_PRODUCTS_MEDIA_TYPE = "application/vnd.nomos.export-law-products-response+protobuf";
16864
16901
  WorkspaceSyncPhase = Object.freeze({
16902
+ Idle: "idle",
16865
16903
  Probe: "probe",
16866
16904
  Offer: "offer",
16867
16905
  Lease: "lease",
@@ -16871,7 +16909,6 @@ var init_workspace_sync = __esm({
16871
16909
  Done: "done"
16872
16910
  });
16873
16911
  trackedMain = "refs/remotes/nomos/main";
16874
- 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";
16875
16912
  deferredRemote = "refs/remotes/nomos/deferred";
16876
16913
  deferredLocal = "refs/nomos/sync-deferred-local";
16877
16914
  judgedThisLifetime = /* @__PURE__ */ new Map();
@@ -16892,7 +16929,6 @@ var init_workspace_sync = __esm({
16892
16929
  #rediscover;
16893
16930
  /** The route the directory's answer yields, recomputed once that answer is observed. */
16894
16931
  #reroute;
16895
- #placementFetch;
16896
16932
  #discoveredFrontier;
16897
16933
  #observePlacement;
16898
16934
  /** Ask the directory for the provider's current placement frontier this round although a
@@ -16901,19 +16937,14 @@ var init_workspace_sync = __esm({
16901
16937
  #directoryAnswered;
16902
16938
  #placementFetched;
16903
16939
  /** A round which converged without leasing, finishing once placement alone is fetched. */
16904
- #afterPlacement;
16905
16940
  #leased = false;
16906
- #lease;
16907
16941
  #command;
16908
16942
  #requestId;
16909
16943
  #started;
16910
- #phase = WorkspaceSyncPhase.Lease;
16944
+ #state = { phase: WorkspaceSyncPhase.Idle };
16911
16945
  #localHead;
16912
16946
  #offerHead;
16913
16947
  #previousHead;
16914
- #fetchStarted;
16915
- #offerStarted;
16916
- #offerRequestId;
16917
16948
  #pushMillis = 0;
16918
16949
  #pushBytes = 0n;
16919
16950
  #desiredHead;
@@ -17008,7 +17039,7 @@ var init_workspace_sync = __esm({
17008
17039
  throw new Error(`replica '${this.#binding.replicaId}' has no custody remote`);
17009
17040
  }
17010
17041
  if (this.#rediscover || this.#recheckPlacement || !this.#route?.placementObserved && !this.#route?.placementFrontier && !this.#kernel.resolveRef(this.#mount, this.#requestId, PLACEMENT_REF3)) {
17011
- this.#phase = WorkspaceSyncPhase.Discover;
17042
+ this.#state = { phase: WorkspaceSyncPhase.Discover };
17012
17043
  return this.#remember({
17013
17044
  case: "pending",
17014
17045
  value: create54(CorrespondencePendingSchema, {
@@ -17028,13 +17059,13 @@ var init_workspace_sync = __esm({
17028
17059
  #openRound() {
17029
17060
  if (this.#receiveState || this.#replaceLocalHead !== void 0) return this.#leaseEffect();
17030
17061
  if (!this.#localHead) return this.#leaseEffect();
17031
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
17062
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:frontier`;
17032
17063
  return this.#beginOffer(encodeInlineCustodyOffer({
17033
17064
  session: this.#binding.replicaId,
17034
- requestId: this.#offerRequestId,
17065
+ requestId,
17035
17066
  observedHead: this.#localHead,
17036
17067
  intents: []
17037
- }), true);
17068
+ }), { case: "awaiting", requestId }, true);
17038
17069
  }
17039
17070
  #offerOrReconcile() {
17040
17071
  if (this.#command.admit && this.#localHead && this.#localHead !== this.#previousHead) {
@@ -17055,13 +17086,13 @@ var init_workspace_sync = __esm({
17055
17086
  throw new Error(`kernel did not classify transport for intent '${unspecified.intentId}'`);
17056
17087
  }
17057
17088
  if (suffix.length > 0) {
17058
- this.#offerStarted = this.#clock.monotonicNanoseconds();
17059
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}`;
17089
+ const requestId2 = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}`;
17090
+ const startedAt = this.#clock.monotonicNanoseconds();
17060
17091
  this.#offerAfterConverge = true;
17061
17092
  this.#rebaseFrom = this.#previousHead;
17062
17093
  return this.#beginOffer(encodeInlineCustodyOffer({
17063
17094
  session: this.#binding.replicaId,
17064
- requestId: this.#offerRequestId,
17095
+ requestId: requestId2,
17065
17096
  ...this.#previousHead === void 0 ? {} : { baseHead: this.#previousHead },
17066
17097
  observedHead: this.#localHead,
17067
17098
  intents: suffix,
@@ -17072,51 +17103,26 @@ var init_workspace_sync = __esm({
17072
17103
  this.#previousHead
17073
17104
  ) : void 0,
17074
17105
  fastForwardOnly: true
17075
- }));
17106
+ }), { case: "awaiting", requestId: requestId2, startedAt });
17076
17107
  }
17077
17108
  }
17078
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:reconcile`;
17109
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:reconcile`;
17079
17110
  return this.#beginOffer(encodeInlineCustodyOffer({
17080
17111
  session: this.#binding.replicaId,
17081
- requestId: this.#offerRequestId,
17112
+ requestId,
17082
17113
  baseHead: this.#previousHead,
17083
17114
  observedHead: this.#localHead,
17084
17115
  intents: []
17085
- }));
17116
+ }), { case: "awaiting", requestId });
17086
17117
  }
17087
17118
  /**
17088
- * NO COMMON BASE — a round that cannot converge, and must not pay for history to find out.
17089
- *
17090
- * This replica holds a non-empty ledger but has never recorded a frontier its upstream
17091
- * confirmed (`refs/remotes/nomos/main` is absent). The kernel refuses convergence in that
17092
- * state ("a non-empty live ledger requires a common admitted base"), so every step after the
17093
- * O(1) frontier probe is wasted work — and it is not cheap waste: the fetch negotiates with
17094
- * no `have` (a full-history pack), and the dependency planner decodes EVERY intent from
17095
- * genesis and inspects every change, once per round. That is O(history) per follow round,
17096
- * repeated at every retry, for a round that can only end in a refusal.
17097
- *
17098
- * The one base this round can establish costs nothing and is established before this is
17099
- * asked: an upstream holding exactly this replica's head (the probe's answer) converges it
17100
- * and records the tracking frontier. Anything else needs the local copy to be dropped and
17101
- * refetched (an application decision, which preserves the copy), or a re-discovery that
17102
- * names a provider holding this lineage. Both are reported, at O(1), as this failure.
17103
- */
17104
- /**
17105
- * Establish this round's base when none is tracked, without walking any history it can avoid.
17106
- *
17107
- * The upstream just named its own frontier. If that commit is in THIS replica's lineage, it is
17108
- * a common admitted base by definition — both sides hold it — and adopting it turns the round
17109
- * into an ordinary fast-forward: the offer carries only the suffix above it, the fetch can name
17110
- * it as a truthful `have`, and convergence has the base the kernel requires. One commit walk
17111
- * (no change decoding, no pack, no network) decides it.
17112
- *
17113
- * If it is not in this replica's lineage, no base exists to establish and the round is refused
17114
- * (#noCommonBase) before it leases, fetches or plans anything.
17115
- *
17116
- * A kernel without the commit walk cannot be asked, so it keeps the previous behaviour.
17119
+ * Establish a cheap base when the provider's current tip is in our local chain.
17120
+ * A negative answer means the base is unknown: both sides may have advanced from
17121
+ * an earlier shared commit. Acquire the candidate and let the kernel discover
17122
+ * and judge that history. A tracking bookmark is not an admission prerequisite.
17117
17123
  */
17118
17124
  #establishBase(upstreamHead) {
17119
- if (!this.#noCommonBase() || !this.#kernel.historySummary) return true;
17125
+ if (!this.#missingTrackedBase() || !this.#kernel.historySummary) return true;
17120
17126
  const summary = this.#kernel.historySummary(this.#mount, this.#requestId, upstreamHead, this.#localHead);
17121
17127
  if (!summary.reachedBase) return false;
17122
17128
  this.#previousHead = upstreamHead;
@@ -17131,26 +17137,9 @@ var init_workspace_sync = __esm({
17131
17137
  get establishedBase() {
17132
17138
  return this.#establishedBase;
17133
17139
  }
17134
- #noCommonBase() {
17140
+ #missingTrackedBase() {
17135
17141
  return this.#previousHead === void 0 && this.#localHead !== void 0 && this.#replaceLocalHead === void 0;
17136
17142
  }
17137
- #noCommonBaseResult() {
17138
- return this.#finish(create54(SyncWorkspaceResponseSchema, {
17139
- workspace: this.#mount.workspace,
17140
- ...this.#localHead === void 0 ? {} : { currentHead: this.#localHead },
17141
- stillAhead: true,
17142
- ...this.#offerReceipt === void 0 ? {} : { offerReceipt: this.#offerReceipt },
17143
- pushError: create54(RuntimeTransportFailureSchema, {
17144
- endpoint: this.#offerEndpoint(),
17145
- status: 409,
17146
- refused: true,
17147
- message: NO_COMMON_BASE
17148
- }),
17149
- timings: create54(SyncPhaseTimingsSchema, {
17150
- convergeMillis: elapsedMillis(this.#clock, this.#started)
17151
- })
17152
- }));
17153
- }
17154
17143
  #holdsLocalWork() {
17155
17144
  return this.#command.admit && !!this.#localHead && this.#localHead !== this.#previousHead;
17156
17145
  }
@@ -17158,18 +17147,18 @@ var init_workspace_sync = __esm({
17158
17147
  #pullBeforeOffer() {
17159
17148
  this.#offerAfterConverge = true;
17160
17149
  this.#rebaseFrom = this.#previousHead;
17161
- this.#offerRequestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:pull-${this.#rebases}`;
17150
+ const requestId = `${this.#binding.replicaId}:${this.#requestId}:${this.workId}:pull-${this.#rebases}`;
17162
17151
  return this.#beginOffer(encodeInlineCustodyOffer({
17163
17152
  session: this.#binding.replicaId,
17164
- requestId: this.#offerRequestId,
17153
+ requestId,
17165
17154
  ...this.#previousHead === void 0 ? {} : { baseHead: this.#previousHead },
17166
17155
  observedHead: this.#localHead,
17167
17156
  intents: []
17168
- }));
17157
+ }), { case: "awaiting", requestId });
17169
17158
  }
17170
- #leaseEffect() {
17159
+ #leaseEffect(afterPlacement) {
17171
17160
  const token = this.#authToken();
17172
- this.#phase = WorkspaceSyncPhase.Lease;
17161
+ this.#state = { phase: WorkspaceSyncPhase.Lease, ...afterPlacement ? { afterPlacement } : {} };
17173
17162
  return this.#remember({
17174
17163
  case: "pending",
17175
17164
  value: create54(CorrespondencePendingSchema, {
@@ -17198,35 +17187,38 @@ var init_workspace_sync = __esm({
17198
17187
  `workspace sync '${this.workId}' expected effect '${expected}', received '${receipt.effectId}'`
17199
17188
  );
17200
17189
  }
17190
+ const state = this.#state;
17201
17191
  const previousReceipt = this.#lastReceiptEffectId;
17202
17192
  this.#lastReceiptEffectId = receipt.effectId;
17203
17193
  try {
17204
17194
  if (receipt.outcome.case === "failure") {
17205
- if (this.#phase === WorkspaceSyncPhase.Discover) return this.#openRound();
17195
+ if (state.phase === WorkspaceSyncPhase.Discover) return this.#openRound();
17206
17196
  return this.#transportFailure(
17207
17197
  receipt.outcome.value.message,
17208
17198
  receipt.outcome.value.reason === PeerEffectFailureReason.OFFLINE
17209
17199
  );
17210
17200
  }
17211
- if (this.#phase === WorkspaceSyncPhase.Offer || this.#phase === WorkspaceSyncPhase.Probe) return this.#acceptOffer(receipt);
17212
- if (this.#phase === WorkspaceSyncPhase.Lease) return this.#acceptLease(receipt);
17213
- if (this.#phase === WorkspaceSyncPhase.Discover) return this.#acceptDiscovery(receipt);
17214
- if (this.#phase === WorkspaceSyncPhase.Placement) {
17215
- if (!this.#placementFetch || !this.#lease) throw new Error("placement transfer lost its lease");
17216
- this.#placementFetch.accept(receipt);
17201
+ if (state.phase === WorkspaceSyncPhase.Offer || state.phase === WorkspaceSyncPhase.Probe) {
17202
+ return this.#acceptOffer(receipt, state);
17203
+ }
17204
+ if (state.phase === WorkspaceSyncPhase.Lease) return this.#acceptLease(receipt, state);
17205
+ if (state.phase === WorkspaceSyncPhase.Discover) return this.#acceptDiscovery(receipt);
17206
+ if (state.phase === WorkspaceSyncPhase.Placement) {
17207
+ state.transfer.accept(receipt);
17217
17208
  this.#placementFetched?.();
17218
- if (this.#afterPlacement) return this.#finish(this.#afterPlacement);
17219
- return this.#beginMainFetch(this.#lease);
17209
+ if (state.afterPlacement) return this.#finish(state.afterPlacement);
17210
+ return this.#beginMainFetch(state.lease);
17220
17211
  }
17221
- if (this.#phase === WorkspaceSyncPhase.Fetch) return this.#acceptFetch(receipt);
17212
+ if (state.phase === WorkspaceSyncPhase.Fetch) return this.#acceptFetch(receipt, state);
17222
17213
  throw new Error(`workspace sync '${this.workId}' is already complete`);
17223
17214
  } catch (error) {
17224
17215
  this.#lastReceiptEffectId = previousReceipt;
17225
17216
  throw error;
17226
17217
  }
17227
17218
  }
17228
- #beginOffer(body, probe = false) {
17229
- this.#phase = probe ? WorkspaceSyncPhase.Probe : WorkspaceSyncPhase.Offer;
17219
+ #beginOffer(body, exchange, probe = false) {
17220
+ const phase = probe ? WorkspaceSyncPhase.Probe : WorkspaceSyncPhase.Offer;
17221
+ this.#state = { phase, exchange };
17230
17222
  const token = this.#authToken();
17231
17223
  this.#pushBytes += BigInt(body.byteLength);
17232
17224
  return this.#remember({
@@ -17236,7 +17228,7 @@ var init_workspace_sync = __esm({
17236
17228
  effect: {
17237
17229
  case: "http",
17238
17230
  value: create54(PeerHttpEffectSchema, {
17239
- effectId: `${this.workId}:${this.#phase}`,
17231
+ effectId: `${this.workId}:${phase}`,
17240
17232
  method: PeerHttpMethod.POST,
17241
17233
  url: this.#offerEndpoint(),
17242
17234
  contentType: CUSTODY_OFFER_MEDIA_TYPE,
@@ -17253,28 +17245,30 @@ var init_workspace_sync = __esm({
17253
17245
  })
17254
17246
  });
17255
17247
  }
17256
- #acceptOffer(receipt) {
17257
- this.#pushMillis = this.#offerStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#offerStarted);
17248
+ #acceptOffer(receipt, state) {
17249
+ const exchange = state.exchange;
17250
+ this.#pushMillis = exchange.startedAt === void 0 ? 0 : elapsedMillis(this.#clock, exchange.startedAt);
17258
17251
  if (receipt.outcome.case !== "response") {
17259
17252
  throw new Error("platform returned the wrong receipt for a custody offer");
17260
17253
  }
17261
- const response = receipt.outcome.value;
17262
- if (!response.contentType?.includes(CUSTODY_OFFER_RESULT_MEDIA_TYPE)) {
17254
+ const outcome = settleCustodyOfferExchange(exchange, receipt.outcome.value);
17255
+ if (outcome.case === "maintenance") {
17256
+ return this.#finishOfferOutcome(true, false);
17257
+ }
17258
+ if (outcome.case === "unexpected") {
17263
17259
  this.#pushError = create54(RuntimeTransportFailureSchema, {
17264
17260
  endpoint: this.#offerEndpoint(),
17265
- status: response.status,
17261
+ status: outcome.status,
17266
17262
  refused: false,
17267
- message: `Sync received an unexpected server response (HTTP ${response.status}; ${response.contentType || "no content type"}). No custody receipt was returned.`
17263
+ message: `Sync received an unexpected server response (HTTP ${outcome.status}; ${outcome.contentType || "no content type"}). No custody receipt was returned.`
17268
17264
  });
17269
17265
  return this.#finishOfferOutcome(false);
17270
17266
  }
17271
- if (!this.#offerRequestId) throw new Error("custody offer has no request identity");
17272
- const outcome = decodeCustodyOffer(response.body, this.#offerRequestId);
17273
- this.#offerReceipt = custodyOfferReceipt(this.#offerRequestId, outcome);
17267
+ this.#offerReceipt = outcome.receipt;
17274
17268
  if (outcome.case === "failure") {
17275
17269
  this.#pushError = create54(RuntimeTransportFailureSchema, {
17276
17270
  endpoint: this.#offerEndpoint(),
17277
- status: response.status,
17271
+ status: outcome.status,
17278
17272
  refused: false,
17279
17273
  message: `${outcome.value.code}: ${outcome.value.message}`
17280
17274
  });
@@ -17283,12 +17277,12 @@ var init_workspace_sync = __esm({
17283
17277
  if (outcome.case === "blocked") {
17284
17278
  return this.#finishOfferOutcome(true);
17285
17279
  }
17286
- if (response.status < 200 || response.status >= 300) {
17280
+ if (outcome.status < 200 || outcome.status >= 300) {
17287
17281
  this.#pushError = create54(RuntimeTransportFailureSchema, {
17288
17282
  endpoint: this.#offerEndpoint(),
17289
- status: response.status,
17290
- refused: response.status === 422,
17291
- message: `custody offer returned an admission verdict with HTTP ${response.status}`
17283
+ status: outcome.status,
17284
+ refused: outcome.status === 422,
17285
+ message: `custody offer returned an admission verdict with HTTP ${outcome.status}`
17292
17286
  });
17293
17287
  return this.#finishOfferOutcome(false);
17294
17288
  }
@@ -17296,8 +17290,7 @@ var init_workspace_sync = __esm({
17296
17290
  this.#desiredHead = admission.main || void 0;
17297
17291
  if (!this.#desiredHead) return this.#transportFailure("resident peer returned no admitted frontier", false);
17298
17292
  this.#candidateDurable = admission.sealedMain === this.#desiredHead;
17299
- if (this.#phase === WorkspaceSyncPhase.Probe && this.#desiredHead !== this.#localHead) {
17300
- if (!this.#establishBase(this.#desiredHead)) return this.#noCommonBaseResult();
17293
+ if (state.phase === WorkspaceSyncPhase.Probe && this.#desiredHead !== this.#localHead) {
17301
17294
  if (this.#alreadyJudged(this.#desiredHead)) {
17302
17295
  return this.#finish(create54(SyncWorkspaceResponseSchema, {
17303
17296
  workspace: this.#mount.workspace,
@@ -17309,6 +17302,22 @@ var init_workspace_sync = __esm({
17309
17302
  offerReceipt: this.#offerReceipt
17310
17303
  }));
17311
17304
  }
17305
+ if (!this.#establishBase(this.#desiredHead)) {
17306
+ this.#offerAfterConverge = this.#command.admit;
17307
+ this.#rebaseFrom = void 0;
17308
+ return this.#leaseEffect();
17309
+ }
17310
+ if (this.#establishedBase && !this.#candidateDurable && this.#kernel.resolveRef(this.#mount, this.#requestId, trackedMain) === void 0) {
17311
+ return this.#finish(create54(SyncWorkspaceResponseSchema, {
17312
+ workspace: this.#mount.workspace,
17313
+ currentHead: this.#localHead,
17314
+ previousHead: this.#previousHead,
17315
+ stillAhead: true,
17316
+ directOfferDeferred: true,
17317
+ reconnectRequired: false,
17318
+ offerReceipt: this.#offerReceipt
17319
+ }));
17320
+ }
17312
17321
  if (this.#probeOnly) {
17313
17322
  this.#needsReconciliation = true;
17314
17323
  return this.#finish(create54(SyncWorkspaceResponseSchema, {
@@ -17354,11 +17363,11 @@ var init_workspace_sync = __esm({
17354
17363
  return this.#converge(this.#desiredHead, admission.resultPack.byteLength, 0);
17355
17364
  }
17356
17365
  if (this.#desiredHead === this.#previousHead) return this.#converge(this.#desiredHead, 0, 0);
17357
- if (!this.#establishBase(this.#desiredHead)) return this.#noCommonBaseResult();
17366
+ this.#establishBase(this.#desiredHead);
17358
17367
  if (admission.recoveryRequired !== false) return this.#leaseEffect();
17359
17368
  return this.#transportFailure("resident peer supplied neither the missing delta nor a history gap", false);
17360
17369
  }
17361
- #acceptLease(receipt) {
17370
+ #acceptLease(receipt, state) {
17362
17371
  if (receipt.outcome.case !== "response") {
17363
17372
  throw new Error("platform returned the wrong receipt for a Git read lease");
17364
17373
  }
@@ -17374,21 +17383,25 @@ var init_workspace_sync = __esm({
17374
17383
  this.#leased = true;
17375
17384
  const frontier = this.#placementFrontier();
17376
17385
  if (frontier) {
17377
- this.#placementFetch = new PlacementFetch(
17386
+ const transfer = new PlacementFetch(
17378
17387
  this.#kernel,
17379
17388
  this.#mount,
17380
17389
  this.#requestId,
17381
17390
  this.workId,
17382
17391
  frontier
17383
17392
  );
17384
- const pending = this.#placementFetch.start(lease);
17393
+ const pending = transfer.start(lease);
17385
17394
  if (pending) {
17386
- this.#phase = WorkspaceSyncPhase.Placement;
17387
- this.#lease = lease;
17395
+ this.#state = {
17396
+ phase: WorkspaceSyncPhase.Placement,
17397
+ transfer,
17398
+ lease,
17399
+ ...state.afterPlacement ? { afterPlacement: state.afterPlacement } : {}
17400
+ };
17388
17401
  return this.#remember({ case: "pending", value: pending });
17389
17402
  }
17390
17403
  }
17391
- if (this.#afterPlacement) return this.#finish(this.#afterPlacement);
17404
+ if (state.afterPlacement) return this.#finish(state.afterPlacement);
17392
17405
  return this.#beginMainFetch(lease);
17393
17406
  }
17394
17407
  /** The provider's placement frontier as this round knows it: what the directory named in this
@@ -17408,8 +17421,7 @@ var init_workspace_sync = __esm({
17408
17421
  if (!new PlacementFetch(this.#kernel, this.#mount, this.#requestId, this.workId, frontier).wanted()) {
17409
17422
  return void 0;
17410
17423
  }
17411
- this.#afterPlacement = presented;
17412
- return this.#leaseEffect();
17424
+ return this.#leaseEffect(presented);
17413
17425
  }
17414
17426
  #acceptDiscovery(receipt) {
17415
17427
  this.#directoryAnswered?.();
@@ -17433,9 +17445,11 @@ var init_workspace_sync = __esm({
17433
17445
  return this.#replaceLocalHead !== void 0 || this.#localHead === void 0 && this.#previousHead === void 0;
17434
17446
  }
17435
17447
  #beginMainFetch(lease) {
17436
- this.#phase = WorkspaceSyncPhase.Fetch;
17437
17448
  const lawProducts = this.#lawProductsAlongside();
17438
- this.#fetchStarted = this.#clock.monotonicNanoseconds();
17449
+ this.#state = {
17450
+ phase: WorkspaceSyncPhase.Fetch,
17451
+ startedAt: this.#clock.monotonicNanoseconds()
17452
+ };
17439
17453
  const haves = this.#replaceLocalHead !== void 0 ? this.#repairMissingCommit ? [] : [this.#kernel.resolveRef(this.#mount, this.#requestId, deferredRemote)].filter(
17440
17454
  (head) => !!head
17441
17455
  ) : [...new Set([
@@ -17466,7 +17480,7 @@ var init_workspace_sync = __esm({
17466
17480
  })
17467
17481
  });
17468
17482
  }
17469
- #acceptFetch(receipt) {
17483
+ #acceptFetch(receipt, state) {
17470
17484
  if (receipt.outcome.case !== "gitFetch") {
17471
17485
  throw new Error("platform returned the wrong receipt for a Git object fetch");
17472
17486
  }
@@ -17476,7 +17490,7 @@ var init_workspace_sync = __esm({
17476
17490
  if (fetched.pack.byteLength > 0) {
17477
17491
  this.#kernel.applyPack(this.#mount, this.#requestId, fetched.pack, fetched.head, fetched.shallow);
17478
17492
  }
17479
- const prefetchMillis = this.#fetchStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#fetchStarted);
17493
+ const prefetchMillis = elapsedMillis(this.#clock, state.startedAt);
17480
17494
  const candidateHead = this.#receiveState ? this.#kernel.resolveStatePosition?.(this.#mount, this.#requestId, fetched.head, this.#receiveState) : fetched.head;
17481
17495
  if (!candidateHead) {
17482
17496
  return this.#finish(create54(SyncWorkspaceResponseSchema, {
@@ -17572,7 +17586,7 @@ var init_workspace_sync = __esm({
17572
17586
  }
17573
17587
  }
17574
17588
  #converge(candidateHead, receivedBytes, prefetchMillis) {
17575
- if (!this.#establishBase(candidateHead)) return this.#noCommonBaseResult();
17589
+ this.#establishBase(candidateHead);
17576
17590
  this.#beforeConverge?.(candidateHead, this.#previousHead);
17577
17591
  const convergeStarted = this.#clock.monotonicNanoseconds();
17578
17592
  let judged;
@@ -17827,11 +17841,11 @@ var init_workspace_sync = __esm({
17827
17841
  pushBytes: this.#pushBytes,
17828
17842
  pullBytes: BigInt(receivedBytes),
17829
17843
  serverMillis: this.#admissionSummary?.serverMillis ?? 0,
17830
- offerInPush: this.#offerRequestId !== void 0
17844
+ offerInPush: this.#pushBytes > 0n
17831
17845
  })
17832
17846
  });
17833
17847
  }
17834
- #finishOfferOutcome(blocked) {
17848
+ #finishOfferOutcome(blocked, reconnectRequired = true) {
17835
17849
  return this.#finish(create54(SyncWorkspaceResponseSchema, {
17836
17850
  workspace: this.#mount.workspace,
17837
17851
  previousHead: this.#previousHead,
@@ -17839,7 +17853,7 @@ var init_workspace_sync = __esm({
17839
17853
  admitted: BigInt(this.#admissionSummary?.admittedIntentIds.length ?? 0),
17840
17854
  refused: BigInt((this.#admissionSummary?.refusedMessages.length ?? 0) + this.#parkedLocal),
17841
17855
  deferred: BigInt(this.#admissionSummary ? this.#admissionSummary.blockedMessages.length + this.#admissionSummary.deadLetteredMessages.length + this.#admissionSummary.quarantinedMessages.length + this.#admissionSummary.deferredMessages.length : blocked ? 1 : 0),
17842
- reconnectRequired: true,
17856
+ reconnectRequired,
17843
17857
  stillAhead: this.#localHead !== this.#previousHead,
17844
17858
  directOfferDeferred: blocked,
17845
17859
  offerReceipt: this.#offerReceipt,
@@ -17853,15 +17867,16 @@ var init_workspace_sync = __esm({
17853
17867
  }));
17854
17868
  }
17855
17869
  #transportFailure(message, offline, status = -1) {
17856
- const pushFailed = this.#phase === WorkspaceSyncPhase.Offer;
17870
+ const state = this.#state;
17871
+ const pushFailed = state.phase === WorkspaceSyncPhase.Offer;
17857
17872
  const failedEndpoint = this.#offerEndpoint();
17858
17873
  const failure = create54(RuntimeTransportFailureSchema, {
17859
17874
  endpoint: pushFailed ? failedEndpoint : this.#binding.cloud ?? "",
17860
17875
  status,
17861
17876
  message
17862
17877
  });
17863
- if (pushFailed) {
17864
- this.#pushMillis = this.#offerStarted === void 0 ? 0 : elapsedMillis(this.#clock, this.#offerStarted);
17878
+ if (state.phase === WorkspaceSyncPhase.Offer) {
17879
+ this.#pushMillis = state.exchange.startedAt === void 0 ? 0 : elapsedMillis(this.#clock, state.exchange.startedAt);
17865
17880
  this.#pushError = failure;
17866
17881
  }
17867
17882
  return this.#finish(create54(SyncWorkspaceResponseSchema, {
@@ -17878,7 +17893,7 @@ var init_workspace_sync = __esm({
17878
17893
  pushMillis: this.#pushMillis,
17879
17894
  pushBytes: this.#pushBytes,
17880
17895
  prefetchMillis: elapsedMillis(this.#clock, this.#started),
17881
- offerInPush: this.#offerRequestId !== void 0
17896
+ offerInPush: this.#pushBytes > 0n
17882
17897
  })
17883
17898
  }));
17884
17899
  }
@@ -17888,7 +17903,7 @@ var init_workspace_sync = __esm({
17888
17903
  return step;
17889
17904
  }
17890
17905
  #finish(value) {
17891
- this.#phase = WorkspaceSyncPhase.Done;
17906
+ this.#state = { phase: WorkspaceSyncPhase.Done };
17892
17907
  this.#current = void 0;
17893
17908
  return this.#remember({ case: "synced", value });
17894
17909
  }
@@ -20105,13 +20120,21 @@ var init_correspondence_desk = __esm({
20105
20120
  }
20106
20121
  #observeSyncResult(requestId, workId2, result) {
20107
20122
  const timings = result.timings;
20123
+ const receipt = result.offerReceipt?.outcome;
20124
+ const admission = receipt?.case === "admission" ? receipt.value : void 0;
20108
20125
  this.#events.instant("peer.follow.sync-result", {
20109
20126
  request: create59(RuntimeRequestSchema, { protocolVersion: 2, requestId }),
20110
20127
  workspace: result.workspace
20111
20128
  }, {
20112
20129
  "sync.workId": workId2,
20113
20130
  ...result.currentHead ? { "sync.head": result.currentHead } : {},
20131
+ ...result.previousHead ? { "sync.previousHead": result.previousHead } : {},
20132
+ ...admission?.main ? { "sync.providerHead": admission.main } : {},
20133
+ ...admission?.sealedMain ? { "sync.sealedHead": admission.sealedMain } : {},
20114
20134
  "sync.stillAhead": result.stillAhead,
20135
+ "sync.reconnectRequired": result.reconnectRequired,
20136
+ "sync.refused": result.refused,
20137
+ "sync.deferred": result.deferred,
20115
20138
  "sync.directOfferDeferred": result.directOfferDeferred,
20116
20139
  "sync.offline": result.offline,
20117
20140
  ...timings ? {
@@ -26413,8 +26436,19 @@ async function ensureApplicationWorkspace(application, opts = {}) {
26413
26436
  }
26414
26437
  const statusUrl = `${cloud}/v2/workspaces/${encodeURIComponent(application)}`;
26415
26438
  const current = await fetch(statusUrl).catch(() => null);
26416
- if (current?.ok) {
26417
- const status = await current.json().catch(() => null);
26439
+ const status = current?.ok ? await current.json().catch(() => null) : null;
26440
+ let unborn = false;
26441
+ if (current?.ok && !status?.lineage && !status?.durableHead && !status?.sealedHead) {
26442
+ const domains2 = await fetch(`${statusUrl}/domains`);
26443
+ if (domains2.status === 409) {
26444
+ const body2 = await domains2.json().catch(() => null);
26445
+ unborn = typeof body2?.error === "string" && body2.error.includes("unborn");
26446
+ }
26447
+ if (!unborn && !domains2.ok) {
26448
+ throw new Error(`could not establish whether application '${application}' has custody (${domains2.status})`);
26449
+ }
26450
+ }
26451
+ if (current?.ok && !unborn) {
26418
26452
  const principal = String(status?.lineage?.principal ?? "");
26419
26453
  const actualParent = String(status?.lineage?.parent ?? "");
26420
26454
  const expectedParent = requestedParent === "root" ? "" : requestedParent;
@@ -26450,7 +26484,7 @@ async function ensureApplicationWorkspace(application, opts = {}) {
26450
26484
  ...principal !== "" && session !== "" && sameIdentity(principal, session) ? { deployPrincipal: principal } : {}
26451
26485
  };
26452
26486
  }
26453
- if (current !== null && current.status !== 404 && current.status !== 409) {
26487
+ if (current !== null && !unborn && current.status !== 404 && current.status !== 409) {
26454
26488
  throw new Error(`could not inspect deploy target '${application}' (${current.status}); refusing to guess that it is unborn`);
26455
26489
  }
26456
26490
  if (requestedParent !== void 0) {