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.
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +43 -7
- package/dist/commands/server.js.map +1 -1
- package/dist/core/OwnerSuspectBreaker.d.ts +79 -0
- package/dist/core/OwnerSuspectBreaker.d.ts.map +1 -0
- package/dist/core/OwnerSuspectBreaker.js +106 -0
- package/dist/core/OwnerSuspectBreaker.js.map +1 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +25 -5
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionRouter.d.ts +7 -0
- package/dist/core/SessionRouter.d.ts.map +1 -1
- package/dist/core/SessionRouter.js +14 -2
- package/dist/core/SessionRouter.js.map +1 -1
- package/dist/monitoring/ContextWedgeSentinel.d.ts +46 -17
- package/dist/monitoring/ContextWedgeSentinel.d.ts.map +1 -1
- package/dist/monitoring/ContextWedgeSentinel.js +92 -30
- package/dist/monitoring/ContextWedgeSentinel.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +14 -3
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +63 -63
- package/upgrades/1.3.338.md +97 -0
- package/upgrades/aup-wedge-fresh-api.eli16.md +45 -0
- package/upgrades/side-effects/aup-wedge-fresh-api.md +83 -0
- package/upgrades/side-effects/owner-suspect-breaker.md +52 -0
|
@@ -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,
|
|
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"}
|
package/dist/commands/server.js
CHANGED
|
@@ -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 —
|
|
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,
|
|
5837
|
-
wedgeSentinel.on('dry-run', (e) => notifier.record('dry-run', 'context-wedge', e.sessionName,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 };
|