loki-mode 7.103.0 → 7.104.1

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,157 @@
1
+ # Sonnet 5 Default - Implementation Plan
2
+
3
+ Status: PLAN (no code written). Worktree: `../loki-sonnet5-wt` (branch `feat/sonnet5-default`).
4
+ Board decision: `strategy/roadmap/13-BOARD-2026-06-30.md`. Verified facts: `reference-sonnet5-model-ids` memory.
5
+ Release class: MINOR (new default execution model for every user). Full local-ci + council 3/3 + release ladder.
6
+
7
+ ## 1. Goal (founder directive, 2026-06-30)
8
+
9
+ Make Sonnet 5 the DEFAULT execution model for Loki runs. Advisor stays Opus (opt-in / when needed).
10
+ User can set all tiers to haiku|sonnet|opus from the dashboard at start, and hot-switch mid-run without
11
+ interrupting executions. Protect the "never lies about done" trust moat: the switch must NOT weaken the
12
+ verdict.
13
+
14
+ ## 2. Ground truth (verified against source 2026-06-30)
15
+
16
+ - Live model resolver: `resolve_model_for_tier()` (providers/claude.sh:390) reads
17
+ `PROVIDER_MODEL_{PLANNING,DEVELOPMENT,FAST}` (claude.sh:65-67) which chain from `CLAUDE_DEFAULT_*`
18
+ (claude.sh:55-57). Today: PLANNING=opus, DEVELOPMENT=opus (comment "was sonnet"), FAST=sonnet.
19
+ - `get_provider_tier_param` case block (run.sh:~2447) with hardcoded `development) echo opus` is the
20
+ INERT legacy fallback, reachable only when claude.sh is unsourced (guard run.sh:2414). Flip anyway
21
+ for consistency.
22
+ - Trust-gate code-review reviewers: `_dispatch_reviewer()` (run.sh:~10148) sets
23
+ `_rv_argv=("--dangerously-skip-permissions")` and deliberately passes NO `--model` -> reviewers run
24
+ on the ACCOUNT DEFAULT model = non-deterministic, config-dependent. The in-code comment (run.sh:~10164)
25
+ explicitly says a future `--model` here "must be pinned to opus, never fable" (Fable refuses cyber
26
+ content, ends -p turn with stop_reason refusal). Bun route mirrors this: quality_gates.ts:28 + :1223.
27
+ - Hot-switch mid-run EXISTS: `.loki/state/model-override` read each iteration (run.sh:16007-16070),
28
+ written by dashboard `POST /api/session/model` (server.py:2852), allowlist haiku|sonnet|opus|fable,
29
+ clamped by `loki_apply_max_tier_clamp` (claude.sh:347). Fresh `claude -p` per iteration = clean switch.
30
+ - Sonnet 5 = alias `claude-sonnet-5` (CLI resolves aliases to latest; loki passes alias verbatim at
31
+ claude.sh:334). Opus 4.8 = `claude-opus-4-8`. Pricing (server.py:6174, run.sh:4847/12153): sonnet
32
+ $3/$15, opus $5/$25, haiku $1/$5, fable $10/$50 - all correct. model_catalog.json has stale IDs
33
+ opus-4-7, sonnet-4-6.
34
+ - Parity-locked: `tests/test-model-override.sh` + dashboard estimator (`_clamp_to_max_tier`, `_max_tier`)
35
+ are byte-locked to the resolver. Flipping defaults MOVES the quote -> expected values must update.
36
+ - Dashboard-ui: no start-time model picker (grep empty). mid-run switcher UI also appears absent
37
+ (POST endpoint exists, no UI consumer found).
38
+
39
+ ## 3. Tier -> model mapping AFTER the change
40
+
41
+ | Tier (RARV phase) | Today | After |
42
+ |--------------------------|--------------------------|----------------------------------------|
43
+ | planning (REASON) | opus | sonnet (Opus opt-in via advisor path) |
44
+ | development (ACT/REFLECT)| opus | sonnet |
45
+ | fast (VERIFY) | sonnet | sonnet (haiku via LOKI_ALLOW_HAIKU) |
46
+ | trust gate (council/review)| account default (float)| account default (UNCHANGED); opus via OPT-IN `LOKI_ADVISOR_MODEL` |
47
+ | advisor / reviewer pin | (does not exist) | `LOKI_ADVISOR_MODEL` (default unset = today's behavior; set=opus) |
48
+ | Opus-for-execution | default | opt-in (dashboard "all opus" / env) |
49
+
50
+ ### CORRECTION (advisor review 2026-06-30) - D2 is OPT-IN, not always-on
51
+
52
+ The original board D2 ("always pin reviewers to --model opus") is REJECTED as written, for four reasons:
53
+ 1. NOT causally forced by the Sonnet flip: `_dispatch_reviewer` reads neither `tier_param` nor
54
+ `CLAUDE_DEFAULT_*`, so flipping the builder default does NOT change the reviewer model. The judge
55
+ floating with the account default is a PRE-EXISTING condition, not something this PR exposes.
56
+ 2. UNCOSTED: pinning 3 reviewers + devil's-advocate + security-sentinel to Opus ADDS Opus-priced tokens
57
+ on top of the builder savings. Opus ~1.7x sonnet. This could eat or exceed the "~40% cheaper" story.
58
+ Net cost is UNKNOWN until we measure reviewer-token vs builder-token volume for a typical `loki start`.
59
+ 3. CONTRADICTS the founder's words: "advisor will be opus IF NEEDED OR USER OPTED" = conditional/opt-in.
60
+ Always-on removes the implicit cost control users have today (account default) - opposite of the
61
+ adoption/cost intent.
62
+ 4. "Deterministic verdict" is the wrong framing: LLM reviewers are never deterministic; this is a
63
+ consistency/quality argument, not determinism.
64
+
65
+ Moat guarantee (corrected): default behavior of the trust gate is UNCHANGED by this release (no
66
+ cost regression, no surprise). Users who want a strong, consistent Opus judge set `LOKI_ADVISOR_MODEL=opus`
67
+ (or the dashboard "advisor: Opus" toggle), which pins the reviewer/override-judge to Opus. This is the
68
+ founder's "opus if needed or user opted", made real and opt-in. Lane B and Lane C COLLAPSE into this one
69
+ opt-in advisor path.
70
+
71
+ ## 4. Per-file change list (disjoint lanes for parallel principal engineers)
72
+
73
+ ### Lane A - Execution default flip (providers/claude.sh) [engineer 1]
74
+ - claude.sh:56 `CLAUDE_DEFAULT_DEVELOPMENT="opus"` -> `"sonnet"`.
75
+ - claude.sh:55 `CLAUDE_DEFAULT_PLANNING="opus"` -> `"sonnet"` (see open question Q1 - founder may want
76
+ planning to stay opus; design so this one line is a trivial revert).
77
+ - claude.sh:57 FAST stays sonnet.
78
+ - Trace + document the clamp ripple: `loki_apply_max_tier_clamp` (claude.sh:347) resolves planning/fable
79
+ DOWN to `PROVIDER_MODEL_DEVELOPMENT`. With dev=sonnet, `LOKI_MAX_TIER=sonnet` now genuinely pins
80
+ sonnet (previously it clamped to opus). Update the comment block at claude.sh:383-386 which currently
81
+ documents the opposite. This is a BEHAVIOR clarification, verify against the parity ports (Lane E).
82
+ - run.sh:~2447 legacy fallback `development) echo opus` -> `sonnet` (inert but consistent).
83
+
84
+ ### Lane B+C (COLLAPSED) - OPT-IN advisor/reviewer Opus pin [engineer 2]
85
+ - Introduce `LOKI_ADVISOR_MODEL` (unset default = TODAY'S behavior, no change; set to `opus` = pin).
86
+ - Bash: `_dispatch_reviewer()` (run.sh:~10148): IF `LOKI_ADVISOR_MODEL` is a valid allowlisted alias,
87
+ add `("--model" "$LOKI_ADVISOR_MODEL")` to `_rv_argv`; else leave unset (current behavior). Honor the
88
+ existing comment (opus ok, never fable - validate the alias is not fable). The override/architect paths
89
+ (which rewrite tier_param, NOT this dispatch) still cannot touch it.
90
+ - Bun: `quality_gates.ts` reviewer dispatch (near :1223): mirror the same opt-in read. BOTH routes match.
91
+ - Update the "reviewers deliberately do NOT pass --model" comments to: default no --model; opt-in pin
92
+ via LOKI_ADVISOR_MODEL; rationale = consistent/strong judge when the user wants it (NOT determinism).
93
+ - Devil's-advocate + security-sentinel inherit the opt-in pin (same dispatch).
94
+ - Dashboard: an "Advisor model" toggle (default: account default; option: Opus) writes LOKI_ADVISOR_MODEL
95
+ into the run env / a state file the dispatch reads. This IS the founder's "opus if needed or user opted".
96
+ - DO NOT make this always-on. Default behavior of the trust gate is unchanged (no cost regression).
97
+
98
+ ### Lane D - Dashboard model selection [engineer 4] (follows frontend-ui-engineering skill)
99
+ - Backend: confirm `POST /api/session/model` (server.py:2852) writes `.loki/state/model-override`
100
+ with allowlist haiku|sonnet|opus|fable (already does). Add start-time selection: `start_build`
101
+ (server.py:3234) accepts an optional `model` that writes the override file BEFORE launch (so iteration
102
+ 1 picks it up). Validate against the same allowlist + clamp.
103
+ - Frontend (dashboard-ui/src): add an accessible model selector (haiku/sonnet/opus) on the start/new-run
104
+ surface AND a mid-run switcher that calls POST /api/session/model. Real design-system tokens, keyboard
105
+ accessible, no AI-aesthetic. Show current effective model + that switch applies at next iteration.
106
+ Rebuild dashboard/static per CLAUDE.md release step 2.
107
+
108
+ ### Lane E - Catalog IDs, pricing note, parity tests [engineer 5]
109
+ - model_catalog.json: opus-4-7 -> claude-opus-4-8 (3 occurrences), sonnet-4-6 -> claude-sonnet-5
110
+ (5 occurrences). Keep the alias->tier structure.
111
+ - Pricing: LEAVE the cost NUMBERS at standing $3/$15 for sonnet (over-estimate is the safe direction;
112
+ avoids date-expiry logic that silently breaks after Aug 31 2026). ADD a one-line intro-price NOTE in
113
+ the dashboard pricing display / label ("Sonnet 5 intro $2/$10 through Aug 31 2026") - display only,
114
+ not a computed rate. Update labels "Sonnet (latest)" -> "Sonnet 5".
115
+ - codex gpt-5.3-codex $1.50/$12: UNVERIFIED external number. WebFetch OpenAI pricing to confirm or leave
116
+ with a "verify" note; do not propagate a guess as fact.
117
+ - Confirm gemini fully absent from pricing (deprecated v7.5.18).
118
+ - Parity tests: update `tests/test-model-override.sh` expected values (dev tier now sonnet). Update
119
+ dashboard estimator expected quotes. Any Bun parity test for the resolver. Run the parity matrix.
120
+
121
+ ## 5. Test / parity changes enumerated
122
+ - tests/test-model-override.sh: dev-tier resolution + LOKI_MAX_TIER=sonnet clamp expectations flip.
123
+ - Dashboard estimator parity test: per-iteration quote changes (opus->sonnet dev cost).
124
+ - New: a test asserting the trust-gate reviewer dispatch includes `--model opus` on BOTH routes
125
+ (grep/behavioral) - locks the moat guarantee so a future edit can't silently un-pin.
126
+ - New: start_build with model param writes a valid override; invalid model rejected.
127
+ - CLI-invariance: existing `loki verify` / `loki start` still run (no crash); default model differs
128
+ (that IS the intended change - do NOT assert byte-identical default output here).
129
+
130
+ ## 6. Calibration protocol (CEO gate - before ship)
131
+ - Pick 5-10 representative specs from benchmarks/ or internal fixtures spanning easy->hard.
132
+ - Run each on Sonnet-default vs current Opus-default (real model calls; NOT in CI - documented manual
133
+ step). Record: iterations-to-council-APPROVE, BLOCK count, wall-clock, and NET cost (builder tokens +
134
+ reviewer tokens, so the "~40% cheaper" claim is verified NET, not just on the builder tier). Append to
135
+ a calibration log under artifacts/sonnet5-calibration/.
136
+ - SHIP criterion: Sonnet-default does not materially increase iterations-to-APPROVE or BLOCK-rate on
137
+ hard specs AND the net cost genuinely drops. If iterations/BLOCK regress: keep the pre-built escape
138
+ hatch (planning->opus one-line revert; dev stays sonnet) and re-measure. Never silently keep Opus -
139
+ make the escalation legible. If net cost does NOT drop as claimed, correct the marketing claim to the
140
+ measured number - never ship an unverified "~40% cheaper".
141
+
142
+ ## 7. Release (per CLAUDE.md)
143
+ - Version bump all files (MINOR). Loud CHANGELOG entry: "Default execution model changed Opus -> Sonnet 5.
144
+ ~40% cheaper builds. Trust-gate reviewers pinned to Opus (deterministic verdict). Override any model
145
+ from the dashboard." Never claim "same accuracy" (no controlled study).
146
+ - bash scripts/local-ci.sh (must be green). Council 3/3 (2 Opus + 1 Sonnet reviewers that RUN tests).
147
+ - Rebuild dashboard frontend (Lane D). Merge worktree to main, tag via CI, verify 4 channels.
148
+ - NEVER run a loki build from the worktree (self-delete trap). Verify engine changes by function
149
+ extraction to scratch repos.
150
+
151
+ ## 8. Open questions for the founder (do NOT block starting)
152
+ - Q1: Should PLANNING tier also default to Sonnet (full flatten), or stay Opus (architecture quality)?
153
+ Plan flattens both per plain reading; Lane A makes planning a one-line revert either way.
154
+ - Q2: "advisor" scope - is it the completion-council override judge (recommended, minimal) or a
155
+ distinct advisory role you envision elsewhere?
156
+ - Q3: Sonnet 5 intro pricing - display-only note (planned) vs actually bill the $2/$10 in estimates
157
+ (rejected: date-expiry bug risk). Confirm display-only is acceptable.
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "$schema_version": 1,
3
3
  "_comment": "Rolling pricing table consumed by loki-ts/src/runner/budget.ts. Update this file when Anthropic / OpenAI / others publish new prices; no code change required. Pricing is USD per 1 million tokens. Aliases (opus/sonnet/haiku) point to the latest model of that family per providers/model_catalog.json.",
4
- "_updated": "2026-05-22",
5
- "_source": "https://www.anthropic.com/pricing + provider docs",
4
+ "_updated": "2026-06-30",
5
+ "_source": "https://www.anthropic.com/pricing + provider docs. sonnet=claude-sonnet-5 (list $3/$15; intro $2/$10 through 2026-08-31). opus=claude-opus-4-8. codex=gpt-5.3-codex standard tier.",
6
6
  "pricing": {
7
7
  "fable": { "input": 10.0, "output": 50.0 },
8
8
  "opus": { "input": 5.0, "output": 25.0 },
9
9
  "sonnet": { "input": 3.0, "output": 15.0 },
10
10
  "haiku": { "input": 1.0, "output": 5.0 },
11
- "gpt-5.3-codex": { "input": 1.5, "output": 12.0 }
11
+ "gpt-5.3-codex": { "input": 1.75, "output": 14.0 }
12
12
  }
13
13
  }