instar 1.3.677 → 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.
@@ -28,6 +28,23 @@ import type { ComponentFrameworksConfig } from './IntelligenceRouter.js';
28
28
  * entry against the real `IntelligenceFramework` enum so an unknown name never ships.
29
29
  */
30
30
  export declare const INTERNAL_FRAMEWORK_PREFERENCE: readonly IntelligenceFramework[];
31
+ /**
32
+ * The LATENCY-SENSITIVE preference chain — used for the `gate` category ONLY.
33
+ *
34
+ * A `gate` is a SYNCHRONOUS, action-blocking check (the user-facing
35
+ * `MessagingToneGate` is the canonical one — a human is waiting for their reply).
36
+ * The general `INTERNAL_FRAMEWORK_PREFERENCE` puts `codex-cli` first by operator
37
+ * directive (spread background LOAD off Claude), but codex-cli is the SLOWEST
38
+ * off-Claude framework (~30s, which exceeds the 20s outbound-gate review budget
39
+ * and times the gate out — the 2026-06-25 silent-outbound class). For a
40
+ * latency-sensitive gate the right default is the FASTEST available off-Claude
41
+ * framework, not the load-spreading order. Ranked fastest→slowest, Claude last.
42
+ *
43
+ * This does NOT override the codex-first directive for the BACKGROUND categories
44
+ * (`sentinel` / `reflector`) — their latency does not block a human, so they keep
45
+ * the load-spreading order. Only `gate` (where a user waits) goes fastest-first.
46
+ */
47
+ export declare const LATENCY_SENSITIVE_FRAMEWORK_PREFERENCE: readonly IntelligenceFramework[];
31
48
  /**
32
49
  * Compute the default `componentFrameworks` from the active-framework set.
33
50
  *
@@ -35,8 +52,12 @@ export declare const INTERNAL_FRAMEWORK_PREFERENCE: readonly IntelligenceFramewo
35
52
  * agent, IN PREFERENCE ORDER (the caller filters `INTERNAL_FRAMEWORK_PREFERENCE`
36
53
  * by `buildProvider(fw) !== null`). MUST already be ordered + de-duplicated.
37
54
  * @returns the effective `ComponentFrameworksConfig`:
38
- * - `categories.{sentinel,gate,reflector}` = `active[0]` (first active off-Claude,
39
- * or claude-code if that's all that's active)
55
+ * - `categories.{sentinel,reflector}` = `active[0]` (first active off-Claude in the
56
+ * codex-first load-spreading order, or claude-code if that's all that's active)
57
+ * - `categories.gate` = the FASTEST active off-Claude framework
58
+ * (`LATENCY_SENSITIVE_FRAMEWORK_PREFERENCE`: pi → gemini → codex → claude) — the
59
+ * gate is synchronous + user-blocking, so it prefers speed over load-spreading.
60
+ * Equals `active[0]` when only one off-Claude framework is active (no-op then).
40
61
  * - `failureSwap` = `active.slice(1)` (the ordered tail, claude-code last)
41
62
  * - `fallback: 'default'`
42
63
  *
@@ -1 +1 @@
1
- {"version":3,"file":"internalFrameworkDefault.d.ts","sourceRoot":"","sources":["../../src/core/internalFrameworkDefault.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,EAAE,SAAS,qBAAqB,EAKhE,CAAC;AAEX;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,+BAA+B,CAC7C,gBAAgB,EAAE,SAAS,qBAAqB,EAAE,GACjD,yBAAyB,CAqB3B"}
1
+ {"version":3,"file":"internalFrameworkDefault.d.ts","sourceRoot":"","sources":["../../src/core/internalFrameworkDefault.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,EAAE,SAAS,qBAAqB,EAKhE,CAAC;AAEX;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sCAAsC,EAAE,SAAS,qBAAqB,EAKzE,CAAC;AAUX;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,+BAA+B,CAC7C,gBAAgB,EAAE,SAAS,qBAAqB,EAAE,GACjD,yBAAyB,CA6B3B"}
@@ -31,6 +31,32 @@ export const INTERNAL_FRAMEWORK_PREFERENCE = [
31
31
  'gemini-cli',
32
32
  'claude-code',
33
33
  ];
34
+ /**
35
+ * The LATENCY-SENSITIVE preference chain — used for the `gate` category ONLY.
36
+ *
37
+ * A `gate` is a SYNCHRONOUS, action-blocking check (the user-facing
38
+ * `MessagingToneGate` is the canonical one — a human is waiting for their reply).
39
+ * The general `INTERNAL_FRAMEWORK_PREFERENCE` puts `codex-cli` first by operator
40
+ * directive (spread background LOAD off Claude), but codex-cli is the SLOWEST
41
+ * off-Claude framework (~30s, which exceeds the 20s outbound-gate review budget
42
+ * and times the gate out — the 2026-06-25 silent-outbound class). For a
43
+ * latency-sensitive gate the right default is the FASTEST available off-Claude
44
+ * framework, not the load-spreading order. Ranked fastest→slowest, Claude last.
45
+ *
46
+ * This does NOT override the codex-first directive for the BACKGROUND categories
47
+ * (`sentinel` / `reflector`) — their latency does not block a human, so they keep
48
+ * the load-spreading order. Only `gate` (where a user waits) goes fastest-first.
49
+ */
50
+ export const LATENCY_SENSITIVE_FRAMEWORK_PREFERENCE = [
51
+ 'pi-cli',
52
+ 'gemini-cli',
53
+ 'codex-cli',
54
+ 'claude-code',
55
+ ];
56
+ /** The first framework in `order` that is also present in `active`, else undefined. */
57
+ function firstActiveIn(order, active) {
58
+ return order.find((fw) => active.includes(fw));
59
+ }
34
60
  /**
35
61
  * Compute the default `componentFrameworks` from the active-framework set.
36
62
  *
@@ -38,8 +64,12 @@ export const INTERNAL_FRAMEWORK_PREFERENCE = [
38
64
  * agent, IN PREFERENCE ORDER (the caller filters `INTERNAL_FRAMEWORK_PREFERENCE`
39
65
  * by `buildProvider(fw) !== null`). MUST already be ordered + de-duplicated.
40
66
  * @returns the effective `ComponentFrameworksConfig`:
41
- * - `categories.{sentinel,gate,reflector}` = `active[0]` (first active off-Claude,
42
- * or claude-code if that's all that's active)
67
+ * - `categories.{sentinel,reflector}` = `active[0]` (first active off-Claude in the
68
+ * codex-first load-spreading order, or claude-code if that's all that's active)
69
+ * - `categories.gate` = the FASTEST active off-Claude framework
70
+ * (`LATENCY_SENSITIVE_FRAMEWORK_PREFERENCE`: pi → gemini → codex → claude) — the
71
+ * gate is synchronous + user-blocking, so it prefers speed over load-spreading.
72
+ * Equals `active[0]` when only one off-Claude framework is active (no-op then).
43
73
  * - `failureSwap` = `active.slice(1)` (the ordered tail, claude-code last)
44
74
  * - `fallback: 'default'`
45
75
  *
@@ -58,10 +88,18 @@ export function resolveInternalFrameworkDefault(activeFrameworks) {
58
88
  return { failureSwap: [], fallback: 'default' };
59
89
  }
60
90
  const primary = active[0];
91
+ // The `gate` category is LATENCY-SENSITIVE: a synchronous, user-blocking check.
92
+ // It gets the FASTEST active off-Claude framework (pi → gemini → codex → claude),
93
+ // NOT the load-spreading codex-first order. `active` is in INTERNAL_FRAMEWORK_
94
+ // PREFERENCE order, so we re-rank it by the latency order to find the fastest.
95
+ // Falls back to `primary` if (somehow) no latency-ranked match — keeping the gate
96
+ // never worse than today. When only one off-Claude framework is active, gatePrimary
97
+ // === primary (byte-identical to the old behavior).
98
+ const gatePrimary = firstActiveIn(LATENCY_SENSITIVE_FRAMEWORK_PREFERENCE, active) ?? primary;
61
99
  return {
62
100
  categories: {
63
101
  sentinel: primary,
64
- gate: primary,
102
+ gate: gatePrimary,
65
103
  reflector: primary,
66
104
  // `job` and `other` are deliberately ABSENT (§4.1).
67
105
  },
@@ -1 +1 @@
1
- {"version":3,"file":"internalFrameworkDefault.js","sourceRoot":"","sources":["../../src/core/internalFrameworkDefault.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAqC;IAC7E,WAAW;IACX,QAAQ;IACR,YAAY;IACZ,aAAa;CACL,CAAC;AAEX;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,+BAA+B,CAC7C,gBAAkD;IAElD,MAAM,MAAM,GAAG,gBAAgB,CAAC;IAEhC,iFAAiF;IACjF,8EAA8E;IAC9E,kFAAkF;IAClF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,EAAE,CAAC;QAChF,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IAClD,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1B,OAAO;QACL,UAAU,EAAE;YACV,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,OAAO;YACb,SAAS,EAAE,OAAO;YAClB,oDAAoD;SACrD;QACD,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5B,QAAQ,EAAE,SAAS;KACpB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"internalFrameworkDefault.js","sourceRoot":"","sources":["../../src/core/internalFrameworkDefault.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAqC;IAC7E,WAAW;IACX,QAAQ;IACR,YAAY;IACZ,aAAa;CACL,CAAC;AAEX;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,sCAAsC,GAAqC;IACtF,QAAQ;IACR,YAAY;IACZ,WAAW;IACX,aAAa;CACL,CAAC;AAEX,uFAAuF;AACvF,SAAS,aAAa,CACpB,KAAuC,EACvC,MAAwC;IAExC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;AACjD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,+BAA+B,CAC7C,gBAAkD;IAElD,MAAM,MAAM,GAAG,gBAAgB,CAAC;IAEhC,iFAAiF;IACjF,8EAA8E;IAC9E,kFAAkF;IAClF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,EAAE,CAAC;QAChF,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IAClD,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1B,gFAAgF;IAChF,kFAAkF;IAClF,+EAA+E;IAC/E,+EAA+E;IAC/E,kFAAkF;IAClF,oFAAoF;IACpF,oDAAoD;IACpD,MAAM,WAAW,GAAG,aAAa,CAAC,sCAAsC,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC;IAC7F,OAAO;QACL,UAAU,EAAE;YACV,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,WAAW;YACjB,SAAS,EAAE,OAAO;YAClB,oDAAoD;SACrD;QACD,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5B,QAAQ,EAAE,SAAS;KACpB,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.677",
3
+ "version": "1.3.678",
4
4
  "description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-06-26T13:12:48.410Z",
5
- "instarVersion": "1.3.677",
4
+ "generatedAt": "2026-06-26T13:16:49.510Z",
5
+ "instarVersion": "1.3.678",
6
6
  "entryCount": 202,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -5,6 +5,17 @@
5
5
 
6
6
  ## What Changed
7
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
+
8
19
  The host spawn cap (the fork-bomb/OOM safety floor that bounds how many LLM
9
20
  subprocesses run at once) now reserves a little headroom for the user's reply. Under
10
21
  load, the user-facing tone gate used to wait in the same undifferentiated line as
@@ -27,6 +38,11 @@ treated as reachable), so it never cries wolf on a normal idle kill.
27
38
 
28
39
  ## What to Tell Your User
29
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
+
30
46
  When the machine is busy, your reply's safety check now jumps to a reserved slot instead
31
47
  of waiting behind background work — fewer slow/held replies under load. The crash
32
48
  protection is exactly as strong as before. Most setups see no change (it's off on the
@@ -41,6 +57,12 @@ follow-up. Off on the fleet for now.
41
57
 
42
58
  ## Summary of New Capabilities
43
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
+
44
66
  - `attribution.lane:'interactive'` requests reserved headroom — honored ONLY for an
45
67
  allowlisted, user-blocking seam (the operator-facing tone gate); everything else stays
46
68
  background.
@@ -58,6 +80,16 @@ follow-up. Off on the fleet for now.
58
80
 
59
81
  ## Evidence
60
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
+
61
93
  - `hostSpawnSemaphore-priority.test.ts` (10): symmetric reserve, OOM floor unconditional,
62
94
  garbage-lane→background-never-dropped, clamp (N=1/N=2/oversized/0), off=byte-identical.
63
95
  - `spawn-cap-provider-lane.test.ts` (7): allowlist downgrade (CoherenceReviewer→background),
@@ -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.