instar 1.3.318 → 1.3.320
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/core/AgeKillBackoff.d.ts +52 -0
- package/dist/core/AgeKillBackoff.d.ts.map +1 -0
- package/dist/core/AgeKillBackoff.js +88 -0
- package/dist/core/AgeKillBackoff.js.map +1 -0
- package/dist/core/SessionManager.d.ts +4 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +29 -1
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/types.d.ts +5 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/monitoring/CommitmentTracker.d.ts +9 -4
- package/dist/monitoring/CommitmentTracker.d.ts.map +1 -1
- package/dist/monitoring/CommitmentTracker.js +36 -38
- package/dist/monitoring/CommitmentTracker.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +4 -4
- package/src/templates/scripts/instar-watchdog.sh +5 -1
- package/upgrades/1.3.319.md +20 -0
- package/upgrades/1.3.320.md +20 -0
- package/upgrades/side-effects/age-kill-backoff.md +75 -0
- package/upgrades/side-effects/hermetic-unit-suite.md +69 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgeKillBackoff — a per-session back-off ledger for the SessionManager age-gate.
|
|
3
|
+
*
|
|
4
|
+
* The age-gate (SessionManager.monitorTick) runs every 5 seconds. When a session is
|
|
5
|
+
* past its max age and idle-at-prompt, it requests a kill via the ReapAuthority. If the
|
|
6
|
+
* §P2 KEEP-guard vetoes that kill (the session got a recent user message, is topic-bound,
|
|
7
|
+
* holds a commitment, …), the session correctly survives — but the age-gate used to
|
|
8
|
+
* re-request the kill every 5 seconds forever (720 attempts/hour/session → the 2026-06-05
|
|
9
|
+
* 17,503-line log flood + wasted CPU that read as "heavy load").
|
|
10
|
+
*
|
|
11
|
+
* This ledger makes the age-gate RESPECT the guard's verdict: after a veto, it suppresses
|
|
12
|
+
* re-requests for `backoffMs` (so a kept session is re-checked on a slow cadence, not every
|
|
13
|
+
* tick). It changes only how OFTEN the age-gate asks — never WHICH sessions are killed
|
|
14
|
+
* (the KEEP-guard remains the sole authority). A genuinely-idle-abandoned session has no
|
|
15
|
+
* keep-reason, so its first request returns terminated:true and it dies exactly as before.
|
|
16
|
+
*
|
|
17
|
+
* Pure logic, injectable clock, bounded memory — unit-testable in isolation (mirrors
|
|
18
|
+
* AttentionTopicGuard).
|
|
19
|
+
*/
|
|
20
|
+
export interface AgeKillBackoffOptions {
|
|
21
|
+
/** Suppress age-kill re-requests for this long after a veto. 0 disables back-off. */
|
|
22
|
+
backoffMs: number;
|
|
23
|
+
/** Hard cap on distinct sessions tracked (memory bound; oldest-evicted). */
|
|
24
|
+
maxTracked: number;
|
|
25
|
+
}
|
|
26
|
+
export declare const DEFAULT_AGE_KILL_BACKOFF: AgeKillBackoffOptions;
|
|
27
|
+
export declare class AgeKillBackoff {
|
|
28
|
+
private readonly backoffMs;
|
|
29
|
+
private readonly maxTracked;
|
|
30
|
+
/** sessionId -> epoch ms until which age-kill re-requests are suppressed. */
|
|
31
|
+
private readonly suppressedUntil;
|
|
32
|
+
constructor(opts?: Partial<AgeKillBackoffOptions>);
|
|
33
|
+
/** Whether the age-gate may request a kill for this session right now. False while the
|
|
34
|
+
* session is inside its post-veto back-off window. With backoffMs=0, always true. */
|
|
35
|
+
shouldRequest(sessionId: string, nowMs: number): boolean;
|
|
36
|
+
/** Record that the guard KEPT this session (kill vetoed) — back off re-requests. */
|
|
37
|
+
recordVeto(sessionId: string, nowMs: number): void;
|
|
38
|
+
/** The session was actually killed — drop its state. */
|
|
39
|
+
recordKilled(sessionId: string): void;
|
|
40
|
+
/** Session is gone (cleanup on removal). */
|
|
41
|
+
clear(sessionId: string): void;
|
|
42
|
+
/** A session's state changed materially (e.g. a new user message / injection) — drop the
|
|
43
|
+
* back-off so it is re-evaluated at the next tick rather than staying suppressed. */
|
|
44
|
+
reset(sessionId: string): void;
|
|
45
|
+
/** Test/inspection seam — ms remaining in the back-off window (0 if not suppressed). */
|
|
46
|
+
remainingMs(sessionId: string, nowMs: number): number;
|
|
47
|
+
/** Test/inspection seam. */
|
|
48
|
+
get trackedCount(): number;
|
|
49
|
+
/** Drop the oldest entry while over the cap (insertion-ordered Map). */
|
|
50
|
+
private evictIfNeeded;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=AgeKillBackoff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgeKillBackoff.d.ts","sourceRoot":"","sources":["../../src/core/AgeKillBackoff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,qBAAqB;IACpC,qFAAqF;IACrF,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,wBAAwB,EAAE,qBAGtC,CAAC;AAQF,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA6B;gBAEjD,IAAI,GAAE,OAAO,CAAC,qBAAqB,CAAM;IAOrD;0FACsF;IACtF,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAMxD,oFAAoF;IACpF,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAMlD,wDAAwD;IACxD,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIrC,4CAA4C;IAC5C,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI9B;0FACsF;IACtF,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI9B,wFAAwF;IACxF,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAKrD,4BAA4B;IAC5B,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,wEAAwE;IACxE,OAAO,CAAC,aAAa;CAOtB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgeKillBackoff — a per-session back-off ledger for the SessionManager age-gate.
|
|
3
|
+
*
|
|
4
|
+
* The age-gate (SessionManager.monitorTick) runs every 5 seconds. When a session is
|
|
5
|
+
* past its max age and idle-at-prompt, it requests a kill via the ReapAuthority. If the
|
|
6
|
+
* §P2 KEEP-guard vetoes that kill (the session got a recent user message, is topic-bound,
|
|
7
|
+
* holds a commitment, …), the session correctly survives — but the age-gate used to
|
|
8
|
+
* re-request the kill every 5 seconds forever (720 attempts/hour/session → the 2026-06-05
|
|
9
|
+
* 17,503-line log flood + wasted CPU that read as "heavy load").
|
|
10
|
+
*
|
|
11
|
+
* This ledger makes the age-gate RESPECT the guard's verdict: after a veto, it suppresses
|
|
12
|
+
* re-requests for `backoffMs` (so a kept session is re-checked on a slow cadence, not every
|
|
13
|
+
* tick). It changes only how OFTEN the age-gate asks — never WHICH sessions are killed
|
|
14
|
+
* (the KEEP-guard remains the sole authority). A genuinely-idle-abandoned session has no
|
|
15
|
+
* keep-reason, so its first request returns terminated:true and it dies exactly as before.
|
|
16
|
+
*
|
|
17
|
+
* Pure logic, injectable clock, bounded memory — unit-testable in isolation (mirrors
|
|
18
|
+
* AttentionTopicGuard).
|
|
19
|
+
*/
|
|
20
|
+
export const DEFAULT_AGE_KILL_BACKOFF = {
|
|
21
|
+
backoffMs: 10 * 60 * 1000, // 10 minutes → 6 attempts/hr (was 720/hr)
|
|
22
|
+
maxTracked: 1024,
|
|
23
|
+
};
|
|
24
|
+
function coerceNonNegInt(v, fallback) {
|
|
25
|
+
const n = typeof v === 'number' ? v : NaN;
|
|
26
|
+
if (!Number.isFinite(n) || n < 0)
|
|
27
|
+
return fallback;
|
|
28
|
+
return Math.floor(n);
|
|
29
|
+
}
|
|
30
|
+
export class AgeKillBackoff {
|
|
31
|
+
backoffMs;
|
|
32
|
+
maxTracked;
|
|
33
|
+
/** sessionId -> epoch ms until which age-kill re-requests are suppressed. */
|
|
34
|
+
suppressedUntil = new Map();
|
|
35
|
+
constructor(opts = {}) {
|
|
36
|
+
const d = DEFAULT_AGE_KILL_BACKOFF;
|
|
37
|
+
// backoffMs may be 0 (disable) — only a negative/NaN falls back to the default.
|
|
38
|
+
this.backoffMs = coerceNonNegInt(opts.backoffMs, d.backoffMs);
|
|
39
|
+
this.maxTracked = Math.max(1, coerceNonNegInt(opts.maxTracked, d.maxTracked));
|
|
40
|
+
}
|
|
41
|
+
/** Whether the age-gate may request a kill for this session right now. False while the
|
|
42
|
+
* session is inside its post-veto back-off window. With backoffMs=0, always true. */
|
|
43
|
+
shouldRequest(sessionId, nowMs) {
|
|
44
|
+
if (this.backoffMs === 0)
|
|
45
|
+
return true;
|
|
46
|
+
const until = this.suppressedUntil.get(sessionId);
|
|
47
|
+
return until == null || nowMs >= until;
|
|
48
|
+
}
|
|
49
|
+
/** Record that the guard KEPT this session (kill vetoed) — back off re-requests. */
|
|
50
|
+
recordVeto(sessionId, nowMs) {
|
|
51
|
+
if (this.backoffMs === 0)
|
|
52
|
+
return;
|
|
53
|
+
this.suppressedUntil.set(sessionId, nowMs + this.backoffMs);
|
|
54
|
+
this.evictIfNeeded();
|
|
55
|
+
}
|
|
56
|
+
/** The session was actually killed — drop its state. */
|
|
57
|
+
recordKilled(sessionId) {
|
|
58
|
+
this.suppressedUntil.delete(sessionId);
|
|
59
|
+
}
|
|
60
|
+
/** Session is gone (cleanup on removal). */
|
|
61
|
+
clear(sessionId) {
|
|
62
|
+
this.suppressedUntil.delete(sessionId);
|
|
63
|
+
}
|
|
64
|
+
/** A session's state changed materially (e.g. a new user message / injection) — drop the
|
|
65
|
+
* back-off so it is re-evaluated at the next tick rather than staying suppressed. */
|
|
66
|
+
reset(sessionId) {
|
|
67
|
+
this.suppressedUntil.delete(sessionId);
|
|
68
|
+
}
|
|
69
|
+
/** Test/inspection seam — ms remaining in the back-off window (0 if not suppressed). */
|
|
70
|
+
remainingMs(sessionId, nowMs) {
|
|
71
|
+
const until = this.suppressedUntil.get(sessionId);
|
|
72
|
+
return until != null && until > nowMs ? until - nowMs : 0;
|
|
73
|
+
}
|
|
74
|
+
/** Test/inspection seam. */
|
|
75
|
+
get trackedCount() {
|
|
76
|
+
return this.suppressedUntil.size;
|
|
77
|
+
}
|
|
78
|
+
/** Drop the oldest entry while over the cap (insertion-ordered Map). */
|
|
79
|
+
evictIfNeeded() {
|
|
80
|
+
while (this.suppressedUntil.size > this.maxTracked) {
|
|
81
|
+
const oldest = this.suppressedUntil.keys().next().value;
|
|
82
|
+
if (oldest === undefined)
|
|
83
|
+
break;
|
|
84
|
+
this.suppressedUntil.delete(oldest);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=AgeKillBackoff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgeKillBackoff.js","sourceRoot":"","sources":["../../src/core/AgeKillBackoff.ts"],"names":[],"mappings":"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"}
|
|
@@ -157,6 +157,10 @@ export declare class SessionManager extends EventEmitter {
|
|
|
157
157
|
* once per session, not every tick.
|
|
158
158
|
*/
|
|
159
159
|
private overAgeButActiveLogged;
|
|
160
|
+
/** Per-session back-off so the age-gate respects the KEEP-guard's verdict: after a kill
|
|
161
|
+
* is vetoed (session kept), suppress re-requests for a window instead of re-asking every
|
|
162
|
+
* 5s tick (the 2026-06-05 17,503-line flood). Constructed in the constructor. */
|
|
163
|
+
private ageKillBackoff;
|
|
160
164
|
/** Cached count of running sessions, updated asynchronously by the monitor tick.
|
|
161
165
|
* Used by the health endpoint to avoid synchronous tmux polling. */
|
|
162
166
|
private _cachedRunningCount;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../src/core/SessionManager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAM3C,OAAO,EAAE,qBAAqB,EAAoC,MAAM,4BAA4B,CAAC;AACrG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAMhD,+CAA+C;AAC/C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,oCAAoC;AACpC,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,GAAG,UAAU,CAAC;AAEtE,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAGD,OAAO,EAAE,UAAU,EAAqB,MAAM,iBAAiB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAGjE,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAiB,SAAS,EAAE,MAAM,YAAY,CAAC;AAC1F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAa9E,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../src/core/SessionManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,6 +27,7 @@ import { buildInjectionTag } from '../types/pipeline.js';
|
|
|
27
27
|
import { sanitizeSenderName, sanitizeTopicName } from '../utils/sanitize.js';
|
|
28
28
|
import { getTelegramInboundDir } from '../messaging/shared/telegramInboundFiles.js';
|
|
29
29
|
import { SessionBuildContextStore } from './SessionBuildContextStore.js';
|
|
30
|
+
import { AgeKillBackoff } from './AgeKillBackoff.js';
|
|
30
31
|
/** Absolute maximum session duration (4 hours) — safety net for sessions without explicit timeout */
|
|
31
32
|
const DEFAULT_MAX_DURATION_MINUTES = 240;
|
|
32
33
|
/** Minutes of idle-at-prompt before a non-protected session is killed */
|
|
@@ -224,6 +225,10 @@ export class SessionManager extends EventEmitter {
|
|
|
224
225
|
* once per session, not every tick.
|
|
225
226
|
*/
|
|
226
227
|
overAgeButActiveLogged = new Set();
|
|
228
|
+
/** Per-session back-off so the age-gate respects the KEEP-guard's verdict: after a kill
|
|
229
|
+
* is vetoed (session kept), suppress re-requests for a window instead of re-asking every
|
|
230
|
+
* 5s tick (the 2026-06-05 17,503-line flood). Constructed in the constructor. */
|
|
231
|
+
ageKillBackoff;
|
|
227
232
|
/** Cached count of running sessions, updated asynchronously by the monitor tick.
|
|
228
233
|
* Used by the health endpoint to avoid synchronous tmux polling. */
|
|
229
234
|
_cachedRunningCount = 0;
|
|
@@ -237,6 +242,10 @@ export class SessionManager extends EventEmitter {
|
|
|
237
242
|
super();
|
|
238
243
|
this.config = config;
|
|
239
244
|
this.state = state;
|
|
245
|
+
// Age-gate kill back-off: default 10 min between re-requests for a kept session
|
|
246
|
+
// (config.ageKillBackoffMinutes; 0 disables → legacy every-tick behavior).
|
|
247
|
+
const backoffMin = typeof config.ageKillBackoffMinutes === 'number' ? config.ageKillBackoffMinutes : 10;
|
|
248
|
+
this.ageKillBackoff = new AgeKillBackoff({ backoffMs: Math.max(0, backoffMin) * 60_000 });
|
|
240
249
|
if (config.respawnBuildContext?.enabled) {
|
|
241
250
|
this.buildContextStore = new SessionBuildContextStore(state, {
|
|
242
251
|
maxAgeMs: config.respawnBuildContext.maxAgeMs,
|
|
@@ -802,6 +811,13 @@ rm() { "${shimRunner}" rm "$@"; }
|
|
|
802
811
|
// Fall through to the rest of the loop — do NOT skip idle detection,
|
|
803
812
|
// because if the session DOES go idle, we still want it killed.
|
|
804
813
|
}
|
|
814
|
+
else if (!this.ageKillBackoff.shouldRequest(session.id, Date.now())) {
|
|
815
|
+
// Over age + idle, but a recent kill-request for this session was VETOED by
|
|
816
|
+
// the KEEP-guard (recent user message / topic-bound / commitment). Respect
|
|
817
|
+
// that verdict: stay silent and back off instead of re-asking every 5s tick
|
|
818
|
+
// (the 2026-06-05 17,503-line flood). Fall through to idle detection — when
|
|
819
|
+
// the keep-reason lapses, the back-off expires and we re-evaluate then.
|
|
820
|
+
}
|
|
805
821
|
else {
|
|
806
822
|
// Check for unanswered injection before timeout kill
|
|
807
823
|
const pendingInjection = this.pendingInjections.get(session.tmuxSession);
|
|
@@ -822,10 +838,22 @@ rm() { "${shimRunner}" rm "$@"; }
|
|
|
822
838
|
// gate, and — critically — gains the P2 KEEP-guard's topic-bound
|
|
823
839
|
// grace, so a session that just received a user message is not
|
|
824
840
|
// age-killed out from under the user.
|
|
825
|
-
await this.terminateSession(session.id, 'age-limit', {
|
|
841
|
+
const ageKillResult = await this.terminateSession(session.id, 'age-limit', {
|
|
826
842
|
finalStatus: 'killed',
|
|
827
843
|
disposition: 'terminal',
|
|
828
844
|
});
|
|
845
|
+
if (ageKillResult.terminated) {
|
|
846
|
+
// Actually killed — drop any back-off state for the (now gone) session.
|
|
847
|
+
this.ageKillBackoff.recordKilled(session.id);
|
|
848
|
+
}
|
|
849
|
+
else {
|
|
850
|
+
// The KEEP-guard kept it (skipped:<reason>). Respect that and back off:
|
|
851
|
+
// suppress re-requests for the back-off window instead of nagging every
|
|
852
|
+
// tick. ONE informative line — not 17,503.
|
|
853
|
+
this.ageKillBackoff.recordVeto(session.id, Date.now());
|
|
854
|
+
console.warn(`[SessionManager] Session "${session.name}" is over age but KEPT (${ageKillResult.skipped ?? 'guard'}); ` +
|
|
855
|
+
`backing off age re-checks. It is NOT being killed.`);
|
|
856
|
+
}
|
|
829
857
|
continue;
|
|
830
858
|
}
|
|
831
859
|
}
|