instar 1.3.260 → 1.3.261

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.
@@ -0,0 +1,52 @@
1
+ # Side-Effects Review — StaleBackstop detection accuracy (PR2 / D5)
2
+
3
+ ## What changed (mechanically)
4
+
5
+ `StaleSessionBackstop` no longer cries wolf on healthy long-running sessions:
6
+ 1. **Protected sessions are never escalated.** New `isProtectedSession?(session)` dep
7
+ (wired in server.ts to the reaper's `getProtectedSessions()`, matched by tmux name
8
+ or session name). A protected session — one the operator deliberately keeps alive —
9
+ skips BOTH escalation paths (no-progress and long-indeterminate).
10
+ 2. **Conversational/autonomous sessions get a forgiving window.** New
11
+ `conversationalEscalateMinutes` option (default 180, clamped to ≥ the job window).
12
+ The no-progress threshold is now `session.jobSlug ? unverifiableEscalateMinutes (30)
13
+ : max(conversationalEscalateMinutes, unverifiableEscalateMinutes)`. A job runs to
14
+ completion (strict 30-min window); a conversational/autonomous session legitimately
15
+ idles between turns and while waiting on multi-minute tool calls, so it gets 180.
16
+
17
+ ## Blast radius
18
+
19
+ - The fake-work guards (`hasForwardProgress`: tail-hash + cpu-seconds delta) are
20
+ UNTOUCHED — wedge detection is unchanged; this only widens the no-progress WINDOW for
21
+ conversational sessions and exempts protected ones.
22
+ - A genuinely-wedged JOB still escalates at 30 min (unchanged).
23
+ - A genuinely-wedged conversational session still escalates — just at 180 min, not 30.
24
+ Combined with PR1's calm lane, even that is a single calm heads-up, not topic-spam.
25
+ - Config additive + defaulted; absent config → defaults apply (180 / protected-from-reaper).
26
+
27
+ ## Failure modes considered
28
+
29
+ - **conversationalEscalateMinutes mis-set below the job window**: clamped up via
30
+ `max(...)` at the decision site, so it can never be MORE aggressive than the job window.
31
+ - **isProtectedSession absent** (older wiring / tests): optional-chained → no session
32
+ treated as protected (prior behavior), never throws.
33
+ - **Protected list by name vs id**: matched against both `tmuxSession` and `name`.
34
+
35
+ ## Non-goals
36
+
37
+ - Does NOT change delivery (that's PR1's lane).
38
+ - Does NOT auto-kill anything (the backstop remains signal-only).
39
+
40
+ ## Reversibility
41
+
42
+ `monitoring.staleBackstop.conversationalEscalateMinutes: 30` restores the old uniform
43
+ window; protection follows the existing `protectedSessions` list. Additive only.
44
+
45
+ ## Tests
46
+
47
+ Unit (stale-session-backstop.test.ts): protected session never escalates; the
48
+ conversational-vs-job threshold split (a healthy long conversational session at 35 min
49
+ does NOT escalate while a wedged job DOES). Existing mechanism tests pinned to the 30-min
50
+ window via `conversationalEscalateMinutes: M`. 82 standards + backstop tests green; tsc
51
+ clean. (Also: bumped the no-silent-fallbacks baseline 458→459 for PR1's lane fallback, and
52
+ tracked main's untacked `/secrets/sync-status` migrator section — both per Zero-Failure.)