instar 0.28.85 → 0.28.87

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.
Files changed (35) hide show
  1. package/dist/core/InitiativeTracker.d.ts +177 -1
  2. package/dist/core/InitiativeTracker.d.ts.map +1 -1
  3. package/dist/core/InitiativeTracker.js +341 -13
  4. package/dist/core/InitiativeTracker.js.map +1 -1
  5. package/dist/core/PlanDocParser.d.ts +62 -0
  6. package/dist/core/PlanDocParser.d.ts.map +1 -0
  7. package/dist/core/PlanDocParser.js +328 -0
  8. package/dist/core/PlanDocParser.js.map +1 -0
  9. package/dist/core/SafeYaml.d.ts +45 -0
  10. package/dist/core/SafeYaml.d.ts.map +1 -0
  11. package/dist/core/SafeYaml.js +230 -0
  12. package/dist/core/SafeYaml.js.map +1 -0
  13. package/dist/core/SessionManager.d.ts +12 -0
  14. package/dist/core/SessionManager.d.ts.map +1 -1
  15. package/dist/core/SessionManager.js +60 -0
  16. package/dist/core/SessionManager.js.map +1 -1
  17. package/dist/core/StageTransitionValidator.d.ts +97 -0
  18. package/dist/core/StageTransitionValidator.d.ts.map +1 -0
  19. package/dist/core/StageTransitionValidator.js +338 -0
  20. package/dist/core/StageTransitionValidator.js.map +1 -0
  21. package/dist/monitoring/StallTriageNurse.d.ts +11 -0
  22. package/dist/monitoring/StallTriageNurse.d.ts.map +1 -1
  23. package/dist/monitoring/StallTriageNurse.js +66 -0
  24. package/dist/monitoring/StallTriageNurse.js.map +1 -1
  25. package/dist/server/routes.d.ts.map +1 -1
  26. package/dist/server/routes.js +312 -0
  27. package/dist/server/routes.js.map +1 -1
  28. package/package.json +1 -1
  29. package/src/data/builtin-manifest.json +47 -47
  30. package/upgrades/0.28.86.md +86 -0
  31. package/upgrades/0.28.87.md +153 -0
  32. package/upgrades/side-effects/0.28.86.md +13 -0
  33. package/upgrades/side-effects/project-scope-phase1a-pr1.md +232 -0
  34. package/upgrades/side-effects/project-scope-phase1a-pr2.md +377 -0
  35. package/upgrades/side-effects/verify-injection-stuck-input.md +107 -0
@@ -0,0 +1,107 @@
1
+ # Side-Effects Review — verifyInjection + StallTriage Fast-Path
2
+
3
+ ## Change Summary
4
+
5
+ Two additive layers that recover stuck-input failures on Claude Code v2.1.105+
6
+ TUIs, where the Enter keypress sent after a bracketed-paste-end sequence is
7
+ occasionally eaten by a race with the paste-end handler.
8
+
9
+ 1. `SessionManager.verifyInjection(tmuxSession, text)` — fires 1.5s after every
10
+ `rawInject`. If a 40-char marker from the message is still visible at the
11
+ `❯` prompt, send one extra Enter. Single-shot per injection.
12
+ 2. `StallTriageNurse` fast-path — at triage time, if the pane shows ≥20 chars
13
+ of text at the `❯` prompt with no processing glyphs, nudge once and skip
14
+ the LLM round-trip.
15
+
16
+ ## Failure Mode Being Fixed
17
+
18
+ Observed in production:
19
+ - Telegram message reaches the agent server
20
+ - Server calls `injectMessage` → `rawInject` → bracketed paste + Enter
21
+ - Claude Code's readline buffers the paste content but the Enter races the
22
+ `\e[201~` paste-end and is consumed by it
23
+ - Message sits at `❯` with no submission; agent appears unresponsive
24
+
25
+ Justin's screenshot (2026-05-11) shows the exact failure on Claude Code v2.1.139.
26
+
27
+ ## Over-Block Risk
28
+
29
+ **verifyInjection:**
30
+ - Marker requires the first 40 chars (whitespace-stripped, ≥8 chars) to be
31
+ visible at a line containing `❯` within 1.5s of injection.
32
+ - False positive requires the pane to show our exact text at a `❯` prompt
33
+ after Claude has already processed and emitted it back. Claude's transcript
34
+ rendering doesn't put `❯` on transcript history lines — only on the active
35
+ input row — so this is structurally implausible.
36
+ - Worst-case impact: one extra Enter to an already-submitted message → empty
37
+ Enter in input box, no behavior change.
38
+
39
+ **StallTriage fast-path:**
40
+ - Requires (a) ≥20 chars of text after the `❯` glyph and (b) absence of all
41
+ of `⎿`, `✶`, `⏺`, `Coalescing`, `thinking`, `esc to interrupt`.
42
+ - A genuine in-progress turn always has at least one of those glyphs visible
43
+ during the work, so the gate refuses to nudge.
44
+ - Worst-case impact: harmless single Enter.
45
+
46
+ ## Under-Block Risk
47
+
48
+ If verifyInjection misses the stuck state (Enter took longer than 1.5s to be
49
+ eaten, marker text was edited out by user, etc.), the StallTriage fast-path is
50
+ the recovery backstop — it runs from the existing zombie-detection idle path.
51
+ If that also misses, the existing `pasteRetried` mechanism for literal
52
+ `[Pasted text #N]` placeholders catches the short-paste path. Three layers
53
+ total; legacy behavior is preserved.
54
+
55
+ ## Level-of-Abstraction Fit
56
+
57
+ - `verifyInjection` is a private method on `SessionManager`, called from
58
+ `rawInject`. Same abstraction layer as the tmux send-keys it verifies.
59
+ - StallTriage fast-path is a heuristic guard *inside* `StallTriageNurse`,
60
+ running before the LLM call. Same abstraction layer as the rest of the
61
+ triage logic.
62
+
63
+ Neither leaks tmux details upward or adds a new public API. Correct level.
64
+
65
+ ## Signal vs Authority Compliance
66
+
67
+ - `verifyInjection` is a signal-emitting verification (capture pane + check
68
+ marker). It takes one structural action: send Enter. This is the only
69
+ reasonable mitigation at this layer — there is no higher gate that needs to
70
+ authorize a missed Enter resend.
71
+ - StallTriage fast-path emits a signal (typed-but-not-submitted heuristic) and
72
+ takes a single bounded action (one Enter). It does NOT replace the LLM gate
73
+ — if the fast-path doesn't fire, full triage runs as before. The fast-path
74
+ is a *short-circuit*, not a *bypass*.
75
+
76
+ Both layers carry a `DegradationReporter` entry on recovery so the higher
77
+ authority (the user / monitoring) sees that a self-heal fired.
78
+
79
+ ## Interactions With Existing Recovery Paths
80
+
81
+ | Layer | Trigger | One-shot scope | Conflicts? |
82
+ |-------|---------|---------------|------------|
83
+ | `verifyInjection` | 1.5s after every `rawInject` | per-injection | independent — different timer, different captureOutput call |
84
+ | `pasteRetried` set (idle-detection) | `[Pasted text #N]` visible at idle prompt | per-session lifetime | independent — distinct match string |
85
+ | StallTriage fast-path | text at `❯` with no glyphs, before LLM | per-triage-pass | independent — runs from triage scheduler, not injection |
86
+ | Existing zombie-kill timer | idleMs > IDLE_PROMPT_KILL_MINUTES | global | unchanged — only fires if all 3 above missed and the session sat for full timeout |
87
+
88
+ The four layers gate from "fast and proactive" to "slow and destructive."
89
+ Adding the new two layers above the existing two is monotonically safer.
90
+
91
+ ## Rollback Cost
92
+
93
+ - Revert: drop `this.verifyInjection(...)` call in `rawInject` and the
94
+ `verifyInjection` method body. Drop the fast-path block in
95
+ `StallTriageNurse`. Pure additive — no schema, no state, no migration.
96
+ - Both changes have dedicated unit tests; removing them removes the tests.
97
+ - Branch surface area: 2 source files touched, 2 test files added.
98
+
99
+ ## Evidence
100
+
101
+ - `tests/unit/session-injection-verify.test.ts` — 7 tests covering marker
102
+ extraction, the captureOutput call, the Enter resend, and the no-op when
103
+ the text already submitted.
104
+ - `tests/unit/stall-triage-typed-not-submitted.test.ts` — 5 tests covering
105
+ detection thresholds, glyph-presence refusal, and the LLM-bypass path.
106
+ - Live reproduction: Justin's 2026-05-11 screenshot on Claude Code v2.1.139
107
+ shows the failure mode this fix targets.