loki-mode 11.4.2 → 11.6.0

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 (129) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/lib/chat.sh +6 -3
  4. package/autonomy/lib/engine10-push.sh +19 -1
  5. package/autonomy/lib/help-core.sh +1 -1
  6. package/autonomy/lib/proof-generator.py +23 -5
  7. package/autonomy/lib/proof-verify.py +607 -5
  8. package/autonomy/lib/run-summary.sh +17 -1
  9. package/autonomy/lib/setup-requirements.json +35 -0
  10. package/autonomy/loki +244 -237
  11. package/autonomy/notification-checker.py +1 -1
  12. package/autonomy/provider-offer.sh +95 -47
  13. package/autonomy/route.sh +38 -6
  14. package/autonomy/run.sh +42 -14
  15. package/autonomy/setup-wizard.sh +19 -10
  16. package/autonomy/verify.sh +40 -1
  17. package/completions/_loki +3 -1
  18. package/completions/loki.bash +9 -3
  19. package/dashboard/__init__.py +3 -10
  20. package/dashboard/control.py +5 -435
  21. package/docs/ARCHITECTURE.md +1 -2
  22. package/docs/CLI-CORE-VERBS.md +2 -6
  23. package/docs/CLI-REFERENCE.md +3 -1
  24. package/docs/COMPONENTS.md +0 -2
  25. package/docs/EVALUATING.md +27 -0
  26. package/docs/HARNESS-INTELLIGENCE-PLAN.md +20 -0
  27. package/docs/INSTALLATION.md +1 -1
  28. package/docs/KNOWN-ISSUES.md +10 -1
  29. package/docs/PROOF-PASSPORT.md +114 -0
  30. package/docs/alternative-installations.md +103 -0
  31. package/docs/authentication.md +19 -1
  32. package/docs/cost-controls.md +139 -0
  33. package/docs/dev/release-checklist.md +9 -8
  34. package/docs/enterprise/security.md +3 -234
  35. package/docs/environment-variables.md +36 -0
  36. package/docs/exit-codes.md +102 -2
  37. package/docs/spec-first-intent.md +29 -0
  38. package/docs/v10/ARCHITECT-CUTS.md +304 -0
  39. package/docs/v10/CLI-MODERN.md +2 -2
  40. package/docs/v10/DECISIONS.md +5 -5
  41. package/docs/v10/ENGINE.md +735 -267
  42. package/docs/v10/GUARDS.md +16 -14
  43. package/docs/v10/GUIDE.md +5 -7
  44. package/docs/v10/PROGRESS.md +12 -1
  45. package/docs/v11/MARKET-SLICES.md +1 -5
  46. package/integrations/openclaw/README.md +20 -0
  47. package/integrations/vibe-kanban.md +12 -50
  48. package/loki-ts/data/model-pricing.json +1 -0
  49. package/loki-ts/dist/loki.js +1156 -1103
  50. package/mcp/__init__.py +1 -1
  51. package/mcp/_sdk_loader.py +1 -1
  52. package/package.json +2 -2
  53. package/packages/control-plane/dist/server.js +2063 -1032
  54. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  55. package/plugins/loki-mode/README.md +41 -1
  56. package/plugins/loki-mode/commands/handoff.md +12 -0
  57. package/plugins/loki-mode/commands/loki-verify.md +9 -2
  58. package/plugins/loki-mode/commands/start.md +20 -0
  59. package/plugins/loki-mode/hooks/hooks.json +11 -0
  60. package/plugins/loki-mode/scripts/loki-stop-verify.sh +84 -0
  61. package/references/quality-control.md +1 -116
  62. package/skills/00-index.md +2 -2
  63. package/skills/artifacts.md +0 -22
  64. package/skills/production.md +2 -38
  65. package/web-app/dist/assets/{AdminPage-CYJ2BWRC.js → AdminPage-DhXdJNQk.js} +1 -1
  66. package/web-app/dist/assets/{Avatar-DdK4wynI.js → Avatar-ixVj76fM.js} +1 -1
  67. package/web-app/dist/assets/{Badge-CrX3MI7J.js → Badge-BGMSp22s.js} +1 -1
  68. package/web-app/dist/assets/{Button-709-wwGM.js → Button-pYJc32tG.js} +1 -1
  69. package/web-app/dist/assets/{CockpitPage-BapdTInO.js → CockpitPage-C1JBBouA.js} +1 -1
  70. package/web-app/dist/assets/{ComparePage-DT99pGvA.js → ComparePage-qD0NV4RK.js} +1 -1
  71. package/web-app/dist/assets/{ErrorBoundary-B0uJSys8.js → ErrorBoundary-C-yxO58j.js} +1 -1
  72. package/web-app/dist/assets/{EvidenceReceiptPanel-BtMFgElP.js → EvidenceReceiptPanel-ByPzuE1S.js} +1 -1
  73. package/web-app/dist/assets/{GitHubIssuesPanel-DjJuU941.js → GitHubIssuesPanel-BNv_2BEJ.js} +1 -1
  74. package/web-app/dist/assets/{GitHubPRsPanel-HXfEX1BC.js → GitHubPRsPanel-CuLZQ9CS.js} +1 -1
  75. package/web-app/dist/assets/{HomePage-Cqyves-S.js → HomePage-CS_FW8Je.js} +2 -2
  76. package/web-app/dist/assets/{LoginPage-jUbtC7_Y.js → LoginPage-DwiNf1Wm.js} +1 -1
  77. package/web-app/dist/assets/{MagicPage-DHRsqjgR.js → MagicPage-CmQybLPZ.js} +1 -1
  78. package/web-app/dist/assets/{MetricsPage-B-pED05R.js → MetricsPage-D9ERdpv8.js} +1 -1
  79. package/web-app/dist/assets/{NotFoundPage-CsbUs21R.js → NotFoundPage-D9ccgdbF.js} +1 -1
  80. package/web-app/dist/assets/{ProjectPage-BtlLEQwB.js → ProjectPage-B9Jslmgv.js} +3 -3
  81. package/web-app/dist/assets/{ProjectsPage-DaRbRjSp.js → ProjectsPage-DnU99Go2.js} +1 -1
  82. package/web-app/dist/assets/{SettingsPage-DALrtP3F.js → SettingsPage-DcTyx6wo.js} +1 -1
  83. package/web-app/dist/assets/{ShowcasePage-CoPHSNP0.js → ShowcasePage-jEY9ghSr.js} +1 -1
  84. package/web-app/dist/assets/{SystemSettingsPage-kOuSN50O.js → SystemSettingsPage-CSGltW-8.js} +1 -1
  85. package/web-app/dist/assets/{TeamsPage-DGWK0LMp.js → TeamsPage-gUuJXb9l.js} +1 -1
  86. package/web-app/dist/assets/{TemplatesPage-C-_10CwA.js → TemplatesPage-37Zhe--v.js} +1 -1
  87. package/web-app/dist/assets/{TerminalOutput-Cz_vPbXL.js → TerminalOutput-B09hRwaR.js} +1 -1
  88. package/web-app/dist/assets/{activity-icIsXJVa.js → activity-q_4MY9J0.js} +1 -1
  89. package/web-app/dist/assets/{bell-DbPR2_4r.js → bell-X8OC_PFP.js} +1 -1
  90. package/web-app/dist/assets/{bot-DvjP3Yh5.js → bot-C-N1PUOD.js} +1 -1
  91. package/web-app/dist/assets/{check-D1OBxHeU.js → check-B2c76Jmp.js} +1 -1
  92. package/web-app/dist/assets/{chevron-left-D09jDZ29.js → chevron-left-BF76YLNw.js} +1 -1
  93. package/web-app/dist/assets/{circle-alert-DyZMLOcC.js → circle-alert-AeFKBD8h.js} +1 -1
  94. package/web-app/dist/assets/{clock-CdpdJTId.js → clock-CiXRf-FH.js} +1 -1
  95. package/web-app/dist/assets/{cloud-CoLTlmoj.js → cloud-DKQ8SRJ5.js} +1 -1
  96. package/web-app/dist/assets/{code-xml-DrkE2ZZY.js → code-xml-DEb6jXWP.js} +1 -1
  97. package/web-app/dist/assets/{database-CMQQuM2R.js → database-6W7e-E9c.js} +1 -1
  98. package/web-app/dist/assets/{dollar-sign-CuioDaOG.js → dollar-sign-Ds2GOuyW.js} +1 -1
  99. package/web-app/dist/assets/{file-code-corner-Cx9j9K1S.js → file-code-corner-CZU0jg52.js} +1 -1
  100. package/web-app/dist/assets/{file-plus-CYD2zaaI.js → file-plus-DTVYnXCN.js} +1 -1
  101. package/web-app/dist/assets/{globe-6w-hnQkL.js → globe-0mUzKYDe.js} +1 -1
  102. package/web-app/dist/assets/{hammer-BpqtautL.js → hammer-BMHZg3YX.js} +1 -1
  103. package/web-app/dist/assets/{index-Dzs-9EgJ.js → index-BvOTvjax.js} +3 -3
  104. package/web-app/dist/assets/{layers-D5hd7jb7.js → layers-Df7TdcWB.js} +1 -1
  105. package/web-app/dist/assets/{loader-circle-C6Y9x_7H.js → loader-circle-kPsVfrSY.js} +1 -1
  106. package/web-app/dist/assets/{lock-D51L7rYh.js → lock-CXYcbEc5.js} +1 -1
  107. package/web-app/dist/assets/{package-BJF8hkP8.js → package-Cqhua1ID.js} +1 -1
  108. package/web-app/dist/assets/{plus-D5kUQ79n.js → plus-lseXhsn-.js} +1 -1
  109. package/web-app/dist/assets/{refresh-cw-BKdlCa7F.js → refresh-cw-OZriI6gD.js} +1 -1
  110. package/web-app/dist/assets/{rotate-ccw-_bd_YI1e.js → rotate-ccw-CKCfjPg8.js} +1 -1
  111. package/web-app/dist/assets/{scroll-text-DbkegIxF.js → scroll-text-DoVyyfKb.js} +1 -1
  112. package/web-app/dist/assets/{server-DAwqFIsq.js → server-DGy7TflW.js} +1 -1
  113. package/web-app/dist/assets/{shield-alert-BuR1tPHu.js → shield-alert-BCzRcMXi.js} +1 -1
  114. package/web-app/dist/assets/{thumbs-up-BF6p3mRd.js → thumbs-up-C_znJd5g.js} +1 -1
  115. package/web-app/dist/assets/{trash-2-BVpnkqqz.js → trash-2-BosCbeeA.js} +1 -1
  116. package/web-app/dist/assets/{trending-down-DpsDvRwW.js → trending-down-CkR5zDkV.js} +1 -1
  117. package/web-app/dist/assets/{trending-up-mFogTjt3.js → trending-up-DpUIfOH4.js} +1 -1
  118. package/web-app/dist/assets/{upload-4T8zpBsi.js → upload-CH9aKc8L.js} +1 -1
  119. package/web-app/dist/assets/{usePolling-DPXQv8WO.js → usePolling-pzxrHJeg.js} +1 -1
  120. package/web-app/dist/assets/{user-BYGIFaTm.js → user-B7OHa-VQ.js} +1 -1
  121. package/web-app/dist/index.html +1 -1
  122. package/dashboard/run.py +0 -63
  123. package/docs/openclaw-integration.md +0 -52
  124. package/docs/v10/HANDOFF-NEXT-WEEK.md +0 -40
  125. package/docs/v10/MORNING-BRIEF-1003.md +0 -25
  126. package/docs/v10/MORNING-BRIEF.md +0 -52
  127. package/docs/v10/TODO.md +0 -35
  128. package/mcp/resources.py +0 -351
  129. package/mcp/tools.py +0 -200
package/dashboard/run.py DELETED
@@ -1,63 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Run the Loki Mode Dashboard server.
4
-
5
- Usage:
6
- python -m dashboard.run [--host HOST] [--port PORT]
7
- python dashboard/run.py [--host HOST] [--port PORT]
8
- """
9
-
10
- import argparse
11
- import os
12
- import sys
13
-
14
-
15
- def main():
16
- parser = argparse.ArgumentParser(description="Loki Mode Dashboard Server")
17
- # Loopback by default, matching server.py:run_server and control.py. This
18
- # launcher defaulted to 0.0.0.0, which published an UNAUTHENTICATED control
19
- # plane on every interface: dashboard auth is opt-in
20
- # (LOKI_ENTERPRISE_AUTH, default false in dashboard/auth.py), so with it
21
- # unset -- the default -- anyone routable to the host could reach endpoints
22
- # that stop builds and read receipts. A default must be safe on its own;
23
- # exposing the network is a decision an operator makes explicitly, so
24
- # --host 0.0.0.0 and LOKI_DASHBOARD_HOST both still work for the container
25
- # and Helm paths that genuinely need it.
26
- parser.add_argument(
27
- "--host",
28
- default=os.environ.get("LOKI_DASHBOARD_HOST", "127.0.0.1"),
29
- help="Host to bind to (default: $LOKI_DASHBOARD_HOST or 127.0.0.1). "
30
- "Use 0.0.0.0 only with authentication enabled.",
31
- )
32
- parser.add_argument(
33
- "--port",
34
- type=int,
35
- default=57374,
36
- help="Port to bind to (default: 57374)",
37
- )
38
- parser.add_argument(
39
- "--reload",
40
- action="store_true",
41
- help="Enable auto-reload for development",
42
- )
43
- args = parser.parse_args()
44
-
45
- try:
46
- import uvicorn
47
- except ImportError:
48
- print("Error: uvicorn not installed. Run: pip install uvicorn[standard]")
49
- sys.exit(1)
50
-
51
- print(f"Starting Loki Mode Dashboard on http://{args.host}:{args.port}")
52
- print(f"API docs available at: http://localhost:{args.port}/docs")
53
-
54
- uvicorn.run(
55
- "dashboard.server:app",
56
- host=args.host,
57
- port=args.port,
58
- reload=args.reload,
59
- )
60
-
61
-
62
- if __name__ == "__main__":
63
- main()
@@ -1,52 +0,0 @@
1
- # OpenClaw Integration
2
-
3
- **Status: skeleton. Not a shipped feature.**
4
-
5
- An earlier version of this page documented an OpenClaw coordination protocol
6
- with `loki openclaw` subcommands, `/api/openclaw/*` REST endpoints,
7
- `LOKI_OPENCLAW_*` environment variables, a `.loki/config.yaml` `openclaw:`
8
- block, and `loki_openclaw_*` Prometheus metrics. **None of that exists in the
9
- source.** It has been removed rather than left in place:
10
-
11
- - `grep -c openclaw autonomy/loki` returns `0` -- there is no `loki openclaw`
12
- command in the CLI dispatch, and no `--openclaw` flag anywhere in
13
- `autonomy/` or `loki-ts/src/`.
14
- - `grep -rn "api/openclaw" dashboard/server.py loki-ts/src/` returns nothing --
15
- none of the documented REST endpoints are implemented.
16
- - No `LOKI_OPENCLAW_*` variable is read by any runtime code.
17
-
18
- ## What actually exists
19
-
20
- Two real things, neither of which is a Loki CLI feature:
21
-
22
- **1. A file-watching bridge skeleton** at `integrations/openclaw/bridge/`. It
23
- watches a `.loki` directory, maps Loki events to an OpenClaw gateway message
24
- shape (`schema_map.py`), and prints the mapped JSON to stdout. Its own module
25
- docstring states the limitation plainly:
26
-
27
- > NOTE: This is a foundation/skeleton. The WebSocket gateway client is not yet
28
- > implemented. Currently logs mapped events to stdout as JSON for testing.
29
- > The --gateway flag is accepted but has no effect until the WebSocket client
30
- > is built in a future phase.
31
-
32
- Run it directly, not through `loki`:
33
-
34
- ```bash
35
- python -m integrations.openclaw.bridge --loki-dir .loki
36
- ```
37
-
38
- **2. An OpenClaw skill package** at `integrations/openclaw/`, which you copy
39
- into an OpenClaw workspace so an OpenClaw agent can invoke the ordinary
40
- `loki start` / `loki status --json` CLI on your behalf. See
41
- [`integrations/openclaw/README.md`](../integrations/openclaw/README.md) for the
42
- install steps and the two helper scripts (`poll-status.sh`,
43
- `format-progress.sh`).
44
-
45
- ## If you need real multi-agent coordination today
46
-
47
- Use the surfaces that are actually implemented and tested:
48
-
49
- - The MCP server (`loki mcp`) exposes Loki's tools to any MCP client.
50
- - `.loki/events.jsonl` is the durable event stream the bridge skeleton reads;
51
- anything that can tail a JSONL file can consume it.
52
- - `loki status --json` is the supported programmatic status surface.
@@ -1,40 +0,0 @@
1
- # Handoff state (D59 pause ended early by D62 on 2026-10-03 about 00:05Z; work resumed, see DECISIONS D62)
2
-
3
- ## On npm now (updated 2026-10-02T23:52Z after the D60 sprint)
4
- - latest and next: 10.6.7 (`npm view loki-mode dist-tags` gave latest 10.6.7, next 10.6.7 at 23:51Z; moved by the D49 auto-promote after Post-Release Smoke passed on bfce1db12; the D58 real-repo gate is still not wired into promote).
5
-
6
- ## Releases this window and their CI
7
- - 10.6.0 (9f9569c35, tree d922ef170): Tests, Bun Parity, Coverage, Security Audit all green on train/72 and on main. Published.
8
- - 10.6.1 (9bc3cfcc7): Tests red, shard 7, `test-engine10-docs.sh` (the D57 docs pass removed the README loki10-default marker). Not published.
9
- - 10.6.2 (5c1e3324d): Tests red from W1-ROUTE (moat P5 egress-blocked-start-seal-verify, P5 local-provider-no-claude-sidecalls, P9 injection-cannot-reach-token; `loki run --help` flags; UI bare loki; progressive isolation help; platform-divergent construct; docs-drift `loki agent` in docs/R10-MARKETPLACE-PLAN.md). Not published; W1-ROUTE reverted (30096450f).
10
- - 10.6.3 (f289f8bf2): Tests red, shard 7, `test-ui-bare-loki` (LEAK3 prints http://127.0.0.1:57374/start where the test expects otherwise). Not published; LEAK3 reverted (05410c554).
11
- - 10.6.4 (3a4df211c): every Tests job failed installing deps (npm 404 on baseline-browser-mapping-2.11.27.tgz, a fresh publish not yet propagated; 200 a few minutes later). Not published; content carried into 10.6.5.
12
- - 10.6.5 (0472f306a): Moat suite red, P9 injection-cannot-reach-token regressed by the minimal `loki start <ref>` route (b2e3afc43): the P9 probe drives `loki start <issue>` and expects a provider session; engine10 exited rc=2 first. Not published; start route reverted (621437c0a).
13
- - 10.6.6 (456058bae): scope control, Control Plane v0, train-cycle fix, docs. Tests, Bun Parity, Coverage, Security Audit all green; Release succeeded. Published.
14
-
15
- ## D60 sprint (2026-10-02, one hour, all five slices in 10.6.7)
16
- - 10.6.7 (bfce1db12, train/79 1917333e1): Tests, Bun Parity, Coverage, Security Audit, First-run gate, SBOM, Release, Post-Release Smoke, Promote all success.
17
- - Shipped: `loki start` runs Loki 10 (moat P9 probe ported, moat rc=0); dashboard prints the bound port (LEAK3, test-ui-bare-loki rc=0); reviewer-first PR body; issue-to-PR Action on Loki 10 plus nightly `loki backlog` example; visible cost cap ($20 default, `--max-cost`, loki.yaml `budgets.per_run`, BUDGET_STOP exit 3).
18
- - Open: no real end-to-end exit 3 run of the cost cap yet; root action.yml still uses `loki start --simple`.
19
- - D61 (speed, docs/v10/D61-SPEED.md) resumed under D62. Worktree agent-ad890c5afa3648ae6 held no saved slice 17 work (clean, no commits), so slice 17 restarts. Peer GO covers slices 1, 2, 7, 8, 17 behind LOKI_SPEED=1.
20
- - D58 basics 1 and 2 below are superseded by 10.6.7 (now PASS on CI; still unproven on a real repo).
21
-
22
- ## D58 basics
23
- 1. `loki start` runs v10: FAIL. Both the minimal route (b2e3afc43, a 7-line bin/loki start arm) and the full re-route regress moat P9, because tests/moat P9 drives `loki start <issue>` through the legacy path; port that probe to the v10 issue path first, then re-land b2e3afc43. The full re-route W1-ROUTE is built (branch slice-D57-W1-ROUTE, commit a8ed5461a, which is based on the old main that still has the CP-00 JWT commits, so cherry-pick it, never merge it) but turned Tests red as listed above. Its docs follow-up is f001bc0f1.
24
- 2. Dashboard: FAIL. LEAK3 (bound URL, scoped reuse, 57374-57399 guard; branch slice-P0-DASH-LEAK3, ceba8a6de) failed `test-ui-bare-loki` in CI and was reverted. The Control Plane v0 live view (CP-RELAND) ships in 10.6.6, off unless LOKI_CONTROL_URL is set.
25
- 3. Scope control: SHIPPED in 10.6.6 (D58-SCOPE, reverts unrelated edits, lists them in NOT PROVEN). Unproven on a real repo.
26
- 4. Clean install: PASS on 10.6.0 (per-platform @oven/bun-* deps; post-release smoke passed, which is what fired the promote).
27
- 5. Real-repo gate before latest moves: FAIL. `scripts/real-repo-gate.sh` exists but promote does not call it, and it needs operator provider auth (ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN, plus GH_TOKEN) that this session does not have. Not run against latest.
28
-
29
- ## NOT DONE and why
30
- - W1-ROUTE and its docs cleanup: red CI (above); dropped per D46 rule 2.
31
- - LEAK3 dashboard fix: red CI (`test-ui-bare-loki`); dropped. Its test expectation and the new bound-URL output disagree; decide which is right.
32
- - Real-repo gate run: no provider auth in the session; never reads stored keys.
33
- - Coverage W1-ROUTE removed and must be replaced when it re-lands: `why --json` schema test, eval harness cost checks (R2, S41-01), five trust-core probe cases (CTO sign-off).
34
- - Wiring the real-repo gate into promote.yml (so latest cannot move without it).
35
-
36
- ## Founder queue
37
- - Re-land W1-ROUTE with the moat P5/P9 regressions fixed first (moat outranks everything).
38
- - Decide whether promote must call the real-repo gate, and supply provider auth for it.
39
- - The D59 override (release without waiting for CI) expired at 20:10Z; the Release workflow's required-ci still enforced green Tests throughout.
40
- - Housekeeping: about 43 worktrees under .claude/worktrees (cap 15); backup branches backup/train-67..70 and backup/main-pre-rebuild hold the CP-00 JWT lineage, so never push them.
@@ -1,25 +0,0 @@
1
- # Morning brief, 2026-10-03 (refreshed 16:29Z, next refresh 17:30Z)
2
-
3
- ## Shipped today
4
- - 8 releases in 24h. The newest is v10.6.14 (tag 7fbbefc30, 14:01Z). npm latest is still 10.6.14.
5
-
6
- ## 10.7.0: one big train, minor bump (D82, D84, D85)
7
- - train/102 (cf5be9026) went red: Tier A (shard-durations rows) and Tests (help and completion registration for acp and merge, `loki web --port` validation, a CP-INGEST type error, the gitleaks baseline count).
8
- - All of them were fixed in place (D85) and rerun locally green. train/103 (d9704dfc4) was pushed at 16:28Z and CI is running. Release follows a green Tests run.
9
- - In: the speed path on by default (with the fix for its 9 reds), quiet-mode live line, the cost cap, loopback-only default listeners, Playwright e2e with video, `loki merge`, `loki review --risk`, project memory, mobile emulator tests, the REST runs API, ACP, Sentry intake, and Control Plane zero-setup ingest, legacy entry points and live runs.
10
- - Moved to 10.7.1: the empty-Wall seal (it failed the engine e2e done run), CP roles and OIDC, the liveline CP URL, the monorepo RealBaseTestRunner, and mobile-verify wiring.
11
-
12
- ## 10.8.0: enterprise Control Plane rebuild (D83)
13
- - On cpe-base: shell, home, runs, run thread, compose, cost, work, receipts, models, plans, merge queue and PR risk pages, a11y and contrast fixes. The suite is 235/0 and UI tsc is 0.
14
- - Settings (loki.yaml write-back, CPE-14) has been blocked by opus three times, on YAML 1.1 parser differences. The shell-command lock now holds. A fixer is on the remaining quoting gaps.
15
- - Opus security review is running on the merge-run endpoint.
16
- - Next: CPE-19 workspaces, CPE-20 integrations, and CPE-24 deleting the legacy dashboard last.
17
-
18
- ## Risks
19
- - Host load makes the pulse git and ps probes time out, so many metrics read UNKNOWN.
20
- - The weekly projection is over the pulse ceiling. Your D68 85% live /usage floor governs.
21
-
22
- ## Needs you
23
- - FOUNDER-QUEUE 18: a screenshot veto on the 10.8.0 look.
24
- - Items 15 and 16 (real-provider gate, Slack webhook) still park the real-model E2E legs.
25
- - Items 7 and 8 gate the external loki-seal launch.
@@ -1,52 +0,0 @@
1
- # Morning brief, 2026-10-01 (written 10:20Z)
2
-
3
- ## Headline
4
- - `npm install -g loki-mode` now runs the Loki 10 engine by default, using a bundled bun. `latest` = 10.5.29, gated on both a machine with bun and one without.
5
- - 18 release tags overnight (10.5.11 to 10.5.28), 16 published. Two were not published: 10.5.18 (CodeQL) and 10.5.21 (a changelog test). Both were fixed forward.
6
-
7
- ## What shipped (on npm latest unless noted)
8
- - Default engine flip (D48 7-9): `loki "<task>"`, issue mode and `loki quick` run Loki 10. A bare `loki verify` after a v10 run exits 4 for a non-VERIFIED outcome.
9
- - Bundled bun 1.4.2 as an optional dependency, with a resolver and a plain line when it cannot run (P0-nobun). It adds about 62MB on macOS arm64; npm lists 79.5MB for linux-x64.
10
- - Two-leg promote gate (E-167): `latest` moves only if the published version passes on a machine with bun (v10 checks) and one without (legacy checks plus the fallback line).
11
- - `loki keys export` and `loki verify --pubkey` let third parties check a receipt (D48 row 2).
12
- - Seal: a failed commit stage now ends FAILED and never seals VERIFIED (A-104b). Shipped in 10.5.28, promoted to `latest` at 10:17Z.
13
- - Also: Jira auto-sync wiring (E-166), provider stdin closed (A-134c), loki-seal counter fixes, CodeQL injection fix in the `/start` API, `loki` with no arguments opens the dashboard onboarding.
14
-
15
- ## D48 table (honest)
16
- | Row | Status |
17
- |---|---|
18
- | 1 gaming matrix | NOT DONE: test built (de71397d), not merged; pre-red case needs a CTO call |
19
- | 2 portable receipt | DONE: tamper detection, keys export, verify --pubkey |
20
- | 3 quiet and fast | PARTIAL: v10 output is 7 lines (gate checks 8 or fewer); the time ratio is not measured |
21
- | 4 commits only the fix | PARTIAL: lockfile and Wall exclusion per directory (10.5.28); no node/pytest/go matrix yet |
22
- | 5 exit ladder plus --json schema | PARTIAL: exit 4 shipped; schema not started |
23
- | 6 doctor --fix under 2s | NOT DONE: dropped from train/26, not reworked |
24
- | 7-9 v10 default, non-null cost | DONE: on latest; gate leg 1 checks the start line and non-null cost |
25
- | 10 loki-seal marketplace | DONE |
26
-
27
- ## Lift (D50): not citable yet
28
- - The baseline had Loki+sonnet 5/10 against raw sonnet 9/10. Of the 5 losses, 1 was also a raw loss (click-3059) and 1 predates the E-164 fix (aiq-52).
29
- - The 3 real defects: a false "already satisfied" (click-2877), an empty diff (humanize-174), and a wrong fix that verify passed (humanize-333).
30
- - 3-rep rerun (sonnet, current main) of the 4 Loki-specific tasks: click-2877 3/3 both arms and humanize-333 1/3 both arms (baseline losses were noise); humanize-174 Loki 0/3 vs raw 2/3 and aiq-52 (no_change_needed) Loki 0/3 vs raw 2/3 are real. Causes: aiq-52 reached ALREADY_SATISFIED only after implement edited source (fix D50-F1 building: restore to base on that outcome); humanize-174 needs spec-required test value changes, which the brief forbids (fix D50-F2: classifier labels value swaps as 'assertion changed per spec' while the verdict stays PARTIAL; S1 building). Internal only, not for publication.
31
-
32
- ## LOKI MORNING TEST
33
- ```
34
- npm install -g loki-mode@latest && loki --version # 10.5.29
35
- mkdir /tmp/lmt && cd /tmp/lmt && git init -q && echo 'module.exports=(a,b)=>a-b' > sum.js && git add sum.js && git commit -qm init
36
- loki quick "sum.js should add, not subtract" # first line names the Loki 10 engine; 8 lines or fewer
37
- loki verify # VERIFIED rc 0, or rc 4 if the run did not verify
38
- loki keys export > pub.jwk && loki verify --pubkey pub.jwk <e10-run-id> # third-party check (run id from .loki/runs)
39
- npm install -g loki-mode@latest --omit=optional # no bun: the plain cannot-run line, then legacy
40
- ```
41
-
42
- ## Slipped and why
43
- - D48 rows 1, 5 and 6: review capacity went to P0s (CodeQL, the gate text drift, the no-bun flip, the Seal false-VERIFIED path).
44
- - The slim `--omit=optional` install (30MB against 408MB) is not documented yet: the plain-line evidence on that install is still missing (E-170).
45
- - The Homebrew formula is in the separate asklokesh/tap, which this repo cannot reach; it needs `depends_on "oven-sh/bun/bun"` (E-169).
46
-
47
- ## Usage
48
- - Weekly projection about 92% (ceiling 90%); the governor allows about 7 engineers. The sprint ran hot and was paced down after 04:35Z.
49
-
50
- ## Founder queue (docs/v10/FOUNDER-QUEUE.md)
51
- - Row 17: bundling bun. Decided as option B by peer relay of your 03:30Z delegation, with install size accepted. Reverse it if you disagree.
52
- - Rows 11-16 still open: opt-in telemetry, relaunch post, repo hook paths, gitleaks scope, the real-provider gate run (needs a token from you), and the Slack test message.
package/docs/v10/TODO.md DELETED
@@ -1,35 +0,0 @@
1
- # v10 TODO lists (Chief of Staff and every team member)
2
-
3
- Updated by the Chief of Staff every turn it changes. Each agent also reports
4
- its own numbered TODO checklist (done / pending) at the top of every reply;
5
- that checklist is copied here when the agent reports. Status comes from
6
- docs/v10/BOARD.md; this file is the per-person view.
7
-
8
- Target: 3-5 releases per hour (CEO 2026-09-27 17:05Z), 60 per day.
9
-
10
- ## Chief of Staff (orchestrator), 19:10Z
11
-
12
- 1. [done 19:05:43Z] Release v9.69.0 from green 7ef5ca28 (main and tag both b2444763 by ls-remote).
13
- 2. [done] v9.68.0 on npm (`npm view loki-mode version` = 9.68.0; Release run 36342384478 success).
14
- 3. [done] v9.69.0 on npm (`npm view loki-mode version` = 9.69.0).
15
- 4. [done 19:06-19:09Z] Train 9 content: S-132, S-134, S-137, S-142, S-143, S-151 (a39c4995), S-139, S-141 (06bf5406), S-140 (e952e1ae).
16
- 5. [done 19:28:09Z] Release 10 = v9.70.0 from green b61045fd (main and tag 6c459dfa by ls-remote).
17
- 6. [done 19:19Z] S-136 landed (b61045fd); S-137 fix-forward 6e48decb.
18
- 7. [running] Batch 5 (wf_38d4e17c-211): reworks S-138, S-146, S-147, S-152; builds S-50, S-153, S-135; Architect cut S-154..S-173.
19
- 8. [running] WORKTREE_COUNT 24 of 15 at 19:37Z: my batch 6 dispatch opened 20 isolated worktrees at once (`git worktree list | grep -c claude/worktrees` = 24, every one owned by a live builder). Prune each as its slice merges; from now on a batch opens at most 15 minus the current count.
20
- 10. [done 19:37:24Z] Release 11 = v9.71.0 from green c6ed3882 (main and tag 4972a112 by ls-remote).
21
- 11. [done] Rows released at tag push reverted to merged until publish-npm succeeds (D27).
22
- 9. [pending] Drift audit every 6 turns; guard review every 50 turns.
23
-
24
- ## Team members
25
-
26
- | Agent | Slice | Role | TODO |
27
- |---|---|---|---|
28
- | Engineer (opus) | S-152 | pre-push: only the Release Manager pushes main | add allowed non-main case, fix commit message; then HIGH re-review |
29
- | Engineer | S-146 | one id="budget-banner" in the dashboard build | fix review CONCERN, rebuild static; then re-review |
30
- | Engineer | S-147 | loki metrics --json nulls for unmeasured values | fix review CONCERN; then re-review |
31
- | Engineer | S-138 | lint: fixtures never write the real ~/.gitconfig | fix 2nd REJECT findings; then re-review |
32
- | Engineer | S-50 | P7 sed workaround vs dynamic repo root | build, red/green, mutate; then review |
33
- | Engineer (opus) | S-153 | Footer.tsx on the release reuse allowlist | stub test reuse/no-reuse; then HIGH review |
34
- | Engineer | S-135 | parallel trust-core probe mutations, private copy per worker | before/after wall time, same CASE lines; then review |
35
- | Architect (opus) | S-154..S-173 | cut 20 ready slices | read-only; returns 20 BOARD rows |
package/mcp/resources.py DELETED
@@ -1,351 +0,0 @@
1
- """
2
- Loki Mode MCP Resources
3
-
4
- Resource definitions and helpers for MCP resource endpoints.
5
- Resources provide read-only access to Loki Mode data.
6
- Uses StateManager for centralized state access with caching.
7
- """
8
-
9
- import os
10
- import sys
11
- import json
12
- from typing import Dict, Any, List, Optional
13
- from datetime import datetime
14
-
15
- # Add parent directory to path for state manager import
16
- sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
17
-
18
- # Import StateManager for centralized state access
19
- try:
20
- from state.manager import StateManager, ManagedFile, get_state_manager
21
- HAS_STATE_MANAGER = True
22
- except ImportError:
23
- HAS_STATE_MANAGER = False
24
- StateManager = None
25
- ManagedFile = None
26
- get_state_manager = None
27
-
28
-
29
- def get_loki_base_path() -> str:
30
- """Get the base .loki directory path."""
31
- return os.path.join(os.getcwd(), '.loki')
32
-
33
-
34
- # Initialize a module-level StateManager instance
35
- _state_manager = None
36
-
37
-
38
- def _get_state_manager() -> Optional['StateManager']:
39
- """Get or create the StateManager instance."""
40
- global _state_manager
41
- if not HAS_STATE_MANAGER:
42
- return None
43
- if _state_manager is None:
44
- _state_manager = get_state_manager(
45
- loki_dir=get_loki_base_path(),
46
- enable_watch=False, # MCP resources don't need watching
47
- enable_events=False
48
- )
49
- return _state_manager
50
-
51
-
52
- # ============================================================
53
- # Continuity Resources
54
- # ============================================================
55
-
56
- def read_continuity() -> str:
57
- """Read the CONTINUITY.md file content."""
58
- continuity_path = os.path.join(get_loki_base_path(), 'CONTINUITY.md')
59
- if os.path.exists(continuity_path):
60
- with open(continuity_path, 'r') as f:
61
- return f.read()
62
- return ""
63
-
64
-
65
- def get_continuity_summary() -> Dict[str, Any]:
66
- """Get a summary of the continuity state."""
67
- content = read_continuity()
68
- if not content:
69
- return {"exists": False, "sections": []}
70
-
71
- # Parse sections from markdown
72
- sections = []
73
- current_section = None
74
- for line in content.split('\n'):
75
- if line.startswith('## '):
76
- if current_section:
77
- sections.append(current_section)
78
- current_section = {"title": line[3:].strip(), "content": []}
79
- elif current_section and line.strip():
80
- current_section["content"].append(line.strip())
81
-
82
- if current_section:
83
- sections.append(current_section)
84
-
85
- return {
86
- "exists": True,
87
- "sections": [s["title"] for s in sections],
88
- "line_count": len(content.split('\n'))
89
- }
90
-
91
-
92
- # ============================================================
93
- # Memory Resources
94
- # ============================================================
95
-
96
- def read_memory_index() -> Dict[str, Any]:
97
- """Read the memory index file using StateManager."""
98
- manager = _get_state_manager()
99
- if manager:
100
- result = manager.get_state(ManagedFile.MEMORY_INDEX)
101
- if result:
102
- return result
103
- # Fallback to direct file read if StateManager not available
104
- index_path = os.path.join(get_loki_base_path(), 'memory', 'index.json')
105
- if os.path.exists(index_path):
106
- with open(index_path, 'r') as f:
107
- return json.load(f)
108
- return {"topics": [], "message": "Index not initialized"}
109
-
110
-
111
- def get_memory_stats() -> Dict[str, Any]:
112
- """Get statistics about the memory system."""
113
- memory_path = os.path.join(get_loki_base_path(), 'memory')
114
- if not os.path.exists(memory_path):
115
- return {"initialized": False}
116
-
117
- stats = {
118
- "initialized": True,
119
- "episodic_count": 0,
120
- "semantic_count": 0,
121
- "skill_count": 0
122
- }
123
-
124
- # Count episodic memories
125
- episodic_path = os.path.join(memory_path, 'episodic')
126
- if os.path.exists(episodic_path):
127
- stats["episodic_count"] = len([
128
- f for f in os.listdir(episodic_path)
129
- if f.endswith('.json')
130
- ])
131
-
132
- # Count semantic patterns
133
- semantic_path = os.path.join(memory_path, 'semantic')
134
- if os.path.exists(semantic_path):
135
- stats["semantic_count"] = len([
136
- f for f in os.listdir(semantic_path)
137
- if f.endswith('.json')
138
- ])
139
-
140
- # Count skills
141
- skills_path = os.path.join(memory_path, 'skills')
142
- if os.path.exists(skills_path):
143
- stats["skill_count"] = len([
144
- f for f in os.listdir(skills_path)
145
- if f.endswith('.json')
146
- ])
147
-
148
- return stats
149
-
150
-
151
- def list_recent_episodes(limit: int = 10) -> List[Dict[str, Any]]:
152
- """List recent episodic memories."""
153
- episodic_path = os.path.join(get_loki_base_path(), 'memory', 'episodic')
154
- if not os.path.exists(episodic_path):
155
- return []
156
-
157
- episodes = []
158
- for filename in sorted(os.listdir(episodic_path), reverse=True)[:limit]:
159
- if filename.endswith('.json'):
160
- filepath = os.path.join(episodic_path, filename)
161
- try:
162
- with open(filepath, 'r') as f:
163
- episode = json.load(f)
164
- episodes.append({
165
- "id": episode.get("id", filename[:-5]),
166
- "timestamp": episode.get("timestamp"),
167
- "task_type": episode.get("task_type"),
168
- "outcome": episode.get("outcome")
169
- })
170
- except (json.JSONDecodeError, IOError):
171
- continue
172
-
173
- return episodes
174
-
175
-
176
- def list_semantic_patterns(category: Optional[str] = None) -> List[Dict[str, Any]]:
177
- """List semantic patterns, optionally filtered by category."""
178
- semantic_path = os.path.join(get_loki_base_path(), 'memory', 'semantic')
179
- if not os.path.exists(semantic_path):
180
- return []
181
-
182
- patterns = []
183
- for filename in os.listdir(semantic_path):
184
- if filename.endswith('.json'):
185
- filepath = os.path.join(semantic_path, filename)
186
- try:
187
- with open(filepath, 'r') as f:
188
- pattern = json.load(f)
189
- if category is None or pattern.get("category") == category:
190
- patterns.append({
191
- "id": pattern.get("id", filename[:-5]),
192
- "pattern": pattern.get("pattern"),
193
- "category": pattern.get("category"),
194
- "confidence": pattern.get("confidence"),
195
- "usage_count": pattern.get("usage_count", 0)
196
- })
197
- except (json.JSONDecodeError, IOError):
198
- continue
199
-
200
- return patterns
201
-
202
-
203
- # ============================================================
204
- # Task Queue Resources
205
- # ============================================================
206
-
207
- def read_task_queue() -> Dict[str, Any]:
208
- """Read the full task queue using StateManager."""
209
- manager = _get_state_manager()
210
- if manager:
211
- # Task queue is stored in state/task-queue.json, but we can use a custom path
212
- result = manager.get_state("state/task-queue.json")
213
- if result:
214
- return result
215
- # Fallback to direct file read if StateManager not available
216
- queue_path = os.path.join(get_loki_base_path(), 'state', 'task-queue.json')
217
- if os.path.exists(queue_path):
218
- with open(queue_path, 'r') as f:
219
- return json.load(f)
220
- return {"tasks": [], "version": "1.0"}
221
-
222
-
223
- def get_pending_tasks() -> List[Dict[str, Any]]:
224
- """Get all pending tasks."""
225
- queue = read_task_queue()
226
- return [t for t in queue.get("tasks", []) if t.get("status") == "pending"]
227
-
228
-
229
- def get_in_progress_tasks() -> List[Dict[str, Any]]:
230
- """Get all in-progress tasks."""
231
- queue = read_task_queue()
232
- return [t for t in queue.get("tasks", []) if t.get("status") == "in_progress"]
233
-
234
-
235
- def get_blocked_tasks() -> List[Dict[str, Any]]:
236
- """Get all blocked tasks."""
237
- queue = read_task_queue()
238
- return [t for t in queue.get("tasks", []) if t.get("status") == "blocked"]
239
-
240
-
241
- def get_task_by_id(task_id: str) -> Optional[Dict[str, Any]]:
242
- """Get a specific task by ID."""
243
- queue = read_task_queue()
244
- for task in queue.get("tasks", []):
245
- if task.get("id") == task_id:
246
- return task
247
- return None
248
-
249
-
250
- # ============================================================
251
- # State Resources
252
- # ============================================================
253
-
254
- def read_autonomy_state() -> Dict[str, Any]:
255
- """Read the autonomy state file using StateManager."""
256
- manager = _get_state_manager()
257
- if manager:
258
- result = manager.get_state(ManagedFile.AUTONOMY)
259
- if result:
260
- return result
261
- # Fallback to direct file read if StateManager not available
262
- state_path = os.path.join(get_loki_base_path(), 'state', 'autonomy-state.json')
263
- if os.path.exists(state_path):
264
- with open(state_path, 'r') as f:
265
- return json.load(f)
266
- return {}
267
-
268
-
269
- def get_current_phase() -> str:
270
- """Get the current SDLC phase."""
271
- state = read_autonomy_state()
272
- return state.get("current_phase", "unknown")
273
-
274
-
275
- def get_session_info() -> Dict[str, Any]:
276
- """Get information about the current session."""
277
- state = read_autonomy_state()
278
- return {
279
- "session_id": state.get("session_id"),
280
- "started_at": state.get("started_at"),
281
- "current_phase": state.get("current_phase"),
282
- "prd_path": state.get("prd_path"),
283
- "provider": state.get("provider", "claude")
284
- }
285
-
286
-
287
- # ============================================================
288
- # Metrics Resources
289
- # ============================================================
290
-
291
- def read_tool_metrics() -> Dict[str, Any]:
292
- """Read tool usage metrics."""
293
- metrics_path = os.path.join(get_loki_base_path(), 'metrics', 'tool-usage.jsonl')
294
- if not os.path.exists(metrics_path):
295
- return {"tool_calls": 0, "breakdown": {}}
296
-
297
- tool_counts = {}
298
- total_calls = 0
299
-
300
- with open(metrics_path, 'r') as f:
301
- for line in f:
302
- try:
303
- entry = json.loads(line)
304
- tool = entry.get("tool", "unknown")
305
- tool_counts[tool] = tool_counts.get(tool, 0) + 1
306
- total_calls += 1
307
- except json.JSONDecodeError:
308
- continue
309
-
310
- return {
311
- "tool_calls": total_calls,
312
- "breakdown": tool_counts
313
- }
314
-
315
-
316
- def get_efficiency_metrics() -> Dict[str, Any]:
317
- """Get efficiency metrics for the current session."""
318
- metrics_path = os.path.join(get_loki_base_path(), 'metrics', 'efficiency')
319
- if not os.path.exists(metrics_path):
320
- return {"available": False}
321
-
322
- metrics = {"available": True}
323
-
324
- # Read token economics if available
325
- token_path = os.path.join(metrics_path, 'token-economics.json')
326
- if os.path.exists(token_path):
327
- with open(token_path, 'r') as f:
328
- metrics["token_economics"] = json.load(f)
329
-
330
- return metrics
331
-
332
-
333
- def get_reward_signals() -> Dict[str, Any]:
334
- """Get reward signals for the current session."""
335
- rewards_path = os.path.join(get_loki_base_path(), 'metrics', 'rewards')
336
- if not os.path.exists(rewards_path):
337
- return {"available": False}
338
-
339
- signals = {"available": True, "rewards": []}
340
-
341
- # Read recent reward signals
342
- for filename in sorted(os.listdir(rewards_path), reverse=True)[:10]:
343
- if filename.endswith('.json'):
344
- filepath = os.path.join(rewards_path, filename)
345
- try:
346
- with open(filepath, 'r') as f:
347
- signals["rewards"].append(json.load(f))
348
- except (json.JSONDecodeError, IOError):
349
- continue
350
-
351
- return signals