instar 1.3.336 → 1.3.338

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.
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA6SH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAuxDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4uRtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA6SH,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAuxDD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgxRtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
@@ -5803,7 +5803,8 @@ export async function startServer(options) {
5803
5803
  ? ' ActiveWorkSilenceSentinel enabled (silent-freeze watchdog — Telegram escalation ON, consolidated)'
5804
5804
  : ' ActiveWorkSilenceSentinel enabled (silent-freeze watchdog — logs only, Telegram escalation OFF)'));
5805
5805
  }
5806
- // ── ContextWedgeSentinel — thinking-block-400 fast-fail wedge ──
5806
+ // ── ContextWedgeSentinel — transcript fast-fail wedges (thinking-block
5807
+ // 400 + AUP-rejection loop) ──
5807
5808
  // Detection + audit ship default-ON (harmless housekeeping). The
5808
5809
  // destructive fresh-respawn is gated by autoRecovery (default OFF +
5809
5810
  // dryRun) and rides the Graduated Feature Rollout track. freshRespawn is
@@ -5832,15 +5833,15 @@ export async function startServer(options) {
5832
5833
  tickIntervalMs: wedgeCfg.tickIntervalMs,
5833
5834
  confirmWindowMs: wedgeCfg.confirmWindowMs,
5834
5835
  });
5835
- wedgeSentinel.on('detected', (e) => notifier.record('detected', 'context-wedge', e.sessionName));
5836
- wedgeSentinel.on('recovered', (e) => notifier.record('recovered', 'context-wedge', e.sessionName, 'fresh respawn'));
5837
- wedgeSentinel.on('dry-run', (e) => notifier.record('dry-run', 'context-wedge', e.sessionName, 'would fresh-respawn'));
5836
+ wedgeSentinel.on('detected', (e) => notifier.record('detected', 'context-wedge', e.sessionName, e.kind));
5837
+ wedgeSentinel.on('recovered', (e) => notifier.record('recovered', 'context-wedge', e.sessionName, `fresh respawn (${e.kind ?? 'unknown'})`));
5838
+ wedgeSentinel.on('dry-run', (e) => notifier.record('dry-run', 'context-wedge', e.sessionName, `would fresh-respawn (${e.kind ?? 'unknown'})`));
5838
5839
  wedgeSentinel.on('false-alarm', (e) => notifier.record('false-alarm', 'context-wedge', e.sessionName, 'signature scrolled out of tail'));
5839
5840
  wedgeSentinel.on('recovery-error', (e) => notifier.record('recovery-error', 'context-wedge', e.sessionName, e.err instanceof Error ? e.err.message : String(e.err)));
5840
5841
  wedgeSentinel.start();
5841
5842
  wedgeRecoveryActive = (s) => wedgeSentinel.isRecoveryActive(s);
5842
5843
  const mode = autoRecovery.enabled ? (autoRecovery.dryRun ? 'auto-recover dry-run' : 'auto-recover LIVE') : 'detect-only';
5843
- console.log(pc.green(` ContextWedgeSentinel enabled (thinking-block-400 wedge — ${mode})`));
5844
+ console.log(pc.green(` ContextWedgeSentinel enabled (thinking-block-400 + aup-rejection wedges — ${mode})`));
5844
5845
  }
5845
5846
  }
5846
5847
  // Recompose the zombie-kill veto to include ALL four recovery sentinels now
@@ -9653,10 +9654,39 @@ export async function startServer(options) {
9653
9654
  // Shared-cluster writes stay blocked on a standby. (bug #9: the moved session's
9654
9655
  // saveSession was blocked by the standby read-only guard.)
9655
9656
  state.setSessionPoolActive(true);
9657
+ // Per-peer suspect breaker (P19) — the markOwnerSuspect hook's missing
9658
+ // half. A peer whose deliveries exhaust retries is short-circuited for
9659
+ // a half-open 30s window: every session it owns goes straight to the
9660
+ // EXISTING failover re-place path instead of re-paying the ~4.5s retry
9661
+ // tax per message. Any successful delivery closes the window; sustained
9662
+ // suspicion (10min of consecutive windows) raises ONE degradation
9663
+ // signal per episode.
9664
+ const ownerSuspectBreaker = new (await import('../core/OwnerSuspectBreaker.js')).OwnerSuspectBreaker({
9665
+ logger: (m) => console.log(pc.dim(m)),
9666
+ reportSustained: ({ machineId, suspectForMs, marks }) => {
9667
+ DegradationReporter.getInstance().report({
9668
+ feature: 'SessionPool.ownerDelivery',
9669
+ primary: 'Messages forward to the machine that owns their session',
9670
+ fallback: `Owner ${machineId} unresponsive to deliveries for ~${Math.round(suspectForMs / 60_000)}min (${marks} suspect windows); its sessions re-place on dispatch; half-open re-probes continue`,
9671
+ reason: 'deliverMessage retries to the owning machine keep exhausting',
9672
+ impact: 'Sessions owned by that machine fail over to other machines on their next message instead of being delivered in place.',
9673
+ });
9674
+ },
9675
+ });
9656
9676
  _sessionRouter = new routerMod.SessionRouter({
9657
9677
  selfMachineId: meshSelfId,
9658
9678
  placement: new placeMod.PlacementExecutor(),
9659
- machineRegistry: () => machinePoolRegistry?.getCapacities() ?? [],
9679
+ // Placement must consult the breaker too: a message re-placed OFF a
9680
+ // suspect owner must not be placed right back ONTO it. Suspect
9681
+ // machines are filtered from the candidate set UNLESS that would
9682
+ // empty it — with every machine suspect, placement proceeds on the
9683
+ // full set (mirrors the all-machines-quota-blocked precedent:
9684
+ // degraded placement beats no placement).
9685
+ machineRegistry: () => {
9686
+ const all = machinePoolRegistry?.getCapacities() ?? [];
9687
+ const ok = all.filter((c) => !ownerSuspectBreaker.isSuspect(c.machineId));
9688
+ return ok.length > 0 ? ok : all;
9689
+ },
9660
9690
  resolveOwnership: (sk) => {
9661
9691
  const r = ownReg.read(sk);
9662
9692
  if (!r)
@@ -9664,7 +9694,13 @@ export async function startServer(options) {
9664
9694
  const status = r.status === 'released' ? null : r.status;
9665
9695
  return { owner: ownReg.ownerOf(sk), epoch: r.ownershipEpoch, status, target: ownReg.placementTargetOf(sk) ?? undefined };
9666
9696
  },
9667
- isMachineAlive: (m) => m === meshSelfId || (machinePoolRegistry?.getCapacity(m)?.online ?? false),
9697
+ // Capacity-online AND not currently suspect: a slow-but-heartbeating
9698
+ // peer that keeps failing deliveries reads as not-alive for routing,
9699
+ // sending its sessions down the existing failover re-place path
9700
+ // without each message re-paying the retry tax.
9701
+ isMachineAlive: (m) => m === meshSelfId || ((machinePoolRegistry?.getCapacity(m)?.online ?? false) && !ownerSuspectBreaker.isSuspect(m)),
9702
+ markOwnerSuspect: (m) => ownerSuspectBreaker.markSuspect(m),
9703
+ onOwnerResponsive: (m) => ownerSuspectBreaker.recordSuccess(m),
9668
9704
  casClaimOwnership: (sk, machineId) => {
9669
9705
  const r = ownReg.cas({ type: 'place', machineId }, { sessionKey: sk, sender: meshSelfId, nonce: `${meshSelfId}:c:${++routerNonce}` });
9670
9706
  return { ok: r.ok, epoch: ownReg.read(sk)?.ownershipEpoch ?? 0 };