loki-mode 10.8.0 → 10.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/.github/actions/issue-to-pr/action.yml +2 -2
  2. package/README.md +11 -5
  3. package/SKILL.md +12 -2
  4. package/VERSION +1 -1
  5. package/autonomy/lib/proof-generator.py +1 -0
  6. package/autonomy/loki +55 -40
  7. package/autonomy/receipt_jwt.py +46 -1
  8. package/autonomy/run.sh +1 -1
  9. package/autonomy/telemetry.sh +1 -1
  10. package/autonomy/trigger-server.py +1 -0
  11. package/autonomy/tui.sh +5 -1
  12. package/bin/loki +12 -1
  13. package/bin/loki-postinstall.js +12 -0
  14. package/dashboard/__init__.py +1 -1
  15. package/dashboard/api_phases.py +1 -1
  16. package/dashboard/api_start.py +0 -1
  17. package/dashboard/server.py +22 -138
  18. package/docs/CLI-REFERENCE.md +139 -0
  19. package/docs/COCKPIT-SPEC.md +3 -1
  20. package/docs/DASHBOARD-9.12-EVIDENCE.md +1 -1
  21. package/docs/DASHBOARD-ARCHITECTURE.md +13 -11
  22. package/docs/DASHBOARD_V2_CHECKLIST.md +2 -0
  23. package/docs/INSTALLATION.md +12 -11
  24. package/docs/LOKI-10-BUILD-PROMPT.md +2 -2
  25. package/docs/MERGE-DEDUP-MAP.md +1 -1
  26. package/docs/MERGE-ROUTE-MAP.md +1 -1
  27. package/docs/MERGE3-PLAN.md +2 -2
  28. package/docs/PLANS-INDEX.md +2 -3
  29. package/docs/R3-COST-OBSERVABILITY-DESIGN.md +2 -2
  30. package/docs/R4-TRUST-TRAJECTORY-DESIGN.md +1 -1
  31. package/docs/R5-AUTO-WIKI-DESIGN.md +1 -1
  32. package/docs/R6-ROLLBACK-CHECKPOINT-PLAN.md +1 -1
  33. package/docs/RARV-C-100X-PLAN.md +3 -3
  34. package/docs/SLO.md +3 -3
  35. package/docs/SONNET5-DEFAULT-PLAN.md +2 -2
  36. package/docs/SYNERGY-TASKS.md +1 -1
  37. package/docs/TOOL-INTEGRATION.md +1 -1
  38. package/docs/TOP-100-BACKLOG.md +1 -1
  39. package/docs/alternative-installations.md +2 -2
  40. package/docs/architecture/ADR-001-runtime-migration.md +1 -1
  41. package/docs/architecture/DASHBOARD_V2_ARCHITECTURE.md +2 -0
  42. package/docs/audit-logging.md +2 -0
  43. package/docs/authentication.md +2 -0
  44. package/docs/authorization.md +2 -0
  45. package/docs/bug-fixes/agent-04-memory-fixes.md +1 -1
  46. package/docs/certification/02-enterprise-features/lab.md +2 -0
  47. package/docs/certification/02-enterprise-features/lesson.md +2 -0
  48. package/docs/certification/04-production-deployment/lab.md +2 -0
  49. package/docs/certification/04-production-deployment/lesson.md +2 -0
  50. package/docs/control-plane-migration.md +97 -0
  51. package/docs/dashboard-guide.md +6 -7
  52. package/docs/dev/release-checklist.md +10 -12
  53. package/docs/enterprise/integration-cookbook.md +2 -0
  54. package/docs/enterprise/migration.md +1 -1
  55. package/docs/enterprise/performance.md +3 -1
  56. package/docs/enterprise/sdk-guide.md +2 -0
  57. package/docs/enterprise/security.md +2 -0
  58. package/{.github/workflows/loki-issue-to-pr.yml → docs/examples/loki-issue-to-pr.yml.example} +2 -0
  59. package/docs/{ONE-RUN-AUDIT.md → history/one-run-audit.md} +6 -0
  60. package/docs/{BUG-AUDIT-v6.61.0.md → history/v6.61.0-audit.md} +6 -0
  61. package/docs/{V8-AGENT-SDK-PLAN.md → history/v8-agent-sdk-plan.md} +6 -0
  62. package/docs/{CONFIG-FILE-PLAN.md → history/v8-config-plan.md} +6 -0
  63. package/docs/plans/FORGE-AUTONOMOUS-QUEUE.md +2 -2
  64. package/docs/research-2026-07/OBSERVABILITY-TOOL-SPEC.md +1 -1
  65. package/docs/retrospectives/v7.5.15-honesty-audit.md +2 -2
  66. package/docs/test-scenarios/enterprise-scenarios.md +3 -3
  67. package/docs/v10/ARCHITECT-CUTS.md +9 -9
  68. package/docs/v10/BACKLOG.md +7 -7
  69. package/docs/v10/BOARD.md +28 -25
  70. package/docs/v10/CLI-MODERN.md +190 -0
  71. package/docs/v10/CONTROL-PLANE.md +4 -4
  72. package/docs/v10/CP-ENTERPRISE-UI.md +66 -66
  73. package/docs/v10/D51-PHASE-B.md +1 -1
  74. package/docs/v10/DECISIONS.md +3 -3
  75. package/docs/v10/DEPS.md +148 -169
  76. package/docs/v10/FAILURE-CLASSES.md +63 -1
  77. package/docs/v10/LEGACY-REMOVAL.md +335 -26
  78. package/docs/v10/PROGRESS.md +15 -0
  79. package/docs/v10/SWARM.md +2 -2
  80. package/loki-ts/dist/cockpit.js +11 -11
  81. package/loki-ts/dist/loki.js +1610 -1813
  82. package/magic/core/design_tokens.py +1 -2
  83. package/magic/core/generator.py +2 -2
  84. package/magic/tokens/README.md +1 -3
  85. package/mcp/__init__.py +1 -1
  86. package/package.json +4 -8
  87. package/packages/control-plane/dist/server.js +1956 -1019
  88. package/packages/control-plane/src/db/fixture-cleanup.ts +47 -0
  89. package/packages/control-plane/src/server/app.ts +2 -0
  90. package/packages/control-plane/src/server/integrity.ts +48 -9
  91. package/packages/control-plane/src/server/legacy/routes-audit.ts +50 -0
  92. package/packages/control-plane/src/server/legacy/routes-control.ts +26 -0
  93. package/packages/control-plane/src/server/legacy/routes-memory.ts +30 -0
  94. package/packages/control-plane/src/server/legacy/routes.ts +58 -58
  95. package/packages/control-plane/src/server/legacy/shim.ts +10 -4
  96. package/packages/control-plane/src/server/routes/checkpoints.ts +171 -0
  97. package/packages/control-plane/src/server/routes/index.ts +4 -1
  98. package/packages/control-plane/src/server/routes/memory.ts +219 -0
  99. package/packages/control-plane/src/server/routes/session_control.ts +155 -0
  100. package/packages/control-plane/src/server/routes/stats.ts +16 -5
  101. package/packages/control-plane/src/server/runs.ts +16 -4
  102. package/packages/control-plane/ui/dist/assets/index-NAMkcA9N.js +165 -0
  103. package/packages/control-plane/ui/dist/index.html +1 -1
  104. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  105. package/references/magic-modules-patterns.md +2 -2
  106. package/schemas/status-result.schema.json +13 -22
  107. package/skills/factory-operations.md +3 -3
  108. package/skills/magic-modules.md +1 -1
  109. package/skills/release-cadence.md +6 -6
  110. package/tools/audit-docs.py +1 -1
  111. package/tools/index-codebase.py +1 -1
  112. package/web-app/dist/assets/{AdminPage-DDDvUz0N.js → AdminPage-B8RjG3sy.js} +1 -1
  113. package/web-app/dist/assets/{Avatar-Dcdz46i6.js → Avatar-Dttmvqc-.js} +1 -1
  114. package/web-app/dist/assets/{Badge-BB24cCpK.js → Badge-Bvyp8VrD.js} +1 -1
  115. package/web-app/dist/assets/{Button-D0-DmPZL.js → Button-DtY5ZrZw.js} +1 -1
  116. package/web-app/dist/assets/{CockpitPage-CdjpU2JW.js → CockpitPage-B2gbOwRp.js} +1 -1
  117. package/web-app/dist/assets/{ComparePage-DT5U0y0d.js → ComparePage-CHi5nZTU.js} +1 -1
  118. package/web-app/dist/assets/{ErrorBoundary-lEHcl0EO.js → ErrorBoundary-BUuTj-OQ.js} +1 -1
  119. package/web-app/dist/assets/{EvidenceReceiptPanel-GpnWvdCr.js → EvidenceReceiptPanel-C5aOn4ES.js} +1 -1
  120. package/web-app/dist/assets/{GitHubIssuesPanel-C7VOh1B7.js → GitHubIssuesPanel-isVxxHXb.js} +1 -1
  121. package/web-app/dist/assets/{GitHubPRsPanel-G_kOuINv.js → GitHubPRsPanel-DtDpxyQl.js} +1 -1
  122. package/web-app/dist/assets/{HomePage-PqRisOny.js → HomePage-Casf-LUB.js} +2 -2
  123. package/web-app/dist/assets/{LoginPage-DU7pFAkf.js → LoginPage-DvB78691.js} +1 -1
  124. package/web-app/dist/assets/{MagicPage-C5JWIWMk.js → MagicPage-DU6hmbnC.js} +1 -1
  125. package/web-app/dist/assets/{MetricsPage-CbIGS_qo.js → MetricsPage-DcPwzoS8.js} +1 -1
  126. package/web-app/dist/assets/{NotFoundPage-vU1pvdSt.js → NotFoundPage-Bs6WxAZ8.js} +1 -1
  127. package/web-app/dist/assets/{ProjectPage-SsixIPPv.js → ProjectPage-RBIqC-DJ.js} +3 -3
  128. package/web-app/dist/assets/{ProjectsPage-BfQKSR9k.js → ProjectsPage-CogXD7jM.js} +1 -1
  129. package/web-app/dist/assets/{SettingsPage-B8YfXAom.js → SettingsPage-pAyJAfPt.js} +1 -1
  130. package/web-app/dist/assets/{ShowcasePage-Ba407f2-.js → ShowcasePage-D6bT2bDd.js} +1 -1
  131. package/web-app/dist/assets/{SystemSettingsPage-DzNQhhBS.js → SystemSettingsPage-CE8xiJRh.js} +1 -1
  132. package/web-app/dist/assets/{TeamsPage-tqUnpZ15.js → TeamsPage-wMS55TDT.js} +1 -1
  133. package/web-app/dist/assets/{TemplatesPage-ClB5EpI3.js → TemplatesPage-COJNVQqu.js} +1 -1
  134. package/web-app/dist/assets/{TerminalOutput-CBvpYfEu.js → TerminalOutput-Cc2XASxd.js} +1 -1
  135. package/web-app/dist/assets/{activity-C1s0L_X9.js → activity-C6eHFDjL.js} +1 -1
  136. package/web-app/dist/assets/{bell-DMEiXr73.js → bell-BJpVYj4n.js} +1 -1
  137. package/web-app/dist/assets/{bot-BF_xIOxu.js → bot-BwRVVUQL.js} +1 -1
  138. package/web-app/dist/assets/{check-Dv1Ynvrs.js → check-CGDwoKy8.js} +1 -1
  139. package/web-app/dist/assets/{chevron-left-Ddhsod7S.js → chevron-left-CF2Nilj6.js} +1 -1
  140. package/web-app/dist/assets/{circle-alert-OATHUkBZ.js → circle-alert-D0RyRec1.js} +1 -1
  141. package/web-app/dist/assets/{clock-C1Ltva07.js → clock-xeF3gW0W.js} +1 -1
  142. package/web-app/dist/assets/{cloud-B-S4oOy9.js → cloud-D5Sy69ZZ.js} +1 -1
  143. package/web-app/dist/assets/{code-xml-D3Femn_F.js → code-xml-C6-5Ql9I.js} +1 -1
  144. package/web-app/dist/assets/{database-DBSeFgO3.js → database-BSjG1_z0.js} +1 -1
  145. package/web-app/dist/assets/{dollar-sign-sgDgNuGE.js → dollar-sign-FnDR2QUu.js} +1 -1
  146. package/web-app/dist/assets/{file-code-corner-C-MbdZEc.js → file-code-corner-BiOK9vR6.js} +1 -1
  147. package/web-app/dist/assets/{file-plus-CCB6yqXv.js → file-plus-3WALQDEE.js} +1 -1
  148. package/web-app/dist/assets/{globe-DlbrNAj1.js → globe-vUdUrQqp.js} +1 -1
  149. package/web-app/dist/assets/{hammer-B-DWm695.js → hammer-0VwHUEpa.js} +1 -1
  150. package/web-app/dist/assets/{index-Dvny-1SU.js → index-BMKIwteZ.js} +3 -3
  151. package/web-app/dist/assets/{layers-99qsKpOT.js → layers-C6q8kzST.js} +1 -1
  152. package/web-app/dist/assets/{loader-circle-ZvZyZl3J.js → loader-circle-B4Tz724d.js} +1 -1
  153. package/web-app/dist/assets/{lock-DosGjcxP.js → lock-yxvEA65n.js} +1 -1
  154. package/web-app/dist/assets/{package-C-PumesN.js → package-BpKD0Ot0.js} +1 -1
  155. package/web-app/dist/assets/{plus-CTYYskTB.js → plus-Ibqx_Vo9.js} +1 -1
  156. package/web-app/dist/assets/{refresh-cw-qW2ztTFS.js → refresh-cw-C9auyvi-.js} +1 -1
  157. package/web-app/dist/assets/{rotate-ccw-ZIKrf-vO.js → rotate-ccw-2cEiXm6O.js} +1 -1
  158. package/web-app/dist/assets/{scroll-text-BamlXjAT.js → scroll-text-BPAWML-w.js} +1 -1
  159. package/web-app/dist/assets/{server-BljXb79I.js → server-CZh6B1zx.js} +1 -1
  160. package/web-app/dist/assets/{shield-alert-Dr6eT9c_.js → shield-alert-CivolUIx.js} +1 -1
  161. package/web-app/dist/assets/{thumbs-up-v3oBXZgU.js → thumbs-up-BP9covEH.js} +1 -1
  162. package/web-app/dist/assets/{trash-2-BOuIrCpi.js → trash-2-BCDfTcNx.js} +1 -1
  163. package/web-app/dist/assets/{trending-down-Dp7jMCgH.js → trending-down-5LypivXh.js} +1 -1
  164. package/web-app/dist/assets/{trending-up-CDiur-nP.js → trending-up-DNt4SFdk.js} +1 -1
  165. package/web-app/dist/assets/{upload-DxIHXhNE.js → upload-DBmHbY6y.js} +1 -1
  166. package/web-app/dist/assets/{usePolling-D2Uu-YZb.js → usePolling-DOPZcbUL.js} +1 -1
  167. package/web-app/dist/assets/{user-BVWCUAfF.js → user-BQTJJDCG.js} +1 -1
  168. package/web-app/dist/index.html +1 -1
  169. package/dashboard/static/assets/mermaid.min.js +0 -2030
  170. package/dashboard/static/cost.html +0 -344
  171. package/dashboard/static/favicon.svg +0 -5
  172. package/dashboard/static/index.html +0 -15577
  173. package/dashboard/static/proofs.html +0 -194
  174. package/dashboard/static/start.html +0 -131
  175. package/dashboard/static/trust.html +0 -325
  176. package/docs/BRANCH-LIFECYCLE-PLAN.md +0 -354
  177. package/docs/EXECUTION-COCKPIT-PLAN.md +0 -289
  178. package/packages/control-plane/ui/dist/assets/index-Dbhu244h.js +0 -155
@@ -1149,14 +1149,8 @@ app.add_middleware(
1149
1149
  allow_headers=["Content-Type", "Authorization", "X-Requested-With"],
1150
1150
  )
1151
1151
 
1152
- # RESPONSE COMPRESSION. Measured, not assumed: the served dashboard bundle
1153
- # (dashboard/static/index.html) is 779,725 bytes raw and 150,341 gzipped --
1154
- # an 81% reduction. Until now only CORS and the collab WS auth middleware were
1155
- # registered, so every dashboard load shipped the full 780KB.
1156
- #
1157
- # That single fact is the most plausible cause of "the dashboard feels slow":
1158
- # it is not a rendering problem, it is 630KB of avoidable transfer on first
1159
- # paint, and it costs one middleware to fix.
1152
+ # RESPONSE COMPRESSION. Large JSON API payloads compress well, and it costs one
1153
+ # middleware. (The legacy single-file UI bundle that motivated it was removed.)
1160
1154
  #
1161
1155
  # minimum_size=1024 leaves small JSON responses uncompressed, where the CPU
1162
1156
  # round-trip outweighs the saving. GZipMiddleware is stdlib-backed and does
@@ -1360,16 +1354,12 @@ else:
1360
1354
  app.include_router(api_operator_router)
1361
1355
 
1362
1356
  # D51 Phase A: first-run onboarding + backlog API and its /start page.
1363
- from .api_start import router as api_start_router, START_HTML as _START_HTML
1357
+ from .api_start import router as api_start_router
1364
1358
  app.include_router(api_start_router)
1365
1359
  from .api_runs_v1 import router as api_runs_v1_router
1366
1360
  app.include_router(api_runs_v1_router)
1367
1361
 
1368
1362
 
1369
- @app.get("/start", include_in_schema=False, dependencies=[Depends(auth.require_scope("read"))])
1370
- async def serve_start_page():
1371
- return FileResponse(_START_HTML, media_type="text/html")
1372
-
1373
1363
 
1374
1364
  # Phase Merge-4: Mount Purple Lab FastAPI app under /lab/ so it appears as a
1375
1365
  # sidebar entry in Dashboard. Same `app` is also wrapped by `standalone_app`
@@ -11579,49 +11569,11 @@ def optimize_prompts(sessions: int = 10, dry_run: bool = True):
11579
11569
 
11580
11570
  from fastapi.responses import FileResponse, HTMLResponse
11581
11571
 
11582
- # Find static files in multiple possible locations
11583
11572
  DASHBOARD_DIR = os.path.dirname(os.path.abspath(__file__))
11584
11573
  PROJECT_ROOT = os.path.dirname(DASHBOARD_DIR)
11585
11574
 
11586
- # Possible static file locations (in order of preference)
11587
- # Resolves correctly regardless of PYTHONPATH, symlinks, or install method
11588
- def _static_candidates(skill_dir=None, home=None):
11589
- """Static dirs in preference order: package, LOKI_SKILL_DIR, ~/.claude skill, dev build."""
11590
- skill_dir = os.environ.get("LOKI_SKILL_DIR", "") if skill_dir is None else skill_dir
11591
- home_skill = os.path.join(home or os.path.expanduser("~"), ".claude", "skills", "loki-mode")
11592
- cands = [os.path.join(DASHBOARD_DIR, "static")]
11593
- if skill_dir:
11594
- cands.append(os.path.join(skill_dir, "dashboard", "static"))
11595
- cands.append(os.path.join(home_skill, "dashboard", "static"))
11596
- cands.append(os.path.join(PROJECT_ROOT, "dashboard-ui", "dist"))
11597
- if skill_dir:
11598
- cands.append(os.path.join(skill_dir, "dashboard-ui", "dist"))
11599
- cands.append(os.path.join(home_skill, "dashboard-ui", "dist"))
11600
- return cands
11601
-
11602
-
11603
- def _pick_static_dir(candidates):
11604
- """First candidate that CONTAINS index.html; an empty or partial dir must not win."""
11605
- for loc in candidates:
11606
- if os.path.isfile(os.path.join(loc, "index.html")):
11607
- return loc
11608
- return None
11609
-
11610
-
11611
- STATIC_LOCATIONS = _static_candidates()
11612
- STATIC_DIR = _pick_static_dir(STATIC_LOCATIONS)
11613
- if STATIC_DIR:
11614
- logger.info("Dashboard frontend served from: %s", STATIC_DIR)
11615
- else:
11616
- logger.warning("Dashboard frontend NOT found (looked in %s); serving built-in fallback page", STATIC_LOCATIONS)
11617
-
11618
- if STATIC_DIR:
11619
- from fastapi.staticfiles import StaticFiles
11620
-
11621
- # Check if assets directory exists (built frontend)
11622
- ASSETS_DIR = os.path.join(STATIC_DIR, "assets")
11623
- if os.path.isdir(ASSETS_DIR):
11624
- app.mount("/assets", StaticFiles(directory=ASSETS_DIR), name="assets")
11575
+ DASHBOARD_DIR = os.path.dirname(os.path.abspath(__file__))
11576
+ PROJECT_ROOT = os.path.dirname(DASHBOARD_DIR)
11625
11577
 
11626
11578
  # ---------------------------------------------------------------------------
11627
11579
  # Activity Logger & Session Diff
@@ -11682,75 +11634,29 @@ async def log_activity(entry: dict):
11682
11634
  return result
11683
11635
 
11684
11636
 
11685
- # Serve favicon.svg from static directory
11686
- @app.get("/favicon.svg", include_in_schema=False)
11687
- async def serve_favicon():
11688
- """Serve the dashboard favicon."""
11689
- if STATIC_DIR:
11690
- favicon_path = os.path.join(STATIC_DIR, "favicon.svg")
11691
- if os.path.isfile(favicon_path):
11692
- return FileResponse(favicon_path, media_type="image/svg+xml")
11693
- return Response(status_code=404)
11694
-
11695
-
11696
- # Serve the self-contained cost + observability panel (R3). Zero-build
11697
- # standalone page that fetches /api/cost/timeline. Mirrors the proofs.html
11698
- # pattern: works without the SPA build.
11699
- @app.get("/cost", include_in_schema=False, dependencies=[Depends(auth.require_scope("read"))])
11700
- async def serve_cost_panel():
11701
- """Serve the standalone cost + observability HTML panel."""
11702
- if STATIC_DIR:
11703
- cost_path = os.path.join(STATIC_DIR, "cost.html")
11704
- if os.path.isfile(cost_path):
11705
- return FileResponse(cost_path, media_type="text/html")
11706
- return Response(status_code=404)
11707
-
11708
-
11709
- # R4: standalone trust-trajectory page that fetches /api/trust/trajectory.
11710
- # Mirrors the cost.html / /cost pattern: works without the SPA build.
11711
- @app.get("/trust", include_in_schema=False, dependencies=[Depends(auth.require_scope("read"))])
11712
- async def serve_trust_panel():
11713
- """Serve the standalone trust-trajectory HTML panel."""
11714
- if STATIC_DIR:
11715
- trust_path = os.path.join(STATIC_DIR, "trust.html")
11716
- if os.path.isfile(trust_path):
11717
- return FileResponse(trust_path, media_type="text/html")
11718
- return Response(status_code=404)
11719
-
11720
-
11721
- # Serve index.html or standalone HTML for root
11637
+ # The legacy dashboard UI was removed (CPE-24). The Control Plane serves the UI;
11638
+ # this server keeps only the /api/* routes that have no Control Plane home yet.
11722
11639
  @app.get("/", include_in_schema=False, dependencies=[Depends(auth.require_scope("read"))])
11723
11640
  async def serve_index():
11724
- """Serve the frontend SPA or standalone HTML."""
11725
- # Try multiple index file locations
11726
- index_candidates = []
11727
- if STATIC_DIR:
11728
- index_candidates.append(os.path.join(STATIC_DIR, "index.html"))
11729
- index_candidates.append(os.path.join(STATIC_DIR, "loki-dashboard-standalone.html"))
11641
+ """Tell a browser where the UI moved; never serve developer JSON to it."""
11642
+ return HTMLResponse(content=_moved_page(), status_code=410)
11730
11643
 
11731
- # Also check dashboard-ui directly for standalone
11732
- standalone_path = os.path.join(PROJECT_ROOT, "dashboard-ui", "dist", "loki-dashboard-standalone.html")
11733
- if standalone_path not in index_candidates:
11734
- index_candidates.append(standalone_path)
11735
11644
 
11736
- for index_path in index_candidates:
11737
- if os.path.isfile(index_path):
11738
- return FileResponse(index_path, media_type="text/html")
11739
-
11740
- # No frontend anywhere: a browser must never see developer JSON.
11741
- return HTMLResponse(content=_fallback_page(), status_code=503)
11742
-
11743
-
11744
- def _fallback_page() -> str:
11645
+ def _moved_page() -> str:
11745
11646
  import html as _html
11647
+ cp = os.environ.get("LOKI_CONTROL_PLANE_URL", "").strip()
11648
+ where = (
11649
+ f'<p>Control Plane: <a href="{_html.escape(cp, quote=True)}">{_html.escape(cp)}</a></p>'
11650
+ if cp.startswith(("http://", "https://"))
11651
+ else "<p>Run <code>loki ui</code> to open the Control Plane.</p>"
11652
+ )
11746
11653
  return (
11747
11654
  '<!doctype html><html lang="en"><head><meta charset="utf-8">'
11748
- "<title>Loki Mode Dashboard</title></head>"
11655
+ "<title>Loki Mode API</title></head>"
11749
11656
  '<body style="font-family:system-ui,sans-serif;max-width:40rem;margin:4rem auto;padding:0 1rem">'
11750
- "<h1>Loki Mode dashboard UI is not installed</h1>"
11751
- f"<p>The dashboard API is running (version {_html.escape(str(_version))}) "
11752
- "but this install has no frontend files.</p>"
11753
- "<p>Reinstall to fix it:</p><pre>npm install -g loki-mode@latest</pre>"
11657
+ "<h1>The dashboard UI moved to the Control Plane</h1>"
11658
+ f"<p>This server (version {_html.escape(str(_version))}) now serves the /api routes only.</p>"
11659
+ f"{where}"
11754
11660
  '<p><a href="/docs">API docs</a> | <a href="/health">Health</a></p>'
11755
11661
  "</body></html>"
11756
11662
  )
@@ -13099,40 +13005,18 @@ async def post_wiki_ask(req: WikiAskRequest):
13099
13005
 
13100
13006
 
13101
13007
  # ---------------------------------------------------------------------------
13102
- # SPA catch-all: serve index.html for any path not matched by API routes
13103
- # or static asset mounts. This lets the dashboard UI handle client-side routing.
13008
+ # Catch-all: unknown paths are real 404s (the SPA was removed, CPE-24).
13104
13009
  # Must be registered LAST so it never shadows an API endpoint.
13105
13010
  # ---------------------------------------------------------------------------
13106
13011
  @app.get("/{full_path:path}", include_in_schema=False, dependencies=[Depends(auth.require_scope("read"))])
13107
13012
  async def serve_spa_catchall(full_path: str):
13108
- """Serve static files or fall back to index.html for SPA routing.
13109
-
13110
- v7.6.1 B-10 fix: requests under /api/, /lab/api/, or /ws/ that fall through
13111
- here are missing routes, not SPA navigation. Returning index.html (text/html)
13112
- silently masks 404s and breaks JSON clients (the dashboard UI's loki-memory-browser
13113
- pinged /api/learning/metrics expecting JSON and got an HTML SPA on prior
13114
- failures). Return a JSON 404 instead so clients fail loud.
13115
- """
13116
- # API paths that fell through are real 404s, not SPA routes.
13013
+ """Return a JSON 404 for API-like paths so JSON clients fail loud, else a bare 404."""
13117
13014
  api_like = full_path.startswith("api/") or full_path.startswith("lab/api/") or full_path.startswith("ws/")
13118
13015
  if api_like:
13119
13016
  return JSONResponse(
13120
13017
  status_code=404,
13121
13018
  content={"error": "Not Found", "path": f"/{full_path}"},
13122
13019
  )
13123
- if STATIC_DIR:
13124
- static_root = os.path.realpath(STATIC_DIR)
13125
- # Try to serve the exact file first (e.g. /vite.svg, /manifest.json)
13126
- # Use realpath to prevent path traversal attacks
13127
- candidate = os.path.realpath(os.path.join(STATIC_DIR, full_path))
13128
- if not candidate.startswith(static_root + os.sep) and candidate != static_root:
13129
- return Response(status_code=404)
13130
- if os.path.isfile(candidate):
13131
- return FileResponse(candidate)
13132
- # Fall back to index.html for client-side routes
13133
- index_path = os.path.join(STATIC_DIR, "index.html")
13134
- if os.path.isfile(index_path):
13135
- return FileResponse(index_path, media_type="text/html")
13136
13020
  return Response(status_code=404)
13137
13021
 
13138
13022
 
@@ -0,0 +1,139 @@
1
+ # CLI reference
2
+
3
+ Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v10.10.1. Do not edit by hand.
4
+ Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for the full inventory.
5
+
6
+ | Command | Description |
7
+ | --- | --- |
8
+ | `loki version` | Show version |
9
+ | `loki status` | Show current run status |
10
+ | `loki doctor` | System prerequisites health check |
11
+ | `loki provider` | Show, list or set the AI provider |
12
+ | `loki provider show` | Show current provider |
13
+ | `loki provider list` | List providers and install status |
14
+ | `loki provider set` | Switch the active provider |
15
+ | `loki memory` | Cross-project learnings |
16
+ | `loki memory list` | All learnings |
17
+ | `loki memory index` | Show or rebuild the memory index |
18
+ | `loki memory show` | Show one learning |
19
+ | `loki memory search` | Search learnings |
20
+ | `loki memory stats` | Memory statistics |
21
+ | `loki memory consolidate` | Episodic-to-semantic pipeline |
22
+ | `loki memory compound` | Compound learnings |
23
+ | `loki rollback` | Restore .loki/ state from a checkpoint |
24
+ | `loki rollback list` | List checkpoints |
25
+ | `loki rollback show` | Show a checkpoint |
26
+ | `loki rollback to` | Restore a checkpoint |
27
+ | `loki rollback latest` | Restore the latest checkpoint |
28
+ | `loki proof` (alias: `receipt`) | Inspect and share proof-of-run receipts |
29
+ | `loki proof list` | List receipts |
30
+ | `loki proof show` | Show a receipt |
31
+ | `loki proof open` | Open a receipt |
32
+ | `loki proof share` | Share a receipt |
33
+ | `loki wiki` | Cited codebase wiki and Q&A |
34
+ | `loki wiki generate` | Generate the wiki |
35
+ | `loki wiki show` | Show a section |
36
+ | `loki wiki ask` | Ask a question |
37
+ | `loki control` | Control Plane (serve, backfill, prune, status) |
38
+ | `loki control serve` | Run the control plane and UI |
39
+ | `loki control backfill` | Ship DIR/.loki/runs to the control plane |
40
+ | `loki control prune` | Delete matching runs |
41
+ | `loki control status` | Show control plane reachability |
42
+ | `loki kpis` | KPI snapshot (alias of report kpis) |
43
+ | `loki report` | Reporting: kpis, session, metrics, cost, export, share, dogfood |
44
+ | `loki report kpis` | Canonical KPI snapshot |
45
+ | `loki report session` | Session report |
46
+ | `loki report metrics` | Metrics report |
47
+ | `loki report cost` | Cost report |
48
+ | `loki report export` | Export session |
49
+ | `loki report share` | Share a report |
50
+ | `loki report dogfood` | Dogfood report |
51
+ | `loki trust` | Trust trajectory from proof history |
52
+ | `loki trust detail` | Trust metrics detail |
53
+ | `loki crash` | Inspect or submit scrubbed crash reports |
54
+ | `loki contract` | Print the spec delivery contract |
55
+ | `loki start` | Run the autonomous build |
56
+ | `loki slack` | Slack inbound handler |
57
+ | `loki slack serve` | Serve the Slack handler |
58
+ | `loki answer` | Resume a BLOCKED run with an answer |
59
+ | `loki engine10` | v10 engine router |
60
+ | `loki engine10 run` | Run the v10 engine |
61
+ | `loki engine10 status` | v10 status |
62
+ | `loki engine10 verify` | v10 verify |
63
+ | `loki engine10 keys` | v10 keys |
64
+ | `loki engine10 dashboard` | v10 dashboard |
65
+ | `loki engine10 modernize` | v10 modernize |
66
+ | `loki help` | Show help |
67
+ | `loki quick` | One small task |
68
+ | `loki quickstart` | Guided first build |
69
+ | `loki init` | Scaffold from a template |
70
+ | `loki template` | Manage PRD templates |
71
+ | `loki verify` | Deterministic PR verification |
72
+ | `loki keys` | Receipt-signing keys |
73
+ | `loki keys export` | Print the public signing key (JWK) |
74
+ | `loki review` | Standalone code review with quality gates |
75
+ | `loki dashboard` | Operations UI server |
76
+ | `loki dashboard start` | Start |
77
+ | `loki dashboard stop` | Stop |
78
+ | `loki dashboard status` | Status |
79
+ | `loki dashboard url` | Print URL |
80
+ | `loki dashboard open` | Open in browser |
81
+ | `loki config` | Manage configuration |
82
+ | `loki config show` | Show config |
83
+ | `loki config init` | Create config |
84
+ | `loki config edit` | Edit config |
85
+ | `loki config path` | Print config path |
86
+ | `loki config set` | Set a value |
87
+ | `loki config get` | Get a value |
88
+ | `loki mcp` | Launch the MCP server (stdio) |
89
+ | `loki acp` | Run Loki as an ACP agent |
90
+ | `loki stop` | Stop execution immediately |
91
+ | `loki pause` | Pause after the current session |
92
+ | `loki resume` | Resume a paused or interrupted run |
93
+ | `loki why` | Explain how the last run ended |
94
+ | `loki next` | Run the right next step |
95
+ | `loki logs` | Tail recent log output |
96
+ | `loki ship` | Ship the verified result |
97
+ | `loki deploy` | Deploy the built product |
98
+ | `loki import` | Import issues or specs |
99
+ | `loki github` | GitHub integration |
100
+ | `loki issue` | Work an issue |
101
+ | `loki ci` | CI helpers |
102
+ | `loki modernize` | Code modernization |
103
+ | `loki share` | Share a run |
104
+ | `loki assets` | Export team assets |
105
+ | `loki assets export` | Export shareable assets |
106
+ | `loki export` | Export session data |
107
+ | `loki notify` | Notifications |
108
+ | `loki tour` | See a sample result |
109
+ | `loki welcome` | First-run opener |
110
+ | `loki onboard` | Onboard to a codebase |
111
+ | `loki setup-skill` | Install the skill symlinks |
112
+ | `loki self-update` (alias: `self_update`, `update`) | Update Loki |
113
+ | `loki remote` (alias: `rc`) | Remote session |
114
+ | `loki cockpit` | Live multi-repo cockpit |
115
+ | `loki code` | Code intelligence |
116
+ | `loki context` (alias: `ctx`) | Cross-project context |
117
+ | `loki secrets` | Secrets handling |
118
+ | `loki api` | Dashboard HTTP API |
119
+ | `loki sandbox` | Docker sandbox |
120
+ | `loki docker` | Docker helpers |
121
+ | `loki web` | Web UI |
122
+ | `loki preview` | Preview the built app |
123
+ | `loki telemetry` (alias: `otel`) | Telemetry controls |
124
+ | `loki syslog` | System log forwarding |
125
+ | `loki explain` | Explain code |
126
+ | `loki docs` | Open docs |
127
+ | `loki test` | Run project tests |
128
+ | `loki bench` | Benchmarks |
129
+ | `loki voice` | Voice input |
130
+ | `loki own` (alias: `handoff`) | Hand off ownership |
131
+ | `loki secure` | Security scan |
132
+ | `loki compliance` | Compliance reports |
133
+ | `loki enterprise` | Enterprise features |
134
+ | `loki projects` | Project registry |
135
+ | `loki audit` | Audit log |
136
+ | `loki cost` | Cost report |
137
+ | `loki metrics` | Metrics |
138
+ | `loki sentrux` | Architecture sensor |
139
+ | `loki magic` | Magic modules |
@@ -1,5 +1,7 @@
1
1
  # Loki Cockpit (rec #6) - build spec
2
2
 
3
+ > **Historical:** this describes the classic dashboard, removed in Loki Mode 10.8. The Control Plane is the only UI; see [control-plane-migration.md](control-plane-migration.md).
4
+
3
5
  Status: IN BUILD (v7.126.0 target). Design approved via mockup
4
6
  (scratchpad/loki-cockpit.html). Grounded in real engine state + Autonomi identity.
5
7
 
@@ -59,7 +61,7 @@ No chafa / no headless Chrome hard dependency. Pipeline:
59
61
  - S3 (render pipeline): SVG-from-state builder + SVG->PNG + terminal-image
60
62
  encoder + capability detection + fallback. Tests (encoder byte-shape, detection).
61
63
  - S4 (dashboard identity redesign): apply logo/purple/fonts/multi-repo switcher to
62
- dashboard-ui; rebuild dist. Lightweight gate.
64
+ legacy-ui; rebuild dist. Lightweight gate.
63
65
  - S5 (docs + wiki + release): help text, README, wiki, CHANGELOG, 14 version files.
64
66
 
65
67
  ## Constraints
@@ -28,7 +28,7 @@ carries a `reason`, an unmeasured number reads `None` rather than `0`, and
28
28
  | `source` | 10 of 43 | Most rows cannot be audited back to the file they came from |
29
29
 
30
30
  ```bash
31
- cd dashboard-ui
31
+ cd legacy-ui
32
32
  grep -l "freshness_s" components/*.js core/*.js | wc -l # 0
33
33
  grep -l "measured" components/*.js core/*.js | wc -l # 0
34
34
  ```
@@ -1,5 +1,7 @@
1
1
  # Dashboard Architecture: Real-Data, Near-Realtime
2
2
 
3
+ > **Historical:** this describes the classic dashboard, removed in Loki Mode 10.8. The Control Plane is the only UI; see [control-plane-migration.md](control-plane-migration.md).
4
+
3
5
  Design only. No implementation in this document.
4
6
 
5
7
  Status: proposal. Measured against the worktree at
@@ -41,7 +43,7 @@ brief's number and my measurement disagree, both are shown.
41
43
 
42
44
  One correction against myself: my first pass reported `0` aria attributes in the
43
45
  built artifact and I nearly wrote that up as a shipped accessibility regression.
44
- It was a measurement error. `dashboard/static/index.html` has lines long enough
46
+ It was a measurement error. `legacy-ui-static/index.html` has lines long enough
45
47
  (577 chars plus minified runs) that `grep` treated the file as binary and
46
48
  suppressed output. With `grep -a` the brief's numbers are confirmed. This is the
47
49
  `grep-absence false-green` failure mode: an empty result was an absent
@@ -178,7 +180,7 @@ machine-checkable instead of a naming habit.
178
180
  `/api/health/processes`.
179
181
 
180
182
  Built artifact realtime constructs: 9
181
- (`grep -oaE "new WebSocket|EventSource|setInterval" dashboard/static/index.html | wc -l`).
183
+ (`grep -oaE "new WebSocket|EventSource|setInterval" legacy-ui-static/index.html | wc -l`).
182
184
  The brief's "34 realtime constructs" is not reproducible by any pattern I tried;
183
185
  I mark that figure **not independently verified** rather than repeat it.
184
186
 
@@ -234,8 +236,8 @@ The bundle is 779,725 bytes raw, 150,341 gzipped
234
236
  gzip stays; nothing in this design touches it.
235
237
 
236
238
  **Progressive disclosure here cannot mean code-splitting.**
237
- `dashboard-ui/scripts/build-standalone.js` produces a single self-contained
238
- file with zero runtime dependencies, written to both `dashboard/static/` and
239
+ `legacy-ui/scripts/build-standalone.js` produces a single self-contained
240
+ file with zero runtime dependencies, written to both `legacy-ui-static/` and
239
241
  `dist/`. That property is why the dashboard works offline and inside Docker
240
242
  without a CDN. Splitting the bundle would trade a real capability for a
241
243
  transfer-size win that gzip has already mostly taken (5.2x). So disclosure is
@@ -265,12 +267,12 @@ Measured on the shipped artifact with `grep -a`:
265
267
 
266
268
  | Property | Count | Command |
267
269
  |---|---|---|
268
- | Custom elements registered | 39 | `grep -oa "customElements.define" dashboard/static/index.html \| wc -l` |
270
+ | Custom elements registered | 39 | `grep -oa "customElements.define" legacy-ui-static/index.html \| wc -l` |
269
271
  | `aria-*` attributes | 100 | `grep -oa "aria-[a-z]*=" ... \| wc -l` |
270
272
  | `aria-` occurrences | 113 | `grep -oa "aria-" ... \| wc -l` |
271
273
  | `role="` | 38 | `grep -oa 'role="' ... \| wc -l` |
272
274
  | `@media` breakpoints | 13 | `grep -oa "@media" ... \| wc -l` |
273
- | Component source files | 43 | `ls dashboard-ui/components \| grep -v vendor \| wc -l` |
275
+ | Component source files | 43 | `ls legacy-ui/components \| grep -v vendor \| wc -l` |
274
276
  | Registrations in source | 44 | `grep -roha "customElements.define" components core \| wc -l` |
275
277
 
276
278
  The brief's 113 aria and 41 role are consistent with mine within pattern choice
@@ -278,7 +280,7 @@ The brief's 113 aria and 41 role are consistent with mine within pattern choice
278
280
  figure is 43 files carrying 44 registrations, not 46.
279
281
 
280
282
  **One gap worth noting:** source registers 44 custom elements, the shipped
281
- artifact registers 39. Five components exist in `dashboard-ui/` and do not reach
283
+ artifact registers 39. Five components exist in `legacy-ui/` and do not reach
282
284
  the browser. This is out of scope for this document and I did not chase it, but
283
285
  it is recorded here because it means the source tree is not a reliable proxy for
284
286
  what ships. All acceptance criteria in section 5 therefore measure the **built
@@ -369,10 +371,10 @@ Every row is measurable by a command. No aspirational entries.
369
371
  |---|---|---|---|
370
372
  | A1 | No route regression | `grep -cE '^@app\.(get\|post\|put\|delete\|patch\|websocket)' dashboard/server.py` | >= 165 |
371
373
  | A2 | api_v2 routes intact | `grep -cE '@router\.(get\|post\|put\|delete)' dashboard/api_v2.py` | >= 24 |
372
- | A3 | Accessibility not regressed | `grep -oa "aria-" dashboard/static/index.html \| wc -l` | >= 113 |
373
- | A4 | Roles not regressed | `grep -oa 'role="' dashboard/static/index.html \| wc -l` | >= 38 |
374
- | A5 | Custom elements not regressed | `grep -oa "customElements.define" dashboard/static/index.html \| wc -l` | >= 39 |
375
- | A6 | Breakpoints not regressed | `grep -oa "@media" dashboard/static/index.html \| wc -l` | >= 13 |
374
+ | A3 | Accessibility not regressed | `grep -oa "aria-" legacy-ui-static/index.html \| wc -l` | >= 113 |
375
+ | A4 | Roles not regressed | `grep -oa 'role="' legacy-ui-static/index.html \| wc -l` | >= 38 |
376
+ | A5 | Custom elements not regressed | `grep -oa "customElements.define" legacy-ui-static/index.html \| wc -l` | >= 39 |
377
+ | A6 | Breakpoints not regressed | `grep -oa "@media" legacy-ui-static/index.html \| wc -l` | >= 13 |
376
378
  | A7 | gzip still active | `grep -c "GZipMiddleware" dashboard/server.py` | >= 1 |
377
379
  | A8 | Zero runtime dependencies | Built artifact contains no external script/CDN src | 0 external hosts |
378
380
  | A9 | Runs store is written by the engine | Drive the lifecycle writer directly (source `run.sh`, call the phase-boundary function), then `GET /api/v2/runs`. No provider call, no spend | Returns >= 1 record with a real run id |
@@ -1,5 +1,7 @@
1
1
  # Loki Mode Dashboard V2 - Implementation Checklist
2
2
 
3
+ > **Historical:** this describes the classic dashboard, removed in Loki Mode 10.8. The Control Plane is the only UI; see [control-plane-migration.md](control-plane-migration.md).
4
+
3
5
  ## Overview
4
6
  Enterprise-grade Kanban dashboard with FastAPI backend, cross-project support, and CLI integration.
5
7
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  The flagship product of [Autonomi](https://www.autonomi.dev/). Loki Mode is a spec-driven autonomous builder with a built-in trust layer that takes any spec to a deployed product and verifies completion with evidence (quality gates plus a completion council), not just a "done" claim. Complete installation instructions for all platforms and use cases.
4
4
 
5
- **Version:** v10.8.0
5
+ **Version:** v10.10.1
6
6
 
7
7
  **Engine note:** `loki "<task>"`, `loki owner/repo#N` and `loki quick` run the Loki 10 engine. `loki start` still routes to the legacy engine, which is being removed (planned work resumes 2026-10-07); prefer `loki owner/repo#N`. See [docs/v10/GUIDE.md](v10/GUIDE.md).
8
8
 
@@ -294,7 +294,7 @@ trade-offs.
294
294
  ## VS Code Extension (Deprecated)
295
295
 
296
296
  > **DEPRECATED as of v7.2.0.** The Loki Mode VS Code extension is no longer
297
- > maintained. Use the dashboard at `loki dashboard start` instead.
297
+ > maintained. Use the Control Plane (`loki dashboard`) instead.
298
298
  >
299
299
  > The marketplace listing remains for users on v7.2.0 and earlier but will
300
300
  > not receive further updates. The `vscode-extension/` source remains in the
@@ -305,8 +305,8 @@ trade-offs.
305
305
  ### Recommended replacement: the dashboard
306
306
 
307
307
  ```bash
308
- loki dashboard start
309
- # Then open http://localhost:57374 in your browser.
308
+ loki dashboard
309
+ # Opens the Control Plane (default http://127.0.0.1:47821).
310
310
  ```
311
311
 
312
312
  The dashboard provides session monitoring, task views, the completion
@@ -450,7 +450,7 @@ behave exactly like the local `loki` CLI. Auth is auto-detected:
450
450
  (Max/Pro subscribers need no API key), else an honest error with guidance. It
451
451
  also forwards `~/.gitconfig` and `~/.config/gh` (read-only) plus
452
452
  `GITHUB_TOKEN`/`GH_TOKEN` if set, so commits and PRs work like local, and
453
- exposes the dashboard on port 57374. Use `--image IMG` to override the image.
453
+ exposes the API on port 57374. Use `--image IMG` to override the image.
454
454
 
455
455
  `loki docker` is a thin host wrapper around the image; it requires loki and
456
456
  Docker installed on the host.
@@ -459,7 +459,7 @@ Multi-repo + unified dashboard: you can run `loki docker start` in several
459
459
  different repos at once, exactly like the host CLI. Each repo gets its own
460
460
  container (deterministic name `loki-<hash-of-path>`) and its own bind-mounted
461
461
  `.loki/` state. Every `loki docker` project registers with the host dashboard,
462
- so running `loki dashboard` on the host shows ALL your projects in one unified
462
+ so running `loki dashboard` on the host (the Control Plane) shows ALL your projects in one unified
463
463
  view, whether they run via local `loki start` or via `loki docker start`. Builds
464
464
  run with the dashboard off by default (so concurrent runs do not collide on port
465
465
  57374); use the host `loki dashboard`, or `loki docker start --api` for a single
@@ -775,11 +775,12 @@ Loki Mode uses two network ports for different services:
775
775
 
776
776
  | Port | Service | Description |
777
777
  |------|---------|-------------|
778
- | **57374** | Dashboard + API (FastAPI) | Unified server serving both the web dashboard UI (real-time monitoring, task board, Completion Council, memory browser, log streaming) and the REST API (used by CLI tools, programmatic access, and the deprecated VS Code extension). Served by `dashboard/server.py`. |
778
+ | **47821** | Control Plane UI + API | The only UI, plus the `/v1/*` API. Started by `loki control serve` or `loki dashboard`. See [control-plane-migration.md](control-plane-migration.md). |
779
+ | **57374** | Legacy API (FastAPI) | The classic dashboard UI is removed in 10.8; this port no longer serves a UI. |
779
780
 
780
781
  ### When to Use Which Port
781
782
 
782
- - **Browser access** (dashboard, monitoring): Use port **57374** -- `http://localhost:57374`
783
+ - **Browser access** (UI, monitoring): Use the Control Plane, port **47821** -- `http://127.0.0.1:47821`
783
784
  - **API calls** (REST, programmatic): Use port **57374** -- `http://localhost:57374`
784
785
  - **VS Code extension** (deprecated as of v7.2.0): Connects to API on port **57374** automatically (configurable via `loki.apiPort` setting). No new releases will be published; see the deprecation notice above.
785
786
  - The server is started automatically when you run `loki start` or `./autonomy/run.sh`. No manual configuration is needed.
@@ -787,8 +788,8 @@ Loki Mode uses two network ports for different services:
787
788
  ### Port Configuration
788
789
 
789
790
  ```bash
790
- # Dashboard port (default: 57374)
791
- LOKI_DASHBOARD_PORT=57374 loki dashboard start
791
+ # Control Plane port (default: 47821)
792
+ loki control serve --port 47821
792
793
 
793
794
  # API port (default: 57374)
794
795
  loki api start --port 57374 # was: loki serve
@@ -796,7 +797,7 @@ loki api start --port 57374 # was: loki serve
796
797
 
797
798
  ### CORS Configuration
798
799
 
799
- For remote or cross-origin access to the dashboard, configure allowed origins via the `LOKI_DASHBOARD_CORS` environment variable:
800
+ The Control Plane has no CORS setting and requires a loopback Host header unless it is bound to a non-loopback address with `LOKI_CONTROL_TOKEN` set (see [control-plane-migration.md](control-plane-migration.md)). The `LOKI_DASHBOARD_CORS` variable below applies only to the legacy API server:
800
801
 
801
802
  ```bash
802
803
  # Allow specific origins
@@ -150,7 +150,7 @@ Order is a default. Re-rank with data, and record why.
150
150
  - Decide whether the Seal replaces the Evidence Receipt or profiles it, and record the decision.
151
151
  - **M3. Assign it like a teammate (the Devin experience).**
152
152
  - Work arrives from:
153
- - a GitHub issue label or `/loki` comment (exists: `.github/workflows/loki-issue-to-pr.yml`);
153
+ - a GitHub issue label or `/loki` comment (exists: `docs/examples/loki-issue-to-pr.yml.example`);
154
154
  - a GitLab equivalent;
155
155
  - Slack @loki (code exists under `src/integrations/slack/`; verify it is actually reachable, because v9.33.0 found unreachable integrations);
156
156
  - Jira (the read path works);
@@ -200,7 +200,7 @@ Order is a default. Re-rank with data, and record why.
200
200
  - it works behind a corporate proxy with SSO;
201
201
  - the only outbound traffic is to configured model endpoints.
202
202
  Measure install-to-first-sealed-PR in the adoption eval.
203
- - Keep `provenance.yml` and `sbom.yml` green.
203
+ - Keep `sbom.yml` and the release.yml signing steps green.
204
204
  - **M10. Simplify and ship v10.0.0.**
205
205
  - Collapse the surface.
206
206
  - Remove deprecated commands and settings that measurement shows nobody needs.
@@ -362,7 +362,7 @@ class FileEventDebouncer(FileSystemEventHandler):
362
362
  ### What Was NOT Audited (and Why)
363
363
 
364
364
  1. **Frontend code duplication** (TypeScript/React):
365
- - Dashboard UI (`dashboard-ui/src/`) and Lab UI (`web-app/dist/` or source) likely have overlapping components (session cards, status displays, log viewers).
365
+ - Dashboard UI (`legacy-ui/src/`) and Lab UI (`web-app/dist/` or source) likely have overlapping components (session cards, status displays, log viewers).
366
366
  - Scope: This audit covers Python backend only. Frontend audit deferred to UI design review in Merge-3 (Vite rebuild).
367
367
 
368
368
  2. **Database schema migrations and compatibility:**
@@ -30,7 +30,7 @@ This document is the source-of-truth route-collision analysis for the Purple Lab
30
30
  | Method | Path | Dashboard purpose | Purple Lab purpose | Resolution |
31
31
  |---|---|---|---|---|
32
32
  | `GET` | `/health` | Dashboard health check | Purple Lab health check | Single `/health` on Dashboard wins. Lab's becomes `/lab/health`. |
33
- | `GET` | `/{full_path:path}` | Dashboard SPA catch-all (serves `dashboard/static/index.html`) | Purple Lab SPA catch-all (serves `web-app/dist/index.html`) | Dashboard catch-all wins at root. Lab's becomes `/lab/{full_path:path}` -- triggered only inside the mount. |
33
+ | `GET` | `/{full_path:path}` | Dashboard SPA catch-all (serves `legacy-ui-static/index.html`) | Purple Lab SPA catch-all (serves `web-app/dist/index.html`) | Dashboard catch-all wins at root. Lab's becomes `/lab/{full_path:path}` -- triggered only inside the mount. |
34
34
  | `WS` | `/ws` | Dashboard WebSocket bus | Purple Lab WebSocket bus | Dashboard `/ws` wins. Lab's becomes `/lab/ws`. Long term: unify into a single bus (Phase Merge-5). |
35
35
 
36
36
  All three collisions resolve automatically when Lab's FastAPI app is mounted at `/lab` via Starlette `app.mount("/lab", purple_lab_app)`. No code dedup needed in Merge-1 -- the mount provides path isolation.
@@ -68,7 +68,7 @@ Change the `open` URL from `http://127.0.0.1:${PURPLE_LAB_DEFAULT_PORT}/` to `ht
68
68
  ## Release Pipeline Wiring
69
69
 
70
70
  ### 7. Root `package.json` `prepublishOnly` (line ~106)
71
- Append `&& cd ../web-app && npm ci && npm run build && test -f dist/index.html` after the existing dashboard-ui build.
71
+ Append `&& cd ../web-app && npm ci && npm run build && test -f dist/index.html` after the existing legacy-ui build.
72
72
 
73
73
  ### 8. `Dockerfile`
74
74
  Add `COPY` for web-app build artifacts + server files. Mirror the `dashboard/` COPY pattern. (Merge-4 owns the actual import; Merge-3 ensures files are in the image.)
@@ -109,7 +109,7 @@ run_check "web-app build produces /lab/-prefixed assets" \
109
109
  ## NOT Done In This Phase
110
110
 
111
111
  - Auto-spawn web-app subprocess from `loki dashboard` (Merge-4).
112
- - Sidebar entry in `dashboard/static/index.html` (Merge-6).
112
+ - Sidebar entry in `legacy-ui-static/index.html` (Merge-6).
113
113
  - Deep state dedup (Merge-5).
114
114
  - Deprecation of `loki web` (Merge-7).
115
115
  - `vite-plugin-html` dev `/` -> `/lab/` redirect (nice-to-have, not blocking).
@@ -4,9 +4,8 @@ This index maps each historical plan doc to its status. Plan docs are kept as de
4
4
 
5
5
  | Plan | Status | Notes |
6
6
  |---|---|---|
7
- | BRANCH-LIFECYCLE-PLAN.md | shipped | Feature-branch-by-default + CI/CD-aware deploy; `feature_branch` logic in `autonomy/run.sh`. |
8
7
  | BUILD-HUD-PLAN.md | shipped | Live in-terminal build HUD; `LOKI_HUD` / `[HUD]` in `autonomy/run.sh`, CHANGELOG "Live in-terminal build HUD". |
9
- | CONFIG-FILE-PLAN.md | shipped | Unified config file; `--config` / `--vars` / `--env-file` flags in `autonomy/loki`. |
8
+ | history/v8-config-plan.md | shipped | Unified config file; `--config` / `--vars` / `--env-file` flags in `autonomy/loki`. |
10
9
  | CRASH-REPORTING-PLAN.md | shipped | Crash-reporting + auto-fix; `cmd_crash()` in `autonomy/loki` (`loki crash`). |
11
10
  | DEPLOY-PLAN.md | shipped | `loki deploy` advisory print-only; CHANGELOG "`loki deploy`: advisory, print-only deploy guidance". |
12
11
  | FAILURE-MEMORY-PLAN.md | shipped | Failure-memory loop; `FailureMode` schema in `memory/schemas.py`. |
@@ -29,5 +28,5 @@ This index maps each historical plan doc to its status. Plan docs are kept as de
29
28
  | UNCERTAINTY-ESCALATION-PLAN.md | shipped | Uncertainty-gated escalation (v7.19.2); uncertainty escalation logic in `autonomy/run.sh`. |
30
29
  | VERIFIED-COMPLETION-PLAN.md | shipped | Verified completion (v7.19.1); verified-completion gate in `autonomy/run.sh` + `autonomy/completion-council.sh`. |
31
30
  | WELCOME-OPENER-PLAN.md | shipped | Welcome opener ("magic opener"); `welcome` path in `autonomy/loki`. |
32
- | V8-AGENT-SDK-PLAN.md | shipped | The v8 Anthropic SDK runtime migration; shipped on `feature/v8-agent-sdk` as v8.0.0 + v8.1 (`loki-ts/src/runner/sdk_invoker.ts`, `sdk_mode.ts`, CHANGELOG v8.0.0/v8.1). Feature-branch-only, not yet merged to main. |
31
+ | history/v8-agent-sdk-plan.md | shipped | The v8 Anthropic SDK runtime migration; shipped on `feature/v8-agent-sdk` as v8.0.0 + v8.1 (`loki-ts/src/runner/sdk_invoker.ts`, `sdk_mode.ts`, CHANGELOG v8.0.0/v8.1). Feature-branch-only, not yet merged to main. |
33
32
  | V8-SDK-RESEARCH-RAW.md | shipped | Research notes underpinning V8-AGENT-SDK-PLAN; design history for the v8 SDK arc. |