instar 1.3.345 → 1.3.346

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-06-06T05:35:52.668Z",
5
- "instarVersion": "1.3.345",
4
+ "generatedAt": "2026-06-06T05:44:57.394Z",
5
+ "instarVersion": "1.3.346",
6
6
  "entryCount": 199,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -11,7 +11,7 @@
11
11
  "domain": "identity",
12
12
  "sourcePath": "src/core/PostUpdateMigrator.ts",
13
13
  "installedPath": ".instar/hooks/instar/session-start.sh",
14
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
14
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
15
15
  "since": "2025-01-01"
16
16
  },
17
17
  "hook:dangerous-command-guard": {
@@ -20,7 +20,7 @@
20
20
  "domain": "safety",
21
21
  "sourcePath": "src/core/PostUpdateMigrator.ts",
22
22
  "installedPath": ".instar/hooks/instar/dangerous-command-guard.sh",
23
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
23
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
24
24
  "since": "2025-01-01"
25
25
  },
26
26
  "hook:grounding-before-messaging": {
@@ -29,7 +29,7 @@
29
29
  "domain": "safety",
30
30
  "sourcePath": "src/core/PostUpdateMigrator.ts",
31
31
  "installedPath": ".instar/hooks/instar/grounding-before-messaging.sh",
32
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
32
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
33
33
  "since": "2025-01-01"
34
34
  },
35
35
  "hook:compaction-recovery": {
@@ -38,7 +38,7 @@
38
38
  "domain": "identity",
39
39
  "sourcePath": "src/core/PostUpdateMigrator.ts",
40
40
  "installedPath": ".instar/hooks/instar/compaction-recovery.sh",
41
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
41
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
42
42
  "since": "2025-01-01"
43
43
  },
44
44
  "hook:external-operation-gate": {
@@ -47,7 +47,7 @@
47
47
  "domain": "safety",
48
48
  "sourcePath": "src/core/PostUpdateMigrator.ts",
49
49
  "installedPath": ".instar/hooks/instar/external-operation-gate.js",
50
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
50
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
51
51
  "since": "2025-01-01"
52
52
  },
53
53
  "hook:deferral-detector": {
@@ -56,7 +56,7 @@
56
56
  "domain": "safety",
57
57
  "sourcePath": "src/core/PostUpdateMigrator.ts",
58
58
  "installedPath": ".instar/hooks/instar/deferral-detector.js",
59
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
59
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
60
60
  "since": "2025-01-01"
61
61
  },
62
62
  "hook:self-stop-guard": {
@@ -65,7 +65,7 @@
65
65
  "domain": "coherence",
66
66
  "sourcePath": "src/core/PostUpdateMigrator.ts",
67
67
  "installedPath": ".instar/hooks/instar/self-stop-guard.js",
68
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
68
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
69
69
  "since": "2025-01-01"
70
70
  },
71
71
  "hook:post-action-reflection": {
@@ -74,7 +74,7 @@
74
74
  "domain": "evolution",
75
75
  "sourcePath": "src/core/PostUpdateMigrator.ts",
76
76
  "installedPath": ".instar/hooks/instar/post-action-reflection.js",
77
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
77
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
78
78
  "since": "2025-01-01"
79
79
  },
80
80
  "hook:external-communication-guard": {
@@ -83,7 +83,7 @@
83
83
  "domain": "safety",
84
84
  "sourcePath": "src/core/PostUpdateMigrator.ts",
85
85
  "installedPath": ".instar/hooks/instar/external-communication-guard.js",
86
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
86
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
87
87
  "since": "2025-01-01"
88
88
  },
89
89
  "hook:scope-coherence-collector": {
@@ -92,7 +92,7 @@
92
92
  "domain": "coherence",
93
93
  "sourcePath": "src/core/PostUpdateMigrator.ts",
94
94
  "installedPath": ".instar/hooks/instar/scope-coherence-collector.js",
95
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
95
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
96
96
  "since": "2025-01-01"
97
97
  },
98
98
  "hook:scope-coherence-checkpoint": {
@@ -101,7 +101,7 @@
101
101
  "domain": "coherence",
102
102
  "sourcePath": "src/core/PostUpdateMigrator.ts",
103
103
  "installedPath": ".instar/hooks/instar/scope-coherence-checkpoint.js",
104
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
104
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
105
105
  "since": "2025-01-01"
106
106
  },
107
107
  "hook:free-text-guard": {
@@ -110,7 +110,7 @@
110
110
  "domain": "safety",
111
111
  "sourcePath": "src/core/PostUpdateMigrator.ts",
112
112
  "installedPath": ".instar/hooks/instar/free-text-guard.sh",
113
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
113
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
114
114
  "since": "2025-01-01"
115
115
  },
116
116
  "hook:claim-intercept": {
@@ -119,7 +119,7 @@
119
119
  "domain": "coherence",
120
120
  "sourcePath": "src/core/PostUpdateMigrator.ts",
121
121
  "installedPath": ".instar/hooks/instar/claim-intercept.js",
122
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
122
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
123
123
  "since": "2025-01-01"
124
124
  },
125
125
  "hook:claim-intercept-response": {
@@ -128,7 +128,7 @@
128
128
  "domain": "coherence",
129
129
  "sourcePath": "src/core/PostUpdateMigrator.ts",
130
130
  "installedPath": ".instar/hooks/instar/claim-intercept-response.js",
131
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
131
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
132
132
  "since": "2025-01-01"
133
133
  },
134
134
  "hook:stop-gate-router": {
@@ -137,7 +137,7 @@
137
137
  "domain": "safety",
138
138
  "sourcePath": "src/core/PostUpdateMigrator.ts",
139
139
  "installedPath": ".instar/hooks/instar/stop-gate-router.js",
140
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
140
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
141
141
  "since": "2025-01-01"
142
142
  },
143
143
  "hook:auto-approve-permissions": {
@@ -146,7 +146,7 @@
146
146
  "domain": "safety",
147
147
  "sourcePath": "src/core/PostUpdateMigrator.ts",
148
148
  "installedPath": ".instar/hooks/instar/auto-approve-permissions.js",
149
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
149
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
150
150
  "since": "2025-01-01"
151
151
  },
152
152
  "job:health-check": {
@@ -1538,7 +1538,7 @@
1538
1538
  "type": "subsystem",
1539
1539
  "domain": "updates",
1540
1540
  "sourcePath": "src/core/PostUpdateMigrator.ts",
1541
- "contentHash": "6449c8a2aaab14962a8e871a700feea312280a30e08d40f35d6c4af7b19a6e90",
1541
+ "contentHash": "2562b5b7c37deb568e00eefebc9acc07571a5e5ccc251f6e424e7e63039ee297",
1542
1542
  "since": "2025-01-01"
1543
1543
  },
1544
1544
  "subsystem:scheduler": {
@@ -0,0 +1,57 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ Honest turn-receipts — the standby (🔭) system now tells the truth about WHY a
9
+ turn failed instead of saying "actively working" while a session is dead.
10
+
11
+ Three incidents in two days had one symptom: a delivered message that never got
12
+ a reply, while the standby showed "🔭 actively working." Root: the tier-3
13
+ assessment classified a session "working" whenever it had a live child process
14
+ — but a rate-limited, policy-wedged, or context-exhausted session HAS a live
15
+ process (the model CLI is alive, just failing every turn). The live process
16
+ forced the lie. Separately, the "conversation too long" standby fired on that
17
+ phrase anywhere in the buffer, so a stale scrolled-past mention surfaced as
18
+ noise on healthy sessions.
19
+
20
+ New `StuckSignatureClassifier` (pure, tail-gated, signal-only) classifies a
21
+ live-but-failing session from its LIVE tmux tail — rate-limited / policy-wedge /
22
+ context-wedge / context-too-long — and PresenceProxy surfaces the real reason
23
+ instead of "working". Tail-gating (the signature must be the live tail, not a
24
+ scrollback mention) is the same discriminator that kills the "conversation too
25
+ long" noise. The classifier defers to any recovery sentinel that already owns a
26
+ session's recovery, so the user always hears one voice. Recovery itself is
27
+ unchanged — this only makes the messaging honest.
28
+
29
+ ## What to Tell Your User
30
+
31
+ When a message of yours goes unanswered, I'll now tell you the real reason if I
32
+ can't reply — "I've hit the usage limit, resets 10:30pm", "my session got stuck
33
+ on a content-policy error, resend your last message" — instead of a misleading
34
+ "actively working." And the "conversation too long" messages that used to pop up
35
+ when nothing was wrong are gone: that only fires now when it's actually
36
+ happening.
37
+
38
+ ## Summary of New Capabilities
39
+
40
+ - `StuckSignatureClassifier` — tail-gated classification of a live-but-failing
41
+ session (rate-limited / policy-wedge / context-wedge / context-too-long) with
42
+ an honest user-facing message per kind. Pure + signal-only.
43
+ - PresenceProxy tier-3 surfaces the honest reason instead of "working", defers
44
+ to an owning recovery sentinel (`isStuckRecoveryActive`), and no longer fires
45
+ the context-too-long notice on a stale scrollback mention.
46
+ - CLAUDE.md "Honest standby (turn-receipts)" section so agents can explain the
47
+ new behavior and the noise fix.
48
+
49
+ ## Evidence
50
+
51
+ Grounded in the real 2026-06-04/05 incidents (rate-limit, AUP-wedge) using the
52
+ verbatim pane text. 30+ new unit tests both sides of every boundary
53
+ (honest-when-stuck AND quiet-when-fine, incl. the stale-scrollback noise case
54
+ and prose-mentions-a-limit false positive) + a behavioral test driving the real
55
+ fireTier3 with a live child process (wedge → honest, NOT "working"; deference →
56
+ silent) + migrator add/idempotent + server.ts wiring guard. All 119 existing
57
+ presence tests pass; tsc clean; preflight PASS.
@@ -0,0 +1,47 @@
1
+ # ELI16 — Honest Turn-Receipts
2
+
3
+ ## The problem
4
+
5
+ Three times in two days, the same thing happened: you sent me a message, you
6
+ saw "✓ Delivered" and "🔭 actively working" — and then nothing. No reply. You
7
+ found out by screenshot each time. Three different reasons underneath (I'd hit
8
+ the usage limit, or my session got stuck on a content-policy error, or the
9
+ conversation ran out of room), but ONE misleading symptom: the system kept
10
+ telling you I was "actively working" when I was actually dead in the water.
11
+
12
+ Why did it lie? Because the way it checked "is this session working?" was "is
13
+ its program still running?" — and a stuck session's program IS still running.
14
+ It's alive, it's even printing stuff to the screen; it just can't answer. So
15
+ the live program fooled the check into saying "working."
16
+
17
+ You also noticed a related annoyance: "conversation too long" messages popping
18
+ up often even when the conversation was fine. Same kind of bug — the system was
19
+ finding that phrase ANYWHERE on the screen, including an old one from an hour
20
+ ago that had already been dealt with and scrolled up out of the way.
21
+
22
+ ## What this fixes
23
+
24
+ Now, before the system says "working," it reads the bottom of the screen — the
25
+ LIVE part, what's happening right now — and checks for the known "alive but
26
+ can't reply" situations. If it finds one, it tells you the truth instead:
27
+
28
+ - "I've hit the usage limit (resets 10:30pm) — I'll pick back up automatically,
29
+ your messages aren't lost."
30
+ - "My session got stuck on a content-policy error — please resend your last
31
+ message."
32
+ - "This conversation got too long — I'm starting fresh, resend your last one."
33
+
34
+ And the "conversation too long" noise is gone: it only fires if that's what's
35
+ ACTUALLY happening right now at the bottom of the screen, not an old mention
36
+ that scrolled by.
37
+
38
+ ## Two safety rules
39
+
40
+ 1. **It only reads — it doesn't act.** Fixing the stuck session is still the
41
+ job of the recovery system. This part just stops lying about what's wrong.
42
+ 2. **One voice.** If the recovery system is already telling you about a stuck
43
+ session, this stays quiet so you don't get two messages about the same thing.
44
+
45
+ Tested with the exact text from the real screenshots you sent — 30+ new checks
46
+ covering both "say the honest thing when stuck" and "stay quiet when fine,"
47
+ plus all 119 existing standby checks still pass.
@@ -0,0 +1,90 @@
1
+ # Side-Effects Review — Honest Turn-Receipts
2
+
3
+ **Version / slug:** `honest-turn-receipts`
4
+ **Date:** `2026-06-06`
5
+ **Author:** `Echo (instar-dev agent, session-robustness topic — Justin: "finish out item number four" + the "conversation too long is noise" observation)`
6
+ **Second-pass reviewer:** `self-adversarial pass over false-positive surface (the one way an honest classifier can become a new liar) + double-messaging`
7
+
8
+ ## Summary of the change
9
+
10
+ A pure tail-gated `StuckSignatureClassifier` recognizes a live-but-failing
11
+ session (rate-limited / policy-wedge / context-wedge / context-too-long) from
12
+ its LIVE tmux tail and returns an honest user-facing message. PresenceProxy's
13
+ `fireTier3` runs it after the existing quota check and before the process-tree
14
+ "working" assessment, surfacing the real reason instead of "working", deferring
15
+ to an owning recovery sentinel, and preserving the context-exhaustion recovery
16
+ path. The un-tail-gated context-exhaustion block it replaces was the source of
17
+ the "conversation too long" noise. Files: `StuckSignatureClassifier.ts` (new),
18
+ `PresenceProxy.ts`, `server.ts` wiring, `PostUpdateMigrator.ts` section, tests.
19
+
20
+ ## Decision-point inventory
21
+
22
+ - Stuck classification — **add (detector)** — signal only; tail-gated.
23
+ - fireTier3 placement (after quota, before process-tree) — **modify** — the
24
+ exact seam where a live process forced the "working" lie.
25
+ - context-exhaustion block — **replace** — same recovery path, now tail-gated
26
+ (fixes the noise) and folded into the unified honest block.
27
+ - `isStuckRecoveryActive` deference — **add (suppression)** — net reduction in
28
+ messaging authority (yields to an owning sentinel).
29
+
30
+ ## 1. Over-block
31
+
32
+ Nothing is blocked — no authority added. The honest message can only fire at
33
+ tier-3 (5 minutes of an unanswered user message), so a session that replied
34
+ promptly never reaches it. The deference callback REMOVES a double-message case
35
+ (standby + sentinel both speaking).
36
+
37
+ ## 2. Under-block (false-positive surface — the real risk)
38
+
39
+ The danger of an honest classifier is becoming a NEW liar (saying "stuck" about
40
+ a healthy session). Defenses, each tested:
41
+ - **Tail-gating:** the signature must be the live tail, not scrollback — kills
42
+ the stale "conversation too long" mention (the reported noise) and a session
43
+ that quoted an error then kept working.
44
+ - **Prose-vs-block rate-limit patterns:** "you've hit your limit" / "limit ·
45
+ resets" match; "when you hit your usage limit, the session pauses" does not.
46
+ - **AUP repetition gate** (inherited from classifyWedgeTail): a single benign
47
+ policy rejection is not a wedge.
48
+ - **Normal-compaction suppression:** the compaction lifecycle banner is not
49
+ treated as context-too-long.
50
+ Residual under-block: a stuck session whose signature the provider rewords
51
+ escapes — inherent to signature matching; the tier-3 LLM path still runs as the
52
+ fallback for the unmatched case (unchanged).
53
+
54
+ ## 3. Level-of-abstraction fit
55
+
56
+ The classifier is a pure module beside the sentinels whose detectors it reuses
57
+ (`classifyWedgeTail`). The wiring lives in `fireTier3` (which owns the
58
+ assessment) and reuses the existing `sendProxyMessage` surface and the composed
59
+ `wedgeRecoveryActive` checker (same one the SessionReaper veto uses). No new
60
+ message path, no new state store.
61
+
62
+ ## 4. Signal vs authority compliance
63
+
64
+ **Required reference:** `docs/signal-vs-authority.md`
65
+
66
+ - [x] Pure signal. The classifier decides nothing; it answers a question.
67
+ Recovery is unchanged (the sentinels'). The only behavioral delta is WHICH
68
+ honest string the standby sends, plus a new SUPPRESSION (deference). No new
69
+ decision-maker, and a net reduction in messaging authority.
70
+
71
+ ## 5. Interactions
72
+
73
+ - **Quota-exhaustion block (runs first):** owns the bare usage-limit form; the
74
+ honest classifier is the backstop for the forms it misses + the wedges +
75
+ tail-gated context-too-long. No double-handling (the first to match returns).
76
+ - **RateLimitSentinel:** already suppresses ALL tiers via
77
+ `hasActiveRateLimitRecovery` (unchanged); the honest rate-limit branch is the
78
+ backstop when no sentinel owns it (e.g. the cross-machine EXO case).
79
+ - **ContextWedgeSentinel:** when it is mid-recovery, `isStuckRecoveryActive`
80
+ makes the standby defer; otherwise the honest message is the only voice.
81
+ - **Existing tests:** all 119 presence-proxy tests pass unmodified; the
82
+ context-exhaustion test's source-grep section was updated to the new wiring.
83
+
84
+ ## 6. External surfaces / 7. Rollback
85
+
86
+ No API, no route, no config key (default-on behavioral change; the new config
87
+ field is an optional injected callback wired in server.ts). One idempotent
88
+ CLAUDE.md section (marker 'Honest standby (turn-receipts)'). Rollback = revert;
89
+ the standby returns to classifying live-but-failing sessions as "working" and
90
+ the context-too-long noise returns.