instar 1.3.373 → 1.3.375

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.
@@ -7957,6 +7957,74 @@ export function createRoutes(ctx) {
7957
7957
  // ownership is a best-effort optimization. If it throws, route() re-places off the pin on
7958
7958
  // the next message regardless, and `releasedLocalOwnership:false` is reported to the caller.
7959
7959
  }
7960
+ // Coherence finding #5 (2026-06-06): the transfer's PLACE half. A QUIET topic
7961
+ // (never-seen or released ownership record) previously journaled NOTHING on
7962
+ // transfer — the pin is router-local and the release half above only fires when
7963
+ // this machine held ownership — so the pinned-to machine could never prove
7964
+ // ownership and its working-set fetch reflex stayed refused ("not-owner") even
7965
+ // after the #926/#930 read-side fallbacks. Land place→claim for the target (the
7966
+ // FSM permits the router to confirm a claim on the placed owner's behalf — the
7967
+ // bug-#11 confirmClaim precedent), which records a REAL epoch and journals a
7968
+ // placement entry that replicates to the target. Claim immediately follows place
7969
+ // so the record never rests at 'placing' (a resting 'placing' record queues every
7970
+ // later message as ownership-contention). Guarded: place is only legal on
7971
+ // never-seen/released records, so an active or in-flight record is never stolen.
7972
+ let placedOwnership = false;
7973
+ try {
7974
+ // Skip only when the target already holds CONFIRMED (active) ownership — a
7975
+ // resting 'placing' record naming the target must still fall through to the
7976
+ // claim repair below (ownerOf reports an owner for 'placing' records too,
7977
+ // which is why this guard reads the record's status directly).
7978
+ const cur0 = ctx.sessionOwnershipRegistry.read(topicId);
7979
+ if (self && !(cur0?.status === 'active' && cur0.ownerMachineId === target)) {
7980
+ const prevOwner = cur0?.ownerMachineId;
7981
+ // Each landed CAS journals (§3.3 call-site pairing — placement history
7982
+ // never grows a hole): the place half AND the placing→active confirm,
7983
+ // exactly like the router's casClaimOwnership/confirmClaim pair. The
7984
+ // entry is what the target's wsOwnerOf journal-placement fallback
7985
+ // (#930) reads after replication.
7986
+ const casAndJournal = (action, half) => {
7987
+ const r = ctx.sessionOwnershipRegistry.cas(action, {
7988
+ sessionKey: topicId,
7989
+ sender: self,
7990
+ nonce: `${self}:${half}:${topicId}:${Date.now()}`,
7991
+ });
7992
+ if (!r.ok)
7993
+ return false;
7994
+ try {
7995
+ const topicNum = Number(topicId);
7996
+ if (Number.isFinite(topicNum)) {
7997
+ ctx.state.getCoherenceJournal()?.emitPlacement(topicNum, {
7998
+ owner: r.record.ownerMachineId ?? target,
7999
+ ...(prevOwner ? { prevOwner } : {}),
8000
+ epoch: r.record.ownershipEpoch,
8001
+ reason: 'user-move',
8002
+ });
8003
+ }
8004
+ }
8005
+ catch { /* observability never endangers the observed */ }
8006
+ return true;
8007
+ };
8008
+ if (casAndJournal({ type: 'place', machineId: target }, 'tplace')) {
8009
+ placedOwnership = casAndJournal({ type: 'claim', machineId: target }, 'tclaim');
8010
+ }
8011
+ else {
8012
+ // A resting 'placing' record already naming the target (legacy pre-fix
8013
+ // state, or a raced earlier transfer) → confirm the claim (placing→active),
8014
+ // the bug-#11 repair. Any other record shape is left strictly untouched.
8015
+ const cur = ctx.sessionOwnershipRegistry.read(topicId);
8016
+ if (cur?.status === 'placing' && cur.ownerMachineId === target) {
8017
+ placedOwnership = casAndJournal({ type: 'claim', machineId: target }, 'tclaim');
8018
+ }
8019
+ }
8020
+ }
8021
+ }
8022
+ catch {
8023
+ // @silent-fallback-ok — landing the place half is the quiet-topic ownership-evidence
8024
+ // repair (coherence finding #5); the pin (set above) still drives re-placement on the
8025
+ // next real message, so a CAS failure must never fail the transfer itself.
8026
+ // `placedOwnership:false` is reported to the caller.
8027
+ }
7960
8028
  res.json({
7961
8029
  ok: true,
7962
8030
  topicId,
@@ -7965,6 +8033,7 @@ export function createRoutes(ctx) {
7965
8033
  action: plan.action,
7966
8034
  pinned: plan.setPin ?? true,
7967
8035
  releasedLocalOwnership,
8036
+ placedOwnership,
7968
8037
  });
7969
8038
  });
7970
8039
  // GET /secrets/sync-status — read-only view of cross-machine secret-sync (spec Phase 4).