instar 1.3.707 → 1.3.709

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 (37) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +12 -1
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/commands/setup-wizard/model-constants.d.ts +16 -2
  5. package/dist/commands/setup-wizard/model-constants.d.ts.map +1 -1
  6. package/dist/commands/setup-wizard/model-constants.js +22 -2
  7. package/dist/commands/setup-wizard/model-constants.js.map +1 -1
  8. package/dist/commands/setup.d.ts +7 -10
  9. package/dist/commands/setup.d.ts.map +1 -1
  10. package/dist/commands/setup.js +7 -9
  11. package/dist/commands/setup.js.map +1 -1
  12. package/dist/core/DispatchExecutor.d.ts +10 -1
  13. package/dist/core/DispatchExecutor.d.ts.map +1 -1
  14. package/dist/core/DispatchExecutor.js +10 -2
  15. package/dist/core/DispatchExecutor.js.map +1 -1
  16. package/dist/core/types.d.ts +28 -0
  17. package/dist/core/types.d.ts.map +1 -1
  18. package/dist/core/types.js.map +1 -1
  19. package/dist/data/llmBenchCoverage.d.ts +34 -0
  20. package/dist/data/llmBenchCoverage.d.ts.map +1 -0
  21. package/dist/data/llmBenchCoverage.js +88 -0
  22. package/dist/data/llmBenchCoverage.js.map +1 -0
  23. package/dist/providers/adapters/anthropic-headless/config.d.ts +8 -0
  24. package/dist/providers/adapters/anthropic-headless/config.d.ts.map +1 -1
  25. package/dist/providers/adapters/anthropic-headless/config.js.map +1 -1
  26. package/dist/providers/adapters/anthropic-headless/control/authCredentialInjection.d.ts.map +1 -1
  27. package/dist/providers/adapters/anthropic-headless/control/authCredentialInjection.js +18 -1
  28. package/dist/providers/adapters/anthropic-headless/control/authCredentialInjection.js.map +1 -1
  29. package/package.json +1 -1
  30. package/src/data/builtin-manifest.json +2 -2
  31. package/src/data/llmBenchCoverage.ts +97 -0
  32. package/upgrades/1.3.708.md +54 -0
  33. package/upgrades/1.3.709.md +42 -0
  34. package/upgrades/config-driven-pinned-models.eli16.md +18 -0
  35. package/upgrades/llm-bench-coverage-ratchet.eli16.md +11 -0
  36. package/upgrades/side-effects/config-driven-pinned-models.md +63 -0
  37. package/upgrades/side-effects/llm-bench-coverage-ratchet.md +41 -0
@@ -8,6 +8,7 @@
8
8
  import { CapabilityFlag } from '../../../capabilities.js';
9
9
  import { AuthError } from '../../../errors.js';
10
10
  import { ANTHROPIC_HEADLESS_ID, mapApiError } from '../errors.js';
11
+ import { ANTHROPIC_MODELS } from '../../../../core/models.js';
11
12
  class AnthropicHeadlessAuthCredentialInjection {
12
13
  _config;
13
14
  capability = CapabilityFlag.AuthCredentialInjection;
@@ -38,6 +39,19 @@ class AnthropicHeadlessAuthCredentialInjection {
38
39
  }
39
40
  return 'unknown credential kind';
40
41
  }
42
+ /**
43
+ * RULE 3.1 RATIONALE (state-detection: credential-validity probe)
44
+ * - Criticality: minor-degradation. A wrong verdict surfaces as a loud
45
+ * AuthError (or a later loud auth failure downstream) — never silent
46
+ * corruption; the probe is a pre-check convenience, not the authority.
47
+ * - Frequency: per-enrollment / per-verification event (rare).
48
+ * - Stability: very-stable — official public Messages-API HTTP status
49
+ * semantics (401/403 for bad credentials), not a scraped surface.
50
+ * - Fallback: every downstream call with the credential fails loudly on
51
+ * its own; mapApiError classifies non-ok statuses.
52
+ * - → Verdict: deterministic, exempt-from-canary (stable public API
53
+ * contract + loud failure path). Registry row: 06-state-detector-registry.md.
54
+ */
41
55
  async probe(credential) {
42
56
  const validation = this.validate(credential);
43
57
  if (validation) {
@@ -60,7 +74,10 @@ class AnthropicHeadlessAuthCredentialInjection {
60
74
  method: 'POST',
61
75
  headers,
62
76
  body: JSON.stringify({
63
- model: 'claude-haiku-4-5',
77
+ // Config-overridable (risk item #7); default sourced from the
78
+ // models.ts tier map, not a string literal — the probe only needs
79
+ // the cheapest valid model on the account.
80
+ model: this._config.credentialProbeModel?.trim() || ANTHROPIC_MODELS.haiku,
64
81
  max_tokens: 4,
65
82
  messages: [{ role: 'user', content: 'ping' }],
66
83
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"authCredentialInjection.js","sourceRoot":"","sources":["../../../../../src/providers/adapters/anthropic-headless/control/authCredentialInjection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authCredentialInjection.js","sourceRoot":"","sources":["../../../../../src/providers/adapters/anthropic-headless/control/authCredentialInjection.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.707",
3
+ "version": "1.3.709",
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-07-02T05:36:09.449Z",
5
- "instarVersion": "1.3.707",
4
+ "generatedAt": "2026-07-02T08:48:48.771Z",
5
+ "instarVersion": "1.3.709",
6
6
  "entryCount": 202,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -0,0 +1,97 @@
1
+ /**
2
+ * LLM Benchmark Coverage Map — INSTAR-Bench v2 ratchet #2.
3
+ *
4
+ * Every LLM-driven component (a key of COMPONENT_CATEGORY in
5
+ * src/core/componentCategories.ts) must map to exactly one of:
6
+ * - { task: '<bench-task-id>' } — covered by an INSTAR-Bench v2 task
7
+ * (task definitions live in the bench harness:
8
+ * research/llm-pathway-bench/instar-bench-v2/tasks/ on the benching
9
+ * agent; the id here is the durable contract),
10
+ * - { pending: '<wave>' } — authoring queued; the pending set is PINNED
11
+ * shrink-only in tests/unit/llm-bench-coverage-ratchet.test.ts (you can
12
+ * graduate an entry to covered, you cannot add one without editing the
13
+ * pinned test — a visible, reviewed act),
14
+ * - { exempt: '<argued reason>' } — a real argument why benching this
15
+ * component is not meaningful (also pinned shrink-only).
16
+ *
17
+ * WHY (operator directive 2026-07-02, topic 29723 + INSTAR-BENCH-V2-SPEC §6):
18
+ * adding an LLM callsite without benchmark coverage must fail the build —
19
+ * an unbenched decision-maker is an unmeasured one, and routing defaults are
20
+ * benchmark-derived. Structure > Willpower.
21
+ *
22
+ * Companion ratchet: the wiring test (componentCategories-evaluate-coverage)
23
+ * keeps COMPONENT_CATEGORY exhaustive over .evaluate() callsites; THIS map +
24
+ * its test keep bench coverage exhaustive over COMPONENT_CATEGORY.
25
+ */
26
+
27
+ export type BenchCoverage =
28
+ | { task: string }
29
+ | { pending: 'wave-2' | 'wave-3' }
30
+ | { exempt: string };
31
+
32
+ export const LLM_BENCH_COVERAGE: Readonly<Record<string, BenchCoverage>> = {
33
+ // ── Covered by the critical set (Wave 1 — authored 2026-07-02) ──
34
+ MessageSentinel: { task: 'sentinel-classify' },
35
+ MessagingToneGate: { task: 'tone-gate' },
36
+ // CompletionEvaluator has TWO judged surfaces; both benched.
37
+ CompletionEvaluator: { task: 'completion-judge+p13-stop-judge' },
38
+ ExternalOperationGate: { task: 'external-op-gate' },
39
+ LLMSanitizer: { task: 'injection-sanitizer' },
40
+ WarrantsReplyGate: { task: 'warrants-reply' },
41
+ InputClassifier: { task: 'input-classifier' },
42
+ Usher: { task: 'usher' },
43
+ 'correction-learning': { task: 'correction-distiller' },
44
+ CoherenceReviewer: { task: 'gate-triage' },
45
+
46
+ // ── Argued exemptions (pinned; each must carry a real reason) ──
47
+ InteractivePoolCanaryJudge: {
48
+ exempt:
49
+ 'judges a FIXED known-answer canary probe — the canary is its own benchmark; a bench task would re-test the same constant',
50
+ },
51
+
52
+ // ── Wave 2 (sentinels/gates/extractors still to author) ──
53
+ InputDetector: { pending: 'wave-2' },
54
+ InputGuard: { pending: 'wave-2' },
55
+ SessionActivitySentinel: { pending: 'wave-2' },
56
+ StallTriageNurse: { pending: 'wave-2' },
57
+ CommitmentSentinel: { pending: 'wave-2' },
58
+ PresenceProxy: { pending: 'wave-2' },
59
+ PromiseBeacon: { pending: 'wave-2' },
60
+ ProjectDriftChecker: { pending: 'wave-2' },
61
+ TemporalCoherenceChecker: { pending: 'wave-2' },
62
+ SessionWatchdog: { pending: 'wave-2' },
63
+ ResumeQueueDrainer: { pending: 'wave-2' },
64
+ TopicIntentArcCheck: { pending: 'wave-2' },
65
+ SlackAdapter: { pending: 'wave-2' },
66
+ TelegramAdapter: { pending: 'wave-2' },
67
+ PromptGate: { pending: 'wave-2' },
68
+ AutoApprover: { pending: 'wave-2' },
69
+ IntegrationGate: { pending: 'wave-2' },
70
+ UnjustifiedStopGate: { pending: 'wave-2' },
71
+ CoherenceGate: { pending: 'wave-2' },
72
+ OverrideDetector: { pending: 'wave-2' },
73
+ TaskClassifier: { pending: 'wave-2' },
74
+ ResumeValidator: { pending: 'wave-2' },
75
+ SessionSummarySentinel: { pending: 'wave-2' },
76
+ TopicIntentExtractor: { pending: 'wave-2' },
77
+
78
+ // ── Wave 3 (reflectors + background/job tasks) ──
79
+ JobReflector: { pending: 'wave-3' },
80
+ crossModelReviewer: { pending: 'wave-3' },
81
+ SelfKnowledgeTree: { pending: 'wave-3' },
82
+ TreeTriage: { pending: 'wave-3' },
83
+ TopicSummarizer: { pending: 'wave-3' },
84
+ ContextualEvaluator: { pending: 'wave-3' },
85
+ RelationshipManager: { pending: 'wave-3' },
86
+ StandardsConformanceReviewer: { pending: 'wave-3' },
87
+ DiscoveryEvaluator: { pending: 'wave-3' },
88
+ PipeSessionSpawner: { pending: 'wave-3' },
89
+ CartographerSweep: { pending: 'wave-3' },
90
+ StandardsCoverageEnrichment: { pending: 'wave-3' },
91
+ PreCompactionFlush: { pending: 'wave-3' },
92
+ TreeSynthesis: { pending: 'wave-3' },
93
+ LLMConflictResolver: { pending: 'wave-3' },
94
+ openConversationBrief: { pending: 'wave-3' },
95
+ 'a2a-checkin': { pending: 'wave-3' },
96
+ 'mentor-stage-b': { pending: 'wave-3' },
97
+ };
@@ -0,0 +1,54 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ The last hardcoded-model callsites from the LLM Routing Registry audit ("Risk
9
+ items" #3/#5/#6/#7) are now overridable configuration with behavior-preserving
10
+ inline defaults — with nothing set, every callsite behaves byte-for-byte as
11
+ before, and nothing is written to any config file (absence IS the default; no
12
+ migration needed).
13
+
14
+ - `DispatchExecutor.runAgentic`'s spawned dispatch session model:
15
+ `intelligence.pinnedModels.dispatchAgentic` (default 'haiku', unchanged).
16
+ - The anthropic-headless credential-probe validation ping:
17
+ `intelligence.pinnedModels.anthropicCredentialProbe` (default now sourced
18
+ from `ANTHROPIC_MODELS.haiku` in the central tier map instead of a
19
+ free-floating `'claude-haiku-4-5'` literal, so a future model bump cannot
20
+ silently miss it).
21
+ - The setup wizard's narrative models (codex + gemini drivers): env-var
22
+ overrides `INSTAR_WIZARD_CODEX_MODEL` / `INSTAR_WIZARD_GEMINI_MODEL` — env
23
+ not config, because the wizard runs before `.instar/config.json` exists.
24
+ `setup.ts`'s duplicate `WIZARD_CODEX_MODEL` const collapsed into a single
25
+ source of truth in `setup-wizard/model-constants.ts` (re-exported, canary
26
+ contract preserved).
27
+ - Honest audit correction: risk item #4 (mentor loop → 'opus') needed no code
28
+ change — it was already config-driven via `mentor.autonomousFix.model`; a
29
+ canary test now pins that fact.
30
+
31
+ 15 new unit tests cover both sides of every boundary (absent ⇒ shipped
32
+ default, present ⇒ override wins, whitespace ⇒ absent) plus wiring canaries
33
+ asserting `server.ts` threads both config keys. This is step one of the
34
+ INSTAR-Bench v2 program (operator-approved 2026-07-02): before benchmark
35
+ results can drive model routing, every model choice must be reachable by
36
+ configuration rather than buried in code.
37
+
38
+ ## What to Tell Your User
39
+
40
+ Nothing proactively — this changes no behavior on its own. If your operator
41
+ asks: a handful of my internal helpers (the background dispatch runner, my
42
+ setup wizard's text generator, and the tiny "does this credential work?"
43
+ check) had their AI model choice typed directly into my code; those choices
44
+ are now ordinary settings, with the old models still used unless someone
45
+ deliberately changes them.
46
+
47
+ ## Summary of New Capabilities
48
+
49
+ - New config block `intelligence.pinnedModels` (`dispatchAgentic`,
50
+ `anthropicCredentialProbe`) — inline-defaulted, absent means today's
51
+ behavior exactly.
52
+ - New env overrides `INSTAR_WIZARD_CODEX_MODEL` / `INSTAR_WIZARD_GEMINI_MODEL`
53
+ for the pre-config setup wizard.
54
+ - New adapter config field `credentialProbeModel` on anthropic-headless.
@@ -0,0 +1,42 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ INSTAR-Bench v2 ratchet #2 (spec §6; operator directive 2026-07-02, topic
9
+ 29723): a new coverage ledger (`src/data/llmBenchCoverage.ts`) maps every LLM
10
+ component in `COMPONENT_CATEGORY` to its benchmark status — covered by a
11
+ named bench task (the 10 Wave-1 critical gates/sentinels), pending (42,
12
+ pinned shrink-only), or exempt (1, argued). A CI test
13
+ (`llm-bench-coverage-ratchet.test.ts`) fails the build when a new LLM
14
+ component ships without a coverage decision, when the pending/exempt sets
15
+ GROW (graduating shrinks them; adding requires editing the pinned baseline in
16
+ the test — a visible, reviewed act), when an exemption's argument is lazy, or
17
+ when a Wave-1 critical component slides back to uncovered.
18
+
19
+ Together with the existing attribution ratchet + category-map wiring test,
20
+ the chain is closed: every LLM callsite must be attributed → categorized/
21
+ routed deliberately → benchmark-covered. No runtime surface; build-time only.
22
+
23
+ ## What to Tell Your User
24
+
25
+ Nothing proactively — no behavior changes. If asked: every one of my internal
26
+ AI helpers is now tracked against a benchmark coverage ledger, so any new
27
+ helper added to my infrastructure must ship with quality measurements (or a
28
+ written argument why not) before the build goes green. It keeps my model
29
+ choices grounded in measured results instead of guesses.
30
+
31
+ ## Summary of New Capabilities
32
+
33
+ None user-facing. New build-time guarantee: `src/data/llmBenchCoverage.ts`
34
+ (the coverage ledger) + `llm-bench-coverage-ratchet.test.ts` (the CI ratchet).
35
+ The ledger is importable by future tooling (e.g. the bench runner's coverage
36
+ report) but nothing at runtime consumes it yet.
37
+
38
+ ## Evidence
39
+
40
+ 6 new tests green (completeness, no-dangling, shrink-only pins ×2, argued
41
+ exemptions, Wave-1 regression pin); `tsc --noEmit` clean; full unit suite
42
+ green at push.
@@ -0,0 +1,18 @@
1
+ # The last few "model choices burned into the code" are now settings
2
+
3
+ Instar makes hundreds of small AI calls a day — checking messages, validating credentials, running its setup wizard, executing background dispatch steps. For almost all of them, WHICH model gets used is a setting an operator can change. But an audit this week found a handful of stragglers where the model name was typed directly into the code: the background dispatch runner always spawned "haiku", the setup wizard always asked "gpt-5.3-codex" (or "gemini-2.5-flash") to write its intro text, and the credential checker always pinged Anthropic with a hard-typed "claude-haiku-4-5". If benchmarking ever showed a better/cheaper model for one of these jobs, changing it meant editing source code and shipping a release — for what should be a one-line setting.
4
+
5
+ This change makes those last callsites configurable, with one iron rule: **if you change nothing, nothing changes.** Every one of them keeps exactly its old model as the built-in default. The new settings don't even get written into config files — absence IS the default, so no existing agent's config is touched on update, and there is nothing to migrate.
6
+
7
+ The specifics, in plain terms:
8
+
9
+ - The background dispatch runner's model can now be set in config (`intelligence.pinnedModels.dispatchAgentic`). Unset, it's "haiku" like always.
10
+ - The credential checker's tiny "does this key work?" ping model is configurable too (`intelligence.pinnedModels.anthropicCredentialProbe`) — and its default now comes from the central model list instead of a lone typed-out string, so a future Claude model bump can't silently miss it.
11
+ - The setup wizard is special: it runs BEFORE the config file exists (creating that file is its whole job), so a config setting could never reach it. Its override is an environment variable instead (`INSTAR_WIZARD_CODEX_MODEL` / `INSTAR_WIZARD_GEMINI_MODEL`), which is the only kind of setting that CAN reach it.
12
+ - One honest discovery: the mentor loop — listed in the audit as hardcoded to "opus" — turned out to already be configurable (`mentor.autonomousFix.model`); the audit row was wrong. A test now pins that so the record stays honest.
13
+
14
+ Also cleaned up: the wizard's codex model name was typed in TWO places that could drift apart; now there's one source of truth that the other re-exports.
15
+
16
+ Safety story: this adds no new decision-making, no gating, no blocking — it only lets an operator choose the model for five existing, unchanged jobs. Fifteen new tests prove both directions on every surface: leave it unset and you get byte-for-byte the old behavior; set it and your value wins; set it to whitespace and it's treated as unset. The existing wizard canary tests (which pin the "-m model" discipline on every codex spawn) pass unmodified. Rollback is deleting a config line.
17
+
18
+ Why now: this is step one of the INSTAR-Bench v2 program (operator-approved 2026-07-02) — before benchmark results can drive model routing, every model choice has to be reachable by configuration rather than buried in code.
@@ -0,0 +1,11 @@
1
+ # New AI decision-makers now have to bring a test report card
2
+
3
+ Instar has about fifty little AI helpers inside it — one classifies your messages, one reviews outgoing replies, one judges whether an autonomous work session really finished, and so on. We just started benchmarking these helpers properly: for each one, a battery of hard test cases that tells us which AI model does that specific job well, fast, and cheap. Those measurements are what our model-routing choices will be based on going forward.
4
+
5
+ But a benchmark only stays trustworthy if it stays complete. The failure mode is silent: someone adds a NEW AI helper next month, nobody writes test cases for it, and suddenly there's an unmeasured decision-maker running in production whose model was picked by vibes. Six months later there are ten of those and the benchmark is a museum piece.
6
+
7
+ This change makes that impossible — not by policy, by build failure. There's now a coverage ledger listing every AI helper and its benchmark status: covered (with the name of its test battery), queued for authoring (an explicitly pinned to-do list), or exempt (with a written argument why testing it makes no sense — and "n/a" is literally rejected as too short). A test in the build system cross-checks that ledger against the master list of AI helpers. Add a new helper without deciding its benchmark story, and the build goes red with instructions telling you exactly what to do.
8
+
9
+ The teeth are in the details: the "queued" list can only shrink. You can graduate an entry to covered, but adding a new name to the queue requires editing the pinned list inside the test itself — a change any reviewer will see and question. Same for exemptions. So the lazy path (quietly park it in the queue forever) is exactly as visible as the honest path (write the test cases). Ten of the most critical helpers — the message classifier, the outbound-message gate, the completion judge, the injection screener, and their peers — are additionally pinned as "may never slide back": once covered, always covered.
10
+
11
+ This is the second ratchet of its kind. The first (already live) forces every new AI call site to register in the routing map so we know which provider runs it. Together they close the loop: every AI decision-maker in instar must be routed deliberately AND measured before it ships. Nothing changes at runtime — this is purely a build-time guarantee, and it costs nothing unless someone tries to skip the homework.
@@ -0,0 +1,63 @@
1
+ # Side-Effects Review — Config-driven pinned-model callsites (routing-registry risk items #3/#5/#6/#7)
2
+
3
+ **Version / slug:** `config-driven-pinned-models`
4
+ **Date:** `2026-07-02`
5
+ **Author:** `Instar Agent (echo)`
6
+ **Second-pass reviewer:** `not required` (no gate/sentinel/lifecycle surface — pure config plumbing with behavior-preserving defaults)
7
+
8
+ ## Summary of the change
9
+
10
+ Migrates the hardcoded-model callsites catalogued as "Risk items" #3, #5, #6, #7 in the LLM Routing Registry audit (2026-07-01, operator-directed) to overridable configuration with **behavior-preserving inline defaults** — with no config/env set, every callsite behaves byte-for-byte as before. Files touched: `src/core/types.ts` (new `intelligence.pinnedModels` block, inline-defaulted per the documented codexExecJson/swapAttemptTimeoutMs precedent), `src/core/DispatchExecutor.ts` (optional `agenticModel` ctor option, default 'haiku'), `src/commands/server.ts` (threads `pinnedModels.dispatchAgentic` + `pinnedModels.anthropicCredentialProbe` into the two construction sites), `src/commands/setup-wizard/model-constants.ts` (env-overridable resolvers `INSTAR_WIZARD_CODEX_MODEL` / `INSTAR_WIZARD_GEMINI_MODEL` — env not config because the wizard runs before `.instar/config.json` exists), `src/commands/setup.ts` (duplicate const replaced with import/re-export from model-constants — single source of truth), `src/providers/adapters/anthropic-headless/config.ts` + `control/authCredentialInjection.ts` (new `credentialProbeModel` field; default now sourced from `ANTHROPIC_MODELS.haiku` in `src/core/models.ts` instead of a free-floating string literal), and `tests/unit/pinned-model-callsites.test.ts` (15 new tests).
11
+
12
+ **Honest scope note:** risk item #4 (mentor loop → opus) required NO code change — it was already config-driven via `mentor.autonomousFix.model` (default 'opus'); the registry row was imprecise. A canary test now pins that fact.
13
+
14
+ ## Decision-point inventory
15
+
16
+ No decision point is added, modified, or removed. Model *selection inputs* to five existing callsites become configurable; the callsites' logic, gating, and control flow are untouched. All five are pass-through surfaces:
17
+
18
+ - `DispatchExecutor.runAgentic` — pass-through — spawned-session model tier now `options.agenticModel ?? 'haiku'`.
19
+ - `setup-wizard codex narrative spawn` — pass-through — model const now env-resolvable, default unchanged.
20
+ - `setup-wizard gemini narrative spawn` — pass-through — same.
21
+ - `anthropic-headless credential probe` — pass-through — ping model now `config.credentialProbeModel ?? ANTHROPIC_MODELS.haiku`.
22
+ - `server.ts boot wiring` — pass-through — threads the two config keys when present; spreads nothing when absent.
23
+
24
+ ---
25
+
26
+ ## 1. Over-block
27
+
28
+ No block/allow surface — over-block not applicable. (No input is ever rejected by this change; a nonsense model value in config flows to the underlying spawn/API call, which fails with that layer's existing error surface — same as a nonsense value in any other model config key like `subscriptionPath.model`.)
29
+
30
+ ## 2. Under-block
31
+
32
+ No block/allow surface — under-block not applicable. One adjacent honest note: this change does NOT validate configured model ids against a known-models list. That is deliberate and consistent with every existing model config key (`sessions.frameworkDefaultModels`, `subscriptionPath.model`, `mentor.autonomousFix.model` — none validate); inventing validation only here would be a new inconsistent behavior surface.
33
+
34
+ ## 3. Level-of-abstraction fit
35
+
36
+ Right layer. The change follows the established three-layer pattern already used by every other model-selection surface: config type (`types.ts`) → boot threading (`server.ts`) → inline default at the consumption site. The wizard deviation (env var instead of config key) is a deliberate fit-to-layer choice: the wizard runs pre-config by definition, so a config key would be unreadable at its runtime — an env var is the only honest override surface there, and the config docblock documents the split. The credential-probe default moving to `ANTHROPIC_MODELS.haiku` removes a string literal that could silently drift from the tier map (registry risk item #8's concern).
37
+
38
+ ## 4. Signal vs authority compliance
39
+
40
+ Compliant — trivially. No signal is produced, no authority is held, no brittle check is added anywhere. (Reference: docs/signal-vs-authority.md.)
41
+
42
+ ## 5. Interactions
43
+
44
+ - **Tier maps / escalation:** `dispatchAgentic` feeds `SessionManager.spawnSession({model})` exactly as the literal did; tier escalation and topic-profile resolution operate on spawned *conversation* sessions, not this job-slugged dispatch session — no new interaction.
45
+ - **componentFrameworks routing:** untouched — these callsites were router-bypasses before and remain framework-pinned; only the *model value* became configurable. (Making them router-routed was considered and rejected for this change: dispatch/wizard/probe are structurally tied to their frameworks. The v2 bench routing pass may revisit.)
46
+ - **Canary tests:** `setup-codex-model-canary.test.ts` still passes unmodified — the const-shape contract (`-m WIZARD_CODEX_MODEL` on every codex spawn; pinned to a subscription-supported model) is preserved by computing the const through the resolver at module load.
47
+ - **No double-fire / shadow / race surface:** nothing fires.
48
+
49
+ ## 6. External surfaces
50
+
51
+ None. No user-visible output changes, no API shape changes, no cross-agent surface. The probe ping still sends 4 max_tokens to the same endpoint with the same default model id.
52
+
53
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
54
+
55
+ **Machine-local BY DESIGN.** `intelligence.pinnedModels` lives in `.instar/config.json`, which deliberately does not sync across machines (same posture as every other `intelligence.*` key — each machine's operator tunes its own routing). The wizard env vars are process-local by nature. No durable state, no user-facing notices, no generated URLs.
56
+
57
+ ## 8. Rollback cost
58
+
59
+ Trivial. Remove the config key / env var → shipped defaults apply immediately (next boot for config, next wizard run for env). Reverting the commit restores literals with zero data migration — no persisted state depends on the new keys (inline-defaulted precisely so absence is the default state; nothing was added to ConfigDefaults/migrateConfig, so no migration parity work is owed).
60
+
61
+ ## Test evidence
62
+
63
+ `tests/unit/pinned-model-callsites.test.ts` — 15 tests: both sides of every boundary (absent ⇒ shipped default, present ⇒ override wins, whitespace ⇒ absent) for all three migrated surfaces, wiring canaries asserting server.ts actually threads both config keys, and the mentor already-config-driven canary. Plus `setup-codex-model-canary.test.ts` (5 tests) unmodified and green. `npx tsc --noEmit` clean.
@@ -0,0 +1,41 @@
1
+ # Side-Effects Review — LLM benchmark-coverage ratchet (INSTAR-Bench v2 §6, ratchet #2)
2
+
3
+ **Version / slug:** `llm-bench-coverage-ratchet`
4
+ **Date:** `2026-07-02`
5
+ **Author:** `Instar Agent (echo)`
6
+ **Second-pass reviewer:** `not required` (build-time test + data map only; zero runtime surface)
7
+
8
+ ## Summary of the change
9
+
10
+ Adds `src/data/llmBenchCoverage.ts` — a coverage ledger mapping every LLM component (every key of `COMPONENT_CATEGORY`) to its INSTAR-Bench v2 status: `{task}` covered (10 Wave-1 critical components), `{pending}` queued (42, pinned), or `{exempt}` argued (1) — and `tests/unit/llm-bench-coverage-ratchet.test.ts`, which fails CI when a new LLM component ships without a coverage decision, when the pending/exempt sets grow (shrink-only pins), when an exemption's argument is lazy (<40 chars), or when a Wave-1 critical component slides back to uncovered. Operator directive 2026-07-02 (topic 29723) + INSTAR-BENCH-V2-SPEC §6. No runtime code is touched.
11
+
12
+ ## Decision-point inventory
13
+
14
+ None at runtime. The only "decision" is a CI pass/fail on repository content — a build-time ratchet identical in class to the existing `llm-attribution-ratchet`.
15
+
16
+ ## 1. Over-block
17
+ The ratchet can block a COMMIT (not a message/action): a developer adding an LLM component who genuinely cannot author bench cases yet must add the component to the pending baseline inside the test — a deliberate, visible act. That is the intended cost, not an over-block; there is no path it rejects that it shouldn't (an argued exemption is always available).
18
+
19
+ ## 2. Under-block
20
+ Honest limits: (a) the ratchet keys off `COMPONENT_CATEGORY` — an LLM callsite that dodges the category map would also dodge this map, but the companion evaluate-coverage wiring test + attribution lint close that hole upstream; (b) it cannot verify the bench task file CONTENT (those live in the bench harness on the benching agent) — the task id is a contract, and a wrong/empty id would surface at the next bench run, not in CI. Accepted for v1 of the ratchet; noted in the map docblock.
21
+
22
+ ## 3. Level-of-abstraction fit
23
+ Right layer: repository data + unit test, the established ratchet pattern (`llm-attribution-ratchet`, `WIRING_EXCLUSIONS` pins). Extends the existing chain (callsite → category map → THIS → bench coverage) rather than inventing a parallel mechanism.
24
+
25
+ ## 4. Signal vs authority compliance
26
+ Compliant. No runtime authority; a CI test is deterministic, cheap, and its "block" is a build failure with instructions. (docs/signal-vs-authority.md concerns runtime decision points; none added.)
27
+
28
+ ## 5. Interactions
29
+ Complements `llm-attribution-ratchet` (attribution presence), `componentCategories` wiring test (map exhaustiveness), and the LLM Routing Registry doc. No double-fire: each guards a different link of the chain. No runtime interaction possible.
30
+
31
+ ## 6. External surfaces
32
+ None. Not user-visible; no API, no message, no config.
33
+
34
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
35
+ Not applicable — repository content evaluated in CI; identical on every machine by construction (git).
36
+
37
+ ## 8. Rollback cost
38
+ Delete the test + map (one revert). No state, no migration, no fleet impact — the ratchet only ever constrained future commits.
39
+
40
+ ## Test evidence
41
+ `llm-bench-coverage-ratchet.test.ts`: 6 tests — completeness over COMPONENT_CATEGORY, no dangling entries, pending pinned shrink-only, exemptions pinned + argued, non-empty task ids, Wave-1 regression pin. All green; `tsc --noEmit` clean.