loki-mode 11.74.2 → 11.75.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 (167) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +2 -3
  3. package/VERSION +1 -1
  4. package/autonomy/completion-council.sh +10 -10
  5. package/autonomy/council-v2.sh +4 -4
  6. package/autonomy/grill.sh +1 -1
  7. package/autonomy/lib/ablation.py +22 -2
  8. package/autonomy/lib/browser-open.sh +1 -1
  9. package/autonomy/lib/chat.sh +1 -1
  10. package/autonomy/lib/cockpit-render.sh +1 -1
  11. package/autonomy/lib/done-recognition.sh +4 -4
  12. package/autonomy/lib/efficiency_cost.py +1 -1
  13. package/autonomy/lib/engine10-push.sh +2 -2
  14. package/autonomy/lib/prd-enrich.sh +1 -1
  15. package/autonomy/lib/proof-check.sh +1 -1
  16. package/autonomy/lib/proof-generator.py +3 -3
  17. package/autonomy/lib/proof-pr.sh +1 -1
  18. package/autonomy/lib/skill-link-heal.sh +1 -1
  19. package/autonomy/lib/voter-agents.sh +1 -1
  20. package/autonomy/loki +26 -37
  21. package/autonomy/prd-checklist.sh +1 -1
  22. package/autonomy/receipt_jwt.py +1 -1
  23. package/autonomy/run.sh +28 -28
  24. package/autonomy/trigger-schedule.py +6 -414
  25. package/autonomy/tui.sh +1 -1
  26. package/autonomy/verify.sh +4 -4
  27. package/completions/loki.bash +0 -5
  28. package/dashboard/__init__.py +1 -1
  29. package/docs/ARCHITECTURE.md +1 -2
  30. package/docs/CLI-REFERENCE.md +1 -1
  31. package/docs/COMPONENTS.md +1 -1
  32. package/docs/INSTALLATION.md +1 -1
  33. package/docs/ROUTING-EVIDENCE.md +1 -2
  34. package/docs/V10-RESEARCH.md +1 -1
  35. package/docs/dev/architecture-reference.md +3 -7
  36. package/docs/dev/project-structure.md +1 -4
  37. package/docs/dev/release-checklist.md +13 -31
  38. package/docs/research-2026-07/OBSERVABILITY-TOOL-SPEC.md +1 -1
  39. package/docs/v11/MARKET-SLICES.md +1 -1
  40. package/docs/v11/REGISTRIES.md +1 -1
  41. package/docs/v11/ROUTER-1.md +2 -2
  42. package/loki-ts/dist/loki.js +2 -2
  43. package/mcp/__init__.py +1 -1
  44. package/package.json +2 -2
  45. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  46. package/skills/extending.md +2 -3
  47. package/skills/factory-operations.md +11 -18
  48. package/skills/release-cadence.md +2 -2
  49. package/web-app/dist/assets/{AdminPage-jkjilfbl.js → AdminPage-CTwi8SUX.js} +1 -1
  50. package/web-app/dist/assets/{Avatar-bd5JWkSJ.js → Avatar-DVtGtLkJ.js} +1 -1
  51. package/web-app/dist/assets/{Badge-DVRit2Xw.js → Badge-rwKzz0Pe.js} +1 -1
  52. package/web-app/dist/assets/{Button-BNAB-pVZ.js → Button-nIsPDfsQ.js} +1 -1
  53. package/web-app/dist/assets/{CockpitPage-DpG29h_w.js → CockpitPage-BCeDpoWa.js} +1 -1
  54. package/web-app/dist/assets/{ComparePage-Dasg5V41.js → ComparePage-CYIYanVq.js} +1 -1
  55. package/web-app/dist/assets/{ErrorBoundary-DJojse6b.js → ErrorBoundary-Bkz6HqWp.js} +1 -1
  56. package/web-app/dist/assets/{EvidenceReceiptPanel-Blxw7_u1.js → EvidenceReceiptPanel-DZT2Np4F.js} +1 -1
  57. package/web-app/dist/assets/{GitHubIssuesPanel-BBvSFj80.js → GitHubIssuesPanel-Bzla91Lu.js} +1 -1
  58. package/web-app/dist/assets/{GitHubPRsPanel-BCIKeSBg.js → GitHubPRsPanel-FjT-Xn5t.js} +1 -1
  59. package/web-app/dist/assets/{HomePage-C7d__oNG.js → HomePage-pXgmRGLt.js} +2 -2
  60. package/web-app/dist/assets/{LoginPage-BXljL3yY.js → LoginPage-CnmpE28B.js} +1 -1
  61. package/web-app/dist/assets/{MagicPage-Xjkts_yE.js → MagicPage-CuSeGsLq.js} +1 -1
  62. package/web-app/dist/assets/{MetricsPage-kQvVp-j2.js → MetricsPage-Bg3PkBOU.js} +1 -1
  63. package/web-app/dist/assets/{NotFoundPage-D-4ZlEaO.js → NotFoundPage-uzBtZNV-.js} +1 -1
  64. package/web-app/dist/assets/{ProjectPage-DfzR5RXP.js → ProjectPage-Dacki8Xr.js} +3 -3
  65. package/web-app/dist/assets/{ProjectsPage-DFDsWzkV.js → ProjectsPage-BRGjksXG.js} +1 -1
  66. package/web-app/dist/assets/{SettingsPage-CLPIoYT3.js → SettingsPage-BbNf3fEJ.js} +1 -1
  67. package/web-app/dist/assets/{ShowcasePage-PZKkyGeY.js → ShowcasePage-XX4830sX.js} +1 -1
  68. package/web-app/dist/assets/{SystemSettingsPage-BsBlcnzo.js → SystemSettingsPage-DOhQeXa6.js} +1 -1
  69. package/web-app/dist/assets/{TeamsPage-BSjgNhoU.js → TeamsPage-2reIRUp_.js} +1 -1
  70. package/web-app/dist/assets/{TemplatesPage-W2KeAzbg.js → TemplatesPage-BUsLEWHW.js} +1 -1
  71. package/web-app/dist/assets/{TerminalOutput-BjroTiCC.js → TerminalOutput-BrBDcgzC.js} +1 -1
  72. package/web-app/dist/assets/{activity-BXZ5YYes.js → activity-B6AZpgmb.js} +1 -1
  73. package/web-app/dist/assets/{bell-D1urp5pa.js → bell-CB792A7S.js} +1 -1
  74. package/web-app/dist/assets/{bot-Chedf2bF.js → bot-uQZwOFAn.js} +1 -1
  75. package/web-app/dist/assets/{check-DhaCuOCV.js → check-DrtG0lIZ.js} +1 -1
  76. package/web-app/dist/assets/{chevron-left-D7BpQyA6.js → chevron-left-CrsJSAqQ.js} +1 -1
  77. package/web-app/dist/assets/{circle-alert-DnGvQ_AQ.js → circle-alert-BUCly4p3.js} +1 -1
  78. package/web-app/dist/assets/{clock-CqfxWhHM.js → clock-B2IT9SnE.js} +1 -1
  79. package/web-app/dist/assets/{cloud-BKxp5AWB.js → cloud-CN6Ux7Q7.js} +1 -1
  80. package/web-app/dist/assets/{code-xml-BDQ6GBtt.js → code-xml-BEm8PWnK.js} +1 -1
  81. package/web-app/dist/assets/{database-BmpEx1y_.js → database-cHe5Fgu8.js} +1 -1
  82. package/web-app/dist/assets/{dollar-sign-DYNY9R_C.js → dollar-sign-BVmP4YrE.js} +1 -1
  83. package/web-app/dist/assets/{file-code-corner-BJi0IBFd.js → file-code-corner-D-m-NrwO.js} +1 -1
  84. package/web-app/dist/assets/{file-plus-Dqyb2bcQ.js → file-plus-6mCjIzAB.js} +1 -1
  85. package/web-app/dist/assets/{globe-DPh4RWfM.js → globe-vcWOujwU.js} +1 -1
  86. package/web-app/dist/assets/{hammer-B3xnuoA1.js → hammer-D4nZFpO2.js} +1 -1
  87. package/web-app/dist/assets/{index-BpX8DcTr.js → index-u8toJ43r.js} +3 -3
  88. package/web-app/dist/assets/{layers-BRCmyCW8.js → layers-CNhYLop8.js} +1 -1
  89. package/web-app/dist/assets/{loader-circle-n07Pky0M.js → loader-circle-Vl7XIMV6.js} +1 -1
  90. package/web-app/dist/assets/{lock-BWqOuQmS.js → lock-SW_KwAvf.js} +1 -1
  91. package/web-app/dist/assets/{package-BJlB_Z-Z.js → package-QPK-7Ej1.js} +1 -1
  92. package/web-app/dist/assets/{plus-oH17BZu2.js → plus-DUgAlgCB.js} +1 -1
  93. package/web-app/dist/assets/{refresh-cw-CPQ476LL.js → refresh-cw-LfUksPHq.js} +1 -1
  94. package/web-app/dist/assets/{rotate-ccw-7hLvOcnS.js → rotate-ccw-CMbuouVq.js} +1 -1
  95. package/web-app/dist/assets/{scroll-text-BCmLauQn.js → scroll-text-C_FxBmNQ.js} +1 -1
  96. package/web-app/dist/assets/{server-DfTfvW84.js → server-7UJe9Jqt.js} +1 -1
  97. package/web-app/dist/assets/{shield-alert-CaeGRq19.js → shield-alert-BMuu6fYB.js} +1 -1
  98. package/web-app/dist/assets/{thumbs-up-Dz-l2GPC.js → thumbs-up-Bhs0d2Gp.js} +1 -1
  99. package/web-app/dist/assets/{trash-2-B-OsDmSo.js → trash-2-BZKxv49w.js} +1 -1
  100. package/web-app/dist/assets/{trending-down-CXTFOxzq.js → trending-down-DKeCMZek.js} +1 -1
  101. package/web-app/dist/assets/{trending-up-FQEdqr3v.js → trending-up-43_9fShg.js} +1 -1
  102. package/web-app/dist/assets/{upload-CacWSNTg.js → upload-pV3irPEW.js} +1 -1
  103. package/web-app/dist/assets/{usePolling-cIjZ9qd2.js → usePolling-CoZQM-WL.js} +1 -1
  104. package/web-app/dist/assets/{user-DAouWFHi.js → user-CMl7dXvC.js} +1 -1
  105. package/web-app/dist/index.html +1 -1
  106. package/autonomy/company-seats.json +0 -82
  107. package/docs/COMPETITIVE-INTEL-2026-09.md +0 -444
  108. package/docs/FOUNDER-DECISIONS-TRUST-SEMANTICS-2026-08-01.md +0 -145
  109. package/docs/FOUNDER-STATUS-AND-DECISIONS-2026-07-01.md +0 -132
  110. package/docs/LOKI-10-BUILD-PROMPT.md +0 -350
  111. package/docs/STRATEGY-2026-2028.md +0 -124
  112. package/docs/V10-VISION.md +0 -161
  113. package/docs/v10/ADOPTION-PLAN.md +0 -375
  114. package/docs/v10/ARCHITECT-CUTS.md +0 -744
  115. package/docs/v10/BACKLOG.md +0 -231
  116. package/docs/v10/BOARD.md +0 -1403
  117. package/docs/v10/CONTROL-PLANE.md +0 -120
  118. package/docs/v10/CONTROL.md +0 -36
  119. package/docs/v10/CP-ASK-PLAN.md +0 -85
  120. package/docs/v10/CP-ENTERPRISE-UI.md +0 -537
  121. package/docs/v10/D51-PHASE-B.md +0 -120
  122. package/docs/v10/D61-SPEED.md +0 -105
  123. package/docs/v10/D63-CARDS.md +0 -354
  124. package/docs/v10/DECISIONS.md +0 -915
  125. package/docs/v10/E2E-D65.md +0 -123
  126. package/docs/v10/ENGINE-LAWS.md +0 -163
  127. package/docs/v10/ENGINE-MEASURE.md +0 -69
  128. package/docs/v10/ENGINE.md +0 -743
  129. package/docs/v10/FAILURE-CLASSES.md +0 -2026
  130. package/docs/v10/FC21B-FC22-PLAN.md +0 -107
  131. package/docs/v10/FIRST-RUN-GATE.md +0 -39
  132. package/docs/v10/FOUNDER-QUEUE.md +0 -29
  133. package/docs/v10/GAP-RESEARCH-1003.md +0 -32
  134. package/docs/v10/GUARDS.md +0 -883
  135. package/docs/v10/L0-WAVE1.md +0 -81
  136. package/docs/v10/LEGACY-REMOVAL.md +0 -408
  137. package/docs/v10/MEDIUM-ANALYSIS.md +0 -346
  138. package/docs/v10/METRICS.md +0 -645
  139. package/docs/v10/MODERNIZE.md +0 -437
  140. package/docs/v10/OPENCODE-PARITY-PLAN.md +0 -84
  141. package/docs/v10/OPERATING-MODEL.md +0 -60
  142. package/docs/v10/PLAN-V12.md +0 -896
  143. package/docs/v10/PROGRESS.md +0 -2735
  144. package/docs/v10/RELEASE-11.md +0 -77
  145. package/docs/v10/RETRO-2026.md +0 -650
  146. package/docs/v10/ROADMAP-D63.md +0 -35
  147. package/docs/v10/SCALE.md +0 -140
  148. package/docs/v10/SCORECARD-PLAN.md +0 -250
  149. package/docs/v10/SWARM-PROMPT.md +0 -98
  150. package/docs/v10/SWARM.md +0 -293
  151. package/docs/v10/cp-redesign/PARITY.md +0 -188
  152. package/docs/v10/cp-redesign/legacy/INDEX.md +0 -1167
  153. package/docs/v10/roadmap-10/01-measurement.md +0 -113
  154. package/docs/v10/roadmap-10/02-cost.md +0 -75
  155. package/docs/v10/roadmap-10/03-speed.md +0 -65
  156. package/docs/v10/roadmap-10/04-first-run.md +0 -61
  157. package/docs/v10/roadmap-10/05-deploy.md +0 -61
  158. package/docs/v10/roadmap-10/06-stability.md +0 -64
  159. package/docs/v10/roadmap-10/07-quality.md +0 -57
  160. package/docs/v10/roadmap-10/08-proof.md +0 -48
  161. package/docs/v10/roadmap-10/09-safety.md +0 -74
  162. package/docs/v10/roadmap-10/README.md +0 -1464
  163. package/skills/sdlc-fleet.md +0 -170
  164. package/tools/cockpit/SPEC.md +0 -275
  165. package/tools/cockpit/index.html +0 -146
  166. package/tools/cockpit/roi-basis.json +0 -33
  167. package/tools/cockpit/server.py +0 -946
@@ -1,537 +0,0 @@
1
- # Control Plane enterprise UI (D83)
2
-
3
- Status: STEP 1 design, architect output. STEP 2 is the slice plan in section 6. Ships as 10.8.0.
4
- Package: packages/control-plane (server in src/server, UI in ui/src). Sources cited as path:line on main e6d6c362f.
5
-
6
- ## 0. Guiding principle (founder addendum, 15:24Z, binding)
7
-
8
- "i want fully controllable loki mode of sessions, configurations and anything from UI, but keep it super clean and lean like claude.ai UI and chatgpt UI, but with loki mode's old dashboard look, should feel amazing for users".
9
-
10
- 1. FULL CONTROL. Everything the CLI does is doable in the UI: start, stop, answer, retry and resume a run; choose repo, issue, model, provider and budget; edit loki.yaml through forms that write back to the file; connect integrations; manage workspaces (and schedules and the merge queue once their backends exist); view and verify receipts. No feature is CLI-only. Section 3.3 is the CLI-to-UI parity table and is a release gate.
11
- 2. CLEAN AND LEAN. One primary surface, like Claude.ai and ChatGPT:
12
- - Left sidebar = wordmark, a "New run" button, and the session list (runs as conversations, grouped Today, Yesterday, Earlier). Nothing else at the top level.
13
- - Main pane = either the New run composer or one run as a single readable thread.
14
- - New run = one input, "Paste an issue link or describe a task", with inline chips for repo, model, provider and budget.
15
- - A run = live steps stream in like messages; diff, evidence and receipt expand inline; a BLOCKED question renders as a reply prompt.
16
- - Everything else (Home, Runs table, Work board, Workspaces, Plans, Receipts, Cost, Models, Integrations, Notifications, Audit log, Settings) sits behind ONE menu entry at the sidebar foot, not 15 sidebar items. Progressive disclosure everywhere.
17
- 3. OLD LOOK on that lean structure: Fraunces serif wordmark and page titles, Inter UI, JetBrains Mono numbers, the purple accent, cards, KPI tiles, badges, status dots, light and dark themes, exactly from section 2 tokens.
18
- 4. FEEL AMAZING: instant navigation (client router, cached list), optimistic updates with rollback, Cmd+K, Cmd+Enter to start, empty states that give the single next action, and no dead or placeholder panel. A page whose backend does not exist is not rendered at all.
19
- 5. HONESTY (D83 item 3): every number comes from ingested events or run artifacts. A missing value renders as "not measured", never 0. Partial cost shows measured_sessions/total_sessions.
20
-
21
- ## 1. Legacy inventory (KEEP / REWORK / DROP)
22
-
23
- Shell: legacy-ui/scripts/build-standalone.js (generates legacy-ui-static/index.html). Nav groups at build-standalone.js:1266-1347 (Build, Quality and Trust, Insights, Ops, Wiki). Pages at :1358-1882. RARV, Council, gates, checkpoints and app runner are legacy engine concepts with no v10 producer (docs/v10/LEGACY-REMOVAL.md:36-37), so they DROP or remap to v10 stages (events stage.started/completed/failed/skipped, loki-ts/src/engine10/status.ts:9).
24
-
25
- | Legacy page or control | Source | Decision | v10 home |
26
- |---|---|---|---|
27
- | Overview (spec, tasks, RARV timeline, diff) | components/loki-overview.js, loki-spec-panel.js, loki-rarv-timeline.js, loki-session-diff.js, loki-task-board.js; build-standalone.js:1358-1415 | REWORK | Home (KPI row, recent runs, BLOCKED inbox). RARV timeline becomes the v10 stage timeline in the run thread. Task board DROP (no v10 task queue). Diff KEEP inside the run thread. |
28
- | First-run hero ("loki quickstart") | build-standalone.js:1365-1387 | REWORK | Empty state of the New run composer (one action: paste an issue). |
29
- | App Runner | loki-app-preview.js, loki-app-status.js (/api/app-runner/*) | DROP | Screenshots and evidence in the run thread replace it. |
30
- | Checkpoints | loki-checkpoint-viewer.js (/api/checkpoints, rollback) | REWORK | Served by the Control Plane: /v1/checkpoints read routes, plus create and rollback on the loopback-only action path (CPE24-P2). |
31
- | Context | loki-context-tracker.js (/api/context) | DROP | Token counts per run (input_tokens, output_tokens) shown in the run cost card. |
32
- | Fleet | loki-fleet.js (/api/fleet/*) | REWORK | Runs table (all repos, filters, group_id rollup). Its table styling is the Table primitive. |
33
- | Quality (score, gates, prompt optimizer) | loki-quality-score.js, loki-quality-gates.js, loki-prompt-optimizer.js | DROP | v10 verify stage plus NOT PROVEN list in the run thread. |
34
- | Trust trajectory and receipts panel | legacy-ui-static/trust.html, proofs.html; build-standalone.js:1811-1828 | KEEP on v10 data | Receipts page (list, inline verify, verified-rate trend from runs). |
35
- | Completion Council | loki-council-dashboard.js, loki-council-transcripts.js | DROP | Remapped: the v10 verify stage and receipt verdict. |
36
- | Spec Checklist | loki-checklist-viewer.js (/api/checklist) | REWORK | Plans and traceability (plan.json, issue.json, receipt claims). |
37
- | Insights: logs | loki-log-stream.js (/api/logs) | KEEP | Streaming log inside the run thread (events.jsonl). |
38
- | Insights: memory, learnings, USAGE.md | loki-memory-browser.js, loki-learning-dashboard.js; build-standalone.js:1427-1590 | DROP now | Memory page deferred until a v10 memory read API exists (section 3.2). USAGE.md becomes a Help link. |
39
- | Analytics | loki-analytics.js (/api/activity) | REWORK | Home trends (runs per day, verified rate) from the runs table. |
40
- | Cost | loki-cost-dashboard.js, loki-cost-waterfall.js, legacy-ui-static/cost.html; spend-cap banner build-standalone.js:1800-1806 | KEEP on v10 data | Cost and usage page; the "no cap" banner is kept and fed by loki.yaml budgets. |
41
- | Notifications | loki-notification-center.js | REWORK | Derived from events: BLOCKED, FAILED, budget.hit, tampered, conflict. |
42
- | Escalations | loki-escalations.js | REWORK | BLOCKED inbox on Home plus the reply prompt in the thread. |
43
- | Migration | loki-migration-dashboard.js | REWORK | Runs filtered to `loki modernize` runs once they ship events (engine10/modernize); hidden until then. |
44
- | Wiki | loki-wiki-browser.js | DROP | Wiki deleted (LEGACY-REMOVAL.md:45). |
45
- | Session panel: Start build, spec textarea | loki-session-control.js:443-500 (/api/control/start, loki-api-client.js:1109) | REWORK | New run composer. |
46
- | Session panel: model picker (start-time) | loki-session-control.js:453-495 | KEEP | Model chip on the composer. |
47
- | Session panel: mid-run model switch | loki-session-control.js:362-437 (/api/session/model) | DROP | v10 has no mid-run switch; Retry with another model instead. |
48
- | Session panel: advisor picker | loki-session-control.js:464-490 | DROP | No v10 advisor. |
49
- | Session panel: Pause, Resume, Stop | loki-session-control.js:19-22 (/api/control/pause, resume, stop) | REWORK | Stop, Retry, Resume on the run header (no pause in v10). |
50
- | Right status sidebar (288 px, 48 px rail) | build-standalone.js:1885-1958, layout :116-140 | REWORK | Run details become an inline collapsible "Details" card in the thread; no permanent third column. |
51
- | Settings disclosure (API URL, theme) | build-standalone.js:1905-1935 | REWORK | Settings page; theme toggle lives in the menu. |
52
- | Project picker and per-app Stop list | build-standalone.js:1244-1258 (/api/running-projects) | REWORK | Repo chip on composer plus a repo filter on the session list. |
53
- | Receipts badge | build-standalone.js:1227-1238, CSS :334-351 (/api/proofs/summary) | KEEP | Sidebar header badge, fed by /v1/stats receipts count. |
54
- | Mascot presence | loki-mascot-presence.js | KEEP | Next to the wordmark, state from "any run running". |
55
- | Budget banner | build-standalone.js:1200-1203 | KEEP | Top banner when a budget is hit (budget.hit event). |
56
- | Run manager, audit viewer | loki-run-manager.js, loki-audit-viewer.js | REWORK | Runs table actions; Audit log page (control-plane actions). |
57
- | API keys, tenant switcher, managed memory | loki-api-keys.js, loki-tenant-switcher.js, loki-managed-memory-panel.js | DROP | Local single user; the bearer token is set by env (src/server/auth.ts). |
58
- | Onboarding (start.html) | legacy-ui-static/start.html (/api/onboarding/*, /api/backlog/*) | REWORK | Integrations page (GitHub connect status) plus the composer empty state. |
59
-
60
- ## 2. Design system (extracted, binding)
61
-
62
- Two legacy layers exist and disagree on ground colors. The SHELL layer in build-standalone.js:113-185 is documented as the founder-approved identity (light-grey ground, comment at :113) and is what users saw around every page; the COMPONENT layer in legacy-ui/core/loki-unified-styles.js:20-146 (also loki-theme.js:44-124) supplies the scales, status colors and component specs. Decision: shell ground and accent per theme from the shell layer; scales, radii, shadows, model colors and component recipes from the component layer. (Open question 1.)
63
-
64
- Package: packages/control-plane/ui/src/design/ with tokens.css (custom properties below), fonts.css (Google Fonts link, build-standalone parity: Fraunces opsz 9..144 wght 400/500/600, Inter 300-700, JetBrains Mono 400/500; static/index.html:11), tailwind.preset.ts (maps Tailwind colors, radius, spacing, fontFamily to the vars, so existing Tailwind classes keep working), and primitives/*.tsx.
65
-
66
- ### 2.1 Tokens (tokens.css)
67
-
68
- ```css
69
- :root, [data-theme="light"] {
70
- /* ground: build-standalone.js:116-139 */
71
- --cp-bg: #F1F2F6; --cp-bg-2: #E6E8EE; --cp-bg-3: #DBDEE6;
72
- --cp-card: rgba(255,255,255,0.86); --cp-hover: #E6E8EE;
73
- --cp-glass: rgba(255,255,255,0.7); --cp-glass-border: rgba(255,255,255,0.4);
74
- --cp-glass-shadow: 0 4px 24px rgba(0,0,0,0.06), 0 1px 2px rgba(0,0,0,0.04);
75
- --cp-text: #201515; --cp-text-2: #4A4640; --cp-text-muted: #8A857C; --cp-text-inverse: #ffffff;
76
- --cp-border: rgba(0,0,0,0.08); --cp-border-light: rgba(0,0,0,0.05);
77
- /* accent: shell :124-126, hover/active unified-styles.js:33-35 */
78
- --cp-accent: #553DE9; --cp-accent-hover: #4432c4; --cp-accent-active: #3828a0;
79
- --cp-accent-glow: rgba(85,61,233,0.15); --cp-accent-muted: rgba(85,61,233,0.10);
80
- /* status text: shell :131-134 (AA on light ground); fills: unified-styles.js:51-58 */
81
- --cp-success: #1f8a52; --cp-warning: #9a6a12; --cp-error: #b23a3a; --cp-info: #2F71E3;
82
- --cp-success-fill: #1FC5A8; --cp-success-muted: rgba(31,197,168,0.12);
83
- --cp-warning-fill: #D4A03C; --cp-warning-muted: rgba(212,160,60,0.12);
84
- --cp-error-fill: #C45B5B; --cp-error-muted: rgba(196,91,91,0.12);
85
- --cp-info-muted: rgba(47,113,227,0.12);
86
- /* models: unified-styles.js:72-75 */
87
- --cp-opus: #d97706; --cp-sonnet: #553DE9; --cp-haiku: #1FC5A8;
88
- --cp-shadow-sm: 0 1px 2px rgba(32,21,21,0.04); --cp-shadow-md: 0 4px 6px rgba(32,21,21,0.06);
89
- --cp-shadow-lg: 0 10px 15px rgba(32,21,21,0.08); --cp-focus: 0 0 0 3px rgba(85,61,233,0.25);
90
- }
91
- [data-theme="dark"] { /* build-standalone.js:164-185; unified-styles.js:86-146 */
92
- --cp-bg: #17161C; --cp-bg-2: #1E1D25; --cp-bg-3: #27262F;
93
- --cp-card: rgba(35,34,43,0.82); --cp-hover: #27262F;
94
- --cp-glass: rgba(23,22,28,0.7); --cp-glass-border: rgba(255,255,255,0.08);
95
- --cp-glass-shadow: 0 4px 24px rgba(0,0,0,0.25), 0 1px 2px rgba(0,0,0,0.12);
96
- --cp-text: #F0ECF8; --cp-text-2: #B8B0C8; --cp-text-muted: #8B85A0; --cp-text-inverse: #17161C;
97
- --cp-border: rgba(255,255,255,0.08); --cp-border-light: rgba(255,255,255,0.04);
98
- --cp-accent: #8b7bf5; --cp-accent-hover: #9c8ff7; --cp-accent-active: #6258D0;
99
- --cp-accent-glow: rgba(139,123,245,0.2); --cp-accent-muted: rgba(123,107,240,0.18);
100
- --cp-success: #2ED8B6; --cp-warning: #E8B84A; --cp-error: #E07070; --cp-info: #5A9CF5;
101
- --cp-success-fill: #2ED8B6; --cp-success-muted: rgba(46,216,182,0.18);
102
- --cp-warning-fill: #E8B84A; --cp-warning-muted: rgba(232,184,74,0.18);
103
- --cp-error-fill: #E07070; --cp-error-muted: rgba(224,112,112,0.18);
104
- --cp-info-muted: rgba(90,156,245,0.18);
105
- --cp-opus: #f59e0b; --cp-sonnet: #8b7bf5; --cp-haiku: #2ED8B6;
106
- --cp-shadow-sm: 0 1px 2px rgba(0,0,0,0.4); --cp-shadow-md: 0 4px 12px rgba(0,0,0,0.5);
107
- --cp-shadow-lg: 0 10px 25px rgba(0,0,0,0.6); --cp-focus: 0 0 0 3px rgba(123,107,240,0.30);
108
- }
109
- @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { /* same as [data-theme="dark"] */ } }
110
- :root {
111
- --cp-font-serif: 'Fraunces', Georgia, 'Times New Roman', serif; /* unified-styles.js:358-362 */
112
- --cp-font-sans: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
113
- --cp-font-mono: 'JetBrains Mono', 'Fira Code', 'SF Mono', Menlo, monospace;
114
- --cp-text-xs: 10px; --cp-text-sm: 11px; --cp-text-base: 12px; --cp-text-md: 13px;
115
- --cp-text-lg: 14px; --cp-text-xl: 16px; --cp-text-2xl: 18px; --cp-text-3xl: 24px;
116
- --cp-space-xs: 4px; --cp-space-sm: 8px; --cp-space-md: 12px; --cp-space-lg: 16px; /* :333-341 */
117
- --cp-space-xl: 24px; --cp-space-2xl: 32px; --cp-space-3xl: 48px;
118
- --cp-radius-sm: 2px; --cp-radius-md: 4px; --cp-radius-lg: 5px; --cp-radius-nav: 8px; --cp-radius-full: 9999px; /* :346-353, nav :400-406 */
119
- --cp-ease: cubic-bezier(0.4,0,0.2,1); --cp-dur-fast: 100ms; --cp-dur: 200ms; --cp-dur-slow: 300ms; /* :390-405 */
120
- --cp-sidebar-w: 240px; /* build-standalone.js:126 grid track */
121
- --cp-detail-w: 288px; --cp-rail-w: 48px; /* :120-121, used only by the optional Details drawer */
122
- --cp-main-pad: 28px 32px; /* .main-content :917-923 */
123
- --cp-thread-max: 820px; /* NEW: reading width of the run thread (Claude.ai-like) */
124
- --cp-z-dropdown: 100; --cp-z-sticky: 200; --cp-z-modal: 300; --cp-z-popover: 400; --cp-z-toast: 600; /* :419-427 */
125
- }
126
- ```
127
-
128
- Breakpoints (unified-styles.js:408-414): 640, 768, 1024, 1280, 1536. Below 768 px the sidebar becomes a drawer (legacy mobile-menu-btn, build-standalone.js:1210 and media :240-266).
129
-
130
- ### 2.2 Typography and wordmark
131
- - Wordmark: "Loki Mode" in --cp-font-serif 22px weight 400, letter-spacing -0.02em, line-height 1.1; subtitle "powered by Autonomi" Inter 9px uppercase 0.08em weight 500 muted (build-standalone.js:312-328). Logo: the 34 px purple rounded-square SVG with the teal dot (:1218-1224), copied verbatim.
132
- - Page and thread titles: serif 1.8rem weight 400, -0.02em (.section-page-title :949-955). Section headings: serif 1.15rem weight 400 (:1432).
133
- - Body: Inter 13px, line-height 1.5, font-feature-settings 'cv02','cv03','cv04','cv11', antialiased (:283-296).
134
- - Numbers (KPI values, cost, seq, SHA): mono. KPI value 28px (compact 20px) (loki-kpi-card.js:258-262).
135
-
136
- ### 2.3 Primitives (ui/src/design/primitives)
137
- | Primitive | Recipe (source) |
138
- |---|---|
139
- | Card | --cp-card bg, 1px --cp-border, radius 5px, padding 16px, hover border --cp-border-light; interactive variant lifts 1px with --cp-shadow-md (unified-styles.js:746-767) |
140
- | KpiTile | Card at 14px 16px (compact 10px 12px), gap 10px, icon chip radius 6px, trend pill 11px radius 3px, mono value, 11px label, optional sparkline SVG from real series only (loki-kpi-card.js:180-293) |
141
- | Badge | inline-flex, 2px 8px, radius 2px, 10px uppercase 0.025em weight 500; variants success, warning, error, info, neutral use muted bg plus solid text (unified-styles.js:799-835). Verdict map: VERIFIED success, PARTIAL warning, FAILED error, SPEC_CONFLICT (BLOCKED) info, running neutral with pulse dot. |
142
- | Pill | receipts badge recipe: radius 999px, 3px 8px, 10px, card bg, 1px border (build-standalone.js:334-351) |
143
- | StatusDot | 12x6 px, radius 2px; active = success with 2s pulse; idle muted; paused warning; error error (unified-styles.js:723-742) |
144
- | Button | 8px 12px, radius 4px, 13px weight 500; primary accent/hover/active; secondary, ghost, danger; sm and lg sizes; disabled opacity 0.5 (:646-722) |
145
- | Input, Textarea, Select | --cp-bg-3 bg, 1px border, radius 4px, focus border accent plus --cp-focus ring (:768-797) |
146
- | Chip | Pill shape with a leading icon and a popover menu (composer repo, model, provider, budget). NEW, built from Pill and Input tokens. |
147
- | Table | wrapper Card radius 5px overflow auto; 12px rows; th 11px weight 600 uppercase 0.05em muted on --cp-bg-3, padding 10px 14px (loki-fleet.js:279-300) |
148
- | NavItem | 8px 12px, radius 8px, 13px weight 500, text-2; hover --cp-hover; active accent text on --cp-accent-glow with a 3x16 px left accent bar (build-standalone.js:400-458) |
149
- | GroupHead | 9.5px weight 600 uppercase 0.09em muted, padding 4px 12px 5px (:389-398); used for Today, Yesterday, Earlier |
150
- | Timeline | vertical stage track (loki-session-timeline.js:328-400): a dot per stage colored by status, connector line --cp-border, label plus mono duration |
151
- | Message | NEW thread item: 32 px gutter icon, serif-free body, mono meta line; expandable body (diff, evidence, receipt) using Card |
152
- | Glass surface | sidebar: --cp-glass with backdrop-filter blur(16px) saturate(1.4), right border --cp-glass-border (:268-280) |
153
- | EmptyState, Spinner, Toast, Dialog, Drawer, Kbd | unified-styles.js:836-880 for empty and spinner; others NEW on the same tokens |
154
-
155
- Motion: page fade-in 0.2s translateY(6px) (build-standalone.js:925-940); respect prefers-reduced-motion.
156
-
157
- ## 3. Feature set and information architecture
158
-
159
- ### 3.1 Shell
160
- - Sidebar (240 px, glass): wordmark plus mascot plus receipts Pill; "New run" primary button (Cmd+Enter submits, Cmd+N focuses); search field (opens Cmd+K); session list grouped Today, Yesterday, Earlier, each row = title (issue ref or first line of task), repo, StatusDot, verdict Badge; footer = Menu button (opens the menu sheet), theme toggle, connection dot.
161
- - Menu sheet (progressive disclosure, like the Claude.ai account menu): Home, Runs, Work board, Workspaces, Plans, Receipts, Cost and usage, Models and providers, Integrations, Notifications, Audit log, Settings. Entries whose backend is missing are not listed.
162
- - Main pane: composer (route /) or run thread (/r/:source/:run) or a menu page.
163
-
164
- ### 3.2 Pages (data backing; "BACKEND" names the slice that must land first)
165
- | Page | Inspired by | Content | Data |
166
- |---|---|---|---|
167
- | New run composer | Claude.ai, Devin | One input "Paste an issue link or describe a task"; chips repo, model, provider, budget (max-cost), deep, no-pr; recent issues suggestions | BACKEND CPE-07 (start), CPE-15 (providers), CPE-03 (repos) |
168
- | Run thread | Devin session | header (title, repo, verdict Badge, elapsed, cost, Stop, Retry, Resume); stage messages streaming; streaming log; diff; evidence and screenshots; receipt with sha256, signed flag, inline Verify; NOT PROVEN list; PR link; BLOCKED reply prompt; Details drawer | exists: /v1/runs/:s/:r, answer. BACKEND CPE-04 (artifacts), CPE-05 (stream), CPE-09 (control) |
169
- | Home | Factory | KPI tiles: runs today, verified rate 7d, cost 7d (measured/partial), BLOCKED waiting; recent runs; BLOCKED inbox | BACKEND CPE-12 (/v1/stats) |
170
- | Runs | Factory fleet | Table with filters verdict, repo, since, group; group_id rollup | exists: /v1/runs filters |
171
- | Work board | Vorflux, Linear | Kanban: Issue (issue_ref) to Running to PR open to Verified or Not proven | exists: runs fields issue_ref, pr_url, verdict |
172
- | Workspaces | Factory | loki.yaml workspaces, per-group status, run a workspace | BACKEND CPE-14 (config read), CPE-07 (start with workspace) |
173
- | Plans and traceability | 8090 | requirement (issue.json, plan.json) to stage to changed file to test to receipt claim; NOT PROVEN highlighted | BACKEND CPE-04 |
174
- | Receipts | trust.html | list, verify in place, verified-rate trend | BACKEND CPE-04, CPE-16 |
175
- | Cost and usage | cost.html | per day, model, repo, provider; tokens; measured vs partial; budgets and "no cap" banner | BACKEND CPE-13 |
176
- | Models and providers | session-control | detected CLIs with version, auth present (boolean only), model catalog, default model | BACKEND CPE-15 |
177
- | Integrations | Vorflux | GitHub (gh auth or git.token_env present), GitLab, Slack (notifications.slack_webhook_env), Jira, Linear, Sentry, MCP: real probe status; connect = write the env var NAME into loki.yaml, never a secret | BACKEND CPE-20 |
178
- | Notifications | legacy center | BLOCKED, FAILED, budget.hit, tampered, ingest conflict; unread state local | BACKEND CPE-21 (derived from events) |
179
- | Audit log | enterprise | every UI action (start, stop, retry, resume, answer, config write) with time, actor, result | BACKEND CPE-03 (actions table) |
180
- | Settings | Claude.ai settings | loki.yaml forms per schema section (provider, models, git, repos, concurrency, budgets, knowledge_sources, workspaces, notifications; schemas/loki-yaml.schema.json); appearance; server token | BACKEND CPE-14 |
181
- | Merge queue, PR reviews with risk, Schedules and triggers | Vorflux | NOT BUILT: backends parked (BOARD.md D64-MERGE :725, D64-REVIEW :726, D64-SERVE :724). Hidden until those land; UI slices are cut then. | none today |
182
- | Memory | Devin knowledge | NOT BUILT: no v10 memory read API (repomemory.ts is engine-internal). Hidden. | none today |
183
- | Cmd+K, search | Linear | jump to run, page, action ("New run", "Toggle theme", "Stop current run") | client side over cached lists |
184
- | Light/dark, mobile, accessibility | | data-theme toggle persisted (localStorage, try/catch), system default; drawer at < 768 px; WCAG AA contrast, focus rings, aria-live for streaming steps, full keyboard path | CPE-23 tests |
185
-
186
- ### 3.3 CLI-to-UI parity table (release gate for 10.8.0)
187
- | CLI | UI control | API |
188
- |---|---|---|
189
- | `loki "<task>"` | composer input | POST /v1/runs (CPE-07) |
190
- | `loki <issue-url or owner/repo#N>` | composer input (issue link detected) | POST /v1/runs |
191
- | `--provider <name>` | provider chip | POST /v1/runs body.provider |
192
- | model (loki.yaml models.default, LOKI_SESSION_MODEL) | model chip | POST /v1/runs body.model |
193
- | `--max-cost <usd>` | budget chip | POST /v1/runs body.max_cost_usd |
194
- | `--deep`, `--no-pr` | toggles in the composer "More" chip | POST /v1/runs body.deep, body.no_pr |
195
- | `loki status [run-id]` | session list plus run thread | GET /v1/runs, GET /v1/runs/:s/:r |
196
- | `loki answer <run>` | BLOCKED reply prompt, Resume | POST /v1/runs/:s/:r/answer (exists), POST .../resume (CPE-09) |
197
- | Ctrl+C on a run | Stop | POST /v1/runs/:s/:r/stop (CPE-09) |
198
- | re-run the same ref | Retry | POST /v1/runs/:s/:r/retry (CPE-09) |
199
- | `loki verify [run-id or receipt.json]` | Verify button on receipt | POST /v1/runs/:s/:r/verify (CPE-16) |
200
- | `loki keys export` | Receipts page "Public key" | GET /v1/keys (CPE-16) |
201
- | `loki workspace list, show, run, status` | Workspaces page | GET /v1/config, POST /v1/runs body.workspace (CPE-19) |
202
- | `loki config` (loki.yaml edit, validate) | Settings forms | GET, PUT /v1/config (CPE-14) |
203
- | `loki provider` | Models and providers | GET /v1/providers (CPE-15) |
204
- | `loki control` | (this UI) | n/a |
205
- | `loki modernize <repo> --to <target>` | composer "Modernize" mode | DEFERRED: modernize does not emit v10 run events yet (open question 3) |
206
- | `loki merge`, `loki review --risk`, `loki serve` schedules | none until built | DEFERRED with D64 backends |
207
-
208
- ## 4. API: what exists and what is new
209
-
210
- Exists (packages/control-plane/src/server): GET /health, /ready; POST /v1/ingest; GET /v1/runs (verdict, repo, since, until, group_id, limit, cursor); GET /v1/runs/:source/:run and /v1/runs/:id (summary, stages, receipt sha256/signed/verdict/path, not_proven, blocked_question, current_stage, files_touched); POST /v1/runs/:source/:run/answer (app.ts:46-75, runs.ts, answer.ts). Guards: hostGuard (loopback), tokenGuard (bearer on /v1/*) (auth.ts). Store: SQLite via Drizzle, tables sources, events, runs (db/schema.ts). Shipper backfills and tails .loki/runs/*/events.jsonl (shipper/*). Run dir artifacts (engine10): events.jsonl, issue.json, plan.json, task.md, receipt.json, receipt.md, report.json, report.md, status.json, eta.json, estimate.json, failures.jsonl.
211
-
212
- Gap: the server stores events only. Artifacts live in the local repo, and source_id is a hash (ship.ts:16-21), so the server cannot find the repo. CPE-03 adds a LOCAL-ONLY table local_repos (source_id, realpath) filled by local discovery, never by /v1/ingest, never returned over the API beyond a display name.
213
-
214
- | New endpoint | Slice | Tier | Notes |
215
- |---|---|---|---|
216
- | GET /v1/runs/:s/:r/events?after=seq | CPE-04 | HIGH | paged events for the log |
217
- | GET /v1/runs/:s/:r/artifact/:name | CPE-04 | HIGH | fixed allowlist of names (issue.json, plan.json, receipt.json, receipt.md, report.md, task.md, diff.patch, evidence/*.png); realpath must stay under <repo>/.loki/runs/<run>; size cap |
218
- | GET /v1/runs/:s/:r/stream, GET /v1/stream | CPE-05 | MEDIUM | SSE of new events and run-row changes, heartbeat 15s |
219
- | GET /v1/stats?since= | CPE-12 | MEDIUM | counts, verified rate, cost measured and partial, receipts count |
220
- | GET /v1/stats/cost?group=day,model,repo,provider | CPE-13 | MEDIUM | from runs table |
221
- | GET /v1/repos | CPE-03 | MEDIUM | display names of discovered local repos |
222
- | POST /v1/runs | CPE-07 | HIGH | start: repo must be a local_repos entry; ref or task text validated; flags whitelisted; spawns `loki` with argv array (no shell), detached, env scrubbed to an allowlist; JSON content type plus Origin check; audit row |
223
- | POST /v1/runs/:s/:r/stop, /retry, /resume | CPE-09 | HIGH | stop signals only the pid recorded in <run>/run.pid whose start time and run id match; retry re-uses the recorded argv; resume = existing answer file plus `loki answer <run>` spawn; audit row |
224
- | GET /v1/config, PUT /v1/config | CPE-14 | HIGH | read and validate against schemas/loki-yaml.schema.json; write atomic (temp plus rename), comment-preserving (adopt the `yaml` package Document API), backup to loki.yaml.bak, optimistic concurrency via sha256 If-Match; secrets refused (env var names only) |
225
- | GET /v1/providers | CPE-15 | MEDIUM | CLI detection with timeout, versions, auth present boolean, providers/model_catalog.json |
226
- | POST /v1/runs/:s/:r/verify, GET /v1/keys | CPE-16 | MEDIUM | calls the existing verify_cmd and keys_cmd in process, read-only |
227
- | GET /v1/integrations | CPE-20 | MEDIUM | status probes only |
228
- | GET /v1/notifications | CPE-21 | LOW | derived query over events |
229
- | GET /v1/audit | CPE-21 | LOW | actions table, newest first |
230
-
231
- Every mutating endpoint: requires the bearer token when the server is not loopback-only, refuses non-JSON bodies, checks Origin against the served host, writes an audit row before acting, and returns the resulting state for optimistic reconciliation.
232
-
233
- ## 5. Legacy integration contract (gate for CPE-24)
234
-
235
- The legacy dashboard (dashboard/server.py, port 57374, 13194 lines) serves 234 routes (method and path entries after dropping HEAD; routers api_v2 at /api/v2, api_operator at /api/operator, api_start, api_runs_v1 at /api/v1/runs, the /lab and /assets mounts, WS /ws and /ws/collab). Deleting it (CPE-24) must not break a real integration. This section is the contract: one row per route, what consumes it, what the Control Plane offers, and what the shim at packages/control-plane/src/server/legacy/ does with it.
236
-
237
- Method. Route list: FastAPI introspection of `dashboard.server.app` (the 234 entries). Consumers: a repo-wide text scan of git-tracked files, then each used route's consumer lines were read by hand. Counted as a consumer: the TypeScript and Python SDKs, vscode-extension (src and the bundled media/loki-dashboard.js webview), autonomy/loki and autonomy/run.sh, web-app, .github/workflows, tests/moat, tests/e2e, tests/integration, scripts/run-dashboard-* (marked "(test)" when a test). Not counted: dashboard/ itself, dashboard-ui/ (the legacy UI is deleted with the server), docs, generated maps, packages/control-plane. The scan matches path text, so single-segment paths (/start, /cost, /trust, /) were checked by hand: every hit was `loki start`, `/api/cost` or `/lab/api/cost`, none a request to that HTML route. Limits: a path built at runtime from parts is invisible to a text scan, and an HTTP verb is inferred from the nearby call text, so a verb on a bundled-JS row is best effort. A route with a consumer is USED, otherwise UNUSED.
238
-
239
- Status values: EXISTS (the CP serves it today), PARTIAL (the shim maps it and says what differs), MISSING (a USED route the CP has no data or mechanism for), UNUSED (no consumer). Shim actions: map (answer from CP data), 308 to CP UI (HTML page), 410 with notice (UNUSED, retired), 501 not yet supported (USED but no CP data or mechanism: the shim answers an explicit 501, never a faked success), none (the CP already serves the path).
240
-
241
- Counts: map 35, 308 5, 501 21, 410 169, none 4; total 234. A 410 row with a non-empty CP column also names that replacement in the 410 body (CPE24-P6).
242
-
243
- Auth contract (never looser than legacy). Legacy `require_scope` is open when LOKI_ENTERPRISE_AUTH and OIDC are both off, and otherwise answers 401 without a token and 403 on a missing scope. Open in every mode: /health, /.well-known/agent.json, /api/enterprise/status, /api/auth/info, /api/providers/models, /metrics, the docs routes. The shim applies one rule to every route the legacy server guarded: if LOKI_CONTROL_TOKEN is set, require the CP bearer token (401 with www-authenticate otherwise); if no CP token is set but legacy enterprise auth or OIDC is enabled in the environment, fail closed with 401 (the CP has no way to check the legacy `loki_*` tokens); if neither is set, open, matching the legacy default. The CP token carries every scope, which is safe because the shim exposes only read routes and answers 501 or 410 for the rest. 501 and 410 answers are also behind the guard, so an unauthenticated caller learns nothing about a guarded route. The shim never binds a port; mounting it on the CP app keeps hostGuard and the loopback-only action routes exactly as they are.
244
-
245
- First hit per process, each route logs one line: `legacy dashboard route <path> is served by the Control Plane; migrate to /v1/...` (mapped and 308 routes). A 501 or 410 route logs the same single line in the words "is not served by the Control Plane (501)" or "is retired (410)".
246
-
247
- ### 5.1 Parity checklist (gate for CPE-24)
248
- 1. Every row of section 1 marked KEEP or REWORK has its v10 home rendered on real data, proven by a UI test with a fixture run.
249
- 2. Every row of section 3.3 not marked DEFERRED works end to end in tests/e2e (start a fixture run, stream, BLOCKED answer, stop, retry, verify, config write).
250
- 3. Visual parity: screenshots of wordmark, nav, card, KPI, badge, table in light and dark compared against legacy captures (CPE-23).
251
- 4. No route under the old dashboard is reachable except the CP-LEGACY redirects (7b701d238).
252
- 5. Lighthouse accessibility at or above 95 on composer, thread, Home; axe zero serious violations.
253
-
254
-
255
- ### 5.2 Route contract
256
-
257
- | Method and path | Consumers (verified file:line) | CP /v1 equivalent | Status | Shim action |
258
- |---|---|---|---|---|
259
- | GET `/openapi.json` | none | none | UNUSED | 410 with notice |
260
- | GET `/docs` | none | none | UNUSED | 410 with notice |
261
- | GET `/docs/oauth2-redirect` | none | none | UNUSED | 410 with notice |
262
- | GET `/redoc` | none | none | UNUSED | 410 with notice |
263
- | POST `/api/v2/tenants` | sdk/python/loki_mode_sdk/client.py:204, sdk/typescript/src/client.ts:237 | no tenants: local single user | DROPPED (section 1) | 410 with notice |
264
- | GET `/api/v2/tenants` | sdk/python/loki_mode_sdk/client.py:191, sdk/typescript/src/client.ts:225 | no tenants: local single user | DROPPED (section 1) | 410 with notice |
265
- | GET `/api/v2/tenants/{tenant_id}` | sdk/typescript/src/client.ts:229 | no tenants: local single user | DROPPED (section 1) | 410 with notice |
266
- | PUT `/api/v2/tenants/{tenant_id}` | none | none | UNUSED | 410 with notice |
267
- | DELETE `/api/v2/tenants/{tenant_id}` | sdk/typescript/src/client.ts:241 | no tenants: local single user | DROPPED (section 1) | 410 with notice |
268
- | GET `/api/v2/tenants/{tenant_id}/projects` | none | none | UNUSED | 410 with notice |
269
- | POST `/api/v2/runs` | vscode-extension/media/loki-dashboard.js:9617 | none | MISSING | 501 not yet supported |
270
- | GET `/api/v2/runs` | sdk/python/loki_mode_sdk/client.py:220, sdk/typescript/src/client.ts:201 | /v1/runs | PARTIAL (ids are source:run strings, not ints; no project_id filter; status maps to running/completed; limit/offset map to limit/cursor) | map |
271
- | GET `/api/v2/runs/{run_id}` | sdk/python/loki_mode_sdk/client.py:228, sdk/typescript/src/client.ts:205 | /v1/runs/:id | PARTIAL (run_id is source:run (URL-encoded) or a bare run id; legacy integer ids answer 404) | map |
272
- | POST `/api/v2/runs/{run_id}/cancel` | sdk/python/loki_mode_sdk/client.py:233, sdk/typescript/src/client.ts:209, vscode-extension/media/loki-dashboard.js:9617 | none | MISSING | 501 not yet supported |
273
- | POST `/api/v2/runs/{run_id}/replay` | sdk/python/loki_mode_sdk/client.py:238, sdk/typescript/src/client.ts:213, vscode-extension/media/loki-dashboard.js:9617 | none | MISSING | 501 not yet supported |
274
- | GET `/api/v2/runs/{run_id}/timeline` | sdk/python/loki_mode_sdk/client.py:243, sdk/typescript/src/client.ts:217, vscode-extension/media/loki-dashboard.js:9255 | /v1/runs/:id (stages, events) | PARTIAL (phases are CP stages; events carry seq, ts, type, stage only) | map |
275
- | POST `/api/v2/api-keys` | sdk/python/loki_mode_sdk/client.py:263, sdk/typescript/src/client.ts:178, vscode-extension/media/loki-dashboard.js:10097 | CP bearer token set by env (LOKI_CONTROL_TOKEN) | DROPPED (section 1) | 410 with notice |
276
- | GET `/api/v2/api-keys` | sdk/python/loki_mode_sdk/client.py:253, sdk/typescript/src/client.ts:170 | CP bearer token set by env (LOKI_CONTROL_TOKEN) | DROPPED (section 1) | 410 with notice |
277
- | GET `/api/v2/api-keys/{identifier}` | none | none | UNUSED | 410 with notice |
278
- | PUT `/api/v2/api-keys/{identifier}` | none | none | UNUSED | 410 with notice |
279
- | DELETE `/api/v2/api-keys/{identifier}` | sdk/typescript/src/client.ts:190, vscode-extension/media/loki-dashboard.js:10097 | CP bearer token set by env (LOKI_CONTROL_TOKEN) | DROPPED (section 1) | 410 with notice |
280
- | POST `/api/v2/api-keys/{identifier}/rotate` | sdk/python/loki_mode_sdk/client.py:271, sdk/typescript/src/client.ts:186, vscode-extension/media/loki-dashboard.js:10097 | CP bearer token set by env (LOKI_CONTROL_TOKEN) | DROPPED (section 1) | 410 with notice |
281
- | GET `/api/v2/policies` | none | none | UNUSED | 410 with notice |
282
- | PUT `/api/v2/policies` | none | none | UNUSED | 410 with notice |
283
- | POST `/api/v2/policies/evaluate` | none | none | UNUSED | 410 with notice |
284
- | GET `/api/v2/audit` | sdk/python/loki_mode_sdk/client.py:293, sdk/typescript/src/client.ts:254, vscode-extension/media/loki-dashboard.js:9813 | /v1/audit (added by the shim) | PARTIAL (CP audit is an operator-action log (run removal, prune), not the legacy hash-chained log; resource_type filter answers 400) | map |
285
- | GET `/api/v2/audit/verify` | tests/moat/p2-honest-verdict.sh:1162 (test), tests/moat/p2-honest-verdict.sh:1258 (test), vscode-extension/media/loki-dashboard.js:9813 | none | MISSING | 501 not yet supported |
286
- | GET `/api/v2/audit/export` | none | /v1/audit | UNUSED | 410 with notice |
287
- | GET `/api/operator/runs/{run_id}` | none | /v1/runs/:id | UNUSED | 410 with notice |
288
- | GET `/api/operator/tests` | none | none | UNUSED | 410 with notice |
289
- | GET `/api/operator/receipts` | none | none | UNUSED | 410 with notice |
290
- | GET `/api/operator/releases` | none | none | UNUSED | 410 with notice |
291
- | GET `/api/operator/phases` | none | none | UNUSED | 410 with notice |
292
- | GET `/api/operator/workspaces/runs` | none | none | UNUSED | 410 with notice |
293
- | GET `/api/operator/workspaces/runs/{ws}/{run_id}` | none | none | UNUSED | 410 with notice |
294
- | GET `/api/onboarding/state` | none | none | UNUSED | 410 with notice |
295
- | POST `/api/onboarding/provider` | none | none | UNUSED | 410 with notice |
296
- | POST `/api/onboarding/github` | none | none | UNUSED | 410 with notice |
297
- | GET `/api/onboarding/repos` | none | none | UNUSED | 410 with notice |
298
- | POST `/api/onboarding/repo` | none | none | UNUSED | 410 with notice |
299
- | GET `/api/backlog/issues` | none | none | UNUSED | 410 with notice |
300
- | POST `/api/backlog/run` | none | none | UNUSED | 410 with notice |
301
- | GET `/api/backlog/status` | none | none | UNUSED | 410 with notice |
302
- | GET `/api/v1/runs` | none | /v1/runs | UNUSED | 410 with notice |
303
- | GET `/api/v1/runs/{run_id}` | none | /v1/runs/:id | UNUSED | 410 with notice |
304
- | POST `/api/v1/runs` | none | /v1/runs | UNUSED | 410 with notice |
305
- | POST `/api/v1/runs/{run_id}/stop` | none | none | UNUSED | 410 with notice |
306
- | GET `/start` | none | CP UI (/) | EXISTS | 308 to CP UI |
307
- | MOUNT `/lab` | none | CP UI (/) | EXISTS | 308 to CP UI |
308
- | GET `/health` | autonomy/loki:1929, autonomy/loki:7760, autonomy/run.sh:19293 (+10) | /health | EXISTS (CP /health answers {service, pid, install_path}, not the legacy body; CLI discovery relies on that identity, so the shim never overrides it) | none (CP /health serves) |
309
- | GET `/api/providers/models` | none | none | UNUSED | 410 with notice |
310
- | GET `/.well-known/agent.json` | .github/workflows/integrity-audit.yml:114, .github/workflows/integrity-audit.yml:115 | none (static card) | PARTIAL (static card from shim constants; capabilities the CP cannot back (streaming, enterprise rbac/multi-tenant) are false) | map |
311
- | GET `/api/status` | autonomy/loki:15601, autonomy/run.sh:19357, autonomy/run.sh:19541 (+10) | /v1/runs (derived) | PARTIAL (status, version, uptime, active_sessions, phase, provider only; no running_agents, pending_tasks, iteration, complexity, mode, current_task (CP has no such data, fields omitted)) | map |
312
- | GET `/api/projects` | sdk/python/loki_mode_sdk/client.py:166, sdk/typescript/src/client.ts:127, tests/moat/p7-no-fabricated-data.sh:446 (test) | none | MISSING | 501 not yet supported |
313
- | POST `/api/projects` | sdk/python/loki_mode_sdk/client.py:184, sdk/typescript/src/client.ts:139, tests/moat/p7-no-fabricated-data.sh:437 (test) (+1) | none | MISSING | 501 not yet supported |
314
- | GET `/api/projects/{project_id}` | sdk/python/loki_mode_sdk/client.py:174, sdk/typescript/src/client.ts:131 | none | MISSING | 501 not yet supported |
315
- | PUT `/api/projects/{project_id}` | vscode-extension/media/loki-dashboard.js:496 | none | MISSING | 501 not yet supported |
316
- | DELETE `/api/projects/{project_id}` | vscode-extension/media/loki-dashboard.js:496 | none | MISSING | 501 not yet supported |
317
- | GET `/api/tasks` | sdk/python/loki_mode_sdk/tasks.py:30, sdk/typescript/src/client.ts:150 | /v1/tasks (CPE24-P3) | PARTIAL (reads the same .loki source; legacy SQLite memory backend not read; unmeasured values are null) | map |
318
- | POST `/api/tasks` | sdk/python/loki_mode_sdk/tasks.py:56, sdk/typescript/src/client.ts:162, vscode-extension/media/loki-dashboard.js:496 | no v10 task queue; read-only GET /v1/tasks | DROPPED (section 1) | 410 with notice |
319
- | GET `/api/tasks/{task_id}` | sdk/python/loki_mode_sdk/tasks.py:38, sdk/typescript/src/client.ts:154, vscode-extension/src/views/dashboardWebview.ts:168 | no v10 task queue; read-only GET /v1/tasks | DROPPED (section 1) | 410 with notice |
320
- | PUT `/api/tasks/{task_id}` | sdk/python/loki_mode_sdk/tasks.py:71, vscode-extension/media/loki-dashboard.js:496 | no v10 task queue; read-only GET /v1/tasks | DROPPED (section 1) | 410 with notice |
321
- | DELETE `/api/tasks/{task_id}` | vscode-extension/media/loki-dashboard.js:496 | no v10 task queue; read-only GET /v1/tasks | DROPPED (section 1) | 410 with notice |
322
- | POST `/api/tasks/{task_id}/move` | vscode-extension/media/loki-dashboard.js:496 | no v10 task queue; read-only GET /v1/tasks | DROPPED (section 1) | 410 with notice |
323
- | WS `/ws` | vscode-extension/media/loki-dashboard.js:496 | SSE at GET /v1/stream | DROPPED (section 1) | 410 with notice |
324
- | GET `/api/registry/projects` | none | none | UNUSED | 410 with notice |
325
- | POST `/api/registry/projects` | vscode-extension/media/loki-dashboard.js:496 | repos are discovered locally; GET /v1/repos | DROPPED (section 1) | 410 with notice |
326
- | GET `/api/registry/projects/{identifier}` | none | none | UNUSED | 410 with notice |
327
- | DELETE `/api/registry/projects/{identifier}` | none | none | UNUSED | 410 with notice |
328
- | GET `/api/registry/projects/{identifier}/health` | none | none | UNUSED | 410 with notice |
329
- | POST `/api/registry/projects/{identifier}/access` | none | none | UNUSED | 410 with notice |
330
- | GET `/api/registry/discover` | none | none | UNUSED | 410 with notice |
331
- | POST `/api/registry/sync` | vscode-extension/media/loki-dashboard.js:496 | repos are discovered locally; GET /v1/repos | DROPPED (section 1) | 410 with notice |
332
- | GET `/api/registry/tasks` | none | none | UNUSED | 410 with notice |
333
- | GET `/api/registry/learnings` | none | none | UNUSED | 410 with notice |
334
- | GET `/api/fleet/runs` | tests/moat/p7-no-fabricated-data.sh:4637 (test), tests/moat/p7-no-fabricated-data.sh:4706 (test), tests/moat/p7-no-fabricated-data.sh:4710 (test) (+1) | /v1/fleet/runs (CPE24-P1) | PARTIAL (reads the same .loki or registry source; unmeasured values are null with a not-measured marker) | map |
335
- | GET `/api/fleet/summary` | tests/moat/p7-no-fabricated-data.sh:4637 (test), tests/moat/p7-no-fabricated-data.sh:4695 (test), tests/moat/p7-no-fabricated-data.sh:4696 (test) (+1) | /v1/fleet/summary (CPE24-P1) | PARTIAL (reads the same .loki or registry source; unmeasured values are null with a not-measured marker) | map |
336
- | GET `/api/fleet/runs/{identifier}` | none | none | UNUSED | 410 with notice |
337
- | POST `/api/focus` | autonomy/run.sh:24831, web-app/server.py:2744 | /v1/focus (CPE24-P3) | PARTIAL (focus only to this checkout or a registered project; loopback, JSON, same-origin) | map |
338
- | GET `/api/focus` | none | none | UNUSED | 410 with notice |
339
- | DELETE `/api/focus` | none | none | UNUSED | 410 with notice |
340
- | GET `/api/session/model` | none | none | UNUSED | 410 with notice |
341
- | POST `/api/session/model` | vscode-extension/media/loki-dashboard.js:496 | no mid-run model switch; start a new run with another model (POST /v1/runs) | DROPPED (section 1) | 410 with notice |
342
- | GET `/api/running-projects` | none | none | UNUSED | 410 with notice |
343
- | POST `/api/control/start` | vscode-extension/media/loki-dashboard.js:496, vscode-extension/src/api/client.ts:257, vscode-extension/src/extension.ts:580 | none | MISSING | 501 not yet supported |
344
- | GET `/api/control/builds/{execution_id}` | none | none | UNUSED | 410 with notice |
345
- | GET `/api/control/builds/{execution_id}/proof` | none | none | UNUSED | 410 with notice |
346
- | POST `/api/control/builds/{execution_id}/stop` | none | none | UNUSED | 410 with notice |
347
- | POST `/api/running-projects/stop` | none | none | UNUSED | 410 with notice |
348
- | POST `/api/fleet/runs/{identifier}/retry` | none | none | UNUSED | 410 with notice |
349
- | POST `/api/fleet/runs/{identifier}/cancel` | none | none | UNUSED | 410 with notice |
350
- | GET `/api/enterprise/status` | none | none | UNUSED | 410 with notice |
351
- | GET `/api/auth/info` | none | none | UNUSED | 410 with notice |
352
- | POST `/api/enterprise/tokens` | none | none | UNUSED | 410 with notice |
353
- | GET `/api/enterprise/tokens` | none | none | UNUSED | 410 with notice |
354
- | DELETE `/api/enterprise/tokens/{identifier}` | none | none | UNUSED | 410 with notice |
355
- | GET `/api/enterprise/audit` | none | /v1/audit (CPE24-P2) | PARTIAL (read-only; the operator audit table, no hash chain access) | map |
356
- | GET `/api/enterprise/audit/summary` | none | /v1/audit/summary (CPE24-P2) | PARTIAL (read-only; success, failure and resource-type counts are null, not measured) | map |
357
- | GET `/api/compliance` | none | none | UNUSED | 410 with notice |
358
- | GET `/api/memory/summary` | none | none | UNUSED | 410 with notice |
359
- | GET `/api/memory/episodes` | vscode-extension/src/views/memoryViewProvider.ts:152 | /v1/memory/episodes (CPE24-P3) | PARTIAL (reads the same .loki source; legacy SQLite memory backend not read; unmeasured values are null) | map |
360
- | GET `/api/memory/episodes/{episode_id}` | vscode-extension/src/views/dashboardWebview.ts:204, vscode-extension/src/views/memoryViewProvider.ts:215 | /v1/memory/episodes/{id} (CPE24-P3) | PARTIAL (reads the same .loki source; legacy SQLite memory backend not read; unmeasured values are null) | map |
361
- | GET `/api/memory/patterns` | vscode-extension/src/views/memoryViewProvider.ts:151 | /v1/memory/patterns (CPE24-P3) | PARTIAL (reads the same .loki source; legacy SQLite memory backend not read; unmeasured values are null) | map |
362
- | GET `/api/memory/patterns/{pattern_id}` | vscode-extension/src/views/dashboardWebview.ts:186, vscode-extension/src/views/memoryViewProvider.ts:197 | /v1/memory/patterns/{id} (CPE24-P3) | PARTIAL (reads the same .loki source; legacy SQLite memory backend not read; unmeasured values are null) | map |
363
- | GET `/api/memory/skills` | vscode-extension/src/views/memoryViewProvider.ts:153 | /v1/memory/skills (CPE24-P3) | PARTIAL (reads the same .loki source; legacy SQLite memory backend not read; unmeasured values are null) | map |
364
- | GET `/api/memory/skills/{skill_id}` | none | none | UNUSED | 410 with notice |
365
- | GET `/api/memory/economics` | tests/moat/p7-no-fabricated-data.sh:4638 (test), tests/moat/p7-no-fabricated-data.sh:4749 (test), tests/moat/p7-no-fabricated-data.sh:4750 (test) (+2) | /v1/memory/economics (CPE24-P3) | PARTIAL (reads the same .loki source; legacy SQLite memory backend not read; unmeasured values are null) | map |
366
- | POST `/api/memory/consolidate` | vscode-extension/media/loki-dashboard.js:496 | read-only GET /v1/memory/* | DROPPED (section 1) | 410 with notice |
367
- | POST `/api/memory/retrieve` | vscode-extension/media/loki-dashboard.js:496 | read-only GET /v1/memory/* | DROPPED (section 1) | 410 with notice |
368
- | GET `/api/memory/index` | none | none | UNUSED | 410 with notice |
369
- | GET `/api/memory/timeline` | none | none | UNUSED | 410 with notice |
370
- | GET `/api/memory/files` | none | none | UNUSED | 410 with notice |
371
- | GET `/api/memory/file` | none | none | UNUSED | 410 with notice |
372
- | GET `/api/memory/search` | none | none | UNUSED | 410 with notice |
373
- | GET `/api/memory/stats` | none | none | UNUSED | 410 with notice |
374
- | GET `/api/learning/metrics` | tests/moat/p7-no-fabricated-data.sh:4638 (test), tests/moat/p7-no-fabricated-data.sh:4752 (test) | none | MISSING | 501 not yet supported |
375
- | GET `/api/learning/trends` | none | none | UNUSED | 410 with notice |
376
- | GET `/api/learning/signals` | none | none | UNUSED | 410 with notice |
377
- | GET `/api/learning/aggregation` | none | none | UNUSED | 410 with notice |
378
- | POST `/api/learning/aggregate` | vscode-extension/media/loki-dashboard.js:496 | read-only GET /v1/memory/patterns | DROPPED (section 1) | 410 with notice |
379
- | GET `/api/learning/preferences` | none | none | UNUSED | 410 with notice |
380
- | GET `/api/learning/errors` | none | none | UNUSED | 410 with notice |
381
- | GET `/api/learning/success` | none | none | UNUSED | 410 with notice |
382
- | GET `/api/learning/tools` | none | none | UNUSED | 410 with notice |
383
- | POST `/api/control/pause` | vscode-extension/media/loki-dashboard.js:496, vscode-extension/src/api/client.ts:277, vscode-extension/src/extension.ts:703 | /v1/control/pause (CPE24-P4) | PARTIAL (writes only the .loki signal file run.sh reads; no process is signalled; same-origin plus loopback or CP token required) | map |
384
- | POST `/api/control/resume` | vscode-extension/media/loki-dashboard.js:496, vscode-extension/src/api/client.ts:285, vscode-extension/src/extension.ts:743 | /v1/control/resume (CPE24-P4) | PARTIAL (writes only the .loki signal file run.sh reads; no process is signalled; same-origin plus loopback or CP token required) | map |
385
- | POST `/api/control/stop` | vscode-extension/media/loki-dashboard.js:496, vscode-extension/src/api/client.ts:269, vscode-extension/src/extension.ts:651 | /v1/control/stop (CPE24-P4) | PARTIAL (writes only the .loki signal file run.sh reads; no process is signalled; same-origin plus loopback or CP token required) | map |
386
- | GET `/api/cost` | tests/moat/p7-no-fabricated-data.sh:4637 (test), tests/moat/p7-no-fabricated-data.sh:4646 (test), tests/moat/p7-no-fabricated-data.sh:4647 (test) (+3) | /v1/cost/snapshot (CPE24-P1) | PARTIAL (reads the same .loki or registry source; unmeasured values are null with a not-measured marker) | map |
387
- | GET `/api/budget` | tests/e2e/dashboard-evidence-panels.mjs:73 (test), tests/moat/p7-no-fabricated-data.sh:4637 (test), tests/moat/p7-no-fabricated-data.sh:4650 (test) (+3) | none | MISSING | 501 not yet supported |
388
- | GET `/api/cost/timeline` | tests/moat/p7-no-fabricated-data.sh:4637 (test), tests/moat/p7-no-fabricated-data.sh:4652 (test), tests/moat/p7-no-fabricated-data.sh:4653 (test) (+15) | /v1/cost/timeline (CPE24-P1) | PARTIAL (reads the same .loki or registry source; unmeasured values are null with a not-measured marker) | map |
389
- | GET `/api/trust/trajectory` | none | none | UNUSED | 410 with notice |
390
- | GET `/api/gate-policy` | none | none | UNUSED | 410 with notice |
391
- | GET `/api/pricing` | none | none | UNUSED | 410 with notice |
392
- | GET `/api/council/state` | none | /v1/council/state (CPE24-P4) | PARTIAL (reads the same .loki/council files; read-only) | map |
393
- | GET `/api/council/verdicts` | none | /v1/council/verdicts (CPE24-P4) | PARTIAL (reads the same .loki/council files; read-only) | map |
394
- | GET `/api/council/convergence` | none | /v1/council/convergence (CPE24-P4) | PARTIAL (reads the same .loki/council files; read-only) | map |
395
- | GET `/api/council/report` | none | /v1/council/report (CPE24-P4) | PARTIAL (reads the same .loki/council files; read-only) | map |
396
- | POST `/api/council/force-review` | vscode-extension/media/loki-dashboard.js:496, vscode-extension/media/loki-dashboard.js:4312 | /v1/control/council-review (CPE24-P4) | PARTIAL (writes only the .loki signal file run.sh reads; no process is signalled; same-origin plus loopback or CP token required) | map |
397
- | GET `/api/council/transcripts` | vscode-extension/media/loki-dashboard.js:12426 | /v1/council/transcripts (CPE24-P4) | PARTIAL (reads the same .loki/council files; read-only) | map |
398
- | GET `/api/council/transcripts/{iteration_id}` | none | none | UNUSED | 410 with notice |
399
- | GET `/api/context` | tests/moat/p7-no-fabricated-data.sh:4638 (test), tests/moat/p7-no-fabricated-data.sh:4745 (test), tests/moat/p7-no-fabricated-data.sh:4746 (test) (+3) | /v1/context (CPE24-P3) | PARTIAL (reads the same .loki source; legacy SQLite memory backend not read; unmeasured values are null) | map |
400
- | GET `/api/notifications` | none | none | UNUSED | 410 with notice |
401
- | GET `/api/notifications/triggers` | none | none | UNUSED | 410 with notice |
402
- | PUT `/api/notifications/triggers` | vscode-extension/media/loki-dashboard.js:496, vscode-extension/media/loki-dashboard.js:6802 | GET /v1/notifications (derived from events) | DROPPED (section 1) | 410 with notice |
403
- | POST `/api/notifications/{notification_id}/acknowledge` | none | none | UNUSED | 410 with notice |
404
- | POST `/api/notifications/{notification_id}/unacknowledge` | none | none | UNUSED | 410 with notice |
405
- | GET `/api/checkpoints` | vscode-extension/src/views/checkpointProvider.ts:108, vscode-extension/src/views/checkpointProvider.ts:134 | /v1/checkpoints (CPE24-P2) | PARTIAL (reads the same .loki/state/checkpoints store; unmeasured values are null) | map |
406
- | GET `/api/checkpoints/{checkpoint_id}` | none | /v1/checkpoints/{id} (CPE24-P2) | PARTIAL (reads the same .loki/state/checkpoints store; unmeasured values are null) | map |
407
- | POST `/api/checkpoints` | vscode-extension/media/loki-dashboard.js:5960 | /v1/checkpoints (CPE24-P2) | PARTIAL (loopback peer, loopback Host and JSON required; audited) | map |
408
- | POST `/api/checkpoints/{checkpoint_id}/rollback` | vscode-extension/media/loki-dashboard.js:5960 | /v1/checkpoints/{id}/rollback (CPE24-P2) | PARTIAL (loopback peer, loopback Host and JSON required; forced pre-rollback snapshot; audited) | map |
409
- | GET `/api/agents` | none | none | UNUSED | 410 with notice |
410
- | POST `/api/agents/{agent_id}/kill` | vscode-extension/media/loki-dashboard.js:4312 | POST /v1/control/stop | DROPPED (section 1) | 410 with notice |
411
- | POST `/api/agents/{agent_id}/pause` | vscode-extension/media/loki-dashboard.js:4312 | POST /v1/control/stop (v10 has no pause) | DROPPED (section 1) | 410 with notice |
412
- | POST `/api/agents/{agent_id}/resume` | vscode-extension/media/loki-dashboard.js:4312 | POST /v1/control/resume | DROPPED (section 1) | 410 with notice |
413
- | GET `/api/logs` | none | none | UNUSED | 410 with notice |
414
- | POST `/api/collab/join` | none | none | UNUSED | 410 with notice |
415
- | POST `/api/collab/leave` | none | none | UNUSED | 410 with notice |
416
- | GET `/api/collab/users` | none | none | UNUSED | 410 with notice |
417
- | GET `/api/collab/users/{user_id}` | none | none | UNUSED | 410 with notice |
418
- | POST `/api/collab/users/{user_id}/heartbeat` | none | none | UNUSED | 410 with notice |
419
- | POST `/api/collab/users/{user_id}/cursor` | none | none | UNUSED | 410 with notice |
420
- | POST `/api/collab/users/{user_id}/status` | none | none | UNUSED | 410 with notice |
421
- | GET `/api/collab/presence` | none | none | UNUSED | 410 with notice |
422
- | GET `/api/collab/file/{file_path:path}` | none | none | UNUSED | 410 with notice |
423
- | GET `/api/collab/state` | none | none | UNUSED | 410 with notice |
424
- | GET `/api/collab/state/value` | none | none | UNUSED | 410 with notice |
425
- | POST `/api/collab/operation` | none | none | UNUSED | 410 with notice |
426
- | POST `/api/collab/sync` | none | none | UNUSED | 410 with notice |
427
- | GET `/api/collab/history` | none | none | UNUSED | 410 with notice |
428
- | WS `/ws/collab` | none | none | UNUSED | 410 with notice |
429
- | GET `/api/collab/status` | none | none | UNUSED | 410 with notice |
430
- | GET `/api/secrets/status` | none | none | UNUSED | 410 with notice |
431
- | GET `/api/github/status` | none | none | UNUSED | 410 with notice |
432
- | GET `/api/github/tasks` | none | none | UNUSED | 410 with notice |
433
- | GET `/api/github/sync-log` | none | none | UNUSED | 410 with notice |
434
- | GET `/api/health/processes` | none | none | UNUSED | 410 with notice |
435
- | GET `/metrics` | autonomy/loki:29162, tests/e2e/webapp-admin-honesty.mjs:271 (test), tests/e2e/webapp-receipt-panel.mjs:54 (test) (+2) | /v1/metrics (CPE24-P1) | PARTIAL (reads the same .loki or registry source; unmeasured values are null with a not-measured marker) | map |
436
- | GET `/api/checklist` | none | none | UNUSED | 410 with notice |
437
- | GET `/api/usage` | none | none | UNUSED | 410 with notice |
438
- | GET `/api/checklist/summary` | none | none | UNUSED | 410 with notice |
439
- | GET `/api/prd-observations` | none | none | UNUSED | 410 with notice |
440
- | GET `/api/checklist/waivers` | none | none | UNUSED | 410 with notice |
441
- | POST `/api/checklist/waivers` | vscode-extension/media/loki-dashboard.js:496 | plan.json and receipt claims in GET /v1/runs/:id | DROPPED (section 1) | 410 with notice |
442
- | DELETE `/api/checklist/waivers/{item_id}` | vscode-extension/media/loki-dashboard.js:496 | plan.json and receipt claims in GET /v1/runs/:id | DROPPED (section 1) | 410 with notice |
443
- | GET `/api/council/gate` | tests/moat/p7-no-fabricated-data.sh:4638 (test), tests/moat/p7-no-fabricated-data.sh:4760 (test), tests/moat/p7-no-fabricated-data.sh:4762 (test) (+1) | none | MISSING | 501 not yet supported |
444
- | GET `/api/app-runner/status` | none | none | UNUSED | 410 with notice |
445
- | GET `/api/app-runner/logs` | none | none | UNUSED | 410 with notice |
446
- | GET `/api/app-runner/errors` | none | none | UNUSED | 410 with notice |
447
- | POST `/api/control/app-restart` | vscode-extension/media/loki-dashboard.js:496 | evidence in GET /v1/runs/:source/:run/artifact/* | DROPPED (section 1) | 410 with notice |
448
- | POST `/api/control/app-stop` | vscode-extension/media/loki-dashboard.js:496 | evidence in GET /v1/runs/:source/:run/artifact/* | DROPPED (section 1) | 410 with notice |
449
- | GET `/api/playwright/results` | none | none | UNUSED | 410 with notice |
450
- | GET `/api/playwright/screenshot` | none | none | UNUSED | 410 with notice |
451
- | GET `/api/failures` | none | none | UNUSED | 410 with notice |
452
- | GET `/api/prompt-versions` | none | none | UNUSED | 410 with notice |
453
- | POST `/api/prompt-optimize` | autonomy/loki:17793, vscode-extension/media/loki-dashboard.js:7581 | verify stage: POST /v1/runs/:source/:run/verify | DROPPED (section 1) | 410 with notice |
454
- | MOUNT `/assets` | none | UI static assets | EXISTS (vite output under ui/dist/assets) | none (CP UI serves it) |
455
- | GET `/api/activity` | vscode-extension/media/loki-dashboard.js:8596 | none | MISSING | 501 not yet supported |
456
- | GET `/api/session-diff` | none | none | UNUSED | 410 with notice |
457
- | POST `/api/activity` | none | none | UNUSED | 410 with notice |
458
- | GET `/favicon.svg` | none | UI static asset | EXISTS (the CP UI serves its own favicon from ui/dist) | none (CP UI serves it) |
459
- | GET `/cost` | none | CP UI (/) | EXISTS | 308 to CP UI |
460
- | GET `/trust` | none | CP UI (/) | EXISTS | 308 to CP UI |
461
- | GET `/` | none | CP UI (/) | EXISTS | 308 to CP UI |
462
- | GET `/api/quality-score` | none | none | UNUSED | 410 with notice |
463
- | GET `/api/quality-score/history` | none | none | UNUSED | 410 with notice |
464
- | POST `/api/quality-scan` | autonomy/loki:23927, vscode-extension/media/loki-dashboard.js:7832 | verify stage: POST /v1/runs/:source/:run/verify | DROPPED (section 1) | 410 with notice |
465
- | GET `/api/quality-report` | autonomy/loki:23994 | verify stage: POST /v1/runs/:source/:run/verify | DROPPED (section 1) | 410 with notice |
466
- | GET `/api/migration/list` | vscode-extension/media/loki-dashboard.js:8173 | none | MISSING | 501 not yet supported |
467
- | POST `/api/migration/start` | none | none | UNUSED | 410 with notice |
468
- | GET `/api/migration/{migration_id}/status` | vscode-extension/media/loki-dashboard.js:8173 | none | MISSING | 501 not yet supported |
469
- | GET `/api/migration/{migration_id}/plan` | none | none | UNUSED | 410 with notice |
470
- | GET `/api/migration/{migration_id}/features` | none | none | UNUSED | 410 with notice |
471
- | GET `/api/migration/{migration_id}/seams` | none | none | UNUSED | 410 with notice |
472
- | POST `/api/migration/{migration_id}/advance` | none | none | UNUSED | 410 with notice |
473
- | POST `/api/migration/{migration_id}/start-phase` | none | none | UNUSED | 410 with notice |
474
- | GET `/api/managed/events` | vscode-extension/media/loki-dashboard.js:11965 | managed memory dropped; GET /v1/runs/:source/:run/events | DROPPED (section 1) | 410 with notice |
475
- | GET `/api/managed/status` | tests/integration/test_dashboard_api_smoke.sh:105 (test), tests/integration/test_dashboard_api_smoke.sh:106 (test), vscode-extension/media/loki-dashboard.js:11965 | managed memory dropped; GET /v1/runs | DROPPED (section 1) | 410 with notice |
476
- | GET `/api/managed/memory_versions/{memory_id}` | none | none | UNUSED | 410 with notice |
477
- | GET `/api/findings/{iteration}` | none | none | UNUSED | 410 with notice |
478
- | GET `/api/quality/architecture` | none | none | UNUSED | 410 with notice |
479
- | GET `/api/learnings` | tests/e2e/dashboard-evidence-panels.mjs:72 (test) | none | MISSING | 501 not yet supported |
480
- | GET `/api/escalations` | vscode-extension/media/loki-dashboard.js:12356 | none | MISSING | 501 not yet supported |
481
- | GET `/api/escalations/{filename}` | none | none | UNUSED | 410 with notice |
482
- | GET `/api/phases` | none | none | UNUSED | 410 with notice |
483
- | GET `/api/proofs` | tests/e2e/dashboard-evidence-panels.mjs:71 (test), tests/e2e/webapp-receipt-panel.mjs:75 (test), tests/e2e/webapp-receipt-panel.mjs:84 (test) | none | MISSING | 501 not yet supported |
484
- | GET `/api/proofs/summary` | tests/e2e/webapp-receipt-panel.mjs:76 (test) | none | MISSING | 501 not yet supported |
485
- | GET `/api/proofs/{run_id}` | tests/moat/p2-honest-verdict.sh:1251 (test) | none | MISSING | 501 not yet supported |
486
- | GET `/api/proofs/{run_id}/html` | none | none | UNUSED | 410 with notice |
487
- | GET `/api/spec` | none | none | UNUSED | 410 with notice |
488
- | GET `/api/spec/history` | none | none | UNUSED | 410 with notice |
489
- | GET `/api/wiki` | none | none | UNUSED | 410 with notice |
490
- | GET `/api/wiki/{section}` | none | none | UNUSED | 410 with notice |
491
- | POST `/api/wiki/ask` | vscode-extension/media/loki-dashboard.js:12595 | wiki deleted; no replacement | DROPPED (section 1) | 410 with notice |
492
- | GET `/{full_path:path}` | none | SPA fallback | EXISTS (CP app.get("*") serves the SPA and 404s missing assets) | none (CP UI serves it) |
493
-
494
- ### 5.3 Notes for the deletion gate
495
-
496
- - Test consumers that block deleting the legacy routes (they run the Python app in process, so they need the routes or a rewrite): tests/moat/p2-honest-verdict.sh (GET /api/proofs/{run_id}, GET /api/v2/audit/verify) and tests/moat/p7-no-fabricated-data.sh (/api/status, /api/projects, /api/cost, /api/budget, /api/cost/timeline, /api/fleet/runs, /api/fleet/summary, /api/context, /api/memory/economics, /api/learning/metrics, /api/council/gate, /metrics). tests/e2e/dashboard-evidence-panels.mjs and webapp-receipt-panel.mjs read /api/proofs, /api/proofs/summary, /api/learnings, /api/budget. None of these may be weakened or added to tests/moat/pending.txt; CPE-24 must port the property each one proves before the route goes.
497
- - Corrections to the inventory hints: tests/moat/p5-sovereignty.sh does not call /api/enterprise/status or /api/enterprise/tokens (it runs `loki start`, matched by the text `/start`); autonomy/loki does not call /api/control/start or /api/control/stop on the dashboard; the VS Code extension requests `/status`, which the legacy server never served (its catch-all answered HTML), so it is not a row.
498
- - /api/memory/* and /api/learning/* are consumed by the VS Code memory view (src/views/memoryViewProvider.ts, dashboardWebview.ts) and the bundled webview, and p7 reads /api/memory/economics and /api/learning/metrics, so those that appear USED above are not deletable on the UI alone.
499
- - /health: the CP /health identity ({service: "loki-control"}) is relied on by CLI discovery. Callers that probe the legacy /health body at port 57374 (autonomy/loki, autonomy/run.sh, web-app) need either a migrated probe or a separate listener; the shim does not add one.
500
-
501
- ## 6. STEP 2 slice plan
502
-
503
- Rules: one writer per file; UI pages register through ui/src/pages/registry.ts and server routes through src/server/routes/index.ts, both CREATED with stubs for every planned page and route by CPE-02 and CPE-03, so later slices only fill their own stub files. Wall checks run from packages/control-plane. HIGH = opus D12 review.
504
-
505
- | ID | Goal | File set | Wall check | Depends | Tier |
506
- |---|---|---|---|---|---|
507
- | CPE-01 | Design token package: tokens.css, fonts.css, tailwind.preset.ts, primitives (Card, KpiTile, Badge, Pill, StatusDot, Button, Input, Chip, Table, NavItem, GroupHead, Timeline, Message, EmptyState, Spinner, Toast, Dialog, Drawer, Kbd) | ui/src/design/**, ui/tailwind.config.js, test/ui/design.test.tsx | `bun test test/ui/design.test.tsx` (every token in 2.1 present in both themes; hex values match the cited sources; primitives render) | none | MEDIUM |
508
- | CPE-02 | Lean shell: glass sidebar with wordmark, mascot, receipts Pill, New run, grouped session list, Menu sheet, theme toggle, mobile drawer; client router; page registry with stubs | ui/src/App.tsx, ui/src/shell/**, ui/src/pages/registry.ts, ui/src/pages/*/index.tsx (stubs), ui/src/main.tsx, ui/src/index.css, test/ui/shell.test.tsx | `bun test test/ui/shell.test.tsx` (Today, Yesterday, Earlier grouping from fixture; hidden entries for stub pages) | 01 | MEDIUM |
509
- | CPE-03 | Server scaffold: routes/index.ts with stub modules, schema tables local_repos and actions plus migration, audit helper, local discovery fills local_repos, GET /v1/repos | src/server/routes/index.ts, src/server/routes/*.ts (stubs), src/server/audit.ts, src/server/repos.ts, src/db/schema.ts, drizzle/**, src/server/app.ts, src/shipper/discover.ts, test/server/scaffold.test.ts | `bun test test/server/scaffold.test.ts` (ingest never writes local_repos; /v1/repos returns names only) | none | MEDIUM |
510
- | CPE-04 | Run artifacts read API: events page, artifact allowlist, path containment | src/server/routes/artifacts.ts, test/server/artifacts.test.ts | `bun test test/server/artifacts.test.ts` (traversal, symlink escape, oversize, unknown name all refused) | 03 | HIGH |
511
- | CPE-05 | SSE stream for one run and for the runs list | src/server/routes/stream.ts, test/server/stream.test.ts | `bun test test/server/stream.test.ts` | 03 | MEDIUM |
512
- | CPE-06 | Run thread view: stage messages, live log, diff, evidence, receipt, NOT PROVEN, cost, PR, BLOCKED reply prompt, Details drawer; replaces Live.tsx | ui/src/pages/run/**, ui/src/Live.tsx (delete), test/ui/run.test.tsx | `bun test test/ui/run.test.tsx` (fixture run renders every section; missing cost shows "not measured") | 02, 04, 05 | MEDIUM |
513
- | CPE-07 | Start-run endpoint POST /v1/runs | src/server/routes/start.ts, src/server/spawn.ts, test/server/start.test.ts | `bun test test/server/start.test.ts` (unknown repo, shell metacharacters, unknown flag, missing token, bad Origin all refused; argv exact) | 03 | HIGH |
514
- | CPE-08 | New run composer: one input, chips, Cmd+Enter, optimistic session row, empty state | ui/src/pages/compose/**, test/ui/compose.test.tsx | `bun test test/ui/compose.test.tsx` | 02, 07 | MEDIUM |
515
- | CPE-09 | Run control: supervisor writes <run>/run.pid (pid, start time, argv); stop, retry, resume endpoints | loki-ts/src/util/run_pid.ts, loki-ts/src/engine10/supervisor.ts, src/server/routes/control.ts, test/server/control.test.ts, loki-ts/tests/engine10/run_pid.test.ts | `bun test test/server/control.test.ts` and `cd loki-ts && bun test tests/engine10/run_pid.test.ts` (stale pid, reused pid, other run's pid refused) | 03 | HIGH |
516
- | CPE-10 | Run control UI: Stop (confirm), Retry, Resume with optimistic state and rollback | ui/src/pages/run-controls/** (mounted in the run header slot CPE-06 provides), test/ui/controls.test.tsx | `bun test test/ui/controls.test.tsx` | 06, 09 | LOW |
517
- | CPE-11 | Runs table page with filters and group rollup | ui/src/pages/runs/**, test/ui/runs.test.tsx | `bun test test/ui/runs.test.tsx` | 02 | LOW |
518
- | CPE-12 | Home: /v1/stats plus KPI tiles, recent runs, BLOCKED inbox | src/server/routes/stats.ts, ui/src/pages/home/**, test/server/stats.test.ts, test/ui/home.test.tsx | `bun test test/server/stats.test.ts test/ui/home.test.tsx` (numbers equal a hand-folded fixture) | 02, 03 | MEDIUM |
519
- | CPE-13 | Cost and usage: /v1/stats/cost plus page with measured vs partial and budget banner | src/server/routes/cost.ts, ui/src/pages/cost/**, test/server/cost.test.ts, test/ui/cost.test.tsx | `bun test test/server/cost.test.ts test/ui/cost.test.tsx` | 02, 03 | MEDIUM |
520
- | CPE-14 | Settings: GET, PUT /v1/config with schema validation, comment-preserving atomic write, If-Match; forms per schema section | src/server/routes/config.ts, ui/src/pages/settings/**, package.json (yaml dep), test/server/config.test.ts, test/ui/settings.test.tsx | `bun test test/server/config.test.ts` (comments survive round trip; invalid rejected; stale If-Match 409; secret-looking value refused) | 02, 03 | HIGH |
521
- | CPE-15 | Models and providers: /v1/providers plus page | src/server/routes/providers.ts, ui/src/pages/models/**, test/server/providers.test.ts | `bun test test/server/providers.test.ts` (probe timeout honored; no secret value returned) | 02, 03 | MEDIUM |
522
- | CPE-16 | Receipts: list, in-place verify, public key, verified-rate trend | src/server/routes/verify.ts, ui/src/pages/receipts/**, test/server/verify.test.ts | `bun test test/server/verify.test.ts` (tampered fixture fails verify) | 04 | MEDIUM |
523
- | CPE-17 | Plans and traceability matrix from issue.json, plan.json, stages, files, receipt | ui/src/pages/plans/**, test/ui/plans.test.tsx | `bun test test/ui/plans.test.tsx` | 04 | MEDIUM |
524
- | CPE-18 | Work board kanban from runs (issue to running to PR to verified or not proven) | ui/src/pages/board/**, test/ui/board.test.tsx | `bun test test/ui/board.test.tsx` | 02 | LOW |
525
- | CPE-19 | Workspaces page: list from config, group status, run a workspace via POST /v1/runs body.workspace | ui/src/pages/workspaces/**, test/ui/workspaces.test.tsx | `bun test test/ui/workspaces.test.tsx` | 07, 14 | MEDIUM |
526
- | CPE-20 | Integrations: /v1/integrations status probes plus page; connect writes env var names through /v1/config | src/server/routes/integrations.ts, ui/src/pages/integrations/**, test/server/integrations.test.ts | `bun test test/server/integrations.test.ts` | 14 | MEDIUM |
527
- | CPE-21 | Notifications and Audit log: derived notifications, actions view | src/server/routes/notify.ts, src/server/routes/audit.ts, ui/src/pages/notifications/**, ui/src/pages/audit/**, test/server/notify.test.ts | `bun test test/server/notify.test.ts` | 03 | LOW |
528
- | CPE-22 | Cmd+K palette, global search, shortcuts (Cmd+Enter, Cmd+N, Cmd+Shift+D, Esc) | ui/src/palette/**, test/ui/palette.test.tsx | `bun test test/ui/palette.test.tsx` | 02 | LOW |
529
- | CPE-23 | Accessibility, mobile and visual parity: axe, keyboard path, 375 px layout, light and dark screenshot comparison to legacy captures | test/e2e/cp-ui.spec.ts, test/e2e/legacy-baseline/**, ui/playwright.config.ts | `bunx playwright test test/e2e/cp-ui.spec.ts` (headless, LOKI_NO_BROWSER=1) | 06, 08, 12 | MEDIUM |
530
- | CPE-24 | Delete legacy dashboard at parity: legacy-ui/, legacy-ui-static/, legacy server routes, their tests and package entries | legacy-ui/**, legacy-ui-static/**, dashboard/server.py (UI routes), package.json files list, tests naming them | section 5 checklist all green plus `bash scripts/local-ci.sh` | all, section 5 | MEDIUM |
531
-
532
- Parallelism: CPE-01 and CPE-03 start at once; after them up to 12 builders run in parallel (04, 05, 07, 09, 11, 12, 13, 14, 15, 18, 21, 22). HIGH slices (04, 07, 09, 14) carry the security review the founder asked for.
533
-
534
- ## 7. Open questions
535
- 1. Ground color: the shell's light-grey #F1F2F6 (founder-approved per build-standalone.js:113) or the components' warm cream #FFFEFB with midnight-purple dark #1A0F2E (unified-styles.js:24, :88)? This spec picks the shell; one screenshot pair for Loki settles it.
536
- 2. Mascot: keep it beside the wordmark (it was part of the old look) or drop it for a cleaner Claude.ai-like header?
537
- 3. Modernize, merge queue, PR risk review, schedules and memory have no v10 run events or API today. They stay hidden in 10.8.0 and get UI slices when their backends land; confirm that is acceptable for "no feature is CLI-only".