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.
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +45 -0
- package/dist/commands/server.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +22 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/monitoring/GuardPostureTripwire.d.ts +90 -0
- package/dist/monitoring/GuardPostureTripwire.d.ts.map +1 -0
- package/dist/monitoring/GuardPostureTripwire.js +182 -0
- package/dist/monitoring/GuardPostureTripwire.js.map +1 -0
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +19 -19
- package/upgrades/1.3.342.md +85 -0
- package/upgrades/guard-posture-tripwire.eli16.md +48 -0
- package/upgrades/side-effects/guard-posture-tripwire.md +76 -0
- package/upgrades/1.3.341.md +0 -41
|
@@ -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.
|
package/upgrades/1.3.341.md
DELETED
|
@@ -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.
|