loki-mode 11.3.0 → 11.3.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 (215) hide show
  1. package/README.md +68 -650
  2. package/SKILL.md +4 -4
  3. package/VERSION +1 -1
  4. package/autonomy/completion-council.sh +2 -2
  5. package/autonomy/context-tracker.py +4 -4
  6. package/autonomy/council-v2.sh +1 -1
  7. package/autonomy/grill.sh +1 -1
  8. package/autonomy/lib/done-recognition.sh +1 -1
  9. package/autonomy/lib/prd-enrich.sh +1 -1
  10. package/autonomy/lib/voter-agents.sh +1 -1
  11. package/autonomy/loki +99 -75
  12. package/autonomy/run.sh +30 -18
  13. package/autonomy/sandbox.sh +1 -1
  14. package/autonomy/tui.sh +6 -5
  15. package/autonomy/verify.sh +1 -1
  16. package/bin/loki +166 -59
  17. package/completions/_loki +2 -0
  18. package/completions/loki.bash +2 -2
  19. package/dashboard/__init__.py +1 -1
  20. package/dashboard/server.py +25 -31
  21. package/docs/ARCHITECTURE.md +337 -0
  22. package/docs/BRANDING.md +124 -0
  23. package/docs/CLI-REFERENCE.md +7 -1
  24. package/docs/COMPONENTS.md +447 -0
  25. package/docs/DEPLOYMENT.md +9 -9
  26. package/docs/DOCKER.md +469 -0
  27. package/docs/INSTALLATION.md +67 -1045
  28. package/docs/KNOWN-ISSUES.md +11 -35
  29. package/docs/TESTING.md +161 -0
  30. package/docs/air-gapped.md +1 -2
  31. package/docs/alternative-installations.md +14 -24
  32. package/docs/architecture/DECISIONS.md +333 -0
  33. package/docs/audit-logging.md +7 -7
  34. package/docs/authentication.md +3 -3
  35. package/docs/authorization.md +1 -1
  36. package/docs/certification/04-production-deployment/lab.md +6 -6
  37. package/docs/certification/04-production-deployment/lesson.md +4 -4
  38. package/docs/certification/README.md +1 -1
  39. package/docs/control-plane-container.md +2 -2
  40. package/docs/dev/real-run.md +34 -0
  41. package/docs/dev/release-checklist.md +2 -2
  42. package/docs/exit-codes.md +3 -3
  43. package/docs/git-workflow.md +3 -3
  44. package/docs/metrics.md +37 -55
  45. package/docs/network-security.md +1 -1
  46. package/docs/siem-integration.md +5 -5
  47. package/docs/v10/CLI-MODERN.md +4 -3
  48. package/docs/v10/DECISIONS.md +44 -0
  49. package/docs/v10/DEPS.md +22 -22
  50. package/docs/v10/ENGINE.md +1 -1
  51. package/docs/v10/FAILURE-CLASSES.md +118 -1
  52. package/docs/v10/FOUNDER-QUEUE.md +1 -0
  53. package/docs/v10/GUARDS.md +13 -0
  54. package/docs/v10/LEGACY-REMOVAL.md +4 -6
  55. package/docs/v10/METRICS.md +2 -2
  56. package/docs/v10/MODERNIZE.md +1 -1
  57. package/docs/v10/OPERATING-MODEL.md +2 -1
  58. package/docs/v10/PROGRESS.md +29 -0
  59. package/docs/v11/COST-HALF.md +352 -0
  60. package/docs/v11/MARKET-SLICES.md +315 -0
  61. package/docs/v11/REGISTRIES.md +730 -0
  62. package/loki-ts/data/model-pricing.json +52 -24
  63. package/loki-ts/dist/loki.js +1036 -957
  64. package/mcp/__init__.py +1 -1
  65. package/package.json +1 -1
  66. package/packages/control-plane/dist/server.js +2467 -736
  67. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  68. package/src/protocols/mcp-client.js +6 -2
  69. package/src/protocols/mcp-server.js +13 -3
  70. package/tools/audit-docs.py +1 -1
  71. package/web-app/dist/assets/{AdminPage-D_e45uTw.js → AdminPage-CMkHNJbF.js} +1 -1
  72. package/web-app/dist/assets/{Avatar-T3nIpoaf.js → Avatar-BJyjV7Zi.js} +1 -1
  73. package/web-app/dist/assets/{Badge-BKqb59pP.js → Badge-D572l0uq.js} +1 -1
  74. package/web-app/dist/assets/{Button-DjVlkh8_.js → Button-T4BnOZgl.js} +1 -1
  75. package/web-app/dist/assets/{CockpitPage-DXJgLGmh.js → CockpitPage-Cj_GFsNn.js} +1 -1
  76. package/web-app/dist/assets/{ComparePage-BRP_eVc_.js → ComparePage-A8m4ZXak.js} +1 -1
  77. package/web-app/dist/assets/{ErrorBoundary-CLjpGLjC.js → ErrorBoundary-hugCg5yg.js} +1 -1
  78. package/web-app/dist/assets/{EvidenceReceiptPanel-DX-vb4Xy.js → EvidenceReceiptPanel-CuJKDC2G.js} +1 -1
  79. package/web-app/dist/assets/{GitHubIssuesPanel-214HVHtX.js → GitHubIssuesPanel-BYGKjarC.js} +1 -1
  80. package/web-app/dist/assets/{GitHubPRsPanel-BEiZKc4t.js → GitHubPRsPanel-c7sFIJlf.js} +1 -1
  81. package/web-app/dist/assets/{HomePage-VvMHS5ga.js → HomePage-A1MIkG2P.js} +2 -2
  82. package/web-app/dist/assets/{LoginPage-5WD-v7n3.js → LoginPage-8KQMRhtR.js} +1 -1
  83. package/web-app/dist/assets/{MagicPage-DUQT_Jye.js → MagicPage-C05QW2Lx.js} +1 -1
  84. package/web-app/dist/assets/{MetricsPage-lga-z79v.js → MetricsPage-Oukv5hme.js} +1 -1
  85. package/web-app/dist/assets/{NotFoundPage-CGhBX3G1.js → NotFoundPage-DKIwsawz.js} +1 -1
  86. package/web-app/dist/assets/{ProjectPage-CdzF2GzZ.js → ProjectPage-DwFRPLCG.js} +3 -3
  87. package/web-app/dist/assets/{ProjectsPage-DRG64N8s.js → ProjectsPage-CgY4YYDX.js} +1 -1
  88. package/web-app/dist/assets/{SettingsPage-5fzW9Frb.js → SettingsPage-BpfcSjUA.js} +1 -1
  89. package/web-app/dist/assets/{ShowcasePage-DrTdxO4y.js → ShowcasePage-BqBakC4K.js} +1 -1
  90. package/web-app/dist/assets/{SystemSettingsPage-C9Mqs6Rd.js → SystemSettingsPage-CZLu5VB0.js} +1 -1
  91. package/web-app/dist/assets/{TeamsPage-CUGPdSWo.js → TeamsPage-D55S1jKz.js} +1 -1
  92. package/web-app/dist/assets/{TemplatesPage-CNraDY0F.js → TemplatesPage-D3SydvxN.js} +1 -1
  93. package/web-app/dist/assets/{TerminalOutput-BIu_6Pea.js → TerminalOutput-hNg8G1-e.js} +1 -1
  94. package/web-app/dist/assets/{activity-Bk-kgqaf.js → activity-D2C0VagO.js} +1 -1
  95. package/web-app/dist/assets/{bell-BXmUdmo8.js → bell-CMvYi36w.js} +1 -1
  96. package/web-app/dist/assets/{bot-CiuzXxUR.js → bot-BvtQ6lmo.js} +1 -1
  97. package/web-app/dist/assets/{check-BEzjXppd.js → check-B13xkXed.js} +1 -1
  98. package/web-app/dist/assets/{chevron-left-AYWCXHf8.js → chevron-left-emu6r49E.js} +1 -1
  99. package/web-app/dist/assets/{circle-alert-BNg2uSRq.js → circle-alert-CExlwjuy.js} +1 -1
  100. package/web-app/dist/assets/{clock-DTj0kkGT.js → clock-D7Uas3oL.js} +1 -1
  101. package/web-app/dist/assets/{cloud-x4nTDBLT.js → cloud-CkB4S86C.js} +1 -1
  102. package/web-app/dist/assets/{code-xml-BVh_MLrk.js → code-xml-SL9IIWIn.js} +1 -1
  103. package/web-app/dist/assets/{database-DdfBaowG.js → database-BQFkd7t1.js} +1 -1
  104. package/web-app/dist/assets/{dollar-sign-XuYFmAOY.js → dollar-sign-qHmnNYsU.js} +1 -1
  105. package/web-app/dist/assets/{file-code-corner-D4cRnmeL.js → file-code-corner-C2YUDP0K.js} +1 -1
  106. package/web-app/dist/assets/{file-plus-CyoVlHc_.js → file-plus-C_ooIkDe.js} +1 -1
  107. package/web-app/dist/assets/{globe-Y6IK2RPW.js → globe-CQ-GL485.js} +1 -1
  108. package/web-app/dist/assets/{hammer-BKzr9VZI.js → hammer-U05L_D7V.js} +1 -1
  109. package/web-app/dist/assets/{index-B20cSx5G.js → index-CooHd7I-.js} +3 -3
  110. package/web-app/dist/assets/{layers-DebNOhGS.js → layers-Buo17rjW.js} +1 -1
  111. package/web-app/dist/assets/{loader-circle-DyGbrEgd.js → loader-circle-15vK3oV1.js} +1 -1
  112. package/web-app/dist/assets/{lock-BKPpyt20.js → lock-BeXLebuJ.js} +1 -1
  113. package/web-app/dist/assets/{package-egF5Wi4y.js → package-MVh_6-6R.js} +1 -1
  114. package/web-app/dist/assets/{plus-OiEgKIc-.js → plus-Dh_nd9vS.js} +1 -1
  115. package/web-app/dist/assets/{refresh-cw-CzKvrONq.js → refresh-cw-C9cBJEAT.js} +1 -1
  116. package/web-app/dist/assets/{rotate-ccw-Bu2mII0p.js → rotate-ccw-D3PAtzST.js} +1 -1
  117. package/web-app/dist/assets/{scroll-text-CSkiyax8.js → scroll-text-DZCoXQjo.js} +1 -1
  118. package/web-app/dist/assets/{server-DlPthJFw.js → server-OCOLI5J_.js} +1 -1
  119. package/web-app/dist/assets/{shield-alert-CbpHWQQX.js → shield-alert-oVhmf1_h.js} +1 -1
  120. package/web-app/dist/assets/{thumbs-up-DgGpZe-Q.js → thumbs-up-B-kbX4vN.js} +1 -1
  121. package/web-app/dist/assets/{trash-2-BV3GlCB-.js → trash-2-EL6moveW.js} +1 -1
  122. package/web-app/dist/assets/{trending-down-Y4TJtXhD.js → trending-down-Cl3kjpsx.js} +1 -1
  123. package/web-app/dist/assets/{trending-up-DsDNoHZY.js → trending-up-DST7I6M2.js} +1 -1
  124. package/web-app/dist/assets/{upload-gkThrc_I.js → upload-CUOT780G.js} +1 -1
  125. package/web-app/dist/assets/{usePolling-jpNSeNAe.js → usePolling-Djmt90eb.js} +1 -1
  126. package/web-app/dist/assets/{user-3Zez1WOK.js → user-BRBohA6J.js} +1 -1
  127. package/web-app/dist/index.html +1 -1
  128. package/docs/ARCHITECTURE-OVERVIEW.md +0 -209
  129. package/docs/AUTONOMI-ECOSYSTEM.md +0 -107
  130. package/docs/COCKPIT-SPEC.md +0 -72
  131. package/docs/COCKPIT-UX-MANDATE.md +0 -53
  132. package/docs/COMPETITIVE-ANALYSIS.md +0 -303
  133. package/docs/COMPETITIVE-NEXT-10.md +0 -316
  134. package/docs/COMPETITIVE-RALPH-ZEROSHOT-2026-07-08.md +0 -81
  135. package/docs/DASHBOARD-9.12-EVIDENCE.md +0 -97
  136. package/docs/DASHBOARD-ARCHITECTURE.md +0 -425
  137. package/docs/DASHBOARD_V2_CHECKLIST.md +0 -243
  138. package/docs/DEMOS.md +0 -63
  139. package/docs/ENTERPRISE-IDENTITY-ROADMAP.md +0 -206
  140. package/docs/EVIDENCE-RECEIPT-BUILD-APPLICABILITY.md +0 -79
  141. package/docs/FEAT-PRDREUSE-DOCKER-PLAN.md +0 -144
  142. package/docs/GATE-FAILURE-TRIAGE.md +0 -254
  143. package/docs/HANDOFF-2026-08-03.md +0 -439
  144. package/docs/LOOP-CANDIDATE-PROPOSAL-v1.md +0 -167
  145. package/docs/LOOP-HARNESS-AUDIT.md +0 -684
  146. package/docs/MERGE-DEDUP-MAP.md +0 -420
  147. package/docs/MERGE-ROUTE-MAP.md +0 -139
  148. package/docs/MODEL-REGISTRY-PLAN.md +0 -155
  149. package/docs/OUTCOME-FRONTIER.md +0 -536
  150. package/docs/P2-SPEC-ROBUSTNESS-PLAN.md +0 -192
  151. package/docs/PLANS-INDEX.md +0 -32
  152. package/docs/PRD-REUSE-DONE-RECOGNITION-PLAN.md +0 -536
  153. package/docs/PROMPT-ABLATION-RESULT.md +0 -97
  154. package/docs/R4-TRUST-TRAJECTORY-DESIGN.md +0 -127
  155. package/docs/R5-AUTO-WIKI-DESIGN.md +0 -137
  156. package/docs/R6-ROLLBACK-CHECKPOINT-PLAN.md +0 -107
  157. package/docs/R7-ZERO-CONFIG-FIRST-RUN-PLAN.md +0 -137
  158. package/docs/R8-SHAREABLE-TEAM-ASSETS-PLAN.md +0 -129
  159. package/docs/R9-OPEN-CORE-HOOKS-PLAN.md +0 -113
  160. package/docs/RARV-C-100X-PLAN.md +0 -286
  161. package/docs/RARV-C-LOOP-EFFICIENCY-PLAN.md +0 -470
  162. package/docs/SHAREABLE-PROOF-PLAN.md +0 -194
  163. package/docs/SONNET5-DEFAULT-PLAN.md +0 -157
  164. package/docs/SPEED-AND-FIRST-PASS-PLAN.md +0 -281
  165. package/docs/STALE-STATE-AUDIT.md +0 -174
  166. package/docs/SYNERGY-TASKS.md +0 -143
  167. package/docs/TASKLIST-ACCURACY-PLAN.md +0 -355
  168. package/docs/TOP-100-BACKLOG.md +0 -159
  169. package/docs/V8-ACCEPTANCE-TRIAGE-2026-07-24.md +0 -114
  170. package/docs/V8-COMPLEXITY-AUDIT-2026-07-24.md +0 -45
  171. package/docs/V8-MAJOR-RELEASE-PLAN.md +0 -137
  172. package/docs/V8-OVERNIGHT-PLAN-2026-07-25.md +0 -82
  173. package/docs/V8-SDK-RESEARCH-RAW.md +0 -129
  174. package/docs/WELCOME-OPENER-PLAN.md +0 -106
  175. package/docs/adoption-baseline-2026-07-31.md +0 -84
  176. package/docs/architecture/bmad-integration-epic.md +0 -271
  177. package/docs/architecture/bmad-integration-review.md +0 -86
  178. package/docs/architecture/bmad-integration-validation.md +0 -249
  179. package/docs/architecture/bmad-loki-voice-agent-council-analysis.md +0 -61
  180. package/docs/auto-claude-comparison.md +0 -250
  181. package/docs/bug-fixes/agent-01-cli-fixes.md +0 -101
  182. package/docs/bug-fixes/agent-02-purplelab-fixes.md +0 -88
  183. package/docs/bug-fixes/agent-03-dashboard-fixes.md +0 -119
  184. package/docs/bug-fixes/agent-04-memory-fixes.md +0 -105
  185. package/docs/bug-fixes/agent-05-provider-fixes.md +0 -86
  186. package/docs/bug-fixes/agent-06-integration-fixes.md +0 -101
  187. package/docs/bug-fixes/agent-07-dash-run-fixes.md +0 -101
  188. package/docs/bug-fixes/agent-08-docker-fixes.md +0 -164
  189. package/docs/bug-fixes/agent-09-e2e-build-fixes.md +0 -69
  190. package/docs/bug-fixes/agent-10-e2e-fullstack-fixes.md +0 -102
  191. package/docs/bug-fixes/agent-11-e2e-session-fixes.md +0 -70
  192. package/docs/bug-fixes/agent-12-scenario-fixes.md +0 -120
  193. package/docs/bug-fixes/agent-13-enterprise-fixes.md +0 -143
  194. package/docs/bug-fixes/agent-14-uat-newuser-fixes.md +0 -88
  195. package/docs/bug-fixes/agent-15-uat-poweruser-fixes.md +0 -132
  196. package/docs/bug-fixes/agent-19-code-review.md +0 -316
  197. package/docs/bug-fixes/agent-20-architecture-review.md +0 -331
  198. package/docs/competitive/bolt-new-analysis.md +0 -579
  199. package/docs/competitive/emergence-others-analysis.md +0 -605
  200. package/docs/competitive/replit-lovable-analysis.md +0 -622
  201. package/docs/dashboard-guide.md +0 -487
  202. package/docs/enterprise/migration.md +0 -265
  203. package/docs/history/one-run-audit.md +0 -304
  204. package/docs/plans/FORGE-AUTONOMOUS-QUEUE.md +0 -312
  205. package/docs/plans/ULTRAPLAN-FORGE-BAAS.md +0 -612
  206. package/docs/plans/UT2-6-LSP-DIAGNOSTIC-BROADCAST.md +0 -394
  207. package/docs/prd-purple-lab-ide.md +0 -152
  208. package/docs/prd-purple-lab-platform-v2.md +0 -223
  209. package/docs/prd-purple-lab-platform.md +0 -319
  210. package/docs/retrospectives/v7.5.15-fleet-postmortem.md +0 -325
  211. package/docs/retrospectives/v7.5.15-honesty-audit.md +0 -136
  212. package/docs/retrospectives/v7.5.15-llm-failure-modes.md +0 -49
  213. package/docs/show-hn-post.md +0 -46
  214. package/docs/test-scenarios/enterprise-scenarios.md +0 -732
  215. package/docs/thick2thin.md +0 -173
package/autonomy/run.sh CHANGED
@@ -7578,12 +7578,13 @@ _write_pricing_json() {
7578
7578
  "updated": "${updated}",
7579
7579
  "source": "static",
7580
7580
  "models": {
7581
- "fable": {"input": 10.00, "output": 50.00, "label": "Fable 5 (top, 2x Opus)", "provider": "claude"},
7582
- "claude-fable-5": {"input": 10.00, "output": 50.00, "label": "Fable 5 (top, 2x Opus)", "provider": "claude"},
7583
- "opus": {"input": 5.00, "output": 25.00, "label": "Opus (latest)", "provider": "claude"},
7584
- "sonnet": {"input": 2.00, "output": 10.00, "label": "Sonnet (latest)", "provider": "claude"},
7585
- "haiku": {"input": 1.00, "output": 5.00, "label": "Haiku (latest)", "provider": "claude"},
7586
- "claude-haiku-5-5": {"input": 0.10, "output": 0.50, "over_100k": {"input": 0.50, "output": 2.50}, "label": "Haiku 5.5", "provider": "claude"},
7581
+ "fable": {"input": 10.00, "output": 50.00, "cache_read": 0.25, "cache_write": 12.5, "cache_write_1h": 20, "label": "Fable 5 (top tier)", "provider": "claude"},
7582
+ "claude-fable-5": {"input": 10.00, "output": 50.00, "cache_read": 0.25, "cache_write": 12.5, "cache_write_1h": 20, "label": "Fable 5 (top tier)", "provider": "claude"},
7583
+ "opus": {"input": 4.00, "output": 20.00, "cache_read": 0.2, "cache_write": 5, "cache_write_1h": 8, "label": "Opus (latest)", "provider": "claude"},
7584
+ "sonnet": {"input": 2.00, "output": 10.00, "cache_read": 0.1, "cache_write": 2.5, "cache_write_1h": 4, "label": "Sonnet (latest)", "provider": "claude"},
7585
+ "haiku": {"input": 0.10, "output": 0.50, "cache_read": 0.01, "cache_write": 0.125, "cache_write_1h": 0.2, "over_100k": {"input": 0.50, "output": 2.50}, "label": "Haiku 5.5 (latest)", "provider": "claude"},
7586
+ "claude-haiku-4-5": {"input": 1.00, "output": 5.00, "cache_read": 0.1, "cache_write": 1.25, "cache_write_1h": 2, "label": "Haiku 4.5", "provider": "claude"},
7587
+ "claude-haiku-5-5": {"input": 0.10, "output": 0.50, "cache_read": 0.01, "cache_write": 0.125, "cache_write_1h": 0.2, "over_100k": {"input": 0.50, "output": 2.50}, "label": "Haiku 5.5", "provider": "claude"},
7587
7588
  "gpt-5.3-codex": {"input": 1.75, "output": 14.00, "label": "GPT-5.3 Codex", "provider": "codex"}
7588
7589
  }
7589
7590
  }
@@ -16425,7 +16426,7 @@ _dispatch_reviewer() {
16425
16426
  _crs_out="$(_loki_with_deadline "$_crs_cap" \
16426
16427
  "${_cr_provider_env[@]}" "$_crs_loki" internal sdk-judge \
16427
16428
  --prompt-file "$_crs_pf" --schema-file "$_crs_schema_file" \
16428
- --model "${LOKI_SDK_REVIEW_MODEL:-claude-sonnet-5}" --effort high \
16429
+ --model "${LOKI_SDK_REVIEW_MODEL:-sonnet}" --effort high \
16429
16430
  --timeout-ms "$(( _crs_to_s * 1000 ))")" || _crs_rc=$?
16430
16431
  _crs_invoked=true
16431
16432
  rm -f "$_crs_pf" 2>/dev/null || true
@@ -20248,15 +20249,20 @@ check_budget_limit() {
20248
20249
  import json, glob
20249
20250
  total = 0.0
20250
20251
  pricing = {
20251
- 'fable': {'input': 10.00, 'output': 50.00},
20252
- 'claude-fable-5': {'input': 10.00, 'output': 50.00},
20253
- 'opus': {'input': 5.00, 'output': 25.00},
20254
- 'sonnet': {'input': 2.00, 'output': 10.00},
20255
- 'haiku': {'input': 1.00, 'output': 5.00},
20252
+ 'fable': {'input': 10.00, 'output': 50.00, 'cache_read': 0.25, 'cache_write': 12.5, 'cache_write_1h': 20},
20253
+ 'claude-fable-5': {'input': 10.00, 'output': 50.00, 'cache_read': 0.25, 'cache_write': 12.5, 'cache_write_1h': 20},
20254
+ 'opus': {'input': 4.00, 'output': 20.00, 'cache_read': 0.2, 'cache_write': 5, 'cache_write_1h': 8},
20255
+ 'sonnet': {'input': 2.00, 'output': 10.00, 'cache_read': 0.1, 'cache_write': 2.5, 'cache_write_1h': 4},
20256
+ # haiku = Haiku 5.5 up to 100K prompt tokens (no over-100K tier in this gate)
20257
+ 'haiku': {'input': 0.10, 'output': 0.50, 'cache_read': 0.01, 'cache_write': 0.125, 'cache_write_1h': 0.2},
20258
+ # Exact ids: this dict is keyed by the recorded model string with a sonnet
20259
+ # fallback, so an id missing here is priced at sonnet (20x for Haiku 5.5).
20260
+ 'claude-haiku-4-5': {'input': 1.00, 'output': 5.00, 'cache_read': 0.1, 'cache_write': 1.25, 'cache_write_1h': 2},
20261
+ 'claude-haiku-5-5': {'input': 0.10, 'output': 0.50, 'cache_read': 0.01, 'cache_write': 0.125, 'cache_write_1h': 0.2},
20256
20262
  'gpt-5.3-codex': {'input': 1.75, 'output': 14.00},
20257
- 'gpt-5.6-sol': {'input': 2.50, 'output': 20.00},
20258
- 'gpt-5.6-terra': {'input': 1.50, 'output': 12.00},
20259
- 'gpt-5.6-luna': {'input': 0.50, 'output': 4.00},
20263
+ 'gpt-5.6-sol': {'input': 4.00, 'output': 20.00},
20264
+ 'gpt-5.6-terra': {'input': 2.00, 'output': 12.00},
20265
+ 'gpt-5.6-luna': {'input': 0.20, 'output': 1.20},
20260
20266
  }
20261
20267
  for f in glob.glob('${efficiency_dir}/*.json'):
20262
20268
  try:
@@ -20273,8 +20279,9 @@ for f in glob.glob('${efficiency_dir}/*.json'):
20273
20279
  # DOMINATE real traffic: a measured iteration carried 797,496
20274
20280
  # cache-read tokens against 10,272 of plain input. Pricing them at
20275
20281
  # zero under-counted a real iteration 5.4x, so a breaker set to
20276
- # stop a runaway let it run far past the cap. Published multipliers:
20277
- # cache read 0.1x input, cache write 1.25x input.
20282
+ # stop a runaway let it run far past the cap. Rates come from the
20283
+ # table row (cache read is 0.05x on Opus 5.5 / Sonnet 5.5, 0.025x
20284
+ # on Fable 5.1, 0.1x elsewhere); rows without them use 0.1x / 1.25x.
20278
20285
  #
20279
20286
  # This mirrors the TS route's calculateCostFromRecords
20280
20287
  # (loki-ts/src/runner/budget.ts). Both routes must agree or the
@@ -20282,7 +20289,7 @@ for f in glob.glob('${efficiency_dir}/*.json'):
20282
20289
  cr = d.get('cache_read_tokens', 0) or 0
20283
20290
  cw = d.get('cache_creation_tokens', 0) or 0
20284
20291
  total += (inp / 1_000_000) * p['input'] + (out / 1_000_000) * p['output']
20285
- total += (cr / 1_000_000) * (p['input'] * 0.1) + (cw / 1_000_000) * (p['input'] * 1.25)
20292
+ total += (cr / 1_000_000) * p.get('cache_read', p['input'] * 0.1) + (cw / 1_000_000) * p.get('cache_write', p['input'] * 1.25)
20286
20293
  except: pass
20287
20294
  print(round(total, 4))
20288
20295
  " 2>/dev/null || echo "0")
@@ -28817,6 +28824,11 @@ main() {
28817
28824
  REMAINING_ARGS=()
28818
28825
  while [[ $# -gt 0 ]]; do
28819
28826
  case "$1" in
28827
+ --attempts|--attempts=*)
28828
+ # T5-D2: run.sh is the legacy loop; attempts run only on the engine10 path.
28829
+ echo "run.sh: --attempts is only supported by 'loki start --attempts N --no-pr' (the Loki 10 engine), not the legacy loop." >&2
28830
+ exit 2
28831
+ ;;
28820
28832
  --parallel)
28821
28833
  PARALLEL_MODE=true
28822
28834
  shift
@@ -279,7 +279,7 @@ check_docker() {
279
279
  }
280
280
 
281
281
  build_sandbox_image() {
282
- local dockerfile="$SKILL_DIR/Dockerfile.sandbox"
282
+ local dockerfile="$SKILL_DIR/docker/Dockerfile.sandbox"
283
283
 
284
284
  if [[ ! -f "$dockerfile" ]]; then
285
285
  log_error "Sandbox Dockerfile not found at $dockerfile"
package/autonomy/tui.sh CHANGED
@@ -390,16 +390,17 @@ display_token_cost() {
390
390
  local input_tokens="$2"
391
391
  local output_tokens="$3"
392
392
 
393
- # Pricing per 1M tokens (March 2026 rates)
393
+ # Pricing per 1M tokens (2026-10-08 rates, loki-ts/data/model-pricing.json)
394
394
  local input_rate=0
395
395
  local output_rate=0
396
396
  case "$model" in
397
- *opus*) input_rate=15.0; output_rate=75.0 ;;
398
- *sonnet*) input_rate=3.0; output_rate=15.0 ;;
399
- *haiku*) input_rate=0.25; output_rate=1.25 ;;
397
+ *opus*) input_rate=4.0; output_rate=20.0 ;;
398
+ *sonnet*) input_rate=2.0; output_rate=10.0 ;;
399
+ # Haiku 5.5 up to 100K prompt tokens (no over-100K tier here)
400
+ *haiku*) input_rate=0.10; output_rate=0.50 ;;
400
401
  *gpt-4o-mini*) input_rate=0.15; output_rate=0.6 ;;
401
402
  *gpt-4o*) input_rate=2.5; output_rate=10.0 ;;
402
- *) input_rate=3.0; output_rate=15.0 ;; # default sonnet-like
403
+ *) input_rate=2.0; output_rate=10.0 ;; # default sonnet-like
403
404
  esac
404
405
 
405
406
  local input_cost
@@ -207,7 +207,7 @@ _verify_llm_review() {
207
207
  }
208
208
  SCHEMA
209
209
 
210
- model="${LOKI_VERIFY_LLM_MODEL:-claude-sonnet-5}"
210
+ model="${LOKI_VERIFY_LLM_MODEL:-sonnet}"
211
211
  local to_s="${LOKI_VERIFY_LLM_TIMEOUT_S:-120}"
212
212
  local wrap=""
213
213
  if command -v timeout >/dev/null 2>&1; then wrap="timeout $(( to_s + 15 ))"
package/bin/loki CHANGED
@@ -32,6 +32,39 @@ SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
32
32
  REPO_ROOT=$(cd "$SCRIPT_DIR/.." 2>/dev/null && pwd)
33
33
  BASH_CLI="$REPO_ROOT/autonomy/loki"
34
34
 
35
+ # FC-38 (scoped): `loki start --attempts` never reaches the legacy bash loop. Every other
36
+ # start, and every other command, keeps the plain bash fallback.
37
+ _LOKI_START_ATTEMPTS=0
38
+ if [ "${1:-}" = "start" ]; then
39
+ for _loki_a0 in "${@:2}"; do
40
+ case "$_loki_a0" in --attempts|--attempts=*) _LOKI_START_ATTEMPTS=1 ;; esac
41
+ done
42
+ unset _loki_a0
43
+ fi
44
+ _loki_bash_or_refuse() {
45
+ if [ "${1:-}" = "start" ] && [ "$_LOKI_START_ATTEMPTS" = "1" ]; then
46
+ echo "loki: 'loki start' runs only the Loki 10 engine, which needs the Bun entry (loki-ts). It cannot fall back to the removed legacy loop; reinstall loki-mode or fix LOKI_TS_ENTRY / BUN_FROM_SOURCE." >&2
47
+ exit 1
48
+ fi
49
+ exec "$BASH_CLI" "$@"
50
+ }
51
+
52
+ # T5-D2 (FC-38 sweep): quick, run, demo and tour have no attempts engine; --attempts there would
53
+ # reach the legacy loop, so it is refused before any route split.
54
+ case "${1:-}" in
55
+ quick|run|demo|tour)
56
+ for _loki_a1 in "${@:2}"; do
57
+ case "$_loki_a1" in
58
+ --attempts|--attempts=*)
59
+ echo "loki: --attempts is only supported by 'loki start --attempts N --no-pr' (the Loki 10 engine). 'loki $1' would run the removed legacy loop; drop --attempts or use 'loki start --attempts N --no-pr'." >&2
60
+ exit 2
61
+ ;;
62
+ esac
63
+ done
64
+ unset _loki_a1
65
+ ;;
66
+ esac
67
+
35
68
  # v8.1: resolve the one-switch SDK mode (LOKI_SDK_MODE=off|judges|full) into the
36
69
  # per-site LOKI_SDK_* flags HERE, in the outermost shim, BEFORE the `start`
37
70
  # routing fork below reads LOKI_SDK_LOOP. Without this, `LOKI_SDK_MODE=full loki
@@ -78,7 +111,7 @@ if [ -n "${LOKI_TS_ENTRY:-}" ]; then
78
111
  # invoke commands while they fix the path.
79
112
  if [ ! -f "$LOKI_TS_ENTRY" ]; then
80
113
  echo "ERROR: LOKI_TS_ENTRY=$LOKI_TS_ENTRY does not exist; falling through to bash CLI. Unset the variable or fix the path." >&2
81
- exec "$BASH_CLI" "$@"
114
+ _loki_bash_or_refuse "$@"
82
115
  fi
83
116
  BUN_CLI="$LOKI_TS_ENTRY"
84
117
  elif [ "${BUN_FROM_SOURCE:-0}" = "1" ] || [ "${BUN_FROM_SOURCE:-}" = "true" ]; then
@@ -89,7 +122,7 @@ elif [ "${BUN_FROM_SOURCE:-0}" = "1" ] || [ "${BUN_FROM_SOURCE:-}" = "true" ]; t
89
122
  BUN_CLI="$REPO_ROOT/loki-ts/dist/loki.js"
90
123
  else
91
124
  echo "ERROR: BUN_FROM_SOURCE set but neither src/cli.ts nor dist/loki.js found; falling through to bash" >&2
92
- exec "$BASH_CLI" "$@"
125
+ _loki_bash_or_refuse "$@"
93
126
  fi
94
127
  elif [ -f "$REPO_ROOT/loki-ts/dist/loki.js" ]; then
95
128
  BUN_CLI="$REPO_ROOT/loki-ts/dist/loki.js"
@@ -112,7 +145,7 @@ elif [ -f "$REPO_ROOT/loki-ts/src/cli.ts" ]; then
112
145
  BUN_CLI="$REPO_ROOT/loki-ts/src/cli.ts"
113
146
  else
114
147
  # Neither dist nor src available; fall through to bash silently.
115
- exec "$BASH_CLI" "$@"
148
+ _loki_bash_or_refuse "$@"
116
149
  fi
117
150
 
118
151
  # FC-30: an install artifact must not outlive the install that made it. If a provider
@@ -259,7 +292,7 @@ esac
259
292
 
260
293
  # Force-fall-through to bash when the rollback flag is set.
261
294
  if [ "${LOKI_LEGACY_BASH:-0}" = "1" ] || [ "${LOKI_LEGACY_BASH:-}" = "true" ]; then
262
- exec "$BASH_CLI" "$@"
295
+ _loki_bash_or_refuse "$@"
263
296
  fi
264
297
 
265
298
  # Loki 10 bun resolver: bun on PATH, then an npm-installed @oven/bun-* optional
@@ -335,6 +368,105 @@ case "${1:-}" in
335
368
  ;;
336
369
  esac
337
370
 
371
+ _loki_start_needs_bash() {
372
+ # $@ = the start args (already know $1 = start). Return 0 (divert to bash) if
373
+ # any bash-only orchestration flag or an issue-ref spec is present.
374
+ local a
375
+ local explicit_provider=""
376
+ local provider_value_next=0
377
+ for a in "$@"; do
378
+ if [ "$provider_value_next" = "1" ]; then
379
+ explicit_provider="$a"
380
+ provider_value_next=0
381
+ continue
382
+ fi
383
+ case "$a" in
384
+ --provider)
385
+ provider_value_next=1 ;;
386
+ --provider=*)
387
+ explicit_provider="${a#--provider=}" ;;
388
+ --parallel|--bg|--background|--github|--api|--sandbox \
389
+ |--fast|--repo-fast|--full|--repo-full \
390
+ |--bmad-project|--openspec \
391
+ |--mirofish|--mirofish-docker|--mirofish-rounds|--mirofish-timeout|--mirofish-bg \
392
+ |--issue|--dry-run|--no-start|--output|--worktree|-w|--pr|--ship|--detach|-d)
393
+ return 0 ;;
394
+ --isolation)
395
+ # value follows; only worktree/docker/sandbox divert (none stays Bun).
396
+ _loki_iso_next=1 ;;
397
+ worktree|wt|docker|sandbox)
398
+ [ "${_loki_iso_next:-0}" = "1" ] && { unset _loki_iso_next; return 0; }
399
+ _loki_iso_next=0 ;;
400
+ *)
401
+ # issue-ref positional: owner/repo#N, a tracker URL, or *#<digits>.
402
+ case "$a" in
403
+ */*\#[0-9]*|http*://*/issues/*|http*://*/browse/*) return 0 ;;
404
+ esac
405
+ _loki_iso_next=0 ;;
406
+ esac
407
+ done
408
+ unset _loki_iso_next
409
+
410
+ # The Bun RARV loop has not ported the opencode invoker yet. Keep the
411
+ # released, autonomous shell adapter reachable when SDK mode is enabled
412
+ # instead of accepting the selection and then failing after intake. CLI
413
+ # selection wins over env, which wins over the project-level saved choice.
414
+ local effective_provider="$explicit_provider"
415
+ if [ -z "$effective_provider" ] && [ -n "${LOKI_PROVIDER:-}" ]; then
416
+ effective_provider="$LOKI_PROVIDER"
417
+ fi
418
+ if [ -z "$effective_provider" ] && [ -f "${PWD}/.loki/state/provider" ]; then
419
+ effective_provider="$(sed -n '1p' "${PWD}/.loki/state/provider" 2>/dev/null || true)"
420
+ fi
421
+ [ "$effective_provider" = "opencode" ] && return 0
422
+ return 1
423
+ }
424
+ _loki_attempts_refuse() {
425
+ if _loki_start_needs_bash "$@"; then
426
+ echo "loki: 'loki start --attempts' runs only the Loki 10 engine; an option or provider in this command (for example --parallel, --github, --sandbox, --issue, --dry-run, --detach, or opencode) was only honored by the removed legacy loop. Remove it, or use a task string, an issue ref or a PRD path." >&2
427
+ exit 2
428
+ fi
429
+ case "${LOKI_PROVIDER:-claude}" in
430
+ claude|codex|cline|aider) ;;
431
+ *) echo "loki: the Loki 10 engine does not support LOKI_PROVIDER=${LOKI_PROVIDER:-}; use claude, codex, cline or aider." >&2; exit 2 ;;
432
+ esac
433
+ }
434
+
435
+ # FC-37: --attempts is handled HERE, once, before any route split (engine10 positional task, Bun
436
+ # loop, bash cmd_start). A flag accepted on one route must be honored or refused loudly on every
437
+ # other. N=1 is stripped so every route sees today's argv byte-for-byte; N=2..5 runs on the Bun
438
+ # start command (loki-ts/src/commands/start.ts), which spawns one engine10 run per worktree.
439
+ if [ "${1:-}" = "start" ]; then
440
+ _loki_att_args=()
441
+ _loki_att_n=""
442
+ _loki_att_skip=0
443
+ for _loki_att_a in "${@:2}"; do
444
+ if [ "$_loki_att_skip" = "1" ]; then _loki_att_n="$_loki_att_a"; _loki_att_skip=0; continue; fi
445
+ case "$_loki_att_a" in
446
+ --attempts) _loki_att_skip=1 ;;
447
+ --attempts=*) _loki_att_n="${_loki_att_a#--attempts=}" ;;
448
+ *) _loki_att_args+=("$_loki_att_a") ;;
449
+ esac
450
+ done
451
+ if [ "$_loki_att_skip" = "1" ]; then
452
+ echo "loki: --attempts requires a value from 1 to 5." >&2
453
+ exit 2
454
+ fi
455
+ if [ -n "$_loki_att_n" ]; then
456
+ case "$_loki_att_n" in
457
+ 1) set -- start ${_loki_att_args[@]+"${_loki_att_args[@]}"} ;;
458
+ [2-5])
459
+ _lb=$(_loki_bun)
460
+ [ -n "$_lb" ] || { echo "loki: --attempts $_loki_att_n needs bun (install from https://bun.sh); refusing to run a single attempt silently." >&2; exit 1; }
461
+ _loki_attempts_refuse "${@:2}"
462
+ exec "$_lb" "$BUN_CLI" "$@"
463
+ ;;
464
+ *) echo "loki: --attempts must be an integer from 1 to 5, got '$_loki_att_n'." >&2; exit 2 ;;
465
+ esac
466
+ fi
467
+ unset _loki_att_args _loki_att_n _loki_att_skip _loki_att_a
468
+ fi
469
+
338
470
  # Loki 10 engine (D29, the only engine from 11.0.0). Routes `loki "<task>"`,
339
471
  # `loki owner/repo#N`, `loki quick "<task>"`, `keys` and `verify --pubkey` to engine10.
340
472
  # shellcheck disable=SC2194
@@ -376,7 +508,23 @@ case "v10" in
376
508
  # `loki <ref>`; any other start call (PRD file, flags first, one word) stays legacy.
377
509
  start)
378
510
  case "${2:-}" in
379
- */*\#[0-9]*|http*://*/issues/*|http*://*/browse/*|jira:*|linear:*|https://linear.app/*/issue/*|*" "*) _e10=1; _e10_args=("${@:2}") ;;
511
+ */*\#[0-9]*|http*://*/issues/*|http*://*/browse/*|jira:*|linear:*|https://linear.app/*/issue/*|*" "*)
512
+ _e10=1; _e10_args=("${@:2}")
513
+ if [ "$_LOKI_START_ATTEMPTS" = "1" ]; then
514
+ _e10_hard=1 # FC-38: --attempts never falls back to the legacy engine
515
+ # FC-37: engine10 has no --budget; unmapped it would be glued onto the task text. Its per-run cap is --max-cost.
516
+ _e10_args=(); _e10_bnext=0
517
+ for _e10_a in "${@:2}"; do
518
+ if [ "$_e10_bnext" = "1" ]; then _e10_args+=("$_e10_a"); _e10_bnext=0; continue; fi
519
+ case "$_e10_a" in
520
+ --budget|--budget-limit) _e10_args+=(--max-cost); _e10_bnext=1 ;;
521
+ --budget=*|--budget-limit=*) _e10_args+=("--max-cost=${_e10_a#*=}") ;;
522
+ *) _e10_args+=("$_e10_a") ;;
523
+ esac
524
+ done
525
+ unset _e10_a _e10_bnext
526
+ fi
527
+ ;;
380
528
  *) _e10=0 ;;
381
529
  esac
382
530
  ;;
@@ -425,6 +573,10 @@ esac
425
573
  # Bun must be installed for the new path; if it isn't, fall through to bash
426
574
  # silently rather than fail. This keeps users on systems without Bun working.
427
575
  if ! command -v bun &>/dev/null; then
576
+ if [ "${1:-}" = "start" ] && [ "$_LOKI_START_ATTEMPTS" = "1" ]; then
577
+ echo "loki: 'loki start' runs the Loki 10 engine, which needs bun. Install bun from https://bun.sh. The legacy loop is not reachable from start." >&2
578
+ exit 1
579
+ fi
428
580
  exec "$BASH_CLI" "$@"
429
581
  fi
430
582
 
@@ -448,59 +600,14 @@ fi
448
600
  # guarantee that makes the eventual loop default-flip a no-regression. Runner
449
601
  # flags (--simple, --allow-haiku, --regen-prd, --skip-memory, provider knobs) are
450
602
  # handled by start.ts and do NOT divert. See artifacts/ITER1-FLAG-RECONCILE.md.
451
- _loki_start_needs_bash() {
452
- # $@ = the start args (already know $1 = start). Return 0 (divert to bash) if
453
- # any bash-only orchestration flag or an issue-ref spec is present.
454
- local a
455
- local explicit_provider=""
456
- local provider_value_next=0
457
- for a in "$@"; do
458
- if [ "$provider_value_next" = "1" ]; then
459
- explicit_provider="$a"
460
- provider_value_next=0
461
- continue
462
- fi
463
- case "$a" in
464
- --provider)
465
- provider_value_next=1 ;;
466
- --provider=*)
467
- explicit_provider="${a#--provider=}" ;;
468
- --parallel|--bg|--background|--github|--api|--sandbox \
469
- |--fast|--repo-fast|--full|--repo-full \
470
- |--bmad-project|--openspec \
471
- |--mirofish|--mirofish-docker|--mirofish-rounds|--mirofish-timeout|--mirofish-bg \
472
- |--issue|--dry-run|--no-start|--output|--worktree|-w|--pr|--ship|--detach|-d)
473
- return 0 ;;
474
- --isolation)
475
- # value follows; only worktree/docker/sandbox divert (none stays Bun).
476
- _loki_iso_next=1 ;;
477
- worktree|wt|docker|sandbox)
478
- [ "${_loki_iso_next:-0}" = "1" ] && { unset _loki_iso_next; return 0; }
479
- _loki_iso_next=0 ;;
480
- *)
481
- # issue-ref positional: owner/repo#N, a tracker URL, or *#<digits>.
482
- case "$a" in
483
- */*\#[0-9]*|http*://*/issues/*|http*://*/browse/*) return 0 ;;
484
- esac
485
- _loki_iso_next=0 ;;
486
- esac
487
- done
488
- unset _loki_iso_next
489
-
490
- # The Bun RARV loop has not ported the opencode invoker yet. Keep the
491
- # released, autonomous shell adapter reachable when SDK mode is enabled
492
- # instead of accepting the selection and then failing after intake. CLI
493
- # selection wins over env, which wins over the project-level saved choice.
494
- local effective_provider="$explicit_provider"
495
- if [ -z "$effective_provider" ] && [ -n "${LOKI_PROVIDER:-}" ]; then
496
- effective_provider="$LOKI_PROVIDER"
497
- fi
498
- if [ -z "$effective_provider" ] && [ -f "${PWD}/.loki/state/provider" ]; then
499
- effective_provider="$(sed -n '1p' "${PWD}/.loki/state/provider" 2>/dev/null || true)"
500
- fi
501
- [ "$effective_provider" = "opencode" ] && return 0
502
- return 1
503
- }
603
+ # FC-38 (scoped to --attempts; plain start keeps the 11.3.0 routing below): no `start --attempts` reaches the legacy loop (bash cmd_start, run.sh, runAutonomous).
604
+ # Issue refs and multi-word tasks were sent to engine10 above; every other start (PRD path, brief,
605
+ # flags) goes to the Bun start command, which runs engine10 and seals a receipt. A flag only the
606
+ # legacy route honored, or a provider engine10 cannot invoke, is refused loudly instead.
607
+ if [ "${1:-}" = "start" ] && [ "$_LOKI_START_ATTEMPTS" = "1" ]; then
608
+ _loki_attempts_refuse "${@:2}"
609
+ exec bun "$BUN_CLI" "$@"
610
+ fi
504
611
  if [ "${1:-}" = "start" ] && { [ "${LOKI_SDK_LOOP:-}" = "1" ] || [ "${LOKI_SDK_LOOP:-}" = "true" ]; }; then
505
612
  if _loki_start_needs_bash "${@:2}"; then
506
613
  exec "$BASH_CLI" "$@"
@@ -603,7 +710,7 @@ fi
603
710
  # Two-token routes (provider show/list, memory list/index) match on the first
604
711
  # token only; the Bun dispatcher handles subcommand routing internally.
605
712
  case "${1:-}" in
606
- version|--version|-v|status|stats|doctor|provider|memory|rollback|internal|kpis|trust|proof|receipt|wiki|crash|control|contract|slack|answer|completion|__complete)
713
+ version|--version|-v|status|stats|doctor|provider|memory|rollback|internal|kpis|trust|proof|receipt|wiki|crash|control|contract|slack|queue|answer|completion|__complete)
607
714
  # v7.5.2: rollback added (wires loki-ts/src/commands/rollback.ts).
608
715
  # v7.5.3: internal added for autonomy/run.sh phase1-hooks calls.
609
716
  # v7.5.28: kpis added (Phase K MVP: read-only KPI snapshot).
package/completions/_loki CHANGED
@@ -209,6 +209,7 @@ function _loki_commands {
209
209
  'otel:OpenTelemetry management'
210
210
  'wiki:Wiki commands'
211
211
  'answer:Resume a BLOCKED run with an answer'
212
+ 'queue:Overnight issue queue with a morning digest'
212
213
  'control:Control plane (preview, LOKI_CONTROL=1)'
213
214
  'workspace:Multi-project workspaces (preview, LOKI_WORKSPACES=1)'
214
215
  'backlog:Run every matching open issue, N in parallel'
@@ -264,6 +265,7 @@ function _loki_start {
264
265
  '-y[Skip confirmation prompts]' \
265
266
  '--budget[Cost budget limit in USD]:amount:' \
266
267
  '--max-iterations[Max iterations]:number:' \
268
+ '--attempts[Independent attempts in worktrees, 1-5]:number:(1 2 3 4 5)' \
267
269
  '*:spec file:_loki_spec_files'
268
270
  }
269
271
 
@@ -5,7 +5,7 @@ _loki_completion() {
5
5
  _init_completion || return
6
6
 
7
7
  # Main subcommands (must match autonomy/loki main case statement)
8
- local main_commands="start backlog quick monitor demo tour welcome init stop pause resume steer status next ship dashboard web serve api sandbox notify import github issue intent config provider reset memory compound checkpoint council dogfood projects enterprise secrets cockpit secure own handoff doctor watchdog audit metrics syslog onboard share proof receipt outcomes explain plan report cost estimate kpis stats test ci watch telemetry agent context ctx code run export review optimize heal modernize migrate cluster worktree wt trigger failover remote deploy docker mcp magic assets analyze compliance crash control workspace open otel preview quickstart rc rollback merge self-update sentrux setup-skill spec state template trust trust-metrics ultracode update verify voice why wiki bench cleanup logs grill docs cp version completions help keys answer acp"
8
+ local main_commands="start backlog quick monitor demo tour welcome init stop pause resume steer status next ship dashboard web serve api sandbox notify import github issue intent config provider reset memory compound checkpoint council dogfood projects enterprise secrets cockpit secure own handoff doctor watchdog audit metrics syslog onboard share proof receipt outcomes explain plan report cost estimate kpis stats test ci watch telemetry agent context ctx code run export review optimize heal modernize migrate cluster worktree wt trigger failover remote deploy docker mcp magic assets analyze compliance crash control workspace open otel preview quickstart rc rollback merge self-update sentrux setup-skill spec state template trust trust-metrics ultracode update verify voice why wiki bench cleanup logs grill docs cp version completions help keys answer queue acp"
9
9
 
10
10
  # 1. If we are on the first argument (subcommand)
11
11
  if [[ $cword -eq 1 ]]; then
@@ -27,7 +27,7 @@ _loki_completion() {
27
27
 
28
28
  # If the word starts with a dash, show flags
29
29
  if [[ "$cur" == -* ]]; then
30
- local flags="--provider --max-iterations --parallel --background --bg --simple --complex --github --no-dashboard --sandbox --skip-memory --yes --budget --help"
30
+ local flags="--provider --max-iterations --parallel --background --bg --simple --complex --github --no-dashboard --sandbox --skip-memory --yes --budget --attempts --help"
31
31
  COMPREPLY=( $(compgen -W "${flags}" -- "$cur") )
32
32
  return 0
33
33
  fi
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "11.3.0"
10
+ __version__ = "11.3.1"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -1520,9 +1520,9 @@ async def get_provider_models() -> dict:
1520
1520
  "schema_version": 1,
1521
1521
  "providers": {
1522
1522
  "claude": {
1523
- "latest_planning": "claude-opus-4-7",
1524
- "latest_development": "claude-opus-4-7",
1525
- "latest_fast": "claude-sonnet-4-6",
1523
+ "latest_planning": "opus",
1524
+ "latest_development": "opus",
1525
+ "latest_fast": "sonnet",
1526
1526
  "models": [],
1527
1527
  }
1528
1528
  },
@@ -3360,7 +3360,7 @@ def _provider_model_offers(provider: str) -> list[dict]:
3360
3360
  Every other provider is offered the generic tiers (small/medium/high), which
3361
3361
  are provider-independent, each annotated with the concrete model id the
3362
3362
  catalog says that provider dispatches. That is what makes the picker read
3363
- "medium -> gpt-5.6-terra" on codex and "medium -> claude-sonnet-5" on claude
3363
+ "medium -> gpt-5.6-terra" on codex and "medium -> <catalog sonnet id>" on claude
3364
3364
  without the frontend knowing a single model id.
3365
3365
  """
3366
3366
  if provider == "claude":
@@ -7738,23 +7738,24 @@ async def stop_session(request: Request):
7738
7738
  # At runtime, overridden by .loki/pricing.json if available
7739
7739
  _DEFAULT_PRICING = {
7740
7740
  # Claude (Anthropic)
7741
- # Fable 5 is the top-tier advisory model at exactly 2x Opus per token.
7742
- "fable": {"input": 10.00, "output": 50.00},
7743
- "claude-fable-5": {"input": 10.00, "output": 50.00},
7744
- "opus": {"input": 5.00, "output": 25.00},
7745
- "sonnet": {"input": 2.00, "output": 10.00},
7746
- "haiku": {"input": 1.00, "output": 5.00},
7741
+ # Fable 5 is the top-tier advisory model at 2.5x Opus 5.5 per token.
7742
+ "fable": {"input": 10.00, "output": 50.00, "cache_read": 0.25, "cache_write": 12.5, "cache_write_1h": 20},
7743
+ "claude-fable-5": {"input": 10.00, "output": 50.00, "cache_read": 0.25, "cache_write": 12.5, "cache_write_1h": 20},
7744
+ "opus": {"input": 4.00, "output": 20.00, "cache_read": 0.2, "cache_write": 5, "cache_write_1h": 8},
7745
+ "sonnet": {"input": 2.00, "output": 10.00, "cache_read": 0.1, "cache_write": 2.5, "cache_write_1h": 4},
7746
+ # haiku = Haiku 5.5 up to 100K prompt tokens (no over-100K tier here)
7747
+ "haiku": {"input": 0.10, "output": 0.50, "cache_read": 0.01, "cache_write": 0.125, "cache_write_1h": 0.2},
7748
+ # Exact ids (a lookup by recorded model string must not fall back to sonnet)
7749
+ "claude-haiku-4-5": {"input": 1.00, "output": 5.00, "cache_read": 0.1, "cache_write": 1.25, "cache_write_1h": 2},
7750
+ "claude-haiku-5-5": {"input": 0.10, "output": 0.50, "cache_read": 0.01, "cache_write": 0.125, "cache_write_1h": 0.2},
7747
7751
  # OpenAI Codex
7748
- "gpt-5.3-codex": {"input": 1.50, "output": 12.00},
7752
+ "gpt-5.3-codex": {"input": 1.75, "output": 14.00},
7749
7753
  # gpt-5.6 line: sol (high) / terra (medium, default) / luna (small).
7750
- # UNVERIFIED RATES. The model IDs are confirmed against
7751
- # developers.openai.com/api/docs/models, but OpenAI's published per-token
7752
- # prices for this line were not, so these are placeholders scaled from the
7753
- # gpt-5.3 rate. They drive a display estimate only, never a gate. Replace
7754
- # from the pricing page; tools/probe-model-catalog.py is the refresh path.
7755
- "gpt-5.6-sol": {"input": 2.50, "output": 20.00},
7756
- "gpt-5.6-terra": {"input": 1.50, "output": 12.00},
7757
- "gpt-5.6-luna": {"input": 0.50, "output": 4.00},
7754
+ # Rates from developers.openai.com/api/docs/pricing (read 2026-10-08),
7755
+ # Standard tier, short context (up to 272K). tests/test-pricing-parity.sh pins them.
7756
+ "gpt-5.6-sol": {"input": 4.00, "output": 20.00},
7757
+ "gpt-5.6-terra": {"input": 2.00, "output": 12.00},
7758
+ "gpt-5.6-luna": {"input": 0.20, "output": 1.20},
7758
7759
  }
7759
7760
 
7760
7761
  # Active pricing - starts with defaults, updated from .loki/pricing.json
@@ -8565,11 +8566,11 @@ async def get_gate_policy():
8565
8566
  # =============================================================================
8566
8567
 
8567
8568
  _PROVIDER_LABELS = {
8568
- # v7.104.0: current model IDs (model_catalog.json): opus=claude-opus-4-8,
8569
- # sonnet=claude-sonnet-5 (the default execution model), haiku=claude-haiku-4-5.
8570
- "opus": "Opus 4.8",
8571
- "sonnet": "Sonnet 5",
8572
- "haiku": "Haiku 4.5",
8569
+ # v7.104.0: current model IDs (model_catalog.json): opus, sonnet (the default execution model), haiku: ids live in
8570
+ # the catalog cli_aliases, not here.
8571
+ "opus": "Opus 5.5",
8572
+ "sonnet": "Sonnet 5.5",
8573
+ "haiku": "Haiku 5.5",
8573
8574
  "gpt-5.3-codex": "GPT-5.3 Codex",
8574
8575
  "gpt-5.6-sol": "GPT-5.6 Sol",
8575
8576
  "gpt-5.6-terra": "GPT-5.6 Terra",
@@ -8580,18 +8581,11 @@ _PROVIDER_LABELS = {
8580
8581
  # the UI WITHOUT changing any computed cost number. The Sonnet 5 intro price
8581
8582
  # ($2/$10 per MTok) became the standard price, so the 2026-09-01 increase to
8582
8583
  # $3/$15 will not occur (platform.claude.com pricing page, read 2026-10-03).
8583
- _UNVERIFIED_RATE_NOTE = (
8584
- "Unverified placeholder rate, scaled from gpt-5.3; not from OpenAI's pricing page."
8585
- )
8586
8584
  _MODEL_PRICING_NOTES = {
8587
8585
  "sonnet": (
8588
8586
  "Standard pricing: $2 / $10 per MTok. "
8589
8587
  "The intro price became the standard price; no increase to $3 / $15."
8590
8588
  ),
8591
- # See the UNVERIFIED RATES comment on the pricing table: shown, not hidden.
8592
- "gpt-5.6-sol": _UNVERIFIED_RATE_NOTE,
8593
- "gpt-5.6-terra": _UNVERIFIED_RATE_NOTE,
8594
- "gpt-5.6-luna": _UNVERIFIED_RATE_NOTE,
8595
8589
  }
8596
8590
 
8597
8591
  _MODEL_PROVIDERS = {