loki-mode 11.3.9 → 11.5.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.
Files changed (119) hide show
  1. package/README.md +34 -18
  2. package/SKILL.md +3 -3
  3. package/VERSION +1 -1
  4. package/agents/custom_agents.py +280 -0
  5. package/autonomy/council-v2.sh +22 -1
  6. package/autonomy/edit.sh +242 -0
  7. package/autonomy/lib/chat.sh +315 -0
  8. package/autonomy/lib/engine10-push.sh +19 -1
  9. package/autonomy/lib/help-core.sh +164 -0
  10. package/autonomy/lib/json-output.sh +38 -0
  11. package/autonomy/lib/proof-generator.py +23 -5
  12. package/autonomy/lib/proof-verify.py +607 -5
  13. package/autonomy/lib/run-summary.sh +112 -0
  14. package/autonomy/lib/setup-requirements.json +35 -0
  15. package/autonomy/loki +337 -46
  16. package/autonomy/provider-offer.sh +95 -47
  17. package/autonomy/route.sh +302 -0
  18. package/autonomy/run.sh +48 -14
  19. package/autonomy/setup-wizard.sh +170 -0
  20. package/autonomy/verify.sh +62 -3
  21. package/bin/loki +73 -18
  22. package/completions/_loki +58 -1
  23. package/completions/loki.bash +57 -5
  24. package/dashboard/__init__.py +1 -1
  25. package/docs/CLI-CORE-VERBS.md +112 -0
  26. package/docs/CLI-REFERENCE.md +9 -1
  27. package/docs/COMPARE-OPENCODE.md +94 -0
  28. package/docs/COMPONENTS.md +1 -0
  29. package/docs/EVALUATING.md +27 -0
  30. package/docs/HARNESS-INTELLIGENCE-PLAN.md +20 -0
  31. package/docs/INSTALLATION.md +56 -12
  32. package/docs/KNOWN-ISSUES.md +8 -9
  33. package/docs/PROOF-PASSPORT.md +114 -0
  34. package/docs/QUICKSTART.md +108 -0
  35. package/docs/alternative-installations.md +103 -0
  36. package/docs/cost-controls.md +139 -0
  37. package/docs/environment-variables.md +45 -2
  38. package/docs/exit-codes.md +129 -12
  39. package/docs/spec-first-intent.md +29 -0
  40. package/docs/v10/CLI-MODERN.md +11 -5
  41. package/docs/v10/ENGINE.md +32 -0
  42. package/docs/v10/GUIDE.md +270 -44
  43. package/docs/v10/OPENCODE-PARITY-PLAN.md +84 -0
  44. package/loki-ts/data/model-pricing.json +1 -0
  45. package/loki-ts/dist/loki.js +1065 -978
  46. package/mcp/__init__.py +1 -1
  47. package/package.json +2 -2
  48. package/packages/control-plane/dist/server.js +1829 -715
  49. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  50. package/plugins/loki-mode/README.md +41 -1
  51. package/plugins/loki-mode/commands/handoff.md +12 -0
  52. package/plugins/loki-mode/commands/loki-verify.md +9 -2
  53. package/plugins/loki-mode/commands/start.md +20 -0
  54. package/plugins/loki-mode/hooks/hooks.json +11 -0
  55. package/plugins/loki-mode/scripts/loki-stop-verify.sh +84 -0
  56. package/providers/claude.sh +16 -2
  57. package/providers/model_route_exec.sh +22 -0
  58. package/providers/model_routes.sh +188 -0
  59. package/skills/providers.md +13 -0
  60. package/templates/agents/planner.md +10 -0
  61. package/templates/agents/reviewer.md +10 -0
  62. package/templates/agents/tester.md +10 -0
  63. package/web-app/dist/assets/{AdminPage-QK-i_x-O.js → AdminPage-Cbu3pXL8.js} +1 -1
  64. package/web-app/dist/assets/{Avatar-DblkLNjB.js → Avatar-DGqGGcGx.js} +1 -1
  65. package/web-app/dist/assets/{Badge-DIV2ny5H.js → Badge-Bhlipt6v.js} +1 -1
  66. package/web-app/dist/assets/{Button--rePJOlQ.js → Button-CpN2sO61.js} +1 -1
  67. package/web-app/dist/assets/{CockpitPage-BZlKxpGy.js → CockpitPage-BqeDJwdL.js} +1 -1
  68. package/web-app/dist/assets/{ComparePage-3_INSVux.js → ComparePage-DUieA2ba.js} +1 -1
  69. package/web-app/dist/assets/{ErrorBoundary-DHG63CNr.js → ErrorBoundary-DTWsYrOm.js} +1 -1
  70. package/web-app/dist/assets/{EvidenceReceiptPanel-DFsBnLlO.js → EvidenceReceiptPanel-BU_B9X19.js} +1 -1
  71. package/web-app/dist/assets/{GitHubIssuesPanel-phPGah98.js → GitHubIssuesPanel-DEZoLOsP.js} +1 -1
  72. package/web-app/dist/assets/{GitHubPRsPanel-T7KQqJmx.js → GitHubPRsPanel-BEsnrq7Y.js} +1 -1
  73. package/web-app/dist/assets/{HomePage-DFjGUF5I.js → HomePage-BoUVuq7h.js} +2 -2
  74. package/web-app/dist/assets/{LoginPage-CorUid_5.js → LoginPage-CmOED7vb.js} +1 -1
  75. package/web-app/dist/assets/{MagicPage-DofbSxKD.js → MagicPage-DATZitrZ.js} +1 -1
  76. package/web-app/dist/assets/{MetricsPage-qzrhhfLC.js → MetricsPage-DGL1v0I-.js} +1 -1
  77. package/web-app/dist/assets/{NotFoundPage-BAZR0mMb.js → NotFoundPage-C2WgOjZd.js} +1 -1
  78. package/web-app/dist/assets/{ProjectPage-BOSUzG9J.js → ProjectPage-BMi1tepj.js} +3 -3
  79. package/web-app/dist/assets/{ProjectsPage-Ba0YLtzD.js → ProjectsPage-vc3y5YPh.js} +1 -1
  80. package/web-app/dist/assets/{SettingsPage-Cr10Ue2K.js → SettingsPage-kbq0Ftvi.js} +1 -1
  81. package/web-app/dist/assets/{ShowcasePage-Czn655fe.js → ShowcasePage-Bn6Q8Kbg.js} +1 -1
  82. package/web-app/dist/assets/{SystemSettingsPage-Dwjnw6Ob.js → SystemSettingsPage-Basmhs_b.js} +1 -1
  83. package/web-app/dist/assets/{TeamsPage-D8nc69Be.js → TeamsPage-BTqOc4TR.js} +1 -1
  84. package/web-app/dist/assets/{TemplatesPage-DHsaCDGv.js → TemplatesPage-2P9002VL.js} +1 -1
  85. package/web-app/dist/assets/{TerminalOutput-DBejni2a.js → TerminalOutput-CAoSPBrg.js} +1 -1
  86. package/web-app/dist/assets/{activity-B2VsBl1C.js → activity-BcWVWCqU.js} +1 -1
  87. package/web-app/dist/assets/{bell-CT77Fq2H.js → bell-CYRqqgZ6.js} +1 -1
  88. package/web-app/dist/assets/{bot-DfaWgF4H.js → bot-CU7gdn3g.js} +1 -1
  89. package/web-app/dist/assets/{check-D1yp7Ndv.js → check-DLlCpz9V.js} +1 -1
  90. package/web-app/dist/assets/{chevron-left-B6Pa8IOX.js → chevron-left-CE9Cb30C.js} +1 -1
  91. package/web-app/dist/assets/{circle-alert-D5jrL_Y7.js → circle-alert-uou4bjua.js} +1 -1
  92. package/web-app/dist/assets/{clock-DIsY_fa_.js → clock-C_dSJcDX.js} +1 -1
  93. package/web-app/dist/assets/{cloud-eGwLh1As.js → cloud-DZ22ITF6.js} +1 -1
  94. package/web-app/dist/assets/{code-xml-CGDIcZ3m.js → code-xml-BrJS0hhS.js} +1 -1
  95. package/web-app/dist/assets/{database-CWpdaykI.js → database-D2HOmxtl.js} +1 -1
  96. package/web-app/dist/assets/{dollar-sign-DZEuTCs6.js → dollar-sign-CQ1vK_6q.js} +1 -1
  97. package/web-app/dist/assets/{file-code-corner-BHBW6m9v.js → file-code-corner-w2vpGm5d.js} +1 -1
  98. package/web-app/dist/assets/{file-plus-D4h1jZSR.js → file-plus-DlF6wjkD.js} +1 -1
  99. package/web-app/dist/assets/{globe-CXdqKgwd.js → globe-Dy3lBJg1.js} +1 -1
  100. package/web-app/dist/assets/{hammer-B3YuuYI_.js → hammer-C3xIiRXN.js} +1 -1
  101. package/web-app/dist/assets/{index-BLEnboSv.js → index-4t-_IW2y.js} +3 -3
  102. package/web-app/dist/assets/{layers-Dvp5nFtw.js → layers-Y8Fs8qXI.js} +1 -1
  103. package/web-app/dist/assets/{loader-circle-DodDmIZ3.js → loader-circle-CxgN1v4m.js} +1 -1
  104. package/web-app/dist/assets/{lock-EiuaH1Ep.js → lock-DFFNbXDs.js} +1 -1
  105. package/web-app/dist/assets/{package-Cx4m2hFg.js → package-5e6qCTUg.js} +1 -1
  106. package/web-app/dist/assets/{plus-D-Sd5rpH.js → plus-C0Go_ytj.js} +1 -1
  107. package/web-app/dist/assets/{refresh-cw-C0w1cdmF.js → refresh-cw-D4i-NW3o.js} +1 -1
  108. package/web-app/dist/assets/{rotate-ccw-C_qk6MTT.js → rotate-ccw-YlKkiUW6.js} +1 -1
  109. package/web-app/dist/assets/{scroll-text-DSxiFtkc.js → scroll-text-4qXOHTap.js} +1 -1
  110. package/web-app/dist/assets/{server-NTJt7I8M.js → server-BB6zXNp9.js} +1 -1
  111. package/web-app/dist/assets/{shield-alert-HBxMQOvH.js → shield-alert-D4tzjB1H.js} +1 -1
  112. package/web-app/dist/assets/{thumbs-up-DEgsHzSD.js → thumbs-up-DZiRwdFj.js} +1 -1
  113. package/web-app/dist/assets/{trash-2-px46FnTD.js → trash-2-Dv_LkRIK.js} +1 -1
  114. package/web-app/dist/assets/{trending-down-CBosVGKa.js → trending-down-BJYp9PQe.js} +1 -1
  115. package/web-app/dist/assets/{trending-up-Dbd7zrQj.js → trending-up-BTcXLklK.js} +1 -1
  116. package/web-app/dist/assets/{upload-nhdFKAs1.js → upload-fcHqwOxr.js} +1 -1
  117. package/web-app/dist/assets/{usePolling-BgaGdinh.js → usePolling-BeJYw_4L.js} +1 -1
  118. package/web-app/dist/assets/{user-CzIihUy9.js → user-BcDwUCsO.js} +1 -1
  119. package/web-app/dist/index.html +1 -1
@@ -26,3 +26,32 @@ A spec that does not parse exits 2 before any run state is created, naming the f
26
26
  ## Unchanged without the flags
27
27
 
28
28
  Without `--spec` or `--spec-first`, `loki plan` stays on its existing route, `loki start` behaves as before, and the plan and implement briefs are byte-identical (pinned by golden fixtures in `loki-ts/tests/engine10/fixtures`).
29
+
30
+ ## Requirement-to-check map (REQTRACE)
31
+
32
+ File: `.loki/state/requirements-map.json`. Written after verification, before the run summary. Read-only view: `loki plan --requirements` (add `--json` for the raw file). Code: `loki-ts/src/features/contract.ts`; tests: `loki-ts/tests/features/contract.test.ts`.
33
+
34
+ ```json
35
+ {"version":1,"revision":"<git sha at write time, or \"unknown\">","requirements":[
36
+ {"id":"R1","text":"...","checks":["<check id>"],"status":"covered","method":"explicit"}
37
+ ]}
38
+ ```
39
+
40
+ - `status` is `covered` only when at least one check that actually ran and passed maps to the requirement. `checks` lists only those passing checks. A failed, flaky, not_run or pending check never covers.
41
+ - `method` is `explicit` when the requirement carries its own link to checks, `heuristic` otherwise. An uncovered requirement with no link is `heuristic` with `checks: []`.
42
+ - Ids `R1..Rn` are assigned in source order. At most 40 requirements are taken from PRD text.
43
+ - The file is never written when there is no requirement source, and a write failure never fails a run.
44
+
45
+ Requirements and checks come from existing extractors, with no second parser:
46
+
47
+ | Run | Requirements | Checks that ran | Link |
48
+ |---|---|---|---|
49
+ | Bun runner (`loki start`, default) | `.loki/checklist/checklist.json` items | that item's `verification[]` entries, id `<item id>:<type>:<n>`; `passed === true` counts | explicit, by construction |
50
+ | engine10 with `--spec` | acceptance criteria of the spec snapshot (`spec_file.ts` parseSpec) | `test.result` events of the run, id = check name (`runner:path`) | explicit if the criterion ends with `[check: id1, id2]`, else heuristic |
51
+ | engine10 text or PRD task | units from `autonomy/lib/requirements_contract.py` `extract_bound_requirement_units`; needs 2 or more units | same `test.result` events | heuristic |
52
+
53
+ Heuristic rule: a passing check matches when it shares at least 2 significant words (4 or more letters, minus a small stop list; all of them when the requirement has only one) with the check id plus command. It is a hint, not proof, which is why `method` is recorded.
54
+
55
+ Surfaces: the run summary next-step line reads `N requirement(s) uncovered, see: loki plan --requirements` when `N > 0`, inside the 8-line cap (engine10 `withNextLine` / `formatRunSummary`, and `autonomy/lib/run-summary.sh` for the bash summary). The JSON summary adds `requirements_uncovered` only when `N > 0`.
56
+
57
+ Known gaps: the legacy bash engine (`autonomy/run.sh` without Bun) does not write the map; its summary only reads one if present. Heuristic matching is word overlap only and can both miss and over-claim, so use explicit `[check: id]` links for requirements that matter.
@@ -6,12 +6,12 @@ Classes: KEEP-MODERN (v10-native or engine-neutral), UPDATE (live but needs mode
6
6
 
7
7
  ## Counts
8
8
 
9
- - KEEP-MODERN: 64
9
+ - KEEP-MODERN: 69
10
10
  - UPDATE: 22
11
- - DROP-LEGACY: 31
11
+ - DROP-LEGACY: 32
12
12
  - DELETE: 14
13
- - Total rows: 131
14
- - Registry paths (commands and nested subcommands): 181
13
+ - Total rows: 137
14
+ - Registry paths (commands and nested subcommands): 190
15
15
 
16
16
  ## Commands
17
17
 
@@ -45,6 +45,11 @@ Classes: KEEP-MODERN (v10-native or engine-neutral), UPDATE (live but needs mode
45
45
  | completion (hidden) | loki-ts/src/cli.ts | KEEP-MODERN | Hidden plumbing; completions install themselves |
46
46
  | __complete (hidden) | loki-ts/src/cli.ts | KEEP-MODERN | Hidden plumbing for generated completions |
47
47
  | help | autonomy/loki | KEEP-MODERN | Core |
48
+ | chat | autonomy/loki | KEEP-MODERN | Provider-neutral conversational verb |
49
+ | edit | autonomy/loki | KEEP-MODERN | Provider-neutral single-edit verb |
50
+ | diff | autonomy/loki | KEEP-MODERN | Passes extra args to git diff |
51
+ | models | autonomy/loki | KEEP-MODERN | Provider-neutral model tiers |
52
+ | setup | autonomy/loki | KEEP-MODERN | Onboarding gate |
48
53
  | quick | autonomy/loki | UPDATE | Routes to the v10 lean path by default |
49
54
  | quickstart | autonomy/loki | KEEP-MODERN | Onboarding path |
50
55
  | init | autonomy/loki | UPDATE | Templates predate v10 |
@@ -129,6 +134,7 @@ Classes: KEEP-MODERN (v10-native or engine-neutral), UPDATE (live but needs mode
129
134
  | cleanup | autonomy/loki | DROP-LEGACY | Legacy run.sh orphans |
130
135
  | state | autonomy/loki | DROP-LEGACY | Legacy engine |
131
136
  | agent | autonomy/loki | DROP-LEGACY | Legacy engine |
137
+ | agents | autonomy/loki | DROP-LEGACY | Legacy engine |
132
138
  | trigger | autonomy/loki | DROP-LEGACY | Legacy engine |
133
139
  | failover | autonomy/loki | DROP-LEGACY | Legacy engine |
134
140
  | reset | autonomy/loki | DROP-LEGACY | Legacy engine |
@@ -178,7 +184,7 @@ Classes: KEEP-MODERN (v10-native or engine-neutral), UPDATE (live but needs mode
178
184
  - preview: 1
179
185
  - projects: 8
180
186
  - proof: 6
181
- - provider: 3
187
+ - provider: 2
182
188
  - quick: 1
183
189
  - resume: 1
184
190
  - rollback: 2
@@ -252,6 +252,38 @@ Every claim below comes from reading main at 84c22568. I edited no files.
252
252
  - **Green:** all five assertions hold against the sandbox repo.
253
253
  - **Deps:** E-23, E-32, E-36.
254
254
 
255
+ ### Recovery of an interrupted run
256
+
257
+ Code: `resumeMain`, `findInterrupted`, `resumePublish`, `startRecovery` in `loki-ts/src/util/run_outputs.ts`, `phaseOf` in `events.ts`, `runOwnerAlive` in `util/run_pid.ts`, the push-skip in `autonomy/lib/engine10-push.sh`, `loki resume` in `autonomy/loki`. Tests: the RECOVERY block in `loki-ts/tests/engine10/pr.test.ts` and the recovery block in `tests/test-engine10-push.sh`.
258
+
259
+ An interrupted run has an `events.jsonl` with neither `run.completed` nor `pr.opened`, and a `run.pid` that does not name a live process with the recorded start time. A run owned by a live supervisor is never resumed. The phase comes from the event log only (`phaseOf`):
260
+
261
+ | Phase | Meaning | Recoverable |
262
+ |-----------|-------------------------------------------------------------|-------------|
263
+ | implement | no `stage.completed` for implement | No (reported) |
264
+ | verify | implement completed, no `receipt.sealed` | No (reported) |
265
+ | publish | `receipt.sealed` present, no `pr.opened` or `run.completed` | Yes |
266
+ | done | `pr.opened` or `run.completed` present | Nothing to do |
267
+
268
+ `loki resume [run-id]`, and `loki start "<same task>"` when the newest interrupted run is in the publish phase, its recorded intake task equals the new task and `--no-pr` is absent, resume the publish phase and print `resumed phase: publish (run <id>); receipt reused; PR <url>`.
269
+
270
+ - The sealed receipt is reused: no second `receipt.json`, no second `receipt.sealed` event. Resume never reseals.
271
+ - Events appended: `run.resumed`, `pr.opened`, `run.completed` (with `resumed: true` and the not-proven note "publish phase resumed after an interruption"), then the log seal.
272
+ - Push is skipped when the remote branch is already at the local commit (GitHub: `gh api .../git/ref/heads/<branch>`; local bare origin: `git ls-remote`). A newer commit is a new revision and is pushed.
273
+ - PR creation checks `gh pr list --head <branch> --state open` first and reuses an open PR, so any number of publish attempts yields one PR.
274
+
275
+ For implement and verify, `loki resume` prints the phase, whether branch `loki/<run-id>` holds preserved work, and exits 4. `loki start` prints a one-line note and starts a new run. `LOKI_NO_RESUME=1` disables the `loki start` check.
276
+
277
+ Exit codes of `loki-ts engine10 resume`: 0 resumed, 3 no interrupted run, 4 phase reported but not auto-resumable, 5 publish attempted and failed (the run stays resumable), 2 not in a git repository or no origin.
278
+
279
+ Honest limits:
280
+ - implement and verify keep stage outputs in the worker's memory; the stage machine cannot skip completed stages. Work committed on `loki/<run-id>` is preserved but the run is not continued.
281
+ - A crash between `gh pr create` returning and `pr.opened` being recorded is recovered by the open-PR lookup, provided GitHub lists the PR by then.
282
+ - A crash after the commit status call but before `run.completed` sets the same status again.
283
+ - GitLab origins (`engine10-push-gitlab.sh`) are unchanged; push-skip and PR reuse are verified for the GitHub and local-bare paths only.
284
+ - The legacy bash loop (`autonomy/run.sh`) keeps its own iteration-level resume.
285
+ - Deep verify (a detached child spawned after `pr.opened`) is not re-spawned on resume.
286
+
255
287
  ### BOARD rows
256
288
 
257
289
  The notes start with the requested "Source: ENGINE.md 23:00Z cut." and then add dependencies, following the 21:50Z rows. If you want the notes to be only that sentence, drop the dependency part.
package/docs/v10/GUIDE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Loki 10 engine guide
2
2
 
3
- Default: Loki 10 engine for `loki "<task>"`, `loki owner/repo#N` and `loki quick "<task>"`. `loki legacy` and LOKI_ENGINE were removed in 11.0.0. <!-- loki10-default -->
3
+ Default: Loki 10 engine for `loki start`, `loki "<task>"`, `loki owner/repo#N` and `loki quick "<task>"`. `loki legacy` was removed in 11.0.0; the previous loop runs only on an explicit `--engine legacy` or `LOKI_ENGINE=legacy` (see Routing). <!-- loki10-default -->
4
4
 
5
5
  Loki 10 is the rewritten engine (docs/v10/ENGINE.md). Since the D48 flip it
6
6
  runs `loki "<task>"`, `loki owner/repo#N` (issue mode) and `loki quick
@@ -12,29 +12,77 @@ newest entry in .loki/runs/ is a v10 run newer than the newest legacy proof
12
12
  it runs the v10 verify, otherwise the legacy verify. If bun is missing or
13
13
  LOKI_PROVIDER is unsupported, the default mode falls back to the bash path
14
14
  and prints one stderr line saying why. In 11.0.0 (LEGACY-ZERO W1-01) `loki
15
- legacy` was removed (it exits 2 with a removal message) and LOKI_ENGINE is no
16
- longer read; any value is ignored.
15
+ legacy` was removed (it exits 2 with a removal message). From 11.4.0
16
+ `--engine legacy|engine10` and LOKI_ENGINE select the engine explicitly (see
17
+ Routing below).
17
18
 
18
- `loki start owner/repo#N`, `loki start <issue URL>` and `loki start "<multi-word
19
- task>"` run Loki 10, the same as `loki owner/repo#N` and `loki "<task>"`. A PRD
20
- file, a flag-first call (`loki start --simple prd.md`) and a one-word start still
21
- run on the previous bash loop (autonomy/run.sh), and so does the opencode
22
- provider, until FC38-SWEEP ports them. `loki legacy` and LOKI_ENGINE remain
23
- removed. The previous loop is being removed (see docs/v10/LEGACY-REMOVAL.md).
19
+ ## Routing
20
+
21
+ Argument order and input form never change the engine. Flags are normalized
22
+ before the routing decision, so these all run on Loki 10:
23
+
24
+ ```
25
+ loki start prd.md loki start --no-pr prd.md
26
+ loki start owner/repo#123 loki start --provider codex owner/repo#123
27
+ loki start "fix the login bug" loki start --no-pr "fix the login bug"
28
+ loki start fixit loki quick -v "fix the login bug"
29
+ ```
30
+
31
+ A PRD file, an issue ref or URL, a multi-word task and a one-word brief take
32
+ the same path. `-v` means `--verbose`, `--budget` and `--budget-limit` mean
33
+ `--max-cost`, and `--yes`, `-y`, `--no-plan`, `--no-mirofish` and
34
+ `--no-dashboard` are accepted and ignored. A PRD file path that does not exist
35
+ exits 2 with "PRD file not found".
36
+
37
+ The previous loop (autonomy/run.sh) runs only when:
38
+
39
+ 1. you pass `--engine legacy` or set `LOKI_ENGINE=legacy` (`--engine engine10`
40
+ forces Loki 10 and refuses a flag it cannot honor; the flag wins over the
41
+ variable), or
42
+ 2. the call carries a flag Loki 10 does not support (for example `--simple`,
43
+ `--complex`, `--parallel`, `--github`, `--sandbox`, `--max-iterations`).
44
+ Only that call goes to the previous loop, and one stderr line names the flag
45
+ and the engine chosen, or
46
+ 3. LOKI_PROVIDER (or `--provider`) names a provider Loki 10 has no invoker
47
+ for (anything but claude, codex, cline, aider, opencode), or bun is missing, or the
48
+ PRD is larger than 100000 bytes. One stderr line says why.
49
+
50
+ `loki <word>` with a single bare word stays the command namespace (`loki doctor`),
51
+ so use `loki start <word>` for a one-word brief. A first argument starting with
52
+ `-` followed by a multi-word task or an issue ref (`loki --no-pr "fix it now"`)
53
+ runs on Loki 10 like the positional form.
54
+
55
+ ### See the route without running
56
+
57
+ ```
58
+ loki route start prd.md
59
+ loki route quick "fix the login redirect loop" --json
60
+ loki start --simple prd.md --explain-route
61
+ ```
62
+
63
+ `loki route [start|quick] <same args>` and `--explain-route` on start or quick
64
+ print the engine, provider, model, input type and the reason, then exit 0
65
+ without running anything. `--json` prints one JSON object with the keys
66
+ `engine`, `provider`, `model`, `input_type`, `input`, `reason`.
24
67
 
25
68
  Some pieces named in this guide are still being built. Each one below says
26
69
  so plainly instead of describing a finished feature.
27
70
 
28
71
  ## Quickstart
29
72
 
30
- Put the task first, as a quoted multi-word string, so bin/loki's router
31
- sends it to the v10 engine. A one-word argument that is not an issue ref,
32
- or any first argument starting with `-`, stays on the legacy engine.
73
+ `loki start` is the primary path. Give it a PRD file, an issue ref, a task in
74
+ quotes or a one-word brief. Flags may come before or after it; the engine is
75
+ the same (see Routing).
33
76
 
34
77
  ```
35
- loki "fix the login redirect loop" --no-pr
78
+ loki start prd.md
79
+ loki start "fix the login redirect loop" --no-pr
36
80
  ```
37
81
 
82
+ `loki "<task>"` and `loki owner/repo#N` are shorthand for the same run.
83
+ `loki chat` is an interactive alternative that can start and join these runs
84
+ (see Chat below).
85
+
38
86
  `loki quick "<task>"` is the small-task entry. It runs the same engine
39
87
  without opening a pull request (the legacy quick never opened one), and the
40
88
  engine's own sizing picks the lean path for a small task: Plan and Wall are
@@ -42,16 +90,16 @@ skipped and implement runs on your run's own model, like a raw session.
42
90
  `LOKI_E10_CASCADE=1` opts in to the cheaper sonnet start (it prints and
43
91
  records the downgrade); a repeated test failure always escalates up, never
44
92
  down (Engine Law L1).
45
- `loki quick --help` and a flag-first `loki quick -v "<task>"` stay on the
46
- legacy quick.
93
+ `loki quick --help` prints the help; `loki quick -v "<task>"` runs on Loki 10 with
94
+ `--verbose`.
47
95
 
48
96
  ```
49
97
  loki quick "fix the login redirect loop"
50
98
  ```
51
99
 
52
100
  If bun is not installed, or LOKI_PROVIDER names a provider the v10 engine
53
- has no invoker for (anything but claude, codex, cline, aider), these entry
54
- points fall back to the legacy engine instead of failing.
101
+ has no invoker for (anything but claude, codex, cline, aider, opencode), these entry
102
+ points fall back to the legacy engine with a one-line notice instead of failing.
55
103
 
56
104
  Issue refs work the same way:
57
105
 
@@ -74,14 +122,19 @@ Flags, from the engine's own `--help`:
74
122
  from 480s to 1800s (`loki-ts/src/engine10/types.ts`).
75
123
  - `--provider <name>`: pick the coding provider for this run. See the
76
124
  provider table below.
77
- - `--max-cost <usd>`: per-run cost cap in dollars. Without the flag the cap is
78
- `budgets.per_run` in the repo's `loki.yaml` (for example
79
- `budgets:` then ` per_run: 5`), else the default of $20.00. The flag wins over
80
- the file. The start line shows the cap in force, for example
81
- `... previous engine), cap $20.00 (default)`. Once priced cost reaches the cap
82
- the running stage is stopped, no later stage starts, and the run ends
83
- BUDGET_STOP with exit code 3. Sessions with no provider price never count
84
- toward the cap.
125
+ - `--max-cost <usd>`: per-run cost cap in dollars (`--budget` and
126
+ `--budget-limit` are aliases). Order of precedence: the flag, then
127
+ `budgets.per_run` in the repo's `loki.yaml` (for example `budgets:` then
128
+ ` per_run: 5`), then the default. The default is $100.00 when
129
+ `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` is set, and no dollar cap on a
130
+ subscription login (usage then counts against your plan limits). Source:
131
+ `loki-ts/src/e10ext/budget_cap.ts`. The start line shows the cap in force,
132
+ for example `cap $100.00 (default)` or `no dollar cap (subscription)`. Once
133
+ priced cost reaches the cap the running stage is stopped, no later stage
134
+ starts, and the run ends BUDGET_STOP with exit code 3. Sessions with no
135
+ provider price never count toward the cap. On the previous loop the same cap
136
+ is `LOKI_BUDGET_LIMIT` (default 100.00 USD; set it to an empty string for
137
+ unlimited), and a breach pauses the run instead of killing it.
85
138
 
86
139
  `--no-pr`, `--deep` and `--provider` are parsed by the supervisor
87
140
  (`loki-ts/src/engine10/supervisor.ts`) and take effect on a real run.
@@ -99,9 +152,117 @@ verify, seal) and then, in the supervisor, the pr stage, ending in the
99
152
  Slack is not part of the v10 engine surface (no command, no notification
100
153
  hook) and is in progress, tracked with the other wave 3 items.
101
154
 
155
+ ## Small changes: loki edit
156
+
157
+ `loki edit` is the lightest path: one Claude pass on the current repo with no
158
+ PRD, plan, council, PR, receipt or branch switch. It prints the diff stat, the
159
+ diff, and one line with cost and elapsed time.
160
+
161
+ ```
162
+ loki edit "rename fooBar to foo_bar"
163
+ loki edit src/foo.ts "rename X to Y"
164
+ loki edit --verify --commit src/a.ts "add null checks"
165
+ loki edit --dry-run "describe the change"
166
+ ```
167
+
168
+ - `--verify` runs the fast verifier on the result.
169
+ - `--receipt` writes an unsigned receipt to `.loki/edit-receipts/`.
170
+ - `--commit` commits only the files the pass touched, by name; skipped when
171
+ verify failed.
172
+ - `--dry-run` plans only (plan permission mode); nothing changes.
173
+ - `LOKI_EDIT_MODEL` overrides the model. Claude provider only for now.
174
+
175
+ Use `loki edit` for a single pass, `loki quick "<task>"` for a small task with
176
+ a verify loop, and `loki start` for anything that needs a plan, verification
177
+ and a sealed receipt. Exit codes: 0 done, 1 provider or verify failure, 2
178
+ usage or setup error ([exit-codes.md](../exit-codes.md)).
179
+
180
+ ## Custom agents
181
+
182
+ Define child agents as markdown with YAML frontmatter in `.loki/agents/<name>.md`
183
+ (project) or `~/.config/loki/agents/<name>.md` (user). A project agent wins
184
+ over a user agent of the same name. The body is the system prompt.
185
+
186
+ Frontmatter keys: `name` (must equal the file name without `.md`),
187
+ `description` (required), `model`, `provider` (`claude` by default; `codex`,
188
+ `cline`, `aider` or `opencode`), `tools` (allow list), `deny` (deny list) and
189
+ `permission` (`plan` default, `edit` or `full`).
190
+
191
+ ```
192
+ loki agents list
193
+ loki agents new reviewer # reviewer, planner and tester copy shipped examples
194
+ loki agents show reviewer
195
+ loki agents export --claude # writes .claude/agents/ (add --user for ~/.claude/agents)
196
+ ```
197
+
198
+ `permission: plan` exports as Claude Code `disallowedTools` Edit, Write,
199
+ NotebookEdit and Bash. Council reviewers pick up a matching agent: one named
200
+ `reviewer`, `tester` or `security` replaces the council-v2 reviewer prompt and
201
+ model for the matching roles (`code_quality_reviewer` and
202
+ `requirements_verifier` use `reviewer`; `test_auditor` uses `tester`;
203
+ `devils_advocate` uses `security`, then `reviewer`). With no agents configured
204
+ nothing changes. `loki agent` (singular) is the unchanged built-in agent-type
205
+ command.
206
+
207
+ ## Chat (interactive alternative)
208
+
209
+ `loki start` stays the primary path. `loki chat` is an interactive session for
210
+ exploring and small steps, and it hands off to and from `loki start`.
211
+
212
+ - Start with `loki chat` (needs a TTY; for one-shot tasks use `loki quick`).
213
+ Bare `loki` does not open chat.
214
+ - The session starts in Plan mode (read-only); `/plan` and `/build` switch
215
+ modes and the prompt shows `loki[plan]>` or `loki[build]>`. Plan mode is
216
+ enforced for Claude (`--permission-mode plan`); other providers get a
217
+ prompt-level read-only instruction.
218
+ - Slash commands: `/plan`, `/build`, `/run <prd|brief>`, `/quick <task>`,
219
+ `/edit <change>`, `/verify`, `/receipt`, `/cost`, `/diff`, `/undo`,
220
+ `/model <id>`, `/provider <name>`, `/help`, `/exit`.
221
+ - `/run` starts a normal `loki start` run with the chat's model and provider.
222
+ - `loki chat --attach` joins a running or the last `loki start` session, with
223
+ `/status`, `/steer`, `/diff`, `/verify`, `/receipt` and `/stop`.
224
+ - `loki chat --tui` launches the full Claude Code TUI with the Loki system
225
+ prompt appended.
226
+
227
+ ## Setup, doctor and config
228
+
229
+ ```
230
+ loki setup # wizard: tools, Claude login, provider, model route, spend cap
231
+ loki setup --yes # non-interactive defaults
232
+ loki setup --check # report only
233
+ loki doctor --fix # create state dirs and a default config; prints exact commands for the rest
234
+ loki config list # also: get <key>, set <key> <value>, path
235
+ ```
236
+
237
+ `loki setup` flags: `--provider claude|codex|cline|aider|opencode`,
238
+ `--model`, `--budget USD` and `--global`. `loki doctor --fix` never installs
239
+ system packages and never runs sudo. Prerequisites are in
240
+ [INSTALLATION.md](../INSTALLATION.md).
241
+
242
+ ## Exit codes
243
+
244
+ One contract, enforced from 11.4.0 (details in [exit-codes.md](../exit-codes.md)).
245
+ `loki verify` exits 0 VERIFIED, 1 CONCERNS, 2 BLOCKED or not a git directory,
246
+ 3 verifier error or empty diff, 64 usage error. Usage errors from `loki quick`
247
+ and `loki start` are also 64. CI gates should use `loki verify || fail`, not
248
+ `[ $rc -eq 1 ]`, and treat any code of 2 or higher as worse than CONCERNS. This
249
+ is a breaking change for scripts that tested rc==1 on an empty diff or a
250
+ non-git directory.
251
+
102
252
  ## The summary
103
253
 
104
- A finished run prints the start line, then one label per line (Outcome,
254
+ Every run on both engines also ends with one unified block: `Result:`
255
+ (verified, done-unverified, failed or stopped), `Files:` (N changed, +ins
256
+ -del), `Cost:` (`$X.XX`, marked `(estimated)` when not provider-reported,
257
+ `not measured` when unknown), `Elapsed:`, `Receipt:` (path, when one exists)
258
+ and one `next:` line naming the suggested command (`loki diff`, `loki verify`,
259
+ `loki undo`, `loki status`, `loki doctor`, or `loki chat --attach`). Pass
260
+ `--quiet` to print only this block and `--json` to add a `summary` object to
261
+ the JSON output. `NO_COLOR=1` disables color, which is also off when stdout is
262
+ not a TTY. On the previous loop, `LOKI_SUMMARY_JSON=1` prints the summary as
263
+ one JSON line, and its cost is always an estimate from the context tracker.
264
+
265
+ A finished engine10 run prints the start line, then one label per line (Outcome,
105
266
  PR, Receipt, NOT PROVEN, Cost, Time; a Reason line is added for any
106
267
  outcome other than VERIFIED or ALREADY_SATISFIED). The quiet default stays
107
268
  within 8 lines. The block below is the older 5-line form; the labels are the
@@ -221,18 +382,82 @@ receipt with no signing key configured (or a key that failed to load) reads
221
382
 
222
383
  ## Provider table
223
384
 
224
- | Provider | Cost measured | Kill blocking enforced |
225
- |----------|----------------|--------------------------|
226
- | claude | yes | yes |
227
- | codex | no | no |
228
- | cline | no | no |
229
- | aider | no | no |
230
- | opencode | not supported | n/a |
385
+ | Provider | Cost measured | Spend cap enforced | Guardrail scan | Kill blocking enforced |
386
+ |----------|---------------|--------------------|----------------|------------------------|
387
+ | claude | yes (provider-reported) | yes | native | yes |
388
+ | codex | yes (parsed or estimated) | yes | yes | no |
389
+ | cline | yes (parsed or estimated) | yes | yes | no |
390
+ | aider | yes (reported or estimated) | yes | yes | no |
391
+ | opencode | no | no (cost not measured); wall clock limit still applies | yes | no |
392
+
393
+ Claude Code is the default and the only Tier-1 provider; the others are
394
+ optional. Select one with `--provider <name>` or `LOKI_PROVIDER`.
395
+
396
+ ### Cost and the spend cap on non-Claude providers
397
+
398
+ For codex, cline and aider, engine10 reads token usage from the CLI output
399
+ (aider's `Cost: $X session` line is used as-is). If the CLI prints no usage,
400
+ cost is estimated from prompt and response sizes (about 4 characters per
401
+ token) with the built-in price table (`loki-ts/src/providers/price_table.ts`).
402
+ A model not in the table prices at a mid-range default of $2 per 1M input
403
+ tokens and $10 per 1M output tokens. Estimated figures carry `estimated: true`
404
+ and `cost_basis` (`provider-tokens` or `size-estimate`) on the `cost` event in
405
+ `events.jsonl`, and the efficiency record has `cost_source: "estimated"`.
406
+ Estimates are approximate. The cap in `--max-cost` applies unchanged. A run
407
+ with no prompt and no output stays `not measured`, never `$0.00`.
408
+
409
+ ### Guardrails on non-Claude providers
410
+
411
+ With codex, cline, aider or opencode, engine10 enforces the wall-clock limit
412
+ and `BUDGET_LIMIT` (for example `BUDGET_LIMIT=5 loki start prd.md`) by killing
413
+ the process group. After each iteration it scans the diff and reverts and
414
+ fails the iteration on mass deletion of tracked files, `.git/config` changes,
415
+ new git hooks, and symlinks or paths outside the project (a `guard.violation`
416
+ event). Native flags are used where the CLI has them: codex runs with
417
+ `--sandbox workspace-write`, aider with `--no-auto-commits`. Cline and
418
+ opencode have no sandbox flag. The scan is post-hoc rather than inline, so
419
+ receipts still list `kill blocking not enforced` for these providers.
420
+
421
+ For opencode, a run's Cost line reads `not measured` and the NOT PROVEN line
422
+ adds the literal entry `kill blocking not enforced`
423
+ (`loki-ts/src/engine10/stages/seal.ts`). opencode is a supported
424
+ engine10 provider (`loki-ts/src/runner/provider_opencode.ts`): install it with
425
+ `npm install -g opencode-ai` and select it with `--provider opencode`. It runs
426
+ `opencode run --auto` non-interactively, takes a `provider/model` id from
427
+ `LOKI_OPENCODE_MODEL` (for example `openrouter/deepseek/deepseek-v3.2`; unset
428
+ uses opencode's own default), passes extra flags from `LOKI_OPENCODE_FLAGS`,
429
+ and honors `LOKI_OPENCODE_CLI` for the binary path. `LOKI_HOST_GUARD=1` is
430
+ incompatible with non-Claude providers.
431
+
432
+ ### Model routes and local models
433
+
434
+ To run OpenRouter or a local model through the Claude harness, so every
435
+ Tier-1 control (cost, kill blocking, receipts) still applies, set
436
+ `LOKI_MODEL_ROUTE=<kind>/<id>` before `loki start`. Selection is by
437
+ environment variable; `loki start` has no `--model` flag.
438
+
439
+ ```
440
+ LOKI_MODEL_ROUTE=ollama/qwen3-coder loki start prd.md
441
+ LOKI_MODEL_ROUTE=openrouter/deepseek/deepseek-v3.2 loki start "fix the login bug"
442
+ ```
443
+
444
+ | Kind | Base URL | Token |
445
+ |------|----------|-------|
446
+ | `openrouter/<id>` | https://openrouter.ai/api | `OPENROUTER_API_KEY` |
447
+ | `ollama/<id>` | http://localhost:11434 | none |
448
+ | `lmstudio/<id>` | http://localhost:1234 | none |
449
+ | `llamacpp/<id>` | http://localhost:8080 | none |
450
+ | `vllm/<id>` | http://localhost:8000 | none |
451
+ | `custom/<id>` | `LOKI_MODEL_BASE_URL` (required) | `LOKI_MODEL_API_KEY` (optional) |
452
+
453
+ A route spec in `LOKI_MODEL_OVERRIDE` works too. The route environment
454
+ applies to the Claude child process only; the token is never exported into
455
+ your shell, put on a command line, or logged. Plain Claude ids (`opus`,
456
+ `sonnet`, `claude-*`) behave as before.
231
457
 
232
- For codex, cline and aider, a run's Cost line reads `not measured` and the
233
- NOT PROVEN line adds the literal entry `kill blocking not enforced`
234
- (`loki-ts/src/engine10/stages/seal.ts`). opencode is not one of engine10's
235
- provider names (`claude`, `codex`, `cline`, `aider`); it is not supported.
458
+ `loki models` lists the routes. `loki models --local` probes Ollama, LM
459
+ Studio, llama.cpp and vLLM on their default ports (1s timeout each) and prints
460
+ ready-to-paste values. Both accept `--json`.
236
461
 
237
462
  ## Model routing
238
463
 
@@ -321,10 +546,11 @@ runs on the B9 corpus, and it can emit shape defaults from those runs
321
546
 
322
547
  ## After the flip
323
548
 
324
- D48 made v10 the default for `loki "<task>"`, `loki owner/repo#N` and
325
- `loki quick "<task>"`. 11.0.0 removed the engine switch: `loki legacy` exits
326
- 2 with a removal message and LOKI_ENGINE is ignored. PRD-file starts
327
- (`loki start ./prd.md`), the opencode provider, and the no-bun
328
- fallback still run on the previous bash loop until FC38-SWEEP ports them; they are tracked in
329
- docs/v10/LEGACY-REMOVAL.md. The marked line near the top of this file and of
330
- README.md's Loki 10 section records the current state.
549
+ D48 made v10 the default for `loki start`, `loki "<task>"`,
550
+ `loki owner/repo#N` and `loki quick "<task>"`. 11.0.0 removed `loki legacy`
551
+ (it exits 2 with a removal message). From 11.4.0, `--engine legacy|engine10`
552
+ and `LOKI_ENGINE` select the engine explicitly, and PRD-file starts, flag-first
553
+ calls, one-word briefs and the opencode provider run on Loki 10 (see Routing).
554
+ The previous bash loop runs only in the cases listed under Routing. The marked
555
+ line near the top of this file and of README.md's Loki 10 section records the
556
+ current state.
@@ -0,0 +1,84 @@
1
+ # v11.4.0 plan: beat opencode by 1-2 points in every category
2
+
3
+ Founder directive (2026-10-15): close every gap an outside assessment found
4
+ against opencode. Keep Loki autonomous. Keep the harness and internals
5
+ (RARV-C, receipts, Seal, council) as they are, and keep Claude Code as the
6
+ primary provider. Ship all of it as one MINOR release, v11.4.0, built in
7
+ parallel. Under the founder's standing waiver nothing is tested.
8
+
9
+ Founder clarification (2026-10-15): `loki start` is always the primary
10
+ path. `loki chat` is an alternative surface. Every improvement in this
11
+ release (model routes, local models, providers, agents, routing, exit codes,
12
+ run summary, onboarding) must work through `loki start` first. Chat must hand
13
+ off to and from `loki start` without friction: `/run` in chat starts the same
14
+ run with the same model, provider and agents, and chat can attach to a
15
+ running or finished `loki start` session (status, steer, diff, verify).
16
+
17
+ ## Scorecard target
18
+
19
+ | Category | Was (Loki / opencode) | Target | Slices |
20
+ |---|---|---|---|
21
+ | Everyday user experience | 6 / 8 | 10 | OC-CHAT, OC-OUTPUT |
22
+ | Installation and onboarding | 6 / 8 | 10 | OC-ONBOARD, OC-DOCS |
23
+ | Learning curve | 5 / 8 | 10 | OC-ROUTE, OC-HELP |
24
+ | Interactive coding and exploration | 6 / 9 | 10 | OC-CHAT |
25
+ | Small, targeted changes | 7 / 8 | 10 | OC-EDIT |
26
+ | Model/provider flexibility | 5 / 9 | 10 | OC-MODELS, OC-OPENCODE-E10 |
27
+ | Local-model setup | 5 / 8 | 10 | OC-MODELS |
28
+ | Multi-agent workflow design | 7 / 8 | 10 | OC-AGENTS |
29
+ | Documentation consistency | 4 / 7 | 10 | OC-DOCS |
30
+ | Predictability across commands/upgrades | 5 / 6 | 10 | OC-ROUTE, OC-EXIT, OC-PARITY-COST, OC-PARITY-ENFORCE |
31
+
32
+ ## Todo (one slice each, parallel, own branch `slice-OC-<KEY>`)
33
+
34
+ - [x] OC-CHAT: `loki chat` opens an interactive session (the first cut
35
+ also opened it from bare `loki` on a TTY; that was reverted, and bare `loki`
36
+ stays unchanged). Plan mode is read-only and Build mode edits; `/plan`
37
+ and `/build` switch between them. Slash commands: /run, /quick, /edit,
38
+ /verify, /receipt, /model, /provider, /cost, /diff, /undo, /help, /exit.
39
+ `loki chat --tui` launches Claude Code's own TUI.
40
+ - [x] OC-ROUTE: one predictable execution path. Flag-first calls, PRD files
41
+ and one-word starts reach the same engine as the positional form. The
42
+ legacy engine runs only on an explicit `--engine legacy` or
43
+ `LOKI_ENGINE=legacy`. `loki route <args>` prints the engine and why.
44
+ - [x] OC-EXIT: close the three `loki verify` exit-code gaps and use one
45
+ exit-code contract for verify, run, quick and edit. Update
46
+ docs/exit-codes.md and remove the KNOWN-ISSUES entry.
47
+ - [x] OC-MODELS: model routes over the Claude harness, so every Tier-1
48
+ control still works. Routes: `--model openrouter/<id>`, `ollama/<id>`,
49
+ `lmstudio/<id>`, `llamacpp/<id>`, `vllm/<id>`, and any
50
+ Anthropic-compatible base URL. `loki models` lists routes;
51
+ `loki models --local` discovers local runtimes.
52
+ - [x] OC-PARITY-COST: engine10 measures cost for Codex, Cline and Aider.
53
+ - [x] OC-PARITY-ENFORCE: engine10 enforces the budget kill, a post-iteration
54
+ guard scan and native sandbox flags for Codex, Cline, Aider and opencode.
55
+ Receipts still list `kill blocking not enforced` because the scan is post-hoc.
56
+ - [x] OC-OPENCODE-E10: opencode becomes a supported engine10 provider.
57
+ - [x] OC-AGENTS: configurable child agents in `.loki/agents/*.md` (model,
58
+ provider, tools, permissions, prompt), managed with
59
+ `loki agents list|new|show`. Councils and reviewers use them when present,
60
+ and they export to Claude Code subagents.
61
+ - [x] OC-EDIT: `loki edit "<change>"` makes a fast single-pass edit with no
62
+ PR, plan or council. It shows the diff; `--verify` and `--receipt` are
63
+ opt-in.
64
+ - [x] OC-ONBOARD: `loki setup` wizard and `loki doctor --fix`. Claude Code
65
+ first, with required and optional prerequisites stated plainly.
66
+ - [x] OC-HELP: `loki help` shows the core verbs, `loki help all` shows the
67
+ full surface, and `loki help <topic>` covers topics. Mistyped commands get
68
+ "did you mean" suggestions, and `--json` works the same everywhere.
69
+ - [x] OC-OUTPUT: one run summary across engines (result, cost, time,
70
+ receipt, next step), with `--quiet` and NO_COLOR honored.
71
+ - [ ] OC-START-INTEGRATION (after merge): wire every feature above into
72
+ `loki start` (`--model <route>`, `--provider`, configured agents, unified
73
+ summary, exit codes, explain-route). Bare `loki` keeps its current
74
+ behavior and does not open chat. Seamless chat handoff: `/run` reuses the
75
+ chat's model, provider and agents; `loki chat --attach` joins the current
76
+ or last `loki start` session; the run summary's next step names
77
+ `loki chat --attach`.
78
+ - [x] OC-DOCS (after merge; README, INSTALLATION, GUIDE, QUICKSTART and
79
+ COMPARE-OPENCODE written): README, INSTALLATION, GUIDE and a new QUICKSTART
80
+ agree with the code on prerequisites, the spend cap, routing and providers.
81
+ Add docs/COMPARE-OPENCODE.md.
82
+ - [ ] Release: merge onto train-v11.4.0, rebuild loki-ts dist, write a full
83
+ CHANGELOG v11.4.0 section, run `scripts/release.sh minor --bump-only`,
84
+ push main, and confirm the release run.
@@ -2,6 +2,7 @@
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
4
  "_updated": "2026-10-08",
5
+ "default_max_cost_usd": 100,
5
6
  "_source": "https://platform.claude.com/docs/en/about-claude/pricing (docs.anthropic.com/en/docs/about-claude/pricing 301-redirects there), read 2026-10-08. Per MTok. fable=Claude Fable 5.1 $10/$50, cache read $0.25 (0.025x), 5m write $12.50, 1h write $20. opus=Claude Opus 5.5 $4/$20, cache read $0.20 (0.05x), 5m write $5, 1h write $8. sonnet=Claude Sonnet 5.5 $2/$10, cache read $0.10 (0.05x), 5m write $2.50, 1h write $4. haiku alias row prices as its catalog target claude-haiku-5-5 (providers/model_catalog.json cli_aliases), so it equals that row including over_100k; Haiku 4.5 ($1/$5) is no longer an alias target. claude-haiku-5-5 (exact id, same as the haiku alias): $0.10/$0.50, read $0.01, 5m $0.125, 1h $0.20 up to 100,000 prompt tokens; over_100k $0.50/$2.50, read $0.05, 5m $0.625, 1h $1. Fields: cache_write is the 5m write rate (legacy readers); cache_write_5m and cache_write_1h are the explicit tiers. Multipliers: 5m write 1.25x, 1h write 2x, read 0.1x (0.05x on Opus 5.5 and Sonnet 5.5, 0.025x on Fable 5.1). OpenAI rows (gpt-5.3-codex, gpt-5.6-sol/terra/luna): https://developers.openai.com/api/docs/pricing, read 2026-10-08, Standard tier, short context (up to 272K); cached input is the cache_read field; OpenAI bills no cache write, cache_write is a 1.25x placeholder.",
6
7
  "pricing": {
7
8
  "fable": {