instar 1.3.676 → 1.3.678

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,110 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ The provider-fallback default policy routed every internal off-Claude category
9
+ (`sentinel`, `gate`, `reflector`) onto the same codex-first primary. But the
10
+ `gate` category includes the **user-facing tone gate** — a synchronous check a
11
+ human is waiting on — and `codex-cli` is the slowest off-Claude framework (~30s),
12
+ which exceeds the 20s outbound-review budget and times the gate out (a cause of
13
+ the 2026-06-25 silent-outbound incident). The `gate` category now resolves its
14
+ default primary from a separate speed-ranked order (`pi → gemini → codex →
15
+ claude`) — the fastest *active* off-Claude framework — while `sentinel`/`reflector`
16
+ keep the codex-first load-spreading order. `failureSwap`, the gate's verdict
17
+ logic, and the F4 degrade floor are all unchanged.
18
+
19
+ The host spawn cap (the fork-bomb/OOM safety floor that bounds how many LLM
20
+ subprocesses run at once) now reserves a little headroom for the user's reply. Under
21
+ load, the user-facing tone gate used to wait in the same undifferentiated line as
22
+ background sentinels and could time out (a cause of the 2026-06-25 silent-outbound
23
+ incident). The cap now SUBDIVIDES into a small interactive reserve + a small background
24
+ reserve, so a synchronous operator reply always has slots and is never starved by
25
+ background chatter. The total cap is NEVER raised — only *who gets which slot* changes.
26
+ Ships dark on the fleet / live on a development agent (dev-agent gate); byte-identical
27
+ to today when off.
28
+
29
+ Lands postmortem fix F7 (Blast-Radius / Verify-After), dark on the fleet / live on a dev
30
+ agent. Two parts: (1) the live inbound spawn-guard is now a token-tagged
31
+ `SpawningTopicsRegistry` — a hung session start no longer silently wedges a topic forever
32
+ (ABA-safe; the `.finally` stays the sole clearer, no risky auto-clear). (2) a pure-signal
33
+ `TopicReachabilityVerifier`: after a session is killed/reaped, it checks (after a grace
34
+ window) that the conversation can still receive your next message, and if a genuine
35
+ orphan (e.g. a wedged start-up) it surfaces ONE calm NORMAL heads-up. It mutates nothing —
36
+ never kills, spawns, or clears. The probe is conservative + fail-safe (uncertain ⇒
37
+ treated as reachable), so it never cries wolf on a normal idle kill.
38
+
39
+ ## What to Tell Your User
40
+
41
+ Your replies' safety check now runs on the fastest available engine instead of
42
+ the slowest, so it stops timing out under load — one fewer cause of slow or
43
+ missing replies. Background checks are unchanged. If only one non-Claude engine is
44
+ installed, nothing changes.
45
+
46
+ When the machine is busy, your reply's safety check now jumps to a reserved slot instead
47
+ of waiting behind background work — fewer slow/held replies under load. The crash
48
+ protection is exactly as strong as before. Most setups see no change (it's off on the
49
+ fleet for now).
50
+
51
+ If I ever shut down a conversation's session and it genuinely can't be reached again
52
+ (e.g. a start-up that hung), you now get one calm "this conversation may be unreachable"
53
+ heads-up instead of your messages silently vanishing. Most of the time you see nothing,
54
+ because most kills self-heal on your next message. It only watches — it never tries to
55
+ auto-fix the stuck state (that proved too risky); the mechanical repair stays a tracked
56
+ follow-up. Off on the fleet for now.
57
+
58
+ ## Summary of New Capabilities
59
+
60
+ - The latency-sensitive `gate` category defaults to the fastest active off-Claude
61
+ framework (`LATENCY_SENSITIVE_FRAMEWORK_PREFERENCE`), not the codex-first order.
62
+ - `sentinel`/`reflector`/`job`/`other` routing and `failureSwap` are unchanged.
63
+ - An explicit `categories.gate` in config always overrides the computed default.
64
+ - Single-off-Claude-framework agents and claude-only agents: byte-identical no-op.
65
+
66
+ - `attribution.lane:'interactive'` requests reserved headroom — honored ONLY for an
67
+ allowlisted, user-blocking seam (the operator-facing tone gate); everything else stays
68
+ background.
69
+ - Symmetric reservation within the existing cap N (`Ri`/`Rb`, default 2/2): interactive
70
+ guaranteed ≥Ri slots, background guaranteed ≥Rb — neither starves the other.
71
+ - `/spawn-limiter` reports per-lane live counts + the reservation config.
72
+ - Off (the fleet default) ⇒ byte-identical to the all-or-nothing cap (no `lane` written).
73
+
74
+ - A hung session start-up can no longer permanently jam a conversation's inbound path
75
+ (token-tagged spawn guard; ABA-safe).
76
+ - After a destructive session/routing op, a dev agent verifies the topic is still
77
+ reachable and surfaces a genuine orphan as ONE NORMAL attention item (deduped,
78
+ flap-backoff-capped, burst-rolled-up, pressure/emergency-stop aware with a re-sweep).
79
+ - Visible in `/guards` (registered). Dark on the fleet (dev-agent gate). Mutates nothing.
80
+
81
+ ## Evidence
82
+
83
+ - `internalFrameworkDefault.test.ts`: gate prefers fastest (pi) while sentinel
84
+ stays codex; pi-down→gemini (the gemini-serves-when-pi-down case); both-down→codex
85
+ (never worse than today); single-framework→no divergence. 17 unit tests pass.
86
+ - `provider-fallback-default-routing.test.ts` (integration): the gate component on
87
+ `GET /intelligence/routing` reports the fastest active framework. 3 pass.
88
+ - `provider-fallback-default-policy-lifecycle.test.ts` (e2e): route alive, policy
89
+ live. `tsc --noEmit` clean. 24 affected tests green.
90
+ - Side-effects review: `upgrades/side-effects/latency-sensitive-gate-framework.md`.
91
+ - Spec amendment: `docs/specs/provider-fallback-default-policy.md` §4.1.
92
+
93
+ - `hostSpawnSemaphore-priority.test.ts` (10): symmetric reserve, OOM floor unconditional,
94
+ garbage-lane→background-never-dropped, clamp (N=1/N=2/oversized/0), off=byte-identical.
95
+ - `spawn-cap-provider-lane.test.ts` (7): allowlist downgrade (CoherenceReviewer→background),
96
+ off→background, interactive fast-path, saturated interactive still fails closed,
97
+ membership pinned.
98
+ - 25 existing spawn-cap tests + 160 tone-gate tests pass unchanged (no regression; the
99
+ fork-bomb burst-invariant test still green). `tsc --noEmit` clean.
100
+ - Side-effects: `upgrades/side-effects/spawn-cap-interactive-priority.md`.
101
+ - Spec (converged + approved): `docs/specs/spawn-cap-interactive-priority.md`.
102
+
103
+ - `spawningTopicsRegistry.test.ts` (5): ABA token-guard; `.finally` sole clearer (no
104
+ timeout/sweep); stuck-age seam.
105
+ - `topicReachabilityVerifier.test.ts` (8): grace; reachable-honesty (no false orphan on a
106
+ topic that self-heals); orphan→one NORMAL item; pressure/halt skip + re-sweep; flap
107
+ backoff; burst roll-up; coalescing.
108
+ - `tsc --noEmit` clean.
109
+ - Side-effects: `upgrades/side-effects/verify-after-reachability.md`.
110
+ - Spec (converged + approved): `docs/specs/verify-after-reachability.md`.
@@ -0,0 +1,79 @@
1
+ # Side-Effects Review — Latency-Sensitive Gate Framework Default
2
+
3
+ **Version / slug:** `latency-sensitive-gate-framework`
4
+ **Date:** `2026-06-26`
5
+ **Author:** `Echo (instar-dev agent)`
6
+ **Tier:** 1 (small, localized; one pure resolver function + its tests + docs)
7
+
8
+ ## Summary
9
+
10
+ The provider-fallback default policy routes internal components off-Claude via a
11
+ single codex-first preference chain (`codex-cli → pi-cli → gemini-cli →
12
+ claude-code`). The `gate` category — which includes the **user-facing
13
+ `MessagingToneGate`**, a synchronous check a human is waiting on — inherited that
14
+ codex-first primary. But `codex-cli` is the SLOWEST off-Claude framework (~30s),
15
+ which exceeds the 20s outbound-gate review budget and times the gate out (the
16
+ 2026-06-25 silent-outbound class). This change gives the `gate` category a
17
+ SEPARATE, speed-ranked order (`LATENCY_SENSITIVE_FRAMEWORK_PREFERENCE = pi →
18
+ gemini → codex → claude`) so it defaults to the FASTEST active off-Claude
19
+ framework. `sentinel`/`reflector` (background) keep codex-first; `failureSwap` and
20
+ all other categories are unchanged.
21
+
22
+ ## The 8 questions
23
+
24
+ 1. **Over-block** — N/A. This is not a gate; it selects which backend computes the
25
+ tone-gate verdict. It rejects nothing.
26
+ 2. **Under-block** — N/A. The tone gate's block/allow logic and its deterministic
27
+ degrade floor (F4) are byte-identical; only the LLM backend that produces the
28
+ verdict changes. A faster backend means FEWER budget-timeout degrades, i.e.
29
+ *more* real verdicts, not fewer.
30
+ 3. **Level-of-abstraction fit** — Correct. The change lives in the one pure policy
31
+ resolver (`resolveInternalFrameworkDefault`) that already computes per-category
32
+ primaries; `ComponentFrameworksConfig.categories` is already a per-category map,
33
+ so no routing-engine change is needed. The router consumes the config unchanged.
34
+ 4. **Signal vs authority** — No authority added. The resolver is a pure function
35
+ (active-set → config); it holds no blocking power. The tone gate's authority
36
+ (hold/send) is untouched. Complies with `docs/signal-vs-authority.md`.
37
+ 5. **Interactions** — The gate's PRIMARY now differs from `sentinel`/`reflector`.
38
+ `failureSwap` is the shared tail (`active.slice(1)`, codex-first); for a gate
39
+ whose primary is `pi`, the tail may list `pi` first (the just-tried framework) —
40
+ harmless: the failure-swap walk is circuit-checked, so a just-failed/open
41
+ provider is skipped. When only one off-Claude framework is active, `gatePrimary
42
+ === active[0]` (byte-identical no-op). No double-fire, no shadowing.
43
+ 6. **External surfaces** — `GET /intelligence/routing` now reports the gate
44
+ component on a (possibly) different framework than sentinels. That is the
45
+ intended, visible effect. No new route, no schema change.
46
+ 7. **Multi-machine posture** — **Machine-local BY DESIGN.** The default policy is
47
+ computed per-agent at boot from that agent's own active-framework set (which
48
+ frameworks' CLIs are installed/configured on THAT machine). No replication, no
49
+ cross-machine coupling. Each machine independently resolves the fastest gate
50
+ backend it has. Correct — framework availability is inherently per-machine.
51
+ 8. **Rollback cost** — Trivial. Revert the commit (one source file + tests + one
52
+ doc amendment). No state, no migration. An operator who wants the gate back on
53
+ codex sets `categories.gate` explicitly (the explicit config always wins over
54
+ the computed default). A single-off-Claude-framework agent is unaffected.
55
+
56
+ ## What it does NOT do
57
+
58
+ - Does NOT change the tone gate's verdict/hold/send logic or the F4 degrade floor.
59
+ - Does NOT touch `sentinel`/`reflector`/`job`/`other` routing, or `failureSwap`.
60
+ - Does NOT introduce a measured latency model — the ranking (pi < gemini < codex)
61
+ is a documented static assertion from observed behavior (~6s / ~9-13s / ~30s),
62
+ owned in `LATENCY_SENSITIVE_FRAMEWORK_PREFERENCE` with a unit-tested enum guard.
63
+ - Does NOT revoke the codex-first operator directive — it narrows it to exclude the
64
+ one latency-sensitive, user-blocking category.
65
+
66
+ ## Second-pass note (outbound-path touch)
67
+
68
+ This touches the OUTBOUND tone-gate path, which is a Phase-5 trigger area. The
69
+ substantive review point: the change adds NO block/allow authority — it only
70
+ selects a faster backend for an existing gate, and the gate's safety behavior
71
+ (including the deterministic degrade floor on backend failure) is unchanged. The
72
+ decision boundary (gate diverges to fastest; background stays codex-first; single-
73
+ framework is a no-op) is covered by the new unit + integration tests. A full
74
+ independent reviewer was judged unnecessary for an authority-free routing-default
75
+ change; the PR is the review surface.
76
+
77
+ ## Rollback
78
+
79
+ Revert the commit. No migration, no state.
@@ -0,0 +1,65 @@
1
+ # Side-Effects Review — Verify-After Topic Reachability (F7 — core components)
2
+
3
+ **Version / slug:** `verify-after-reachability`
4
+ **Date:** `2026-06-26`
5
+ **Author:** `Echo (instar-dev agent)`
6
+ **Tier:** 2 (converged + approved spec: `docs/specs/verify-after-reachability.md`)
7
+ **Scope:** the two pure components (first commit) PLUS the server wiring (this commit):
8
+ Piece 1 (`spawningTopics` closure→`SpawningTopicsRegistry` refactor of the live inbound
9
+ path, token-guarded at all 4 callsites) and Piece 2 (the verifier constructed dev-gated,
10
+ triggered by `sessionReaped`, a conservative fail-safe probe, a 15s tick, NORMAL
11
+ attention surfacing, and `guardRegistry` registration). The probe is deliberately
12
+ CONSERVATIVE: a live session ⇒ reachable; a topic stuck-spawning past `stuckSpawnMs` ⇒
13
+ orphan; ANYTHING ELSE ⇒ reachable (the next inbound self-heals) — so it never
14
+ false-orphans an idle kill. The multi-machine released-no-placement + at-capacity orphan
15
+ cases (placement reads) and a dedicated `/topic-reachability` route are a tracked
16
+ follow-up; their absence means LESS coverage, never a false orphan (the probe fails safe
17
+ to reachable). <!-- tracked: topic-28744 F7-followup multimachine-probe-and-route -->
18
+
19
+ ## What this commit adds
20
+
21
+ - `SpawningTopicsRegistry` (src/core) — token-tagged replacement for the closure-local
22
+ `spawningTopics` Set: `add` returns a token, `clear` is token-guarded (the ABA fix so a
23
+ late `.finally` from a superseded spawn cannot delete a newer entry), `stuckSinceMs`
24
+ exposes in-flight age for the verifier. NO timeout, NO sweep — the `.finally` remains
25
+ the sole clearer (round-2 proved any external clear relocates the double-spawn race).
26
+ - `TopicReachabilityVerifier` (src/monitoring) — the PURE-SIGNAL decision core: grace +
27
+ per-topic coalescing, the reachable-honesty guard (a topic that will self-heal on next
28
+ inbound is REACHABLE, not orphaned), NORMAL-priority surfacing with per-topic
29
+ exponential backoff (flap cap), burst roll-up, pressure-skip + emergency-stop-suppress
30
+ WITH a re-sweep on clear (no never-surfaced orphan). It MUTATES NOTHING.
31
+
32
+ Neither component is wired into the running server yet (no runtime surface), so this
33
+ commit is inert at runtime — pure library code under test.
34
+
35
+ ## The 8 questions (for the components as committed)
36
+
37
+ 1. **Over-block** — N/A. The verifier blocks nothing; it surfaces a signal. The registry
38
+ only guards double-spawn (existing behavior), now ABA-safe.
39
+ 2. **Under-block** — N/A.
40
+ 3. **Level-of-abstraction fit** — Correct. Pure decision logic separated from the server
41
+ wiring + live-state probe (the spec's design).
42
+ 4. **Signal vs authority** — The verifier is a pure signal (zero mutation). The registry's
43
+ only authority is the EXISTING token-guarded clear (no new clearer). Complies.
44
+ 5. **Interactions** — None at runtime (unwired). The registry, once wired, replaces the
45
+ closure Set; the token guard makes its clear idempotent/ABA-safe.
46
+ 6. **External surfaces** — None yet (unwired). The future wiring adds a NORMAL attention
47
+ item + a `/topic-reachability` status route + a `/guards` entry.
48
+ 7. **Multi-machine** — The verifier's released-no-placement detection (future probe) is
49
+ machine-local (reads the local placement snapshot, freshness-gated); machine-local BY
50
+ DESIGN. The components themselves hold no cross-machine state.
51
+ 8. **Rollback cost** — Trivial. Delete two new files + their tests; nothing references
52
+ them at runtime yet.
53
+
54
+ ## Tests
55
+
56
+ - `spawningTopicsRegistry.test.ts` (5): the ABA token-guard, `.finally` is the sole
57
+ clearer (no timeout/sweep), `stuckSinceMs`, entries snapshot.
58
+ - `topicReachabilityVerifier.test.ts` (8): grace; reachable-honesty (no false orphan);
59
+ orphan→one NORMAL item; pressure-skip+re-sweep; halt-suppress+re-sweep; flap backoff;
60
+ burst roll-up; coalescing.
61
+ - `tsc --noEmit` clean.
62
+
63
+ ## Rollback
64
+
65
+ Delete the two component files + tests. No runtime reference.
@@ -1,45 +0,0 @@
1
- # Upgrade Guide — vNEXT
2
-
3
- <!-- assembled-by: assemble-next-md -->
4
- <!-- bump: patch -->
5
-
6
- ## What Changed
7
-
8
- The host spawn cap (the fork-bomb/OOM safety floor that bounds how many LLM
9
- subprocesses run at once) now reserves a little headroom for the user's reply. Under
10
- load, the user-facing tone gate used to wait in the same undifferentiated line as
11
- background sentinels and could time out (a cause of the 2026-06-25 silent-outbound
12
- incident). The cap now SUBDIVIDES into a small interactive reserve + a small background
13
- reserve, so a synchronous operator reply always has slots and is never starved by
14
- background chatter. The total cap is NEVER raised — only *who gets which slot* changes.
15
- Ships dark on the fleet / live on a development agent (dev-agent gate); byte-identical
16
- to today when off.
17
-
18
- ## What to Tell Your User
19
-
20
- When the machine is busy, your reply's safety check now jumps to a reserved slot instead
21
- of waiting behind background work — fewer slow/held replies under load. The crash
22
- protection is exactly as strong as before. Most setups see no change (it's off on the
23
- fleet for now).
24
-
25
- ## Summary of New Capabilities
26
-
27
- - `attribution.lane:'interactive'` requests reserved headroom — honored ONLY for an
28
- allowlisted, user-blocking seam (the operator-facing tone gate); everything else stays
29
- background.
30
- - Symmetric reservation within the existing cap N (`Ri`/`Rb`, default 2/2): interactive
31
- guaranteed ≥Ri slots, background guaranteed ≥Rb — neither starves the other.
32
- - `/spawn-limiter` reports per-lane live counts + the reservation config.
33
- - Off (the fleet default) ⇒ byte-identical to the all-or-nothing cap (no `lane` written).
34
-
35
- ## Evidence
36
-
37
- - `hostSpawnSemaphore-priority.test.ts` (10): symmetric reserve, OOM floor unconditional,
38
- garbage-lane→background-never-dropped, clamp (N=1/N=2/oversized/0), off=byte-identical.
39
- - `spawn-cap-provider-lane.test.ts` (7): allowlist downgrade (CoherenceReviewer→background),
40
- off→background, interactive fast-path, saturated interactive still fails closed,
41
- membership pinned.
42
- - 25 existing spawn-cap tests + 160 tone-gate tests pass unchanged (no regression; the
43
- fork-bomb burst-invariant test still green). `tsc --noEmit` clean.
44
- - Side-effects: `upgrades/side-effects/spawn-cap-interactive-priority.md`.
45
- - Spec (converged + approved): `docs/specs/spawn-cap-interactive-priority.md`.