loki-mode 11.3.0 → 11.3.2

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 (242) hide show
  1. package/README.md +68 -650
  2. package/SKILL.md +5 -5
  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/efficiency_cost.py +8 -0
  10. package/autonomy/lib/engine10-push.sh +22 -8
  11. package/autonomy/lib/prd-enrich.sh +1 -1
  12. package/autonomy/lib/voter-agents.sh +1 -1
  13. package/autonomy/loki +161 -105
  14. package/autonomy/run.sh +30 -18
  15. package/autonomy/sandbox.sh +1 -1
  16. package/autonomy/tui.sh +6 -5
  17. package/autonomy/verify.sh +1 -1
  18. package/bin/loki +195 -59
  19. package/completions/_loki +8 -0
  20. package/completions/loki.bash +3 -3
  21. package/dashboard/__init__.py +1 -1
  22. package/dashboard/server.py +47 -45
  23. package/docs/AGENT-CHANGE-RECEIPT.md +2 -2
  24. package/docs/ARCHITECTURE.md +337 -0
  25. package/docs/BRANDING.md +124 -0
  26. package/docs/CLI-REFERENCE.md +11 -1
  27. package/docs/COMPONENTS.md +447 -0
  28. package/docs/DEPLOYMENT.md +9 -9
  29. package/docs/DOCKER.md +469 -0
  30. package/docs/INSTALLATION.md +67 -1045
  31. package/docs/KNOWN-ISSUES.md +11 -35
  32. package/docs/OTEL-COLLECTOR.md +24 -0
  33. package/docs/ROUTING-EVIDENCE.md +32 -0
  34. package/docs/TESTING.md +161 -0
  35. package/docs/air-gapped.md +1 -2
  36. package/docs/alternative-installations.md +14 -24
  37. package/docs/architecture/DECISIONS.md +333 -0
  38. package/docs/audit-logging.md +7 -7
  39. package/docs/authentication.md +3 -3
  40. package/docs/authorization.md +1 -1
  41. package/docs/certification/04-production-deployment/lab.md +6 -6
  42. package/docs/certification/04-production-deployment/lesson.md +4 -4
  43. package/docs/certification/README.md +1 -1
  44. package/docs/control-plane-container.md +2 -2
  45. package/docs/dev/real-run.md +34 -0
  46. package/docs/dev/release-checklist.md +2 -2
  47. package/docs/environment-variables.md +1 -0
  48. package/docs/exit-codes.md +3 -3
  49. package/docs/git-workflow.md +3 -3
  50. package/docs/metrics.md +37 -55
  51. package/docs/network-security.md +1 -1
  52. package/docs/siem-integration.md +5 -5
  53. package/docs/spec-first-intent.md +28 -0
  54. package/docs/v10/CLI-MODERN.md +7 -3
  55. package/docs/v10/DECISIONS.md +59 -0
  56. package/docs/v10/DEPS.md +22 -22
  57. package/docs/v10/ENGINE.md +1 -1
  58. package/docs/v10/FAILURE-CLASSES.md +212 -1
  59. package/docs/v10/FOUNDER-QUEUE.md +1 -0
  60. package/docs/v10/GUARDS.md +31 -0
  61. package/docs/v10/GUIDE.md +7 -5
  62. package/docs/v10/LEGACY-REMOVAL.md +4 -6
  63. package/docs/v10/METRICS.md +14 -2
  64. package/docs/v10/MODERNIZE.md +1 -1
  65. package/docs/v10/OPERATING-MODEL.md +4 -3
  66. package/docs/v10/PROGRESS.md +35 -0
  67. package/docs/v11/COST-HALF.md +352 -0
  68. package/docs/v11/INTOTO-AGENT-CHANGE-PREDICATE.md +77 -0
  69. package/docs/v11/MARKET-SLICES.md +315 -0
  70. package/docs/v11/MCP-2026-07-28.md +55 -0
  71. package/docs/v11/REGISTRIES.md +730 -0
  72. package/docs/v11/VERIFY-PR-SANDBOX.md +41 -0
  73. package/loki-ts/data/model-pricing.json +52 -24
  74. package/loki-ts/dist/loki.js +1185 -945
  75. package/mcp/__init__.py +1 -1
  76. package/mcp/v10_tools.py +29 -0
  77. package/package.json +9 -11
  78. package/packages/control-plane/dist/ask-tools-server.js +8 -2
  79. package/packages/control-plane/dist/server.js +15832 -12361
  80. package/packages/control-plane/drizzle/0006_token_sessions.sql +1 -0
  81. package/packages/control-plane/drizzle/meta/0006_snapshot.json +807 -0
  82. package/packages/control-plane/drizzle/meta/_journal.json +7 -0
  83. package/packages/control-plane/src/db/schema.ts +1 -0
  84. package/packages/control-plane/src/server/routes/cost.ts +4 -3
  85. package/packages/control-plane/src/server/runs.ts +3 -3
  86. package/packages/control-plane/ui/dist/assets/index-DbLzr87u.js +190 -0
  87. package/packages/control-plane/ui/dist/index.html +1 -1
  88. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  89. package/providers/opencode.sh +2 -3
  90. package/src/observability/genai-spans.js +104 -0
  91. package/src/observability/otel-bridge.js +49 -1
  92. package/src/observability/otel.js +2 -2
  93. package/src/protocols/mcp-client.js +6 -2
  94. package/src/protocols/mcp-server.js +191 -6
  95. package/src/protocols/transport/sse.js +23 -2
  96. package/tools/audit-docs.py +1 -1
  97. package/web-app/dist/assets/{AdminPage-D_e45uTw.js → AdminPage-DuRQZsF9.js} +1 -1
  98. package/web-app/dist/assets/{Avatar-T3nIpoaf.js → Avatar-7GtOQvsO.js} +1 -1
  99. package/web-app/dist/assets/{Badge-BKqb59pP.js → Badge-CYgTnIxj.js} +1 -1
  100. package/web-app/dist/assets/{Button-DjVlkh8_.js → Button-rYSyIu7X.js} +1 -1
  101. package/web-app/dist/assets/{CockpitPage-DXJgLGmh.js → CockpitPage-9adANY4o.js} +1 -1
  102. package/web-app/dist/assets/{ComparePage-BRP_eVc_.js → ComparePage-DEG2oA-R.js} +1 -1
  103. package/web-app/dist/assets/{ErrorBoundary-CLjpGLjC.js → ErrorBoundary-CwtvY4xs.js} +1 -1
  104. package/web-app/dist/assets/{EvidenceReceiptPanel-DX-vb4Xy.js → EvidenceReceiptPanel-DTT73pPB.js} +1 -1
  105. package/web-app/dist/assets/{GitHubIssuesPanel-214HVHtX.js → GitHubIssuesPanel-CpWZLz2x.js} +1 -1
  106. package/web-app/dist/assets/{GitHubPRsPanel-BEiZKc4t.js → GitHubPRsPanel-H293R7E2.js} +1 -1
  107. package/web-app/dist/assets/{HomePage-VvMHS5ga.js → HomePage-B11Imp9k.js} +2 -2
  108. package/web-app/dist/assets/{LoginPage-5WD-v7n3.js → LoginPage-BZBgx5Jr.js} +1 -1
  109. package/web-app/dist/assets/{MagicPage-DUQT_Jye.js → MagicPage-B27S4_X8.js} +1 -1
  110. package/web-app/dist/assets/{MetricsPage-lga-z79v.js → MetricsPage-CfbJWNDG.js} +1 -1
  111. package/web-app/dist/assets/{NotFoundPage-CGhBX3G1.js → NotFoundPage-Tp_4zMSm.js} +1 -1
  112. package/web-app/dist/assets/{ProjectPage-CdzF2GzZ.js → ProjectPage-CM4fgMsV.js} +3 -3
  113. package/web-app/dist/assets/{ProjectsPage-DRG64N8s.js → ProjectsPage-DP2Fvsrd.js} +1 -1
  114. package/web-app/dist/assets/{SettingsPage-5fzW9Frb.js → SettingsPage-C4G9-EAy.js} +1 -1
  115. package/web-app/dist/assets/{ShowcasePage-DrTdxO4y.js → ShowcasePage-Dj-n4dwu.js} +1 -1
  116. package/web-app/dist/assets/{SystemSettingsPage-C9Mqs6Rd.js → SystemSettingsPage-BqMLpuGt.js} +1 -1
  117. package/web-app/dist/assets/{TeamsPage-CUGPdSWo.js → TeamsPage-mIH8H96m.js} +1 -1
  118. package/web-app/dist/assets/{TemplatesPage-CNraDY0F.js → TemplatesPage-BagW-v4n.js} +1 -1
  119. package/web-app/dist/assets/{TerminalOutput-BIu_6Pea.js → TerminalOutput-CTQRHhnK.js} +1 -1
  120. package/web-app/dist/assets/{activity-Bk-kgqaf.js → activity-DNQiBDDL.js} +1 -1
  121. package/web-app/dist/assets/{bell-BXmUdmo8.js → bell-Coiwdad1.js} +1 -1
  122. package/web-app/dist/assets/{bot-CiuzXxUR.js → bot-Cou-rTgR.js} +1 -1
  123. package/web-app/dist/assets/{check-BEzjXppd.js → check-CsF-XtQp.js} +1 -1
  124. package/web-app/dist/assets/{chevron-left-AYWCXHf8.js → chevron-left-BJiy55Ht.js} +1 -1
  125. package/web-app/dist/assets/{circle-alert-BNg2uSRq.js → circle-alert-D6-pQQWq.js} +1 -1
  126. package/web-app/dist/assets/{clock-DTj0kkGT.js → clock-BOGqwgt9.js} +1 -1
  127. package/web-app/dist/assets/{cloud-x4nTDBLT.js → cloud-DsxhTtf5.js} +1 -1
  128. package/web-app/dist/assets/{code-xml-BVh_MLrk.js → code-xml-CxJDHUlE.js} +1 -1
  129. package/web-app/dist/assets/{database-DdfBaowG.js → database-BJePscl_.js} +1 -1
  130. package/web-app/dist/assets/{dollar-sign-XuYFmAOY.js → dollar-sign-6qWGAkZo.js} +1 -1
  131. package/web-app/dist/assets/{file-code-corner-D4cRnmeL.js → file-code-corner-DcOtYeDb.js} +1 -1
  132. package/web-app/dist/assets/{file-plus-CyoVlHc_.js → file-plus-WuRyLFo0.js} +1 -1
  133. package/web-app/dist/assets/{globe-Y6IK2RPW.js → globe-r-xCP4DE.js} +1 -1
  134. package/web-app/dist/assets/{hammer-BKzr9VZI.js → hammer-DTt0SsCB.js} +1 -1
  135. package/web-app/dist/assets/{index-B20cSx5G.js → index-BkbXyH8y.js} +3 -3
  136. package/web-app/dist/assets/{layers-DebNOhGS.js → layers-BvZhvSMY.js} +1 -1
  137. package/web-app/dist/assets/{loader-circle-DyGbrEgd.js → loader-circle-3gosTei9.js} +1 -1
  138. package/web-app/dist/assets/{lock-BKPpyt20.js → lock-CZZMxP0U.js} +1 -1
  139. package/web-app/dist/assets/{package-egF5Wi4y.js → package-C5A8CkJr.js} +1 -1
  140. package/web-app/dist/assets/{plus-OiEgKIc-.js → plus-Btv7tTIF.js} +1 -1
  141. package/web-app/dist/assets/{refresh-cw-CzKvrONq.js → refresh-cw-DsWLXgs_.js} +1 -1
  142. package/web-app/dist/assets/{rotate-ccw-Bu2mII0p.js → rotate-ccw-DOVDjway.js} +1 -1
  143. package/web-app/dist/assets/{scroll-text-CSkiyax8.js → scroll-text-smySzlrX.js} +1 -1
  144. package/web-app/dist/assets/{server-DlPthJFw.js → server-b5PHsqAU.js} +1 -1
  145. package/web-app/dist/assets/{shield-alert-CbpHWQQX.js → shield-alert-BD7FDlh-.js} +1 -1
  146. package/web-app/dist/assets/{thumbs-up-DgGpZe-Q.js → thumbs-up-CAsFzbyE.js} +1 -1
  147. package/web-app/dist/assets/{trash-2-BV3GlCB-.js → trash-2-BJ35qHgl.js} +1 -1
  148. package/web-app/dist/assets/{trending-down-Y4TJtXhD.js → trending-down-Ozrd26cZ.js} +1 -1
  149. package/web-app/dist/assets/{trending-up-DsDNoHZY.js → trending-up-BhnMcM32.js} +1 -1
  150. package/web-app/dist/assets/{upload-gkThrc_I.js → upload-JVHfdwoA.js} +1 -1
  151. package/web-app/dist/assets/{usePolling-jpNSeNAe.js → usePolling-CTzbDV-e.js} +1 -1
  152. package/web-app/dist/assets/{user-3Zez1WOK.js → user-Bks3-GYv.js} +1 -1
  153. package/web-app/dist/index.html +1 -1
  154. package/docs/ARCHITECTURE-OVERVIEW.md +0 -209
  155. package/docs/AUTONOMI-ECOSYSTEM.md +0 -107
  156. package/docs/COCKPIT-SPEC.md +0 -72
  157. package/docs/COCKPIT-UX-MANDATE.md +0 -53
  158. package/docs/COMPETITIVE-ANALYSIS.md +0 -303
  159. package/docs/COMPETITIVE-NEXT-10.md +0 -316
  160. package/docs/COMPETITIVE-RALPH-ZEROSHOT-2026-07-08.md +0 -81
  161. package/docs/DASHBOARD-9.12-EVIDENCE.md +0 -97
  162. package/docs/DASHBOARD-ARCHITECTURE.md +0 -425
  163. package/docs/DASHBOARD_V2_CHECKLIST.md +0 -243
  164. package/docs/DEMOS.md +0 -63
  165. package/docs/ENTERPRISE-IDENTITY-ROADMAP.md +0 -206
  166. package/docs/EVIDENCE-RECEIPT-BUILD-APPLICABILITY.md +0 -79
  167. package/docs/FEAT-PRDREUSE-DOCKER-PLAN.md +0 -144
  168. package/docs/GATE-FAILURE-TRIAGE.md +0 -254
  169. package/docs/HANDOFF-2026-08-03.md +0 -439
  170. package/docs/LOOP-CANDIDATE-PROPOSAL-v1.md +0 -167
  171. package/docs/LOOP-HARNESS-AUDIT.md +0 -684
  172. package/docs/MERGE-DEDUP-MAP.md +0 -420
  173. package/docs/MERGE-ROUTE-MAP.md +0 -139
  174. package/docs/MODEL-REGISTRY-PLAN.md +0 -155
  175. package/docs/OUTCOME-FRONTIER.md +0 -536
  176. package/docs/P2-SPEC-ROBUSTNESS-PLAN.md +0 -192
  177. package/docs/PLANS-INDEX.md +0 -32
  178. package/docs/PRD-REUSE-DONE-RECOGNITION-PLAN.md +0 -536
  179. package/docs/PROMPT-ABLATION-RESULT.md +0 -97
  180. package/docs/R4-TRUST-TRAJECTORY-DESIGN.md +0 -127
  181. package/docs/R5-AUTO-WIKI-DESIGN.md +0 -137
  182. package/docs/R6-ROLLBACK-CHECKPOINT-PLAN.md +0 -107
  183. package/docs/R7-ZERO-CONFIG-FIRST-RUN-PLAN.md +0 -137
  184. package/docs/R8-SHAREABLE-TEAM-ASSETS-PLAN.md +0 -129
  185. package/docs/R9-OPEN-CORE-HOOKS-PLAN.md +0 -113
  186. package/docs/RARV-C-100X-PLAN.md +0 -286
  187. package/docs/RARV-C-LOOP-EFFICIENCY-PLAN.md +0 -470
  188. package/docs/SHAREABLE-PROOF-PLAN.md +0 -194
  189. package/docs/SONNET5-DEFAULT-PLAN.md +0 -157
  190. package/docs/SPEED-AND-FIRST-PASS-PLAN.md +0 -281
  191. package/docs/STALE-STATE-AUDIT.md +0 -174
  192. package/docs/SYNERGY-TASKS.md +0 -143
  193. package/docs/TASKLIST-ACCURACY-PLAN.md +0 -355
  194. package/docs/TOP-100-BACKLOG.md +0 -159
  195. package/docs/V8-ACCEPTANCE-TRIAGE-2026-07-24.md +0 -114
  196. package/docs/V8-COMPLEXITY-AUDIT-2026-07-24.md +0 -45
  197. package/docs/V8-MAJOR-RELEASE-PLAN.md +0 -137
  198. package/docs/V8-OVERNIGHT-PLAN-2026-07-25.md +0 -82
  199. package/docs/V8-SDK-RESEARCH-RAW.md +0 -129
  200. package/docs/WELCOME-OPENER-PLAN.md +0 -106
  201. package/docs/adoption-baseline-2026-07-31.md +0 -84
  202. package/docs/architecture/bmad-integration-epic.md +0 -271
  203. package/docs/architecture/bmad-integration-review.md +0 -86
  204. package/docs/architecture/bmad-integration-validation.md +0 -249
  205. package/docs/architecture/bmad-loki-voice-agent-council-analysis.md +0 -61
  206. package/docs/auto-claude-comparison.md +0 -250
  207. package/docs/bug-fixes/agent-01-cli-fixes.md +0 -101
  208. package/docs/bug-fixes/agent-02-purplelab-fixes.md +0 -88
  209. package/docs/bug-fixes/agent-03-dashboard-fixes.md +0 -119
  210. package/docs/bug-fixes/agent-04-memory-fixes.md +0 -105
  211. package/docs/bug-fixes/agent-05-provider-fixes.md +0 -86
  212. package/docs/bug-fixes/agent-06-integration-fixes.md +0 -101
  213. package/docs/bug-fixes/agent-07-dash-run-fixes.md +0 -101
  214. package/docs/bug-fixes/agent-08-docker-fixes.md +0 -164
  215. package/docs/bug-fixes/agent-09-e2e-build-fixes.md +0 -69
  216. package/docs/bug-fixes/agent-10-e2e-fullstack-fixes.md +0 -102
  217. package/docs/bug-fixes/agent-11-e2e-session-fixes.md +0 -70
  218. package/docs/bug-fixes/agent-12-scenario-fixes.md +0 -120
  219. package/docs/bug-fixes/agent-13-enterprise-fixes.md +0 -143
  220. package/docs/bug-fixes/agent-14-uat-newuser-fixes.md +0 -88
  221. package/docs/bug-fixes/agent-15-uat-poweruser-fixes.md +0 -132
  222. package/docs/bug-fixes/agent-19-code-review.md +0 -316
  223. package/docs/bug-fixes/agent-20-architecture-review.md +0 -331
  224. package/docs/competitive/bolt-new-analysis.md +0 -579
  225. package/docs/competitive/emergence-others-analysis.md +0 -605
  226. package/docs/competitive/replit-lovable-analysis.md +0 -622
  227. package/docs/dashboard-guide.md +0 -487
  228. package/docs/enterprise/migration.md +0 -265
  229. package/docs/history/one-run-audit.md +0 -304
  230. package/docs/plans/FORGE-AUTONOMOUS-QUEUE.md +0 -312
  231. package/docs/plans/ULTRAPLAN-FORGE-BAAS.md +0 -612
  232. package/docs/plans/UT2-6-LSP-DIAGNOSTIC-BROADCAST.md +0 -394
  233. package/docs/prd-purple-lab-ide.md +0 -152
  234. package/docs/prd-purple-lab-platform-v2.md +0 -223
  235. package/docs/prd-purple-lab-platform.md +0 -319
  236. package/docs/retrospectives/v7.5.15-fleet-postmortem.md +0 -325
  237. package/docs/retrospectives/v7.5.15-honesty-audit.md +0 -136
  238. package/docs/retrospectives/v7.5.15-llm-failure-modes.md +0 -49
  239. package/docs/show-hn-post.md +0 -46
  240. package/docs/test-scenarios/enterprise-scenarios.md +0 -732
  241. package/docs/thick2thin.md +0 -173
  242. package/packages/control-plane/ui/dist/assets/index-DcBJXjCJ.js +0 -190
@@ -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
@@ -7888,6 +7889,9 @@ def _compute_cost_snapshot() -> dict:
7888
7889
  cost_recorded = False
7889
7890
  # Tokens were measured (tracker fallback) but no USD figure was recorded.
7890
7891
  cost_unknown = False
7892
+ # FC-44: sessions whose usage could not be recorded (efficiency record flagged tokens_measured:false). Any of them makes
7893
+ # every token and dollar total NOT RECORDED; the response key appears only then.
7894
+ unmeasured_sessions = 0
7891
7895
 
7892
7896
  # Read efficiency files (one JSON file per iteration/task).
7893
7897
  # Use the iteration-*.json pattern so this reader sees the same
@@ -7905,6 +7909,9 @@ def _compute_cost_snapshot() -> dict:
7905
7909
  if not isinstance(data, dict):
7906
7910
  continue
7907
7911
  measured = _record_is_measured(data)
7912
+ rec_unmeasured = data.get("tokens_measured") is False
7913
+ if rec_unmeasured:
7914
+ unmeasured_sessions += 1
7908
7915
  if measured:
7909
7916
  cost_recorded = True
7910
7917
  # Tokens are measured apart from cost: a record that priced an
@@ -7940,17 +7947,18 @@ def _compute_cost_snapshot() -> dict:
7940
7947
  for bucket, name in ((by_phase, phase), (by_model, model)):
7941
7948
  if name not in bucket:
7942
7949
  bucket[name] = {"input_tokens": 0, "output_tokens": 0, "cost_usd": 0.0,
7943
- "measured": False, "tokens_measured": False}
7950
+ "measured": False, "tokens_measured": False, "unmeasured": False}
7944
7951
  bucket[name]["input_tokens"] += inp
7945
7952
  bucket[name]["output_tokens"] += out
7946
7953
  bucket[name]["cost_usd"] += cost
7947
7954
  bucket[name]["measured"] = bucket[name]["measured"] or measured
7948
7955
  bucket[name]["tokens_measured"] = bucket[name]["tokens_measured"] or tokens_measured
7956
+ bucket[name]["unmeasured"] = bucket[name]["unmeasured"] or rec_unmeasured
7949
7957
  except (json.JSONDecodeError, KeyError, TypeError, AttributeError):
7950
7958
  pass
7951
7959
 
7952
7960
  # Fallback: read from context tracking if efficiency files have no token data
7953
- if total_input == 0 and total_output == 0:
7961
+ if total_input == 0 and total_output == 0 and not unmeasured_sessions:
7954
7962
  ctx_file = loki_dir / "context" / "tracking.json"
7955
7963
  if ctx_file.exists():
7956
7964
  try:
@@ -8023,25 +8031,26 @@ def _compute_cost_snapshot() -> dict:
8023
8031
  # set of measured records that genuinely sums to zero still renders 0.0 --
8024
8032
  # the direction that would otherwise blank real data (the v8.72.0 trap).
8025
8033
  return {
8026
- "total_input_tokens": total_input if cost_recorded else None,
8027
- "total_output_tokens": total_output if cost_recorded else None,
8028
- "total_cache_read_tokens": total_cache_read if cost_recorded else None,
8029
- "total_cache_creation_tokens": total_cache_creation if cost_recorded else None,
8034
+ **({"unmeasured_sessions": unmeasured_sessions} if unmeasured_sessions else {}),
8035
+ "total_input_tokens": total_input if cost_recorded and not unmeasured_sessions else None,
8036
+ "total_output_tokens": total_output if cost_recorded and not unmeasured_sessions else None,
8037
+ "total_cache_read_tokens": total_cache_read if cost_recorded and not unmeasured_sessions else None,
8038
+ "total_cache_creation_tokens": total_cache_creation if cost_recorded and not unmeasured_sessions else None,
8030
8039
  "total_tokens": (
8031
8040
  total_input + total_output + total_cache_read + total_cache_creation
8032
- ) if cost_recorded else None,
8041
+ ) if cost_recorded and not unmeasured_sessions else None,
8033
8042
  "cache_hit_ratio": round(total_cache_read / _read_in, 4) if _read_in > 0 else None,
8034
- "estimated_cost_usd": round(estimated_cost, 6) if cost_recorded and not cost_unknown else None,
8043
+ "estimated_cost_usd": round(estimated_cost, 6) if cost_recorded and not cost_unknown and not unmeasured_sessions else None,
8035
8044
  "cost_recorded": cost_recorded,
8036
8045
  "by_phase": {k: {
8037
- "input_tokens": v["input_tokens"] if v.get("tokens_measured") else None,
8038
- "output_tokens": v["output_tokens"] if v.get("tokens_measured") else None,
8039
- "cost_usd": round(v["cost_usd"], 6) if v.get("measured") else None,
8046
+ "input_tokens": v["input_tokens"] if v.get("tokens_measured") and not v.get("unmeasured") else None,
8047
+ "output_tokens": v["output_tokens"] if v.get("tokens_measured") and not v.get("unmeasured") else None,
8048
+ "cost_usd": round(v["cost_usd"], 6) if v.get("measured") and not v.get("unmeasured") else None,
8040
8049
  } for k, v in by_phase.items()},
8041
8050
  "by_model": {k: {
8042
- "input_tokens": v["input_tokens"] if v.get("tokens_measured") else None,
8043
- "output_tokens": v["output_tokens"] if v.get("tokens_measured") else None,
8044
- "cost_usd": round(v["cost_usd"], 6) if v.get("measured") else None,
8051
+ "input_tokens": v["input_tokens"] if v.get("tokens_measured") and not v.get("unmeasured") else None,
8052
+ "output_tokens": v["output_tokens"] if v.get("tokens_measured") and not v.get("unmeasured") else None,
8053
+ "cost_usd": round(v["cost_usd"], 6) if v.get("measured") and not v.get("unmeasured") else None,
8045
8054
  } for k, v in by_model.items()},
8046
8055
  "budget_limit": budget_limit,
8047
8056
  "budget_used": round(budget_used, 6) if budget_limit is not None and budget_used is not None else None,
@@ -8565,11 +8574,11 @@ async def get_gate_policy():
8565
8574
  # =============================================================================
8566
8575
 
8567
8576
  _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",
8577
+ # v7.104.0: current model IDs (model_catalog.json): opus, sonnet (the default execution model), haiku: ids live in
8578
+ # the catalog cli_aliases, not here.
8579
+ "opus": "Opus 5.5",
8580
+ "sonnet": "Sonnet 5.5",
8581
+ "haiku": "Haiku 5.5",
8573
8582
  "gpt-5.3-codex": "GPT-5.3 Codex",
8574
8583
  "gpt-5.6-sol": "GPT-5.6 Sol",
8575
8584
  "gpt-5.6-terra": "GPT-5.6 Terra",
@@ -8580,18 +8589,11 @@ _PROVIDER_LABELS = {
8580
8589
  # the UI WITHOUT changing any computed cost number. The Sonnet 5 intro price
8581
8590
  # ($2/$10 per MTok) became the standard price, so the 2026-09-01 increase to
8582
8591
  # $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
8592
  _MODEL_PRICING_NOTES = {
8587
8593
  "sonnet": (
8588
8594
  "Standard pricing: $2 / $10 per MTok. "
8589
8595
  "The intro price became the standard price; no increase to $3 / $15."
8590
8596
  ),
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
8597
  }
8596
8598
 
8597
8599
  _MODEL_PROVIDERS = {
@@ -13,8 +13,8 @@ An Agent Change Receipt is the JSON file a Loki 10 run seals at `.loki/runs/<run
13
13
  - `not_proven`: list of strings naming what the run did not prove.
14
14
  - `verdict`: one of `VERIFIED`, `PARTIAL`, `ALREADY_SATISFIED`, `SPEC_CONFLICT`, `FAILED` (`types.ts:44`).
15
15
  - `evidence`: list of strings (search hits and citation for an ALREADY_SATISFIED verdict).
16
- - `cost`: `{ usd (number or null), input_tokens, output_tokens, measured_sessions, total_sessions, partial_usd, source? }`.
17
- - `time`: `{ wall_s, stages }`.
16
+ - `cost`: `{ usd (number or null), input_tokens, output_tokens, cache_read_tokens?, cache_creation_tokens?, sdk_duration_ms?, measured_sessions, total_sessions, partial_usd, source? }`.
17
+ - `time`: `{ wall_s, total_s?, stages, stage_s? }`. `stages` is a disjoint partition of `total_s`: `setup` (first event to machine start), each stage, a parallel group as one bucket (for example `plan+wall`), `orchestration` gaps and `seal`, so a consumer may simply add them. `stage_s` holds each stage's own seconds (parallel members overlap, so they can add to more than their bucket). `wall_s` is the stage buckets without setup, orchestration and seal. `total_s` is elapsed seconds from the run's first event to seal (PR stage excluded); treat it as NOT RECORDED unless every bucket is a non-negative number and they sum to it within 1%. `total_s`, `stage_s` and the cache token keys are additive: older receipts omit them, which reads NOT RECORDED, never 0.
18
18
  - `events_sha256`: digest of the run event log.
19
19
  - `receipt_sha256`: sha256 of the canonical JSON with `verification` and `receipt_sha256` removed (`loki-ts/src/engine10/verify_cmd.ts:19`).
20
20
  - `verification`: `{ jwt, kid }`. `jwt` is a compact EdDSA (Ed25519) token binding the receipt hash; both are null when the receipt is unsigned (`stages/seal.ts:92-95`).
@@ -0,0 +1,337 @@
1
+ # Architecture
2
+
3
+ Loki Mode is the flagship product of [Autonomi](https://www.autonomi.dev/): an
4
+ autonomous spec-to-product system. It accepts any spec source (a PRD, a GitHub
5
+ issue, an OpenAPI/JSON/YAML document, or a one-line brief) and drives it to a
6
+ verified, deployable product through the RARV-C closure loop, with minimal human
7
+ intervention. This document describes the system at a level above the code: how
8
+ the major pieces fit together, how data flows through a build, and the design
9
+ decisions that shaped the current structure.
10
+
11
+
12
+ ## System Overview
13
+
14
+ At its core, Loki Mode is an autonomous orchestration engine wrapped in a trust
15
+ layer. The orchestrator runs iterative RARV cycles (Reason, Act, Reflect,
16
+ Verify) against a provider CLI, and a closure stage (the "C" in RARV-C) refuses
17
+ to declare work "done" until deterministic evidence supports the claim. Eight
18
+ quality gates, a blind multi-reviewer council, and a verified-completion
19
+ evidence gate stand between an in-progress build and a "complete" verdict.
20
+
21
+ The system is built around a few load-bearing principles:
22
+
23
+ - **Verified completion over claimed completion.** A build is not done because
24
+ the model says so. It is done when the git diff is non-empty against the
25
+ run-start commit, tests recorded a real command and exited zero, and no gate
26
+ was skipped. Every build emits an Evidence Receipt that a skeptic can
27
+ re-derive independently.
28
+ - **Provider-agnostic execution.** The same workflow runs on Claude Code,
29
+ OpenAI Codex CLI, Cline, and Aider, with automatic failover. Feature richness
30
+ degrades gracefully by provider tier rather than failing.
31
+ - **Filesystem as the system bus.** Components do not share memory. They
32
+ communicate through `.loki/` state files (session, queue, checkpoints,
33
+ findings, memory), which makes the system inspectable, resumable, and
34
+ crash-tolerant.
35
+ - **Progressive disclosure.** A slim core skill loads on-demand modules and
36
+ detailed references only when a task needs them, keeping the working context
37
+ small.
38
+ - **Dual runtime, single behavior.** A modern Bun/TypeScript runner is the
39
+ default path; a legacy Bash route remains as a verified-parity fallback. Both
40
+ routes must produce byte-identical behavior, enforced by a parity matrix.
41
+
42
+ ## High-Level Design
43
+
44
+ A build proceeds through these stages:
45
+
46
+ 1. **Ingest and classify.** A spec enters via `loki start`. The orchestrator
47
+ detects project complexity and selects a RARV tier (which maps iterations to
48
+ model strength: Opus for planning, Sonnet for development, Haiku for cheap
49
+ parallel work).
50
+ 2. **Plan.** An architect pass produces a plan. Scope is locked, and a checklist
51
+ is derived from the spec.
52
+ 3. **Iterate (RARV).** Each iteration builds a prompt (injecting RARV
53
+ instructions, SDLC phase, memory context, queued tasks, and checklist
54
+ status), invokes the provider, then runs checklist verification, app-runner
55
+ management, and smoke tests.
56
+ 4. **Review.** A blind 3-reviewer council reviews the diff. Critical/High
57
+ findings block; an override council can contest a BLOCK when backed by
58
+ evidence.
59
+ 5. **Close (the "C").** Findings are injected into the next iteration, learnings
60
+ are written to memory, and a handoff document is produced.
61
+ 6. **Verify completion.** A completion council votes on whether the work is
62
+ actually done. The verified-completion evidence gate computes the Evidence
63
+ Receipt headline (VERIFIED / VERIFIED WITH GAPS / NOT VERIFIED) from
64
+ deterministic facts only.
65
+ 7. **Deliver.** The output is a Git repository with source, tests, configs,
66
+ audit logs, and a re-checkable Evidence Receipt.
67
+
68
+ The orchestration logic lives in two parallel implementations. The TypeScript
69
+ runner (`loki-ts/src/runner/`) is the default; the Bash engine
70
+ (`autonomy/run.sh`) is the legacy fallback. Both are driven by the CLI
71
+ (`autonomy/loki`).
72
+
73
+ ## Component Diagram
74
+
75
+ ```
76
+ +------------------------------+
77
+ | User / CI / MCP client |
78
+ | spec: PRD | issue | OpenAPI |
79
+ +---------------+--------------+
80
+ |
81
+ +-----------------------+-----------------------+
82
+ | | |
83
+ loki CLI MCP server REST API
84
+ (autonomy/loki) (mcp/server.py) (api/server.ts)
85
+ | | |
86
+ +-----------+-----------+-----------+-----------+
87
+ | |
88
+ v v
89
+ +---------------------------+ +-------------------+
90
+ | Orchestration Engine | | Dashboard |
91
+ | | | (dashboard/ |
92
+ | default: loki-ts/runner | | server.py + |
93
+ | legacy: autonomy/run.sh | | API only) |
94
+ | | +---------+---------+
95
+ | RARV-C loop: | |
96
+ | build_prompt -> provider| |
97
+ | -> reflect -> verify | |
98
+ | -> council -> close | |
99
+ +-----+-------+-------+-----+ |
100
+ | | | |
101
+ +------------+ +---+---+ +--------+ |
102
+ | | | | |
103
+ v v v v |
104
+ +---------------+ +-----------+ +---------+ +----------+ |
105
+ | Providers | | Quality | | Memory | | Events | |
106
+ | claude/codex/ | | Gates + | | engine | | bus |<+
107
+ | cline/aider | | Council | | (RAG, | | (py/ts/ |
108
+ | (failover) | | (8 gates) | | vector) | | sh) |
109
+ +-------+-------+ +-----------+ +----+----+ +----------+
110
+ | |
111
+ v v
112
+ +---------------+ +-----------------+
113
+ | Provider CLI | | .loki/ state |
114
+ | (model calls) | | session, queue, |
115
+ +---------------+ | checkpoints, |
116
+ | memory, findings|
117
+ | (system bus) |
118
+ +-----------------+
119
+ ```
120
+
121
+ All long-lived coordination flows through `.loki/` on the filesystem. The three
122
+ entry surfaces (CLI, MCP, REST API) and the dashboard all read and write the
123
+ same state, which is what makes runs resumable and independently verifiable.
124
+
125
+ ## Data Flow
126
+
127
+ A representative end-to-end flow:
128
+
129
+ 1. **Entry.** `loki start ./prd.md` (CLI dispatch in `autonomy/loki`) resolves
130
+ the provider and execs the orchestration engine. The TS runner
131
+ (`loki-ts/src/runner/autonomous.ts`) is default; `LOKI_LEGACY_BASH=1` selects
132
+ `autonomy/run.sh`.
133
+ 2. **Complexity and tier.** The engine detects complexity and maps the iteration
134
+ to a model tier (`rarv.ts` / `run.sh:get_rarv_tier`).
135
+ 3. **Prompt construction.** `build_prompt.ts` (`run.sh:build_prompt`) assembles
136
+ the iteration prompt: RARV instructions, SDLC phase, retrieved memory context
137
+ (`memory/retrieval.py` via the RAG injector), queued tasks, and checklist
138
+ status.
139
+ 4. **Provider invocation.** The prompt is dispatched to the selected provider
140
+ (`providers.ts`). Claude Code runs with full features (subagents, parallel
141
+ worktrees, Task tool, MCP); Codex/Cline/Aider run in degraded, sequential
142
+ modes. Failures trigger failover to the next available provider.
143
+ 5. **Reflect and verify.** Post-iteration, the engine runs checklist
144
+ verification (`autonomy/checklist-verify.py`), manages the app runner
145
+ (`autonomy/app-runner.sh`), and runs Playwright smoke tests.
146
+ 6. **Review.** `quality_gates.ts` (`run.sh:run_code_review`) runs the 8 gates and
147
+ the blind 3-reviewer council (`loki-ts/src/council/voter_agents.ts`). Findings
148
+ are scored; Critical/High block. An override council can lift a BLOCK only
149
+ when a non-empty evidence artifact backs a trusted proof type.
150
+ 7. **Close.** Structured findings are persisted
151
+ (`.loki/state/findings-<iter>.json`) and injected into the next iteration
152
+ (`findings_injector.ts`); learnings are written (`learnings_writer.ts`); a
153
+ handoff doc is emitted (`escalation_handoff.ts`).
154
+ 8. **Completion decision.** The completion council
155
+ (`autonomy/completion-council.sh:council_should_stop`) votes. Independently,
156
+ the verified-completion evidence gate computes the Evidence Receipt from
157
+ deterministic facts (diff SHAs and counts, test/build commands and exit
158
+ codes, per-gate verdicts) and assessments (council judgment), and derives the
159
+ headline from facts alone.
160
+ 9. **Persistence and events.** State is checkpointed throughout
161
+ (`checkpoint.ts`); episodes are stored to memory (`episode_bridge.ts`); the
162
+ event bus (`events/bus.{py,ts}`, `events/emit.sh`) broadcasts progress to the
163
+ dashboard and any subscribers. The dashboard reads `.loki/` and the event
164
+ stream over WebSocket.
165
+
166
+ Crash recovery and resume work because every meaningful step lands in `.loki/`.
167
+ A killed run can be resumed from its last checkpoint; durable-state mode
168
+ (`LOKI_DURABLE_STATE=1`) extends this to run-to-completion k8s Jobs with
169
+ crash-resume and an exit-code contract.
170
+
171
+ ## Directory Structure
172
+
173
+ ```
174
+ autonomy/ Runtime and orchestration (legacy + shared shell)
175
+ loki CLI: command dispatch, ~100 cmd_ functions
176
+ run.sh Legacy Bash orchestration engine (RARV loop)
177
+ completion-council.sh Completion detection via council voting
178
+ council-v2.sh Reviewer council (v2)
179
+ app-runner.sh Builds, runs, and health-checks the generated app
180
+ checklist-verify.py Per-iteration checklist verification
181
+ context-tracker.py Context-window usage tracking
182
+ hooks/ Lifecycle hooks (quality gate, healing, episode store)
183
+ lib/ Shared helpers: proof generation/verify, crash
184
+ capture/redact, launch-kit, secure-scan, trust metrics,
185
+ wiki generation, MCP config
186
+
187
+ loki-ts/ Default Bun/TypeScript runtime
188
+ src/cli.ts TS CLI entry
189
+ src/runner/ RARV-C loop: autonomous, build_prompt, rarv, council,
190
+ quality_gates, completion, findings_injector,
191
+ learnings_writer, proof, checkpoint, providers, state
192
+ src/council/ Voter agents and finding schema
193
+ src/providers/ Provider flag/config helpers (claude, mcp config)
194
+ src/commands/ Subcommands: doctor, status, memory, trust, wiki, ...
195
+ src/metrics/ Efficiency and reward metrics
196
+
197
+ providers/ Provider configs (shell-sourceable)
198
+ claude.sh Claude Code - Tier 1 (full features)
199
+ cline.sh Cline - Tier 2
200
+ codex.sh / aider.sh Codex / Aider - Tier 3 (degraded, sequential)
201
+ loader.sh / models.sh Provider loader and model registry
202
+ model_catalog.json Model catalog (probed)
203
+
204
+ memory/ Memory system (Python package, ~19 modules)
205
+ engine.py Memory orchestrator
206
+ schemas.py / storage.py Pydantic schemas; file-based backend
207
+ retrieval.py Task-aware retrieval
208
+ consolidation.py Episodic-to-semantic pipeline
209
+ embeddings.py Vector embeddings (optional)
210
+ vector_index.py Vector search index
211
+ cross_project.py Cross-project knowledge transfer
212
+ rag_injector.py RAG context injection into prompts
213
+ knowledge_graph.py Knowledge graph over memories
214
+ layers/ Progressive-disclosure loading
215
+
216
+ mcp/ Model Context Protocol server
217
+ server.py MCP server (tools + resources + prompts)
218
+ tools.py / magic_tools.py / managed_tools.py Tool registries
219
+ resources.py MCP resources
220
+ lsp_proxy.py LSP proxy (references, definitions, symbols)
221
+
222
+ dashboard/ FastAPI control-plane backend
223
+ server.py 100+ endpoints, WebSocket event stream
224
+ control.py / auth.py Run control and authentication
225
+ database.py / audit.py Persistence and audit logging
226
+ packages/control-plane/ Control Plane: browser UI and service (Bun)
227
+
228
+ web-app/ Web surface (FastAPI + built dist) for browser PRD input
229
+
230
+ api/ REST API (TypeScript/Deno-style)
231
+ server.ts / mod.ts Server entry and module map
232
+ routes/ events, health, learning, memory, sessions, tasks
233
+ services/ cli-bridge, event-bus, learning-collector, state-*
234
+ middleware/ auth, cors, error, timing
235
+
236
+ events/ Unified event bus (py + ts + sh emitter)
237
+
238
+ skills/ On-demand skill modules (progressive disclosure)
239
+ 00-index.md Module selection and routing
240
+ quality-gates.md The 8-gate system (canonical)
241
+ healing.md / testing.md / production.md / providers.md / agents.md / ...
242
+
243
+ references/ Detailed documentation (~24 files): research patterns,
244
+ agent types, SDLC phases, deployment, MCP, memory
245
+
246
+ templates/ 21 PRD templates (saas, cli, discord-bot, ...)
247
+ agents/ Agent registry: types.json, hub install, managed registry
248
+ benchmarks/ SWE-bench and HumanEval harnesses
249
+ plugins/ Claude Code plugin packaging
250
+ .github/workflows/ CI: tests, release, sbom,
251
+ security-audit, post-release-smoke, ...
252
+ SKILL.md Slim core skill (progressive disclosure entry)
253
+ CLAUDE.md Project + agent operating instructions
254
+ VERSION / package.json Single source of version truth
255
+ docker/ Container distribution (Dockerfiles, compose)
256
+ ```
257
+
258
+ ## Key Design Decisions
259
+
260
+ - **Verified completion as the product, not a feature.** The Evidence Receipt
261
+ splits deterministic *facts* (diff, test/build exit codes, gate verdicts) from
262
+ AI *assessments* (council judgment) and computes the green/amber/red headline
263
+ from facts alone. This is a deliberate stance against transcript-narrated
264
+ "done." It guarantees a "complete" verdict is independently re-checkable, not a
265
+ promise.
266
+
267
+ - **Dual runtime with enforced parity.** Rather than a risky big-bang migration,
268
+ the modern Bun/TS runner runs as the default while the Bash engine remains a
269
+ fallback. Parity suites under `tests/` check identical
270
+ behavior across both routes; there is no continuous parity CI workflow.
271
+
272
+ - **Filesystem state bus over in-process coupling.** Coordination through
273
+ `.loki/` files (rather than shared memory or a message broker) buys
274
+ inspectability, crash-resume, and the ability for three independent entry
275
+ surfaces (CLI, MCP, REST) plus the dashboard to observe and drive the same run.
276
+
277
+ - **Provider tiering with graceful degradation.** Provider capability is encoded
278
+ as tiers (full -> reduced -> sequential) instead of hard requirements. A weaker
279
+ provider loses parallelism and the Task tool but still completes the workflow,
280
+ preserving "no vendor lock-in" as a real property.
281
+
282
+ - **Model-tier selection by task, not by knob.** Opus is reserved for planning
283
+ and architecture, Sonnet for implementation, Haiku for cheap parallel work.
284
+ The tier is auto-selected from task signals; explicit knobs exist only as
285
+ opt-out escape hatches.
286
+
287
+ - **Council and override council for trust under uncertainty.** A blind
288
+ 3-reviewer council must reach consensus; a separate override council can only
289
+ lift a BLOCK when a non-empty evidence artifact backs a trusted proof type.
290
+ This prevents a confident-but-wrong verdict from silently shipping.
291
+
292
+ - **Progressive disclosure of instructions.** A slim `SKILL.md` plus on-demand
293
+ `skills/` modules and `references/` keeps the orchestrator's working context
294
+ focused, loading deep documentation only when a task requires it.
295
+
296
+ - **Memory as a cross-project asset.** Episodic, semantic, and procedural memory
297
+ with optional vector search and RAG injection means lessons learned on one
298
+ build surface on the next, with token-economics tracking to keep retrieval
299
+ cheap.
300
+
301
+ - **Closure loop (RARV-C) wiring.** Findings injection, override council,
302
+ auto-learnings, and structured handoff are wired together (gated by
303
+ `LOKI_INJECT_FINDINGS`, `LOKI_OVERRIDE_COUNCIL`, `LOKI_AUTO_LEARNINGS`,
304
+ `LOKI_HANDOFF_MD`) so each iteration closes on the last instead of starting
305
+ cold.
306
+
307
+ ## Technology Choices
308
+
309
+ - **Bun + TypeScript** for the default runtime (`loki-ts/`). Fast startup, a
310
+ single bundled binary path, and strong typing for the orchestration core.
311
+ - **Bash** for the legacy engine (`autonomy/run.sh`, `autonomy/loki`) and shared
312
+ shell helpers. Retained as a verified-parity fallback and for the broadest
313
+ host portability.
314
+ - **Python** for the memory system, the MCP server, the dashboard backend, and
315
+ numerous lib helpers (proof generation/verification, crash capture/redaction,
316
+ secure scanning, wiki generation). Chosen for its data and ML ecosystem
317
+ (Pydantic schemas, optional sentence-transformers embeddings, FastAPI).
318
+ - **FastAPI** for the dashboard control plane and web surface, with a WebSocket
319
+ event stream for live run telemetry.
320
+ - **Vite + Playwright** for the Control Plane UI (`packages/control-plane/ui`): a
321
+ lightweight build and end-to-end browser tests.
322
+ - **Model Context Protocol (MCP)** as a first-class integration surface
323
+ (`mcp/server.py`): tools, resources, and prompts, plus an LSP proxy for
324
+ code intelligence (references, definitions, symbols).
325
+ - **Provider CLIs** (Claude Code, OpenAI Codex CLI, Cline, Aider) as the model
326
+ execution layer, abstracted behind shell-sourceable provider configs and the
327
+ TS providers module.
328
+ - **Docker / Docker Compose** for distribution and for the multi-service,
329
+ 12-factor stacks Loki generates (web + database + cache with healthchecks).
330
+ - **GitHub Actions** for CI/CD: test suites, SBOM and security audits,
331
+ multi-channel release (npm, Docker, Homebrew), and post-release smoke tests.
332
+
333
+ ---
334
+
335
+ For deeper detail, see `SKILL.md` (core skill), `skills/quality-gates.md` (the
336
+ canonical 8-gate table), `skills/sdlc-fleet.md` (the standing SDLC fleet
337
+ pattern), and the `references/` directory.
@@ -0,0 +1,124 @@
1
+ # Branding: Loki (the agent) by Autonomi (the company)
2
+
3
+ Authoritative naming reference. Founder directive 2026-06-12. Consult this
4
+ before naming any product, doc heading, marketing surface, CLI string, or
5
+ release note. When in doubt, this file wins.
6
+
7
+ ## The one rule
8
+
9
+ **Loki Mode is the agent / brand ambassador. Autonomi is the company and the
10
+ name on everything commercial.**
11
+
12
+ **CRITICAL: this is a BRANDING distinction only. Nothing technical changes
13
+ between free and paid.** The same software, CLI, SDK, MCP server, agent, and
14
+ code ship to free OSS users and to paid/enterprise/cloud users. Loki is the CLI,
15
+ the SDK, the MCP server, the agent - for everyone. The ONLY difference is the
16
+ brand label on the *offering*: an OSS/free user runs "Loki Mode"; a paying
17
+ team/enterprise buys the same thing under the "Autonomi" brand (Autonomi Cloud,
18
+ Autonomi Enterprise). There is no separate "enterprise build" or "cloud fork" of
19
+ the engine - it is one product, two brand labels chosen by audience. Do NOT
20
+ rename, fork, gate, or technically diverge anything; only relabel the commercial
21
+ *presentation*.
22
+
23
+ The relationship is the industry pattern of "named assistant, by company":
24
+ - Alexa by Amazon
25
+ - Copilot by GitHub
26
+ - Watson by IBM
27
+ - Gemini by Google
28
+ - Ellie by Entelligence
29
+ - **Loki by Autonomi**
30
+
31
+ Loki is *who you talk to and what you run*. Autonomi is *who you pay and who
32
+ stands behind the enterprise/cloud product*. The chat box on autonomi.dev is
33
+ "chat with Loki." The invoice says Autonomi.
34
+
35
+ ## What is called "Loki Mode" (the agent / free / OSS)
36
+
37
+ Everything free, source-available, OSS, and developer-facing keeps the **Loki**
38
+ name:
39
+ - The CLI: `loki` (binary), "Loki Mode" (product name of the OSS tool).
40
+ - The SDK(s): "Loki SDK".
41
+ - The local dashboard / web app (runs on the user's machine): "Loki Mode dashboard".
42
+ - The agent persona / chat: "Loki" (the thing users converse with, everywhere -
43
+ including inside Autonomi Cloud and on autonomi.dev).
44
+ - The npm package `loki-mode`, the Docker image `asklokesh/loki-mode`, the
45
+ Homebrew formula, the MCP server `io.github.asklokesh/loki-mode` - all KEEP
46
+ their identifiers (renaming published artifact IDs breaks installs; do NOT
47
+ rename them).
48
+ - The benchmarks, the RARV/council engine, the memory system - the *technology*
49
+ is Loki.
50
+
51
+ ## What is called "Autonomi" (the company / commercial / paid)
52
+
53
+ Everything commercial, hosted, paid, or enterprise wears the **Autonomi** brand:
54
+ - **Autonomi** - the company (autonomi.dev).
55
+ - **Autonomi Cloud** - the hosted/SaaS surface (was/never "Loki Cloud").
56
+ - **Autonomi Enterprise** - the enterprise offering (SSO, RBAC, audit, SLAs).
57
+ - **Autonomi** (VaaS) - the hosted Verification-as-a-Service product (the
58
+ ~/loki-vaas scaffold's *product* name is Autonomi-branded; the engine is Loki).
59
+ - Any paid tier, support plan, or commercial license: Autonomi.
60
+
61
+ Each commercial product carries a **"powered by Loki"** (or "runs Loki" /
62
+ "built on Loki") attribution so the engine lineage stays visible - the Copilot/
63
+ GPT pattern. Example: "Autonomi Cloud, powered by Loki."
64
+
65
+ ## Mapping table (rename these going forward)
66
+
67
+ | Old / ambiguous | New | Notes |
68
+ |---|---|---|
69
+ | Loki Cloud | **Autonomi Cloud** (powered by Loki) | commercial hosted |
70
+ | Loki Enterprise (as a *product/offering* name) | **Autonomi Enterprise** (powered by Loki) | the paid offering |
71
+ | Loki VaaS / Loki Verification Cloud | **Autonomi Verify** (VaaS), powered by Loki | ~/loki-vaas product brand (renamed 2026-06-12) |
72
+ | "Loki, the company" | **Autonomi** | the company is Autonomi |
73
+ | Loki SaaS / Loki Pro / Loki Business | **Autonomi Cloud** / **Autonomi Enterprise** | no paid tier wears "Loki" |
74
+ | Loki Mode (the CLI/SDK/agent) | **Loki Mode** (unchanged) | the agent keeps its name |
75
+ | `loki` CLI binary | `loki` (unchanged) | never rename the binary |
76
+
77
+ ## Tricky cases (decided)
78
+
79
+ 1. **The `loki enterprise` CLI subcommand** (`loki enterprise token …`, `loki
80
+ enterprise audit …`): the COMMAND stays `loki enterprise` for backward
81
+ compatibility (renaming breaks every user/script). It is the Loki CLI's
82
+ gateway to enterprise *features*. But in PROSE / docs / marketing, the
83
+ enterprise *offering* it unlocks is branded "Autonomi Enterprise." So:
84
+ command = `loki enterprise`; product = Autonomi Enterprise. Doc pattern:
85
+ "Use `loki enterprise` to manage your **Autonomi Enterprise** license."
86
+ (A future `autonomi` alias for the command MAY be added as a superset, but
87
+ `loki enterprise` is never removed.)
88
+
89
+ 2. **Published artifact IDs** (npm `loki-mode`, Docker `asklokesh/loki-mode`,
90
+ brew `loki-mode`, MCP `io.github.asklokesh/loki-mode`): KEEP. These are
91
+ install identifiers; the brand on the *page* can say "Loki Mode (by
92
+ Autonomi)" but the package name does not change. Renaming = broken installs.
93
+
94
+ 3. **The dashboard/web-app chat**: the agent in the chat box is "Loki"
95
+ everywhere - in the OSS dashboard AND inside Autonomi Cloud. The container
96
+ product (local dashboard = Loki Mode dashboard; hosted = Autonomi Cloud) is
97
+ what changes, not the agent's name.
98
+
99
+ 4. **autonomi.dev website**: company + commercial = Autonomi branding; the
100
+ product you download is "Loki Mode"; the assistant is "Loki". The hero can be
101
+ "Autonomi - autonomous software delivery, powered by Loki" with a "Download
102
+ Loki Mode (free)" CTA and a "Autonomi Cloud / Enterprise" commercial CTA.
103
+
104
+ 5. **License/legal**: BUSL-1.1 is held by Autonomi; "Free for personal/internal/
105
+ academic use" applies to Loki Mode (source-available); commercial licensing = Autonomi.
106
+ Keep "source-available," never "open source" (BUSL is not OSI-approved).
107
+
108
+ ## Taglines (approved patterns)
109
+
110
+ - "Loki Mode - the autonomous coding agent. Free and source-available."
111
+ - "Autonomi - autonomous software delivery for teams and enterprises. Powered by Loki."
112
+ - "Autonomi Cloud - hosted Loki, managed for your team."
113
+ - "Autonomi Enterprise - Loki with SSO, RBAC, audit, and SLAs."
114
+ - "Chat with Loki." (the assistant, anywhere)
115
+
116
+ ## Going forward
117
+
118
+ Any new product, page, heading, or release note must place itself on the correct
119
+ side of this line:
120
+ - Free / OSS / CLI / SDK / agent / chat -> **Loki Mode** / **Loki**.
121
+ - Paid / hosted / cloud / enterprise / company -> **Autonomi** (+ "powered by Loki").
122
+
123
+ Update this file if the founder revises the rule; this file is the single source
124
+ of truth for naming.