instar 1.3.341 → 1.3.342

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,76 @@
1
+ # Side-Effects Review — GuardPostureTripwire
2
+
3
+ **Version / slug:** `guard-posture-tripwire`
4
+ **Date:** `2026-06-06`
5
+ **Author:** `Echo (instar-dev agent, session-robustness topic per Justin's "work on more robust ways to handle these scenarios")`
6
+ **Second-pass reviewer:** `self-adversarial pass over alarm fatigue + boot-safety (the two ways a boot-time alarm can go wrong)`
7
+
8
+ ## Summary of the change
9
+
10
+ A boot-time detector compares the resolved guard posture (every
11
+ `monitoring.*` enabled flag + `scheduler.enabled`) against the previous
12
+ boot's persisted snapshot. enabled→disabled → loud log + one aggregated
13
+ `logs/guard-posture.jsonl` row + ONE aggregated HIGH Attention item;
14
+ disabled→enabled → log + breadcrumb only; first boot → baseline only.
15
+ Files: `GuardPostureTripwire.ts` (new), `server.ts` boot wiring,
16
+ `PostUpdateMigrator.ts` CLAUDE.md section, three test files, spec.
17
+
18
+ ## Decision-point inventory
19
+
20
+ - Posture extraction — **add (read-only)** — resolved config in, key/boolean map out; generic convention, no registry.
21
+ - Transition diff — **add (pure)** — intersection-only (shape changes are not flips).
22
+ - Attention emit — **add (signal)** — one aggregated HIGH item per boot-with-disables; dedupe by stable id; absent Telegram → breadcrumb only.
23
+ - Snapshot write order — **deliberate** — baseline advances BEFORE alarms so an emit failure cannot cause repeat alarms.
24
+
25
+ ## 1. Over-block
26
+
27
+ Nothing is blocked — the tripwire has no authority. Worst noise case: an
28
+ operator deliberately disabling a guard gets exactly ONE Attention item at the
29
+ next boot (transition-based; the following boots are silent). A batch flip of
30
+ N guards is ONE item, not N (Bounded Notification Surface).
31
+
32
+ ## 2. Under-block
33
+
34
+ (a) A flip that is reverted BETWEEN boots (off at 2pm, back on at 5pm, no
35
+ restart in between) never trips — acceptable: the guard never actually ran
36
+ disabled. (b) Mid-run flips alarm only at the next boot — that is when config
37
+ takes effect, so the alarm coincides with the guard actually dying; with
38
+ auto-update restarts every ~30 min the window is bounded. (c) Guards that
39
+ don't follow the `enabled` convention (none today) would be invisible —
40
+ the convention IS the contract, documented in the spec.
41
+
42
+ ## 3. Level-of-abstraction fit
43
+
44
+ Lives in `monitoring/` beside the sentinels it watches over; wired in
45
+ server.ts boot exactly like the worktree detector (same emitAttention
46
+ adapter, same placement constraint). The CLAUDE.md knowledge rides the
47
+ existing migrateClaudeMd path with a content-sniff marker.
48
+
49
+ ## 4. Signal vs authority compliance
50
+
51
+ **Required reference:** `docs/signal-vs-authority.md`
52
+
53
+ - [x] Pure signal. Never re-enables, never blocks a boot (every failure path
54
+ degrades into `result.error` + a log line), never edits config. The
55
+ Attention item is the operator's consent surface, not an action.
56
+
57
+ ## 5. Interactions
58
+
59
+ - **Attention flood guard:** a single aggregated item with sourceContext
60
+ `guard-posture-tripwire` — inside every budget; HIGH priority is justified
61
+ (a dark guard is exactly the "user should know" class) and HIGH items are
62
+ never coalesced away.
63
+ - **AttentionQueue dedupe:** stable id (`guard-posture-disabled:<date>:<list>`)
64
+ makes a same-day re-emit a no-op via the existing id-collision path.
65
+ - **No Telegram:** breadcrumb still lands (the worktree-detector fallback
66
+ pattern); boot line says "breadcrumb only".
67
+ - **Snapshot corruption:** degrades to first-boot semantics + self-repairs.
68
+
69
+ ## 6. External surfaces / 7. Rollback
70
+
71
+ New files only: `state/guard-posture.json` (snapshot), `logs/guard-posture.jsonl`
72
+ (append-only history), one CLAUDE.md section (idempotent migration). No API,
73
+ no schema, no config key (default-on by design — a tripwire you can silently
74
+ disable would be the joke version of this feature; disabling it means deleting
75
+ the wiring, which is a reviewed code change). Rollback = revert; the files
76
+ stay as inert history.
@@ -1,41 +0,0 @@
1
- # Upgrade Guide — vNEXT
2
-
3
- <!-- assembled-by: assemble-next-md -->
4
- <!-- bump: patch -->
5
-
6
- ## What Changed
7
-
8
- Queued initial messages now survive server restarts. When a session is
9
- spawned for an inbound message, the pending inject is recorded durably
10
- (`<stateDir>/state/pending-injects/`) and cleared only after the message is
11
- actually typed into the session. On boot, `recoverPendingInjects` sweeps
12
- survivors: still-alive sessions get re-delivery through the normal readiness
13
- path; dead or >6h-old records are reported via DegradationReporter and
14
- retired — a loss is now always VISIBLE.
15
-
16
- Why: the auto-updater restarted the server while a fresh codex session was
17
- still booting; the in-memory pending inject died with the process, tmux
18
- survived idle, and the operator waited 50+ minutes on a silently dropped
19
- message (finding 8d300555). Delivery is at-least-once by design — a rare
20
- duplicate beats a silent drop.
21
-
22
- Also: the "Fresh-spawn fallback succeeded" log now honestly says "launched
23
- (inject pending)" — it printed before the inject ran.
24
-
25
- ## What to Tell Your User
26
-
27
- If your agent's server restarts at the exact moment you message it, your
28
- message no longer risks silently vanishing — it is delivered when the session
29
- finishes starting, even across the restart.
30
-
31
- ## Summary of New Capabilities
32
-
33
- - `SessionManager.recoverPendingInjects()` — boot-time orphaned-inject sweep
34
- (wired automatically; not a user-facing surface).
35
-
36
- ## Evidence
37
-
38
- 13 new tests (store CRUD/corruption, all four sweep verdicts incl. the live
39
- incident shape, and wiring-integrity through a real SessionManager: record
40
- visible on disk DURING the spawn→inject window, cleared after). Adjacent
41
- session suites green (53 tests); tsc clean.