loki-mode 10.6.9 → 10.6.10

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 (80) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +2 -2
  3. package/VERSION +1 -1
  4. package/autonomy/loki +7 -5
  5. package/dashboard/__init__.py +1 -1
  6. package/docs/INSTALLATION.md +1 -1
  7. package/docs/TOOL-INTEGRATION.md +3 -3
  8. package/docs/v10/BOARD.md +7 -1
  9. package/docs/v10/DECISIONS.md +5 -0
  10. package/docs/v10/E2E-D65.md +28 -0
  11. package/docs/v10/PROGRESS.md +13 -0
  12. package/loki-ts/dist/loki.js +3 -3
  13. package/mcp/__init__.py +1 -1
  14. package/package.json +2 -1
  15. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  16. package/schemas/features.schema.json +71 -0
  17. package/schemas/loki-yaml.schema.json +123 -0
  18. package/schemas/manifest.schema.json +77 -0
  19. package/schemas/migration-plan.schema.json +109 -0
  20. package/schemas/outcome-contract.schema.json +73 -0
  21. package/schemas/seams.schema.json +90 -0
  22. package/schemas/status-result.schema.json +30 -0
  23. package/schemas/why-result.schema.json +51 -0
  24. package/web-app/dist/assets/{AdminPage-CZKZLuWU.js → AdminPage-OaSCF3M4.js} +1 -1
  25. package/web-app/dist/assets/{Avatar-Dcy9kO2E.js → Avatar-xa3G7_vs.js} +1 -1
  26. package/web-app/dist/assets/{Badge-DUotUSyx.js → Badge-Ci_UcHij.js} +1 -1
  27. package/web-app/dist/assets/{Button-CFz_zfMZ.js → Button-CFrrmbvL.js} +1 -1
  28. package/web-app/dist/assets/{CockpitPage-BhRw_oiM.js → CockpitPage-6hyVl_QZ.js} +1 -1
  29. package/web-app/dist/assets/{ComparePage-DfnsRTTC.js → ComparePage-B5H56KCG.js} +1 -1
  30. package/web-app/dist/assets/{ErrorBoundary-Dn0gUu3D.js → ErrorBoundary-CBbRHsYr.js} +1 -1
  31. package/web-app/dist/assets/{EvidenceReceiptPanel-Co-xi282.js → EvidenceReceiptPanel-D-Zoneum.js} +1 -1
  32. package/web-app/dist/assets/{GitHubIssuesPanel-CoCpfexq.js → GitHubIssuesPanel-D7XPRsic.js} +1 -1
  33. package/web-app/dist/assets/{GitHubPRsPanel-Dg0Eg6F_.js → GitHubPRsPanel-CzHbBPAn.js} +1 -1
  34. package/web-app/dist/assets/{HomePage-BysxL4mV.js → HomePage-ClOx5qF1.js} +2 -2
  35. package/web-app/dist/assets/{LoginPage-CQ366p_d.js → LoginPage-3Yz_9j8E.js} +1 -1
  36. package/web-app/dist/assets/{MagicPage-DD7YcbNq.js → MagicPage-Dumn48gC.js} +1 -1
  37. package/web-app/dist/assets/{MetricsPage-BYz49xQj.js → MetricsPage-CYCYVG_8.js} +1 -1
  38. package/web-app/dist/assets/{NotFoundPage-CKs09MeO.js → NotFoundPage-CV-x_1qH.js} +1 -1
  39. package/web-app/dist/assets/{ProjectPage-Ci2BIA_D.js → ProjectPage-CeO7dnyM.js} +3 -3
  40. package/web-app/dist/assets/{ProjectsPage-ClwMH0eu.js → ProjectsPage-BT9mz6iD.js} +1 -1
  41. package/web-app/dist/assets/{SettingsPage-Cm0rCX-y.js → SettingsPage-BL8X9fAB.js} +1 -1
  42. package/web-app/dist/assets/{ShowcasePage-CxvESt8X.js → ShowcasePage-8f3lnSpc.js} +1 -1
  43. package/web-app/dist/assets/{SystemSettingsPage-W_CGYPOY.js → SystemSettingsPage-BUNAAzh2.js} +1 -1
  44. package/web-app/dist/assets/{TeamsPage-feVvRvys.js → TeamsPage-Qj-VEZJz.js} +1 -1
  45. package/web-app/dist/assets/{TemplatesPage-C-pUWMmF.js → TemplatesPage-b8lKqe5q.js} +1 -1
  46. package/web-app/dist/assets/{TerminalOutput-j5ibjKY3.js → TerminalOutput-jOnfQKB4.js} +1 -1
  47. package/web-app/dist/assets/{activity-TTdVYMa_.js → activity-w7GnyBNp.js} +1 -1
  48. package/web-app/dist/assets/{bell-DeoTFwpv.js → bell-2i4ejMOA.js} +1 -1
  49. package/web-app/dist/assets/{bot-B5SghxqU.js → bot-jaPm4NIs.js} +1 -1
  50. package/web-app/dist/assets/{check-k8SzsdbE.js → check-CvNtxeKM.js} +1 -1
  51. package/web-app/dist/assets/{chevron-left-DHnEllFz.js → chevron-left-zzBjHAtX.js} +1 -1
  52. package/web-app/dist/assets/{circle-alert-DW_SLdcB.js → circle-alert-CCU0IU2m.js} +1 -1
  53. package/web-app/dist/assets/{clock-Bmoaxy09.js → clock-BvZckMwN.js} +1 -1
  54. package/web-app/dist/assets/{cloud-eg3tzXTh.js → cloud-hrMWDdYp.js} +1 -1
  55. package/web-app/dist/assets/{code-xml-VAfXihhD.js → code-xml-v6l40T-K.js} +1 -1
  56. package/web-app/dist/assets/{database-CY3_-5aK.js → database-l2TMUrQd.js} +1 -1
  57. package/web-app/dist/assets/{dollar-sign-DYC0OLlg.js → dollar-sign-C2V6OvpO.js} +1 -1
  58. package/web-app/dist/assets/{file-code-corner-0X3SveKz.js → file-code-corner-Bytb5JGA.js} +1 -1
  59. package/web-app/dist/assets/{file-plus-B_oh_ukl.js → file-plus-BynCYQB8.js} +1 -1
  60. package/web-app/dist/assets/{globe-F0tLA8WJ.js → globe-DifDdNMH.js} +1 -1
  61. package/web-app/dist/assets/{hammer-DrlvBmfW.js → hammer-D7TsOJD6.js} +1 -1
  62. package/web-app/dist/assets/{index-YihVaZAj.js → index-Zohfqaz4.js} +3 -3
  63. package/web-app/dist/assets/{layers-CbJfn5UC.js → layers-Bk8c2YLS.js} +1 -1
  64. package/web-app/dist/assets/{loader-circle-CpmOggou.js → loader-circle-BrLdbMwP.js} +1 -1
  65. package/web-app/dist/assets/{lock-BGJ6QWrI.js → lock-COpmjMyJ.js} +1 -1
  66. package/web-app/dist/assets/{package-BTmH4Xto.js → package-BMzYdY7F.js} +1 -1
  67. package/web-app/dist/assets/{plus-mKQ7hz-8.js → plus-B9xpu1Pg.js} +1 -1
  68. package/web-app/dist/assets/{refresh-cw-vPetpLsm.js → refresh-cw-C2Lzh-AA.js} +1 -1
  69. package/web-app/dist/assets/{rotate-ccw-DiJ8GFhj.js → rotate-ccw-2Yyy-uQd.js} +1 -1
  70. package/web-app/dist/assets/{scroll-text-DpPQIlQR.js → scroll-text-DiK2yhsT.js} +1 -1
  71. package/web-app/dist/assets/{server-CiaV4drx.js → server-xlJBgleU.js} +1 -1
  72. package/web-app/dist/assets/{shield-alert-BaaQqyco.js → shield-alert-D9w4yBCi.js} +1 -1
  73. package/web-app/dist/assets/{thumbs-up-2zNCKp0Q.js → thumbs-up-CcWfvcE9.js} +1 -1
  74. package/web-app/dist/assets/{trash-2-CiVDx5Co.js → trash-2-_hk_pEAp.js} +1 -1
  75. package/web-app/dist/assets/{trending-down-tcxvw5BH.js → trending-down-CDZT99tC.js} +1 -1
  76. package/web-app/dist/assets/{trending-up-C2bv2_v_.js → trending-up-A0oreTXc.js} +1 -1
  77. package/web-app/dist/assets/{upload-DS4VPUAp.js → upload-DfLwhGG2.js} +1 -1
  78. package/web-app/dist/assets/{usePolling-JggBcVln.js → usePolling-B7gW2YY_.js} +1 -1
  79. package/web-app/dist/assets/{user-CvavvOxM.js → user-C-y7_Oon.js} +1 -1
  80. package/web-app/dist/index.html +1 -1
package/README.md CHANGED
@@ -553,7 +553,7 @@ Loki 10 engine:
553
553
  | `loki status [--json]` | Current status |
554
554
  | `loki verify [run-id]` | Re-check a sealed receipt (exit codes above) |
555
555
  | `loki doctor [--json] [--airgap]` | Check environment and providers |
556
- | `LOKI_CONTROL=1 loki control serve\|backfill\|status` | Control Plane v0 preview |
556
+ | `loki control serve\|backfill\|status` | Control Plane server, ship existing runs, reachability check (on by default; `LOKI_CONTROL=0` turns it off) |
557
557
  | `loki modernize <repo> --to <target> --dry-run` | Estimate only |
558
558
  | `loki plan [PRD]` | Dry-run analysis: complexity, cost, execution plan |
559
559
  | `loki version` | Show version |
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: loki-mode
3
3
  description: An autonomous software factory that knows what it is supposed to deliver, and proves it did. Use when the user says Loki Mode or asks to build, fix or verify software autonomously.
4
4
  ---
5
5
 
6
- # Loki Mode v10.6.9
6
+ # Loki Mode v10.6.10
7
7
 
8
8
  **Current entry points (Loki 10 engine):** `loki "<task>"`, `loki owner/repo#N` and `loki quick "<task>"` run the Loki 10 engine and end with a signed receipt (`loki verify`). `loki backlog owner/repo --all` runs many issues in parallel. Guide: `docs/v10/GUIDE.md`. The skill instructions below, and `loki start`, describe the legacy engine, which still ships and is being removed (`loki start owner/repo#N` still routes to it; prefer `loki owner/repo#N`).
9
9
 
@@ -473,4 +473,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
473
473
 
474
474
  ---
475
475
 
476
- **v10.6.9 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
476
+ **v10.6.10 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 10.6.9
1
+ 10.6.10
package/autonomy/loki CHANGED
@@ -21965,6 +21965,8 @@ main() {
21965
21965
  echo "Alias for 'loki api start'. Starts the dashboard HTTP API"
21966
21966
  echo "server (FastAPI, port 57374 by default)."
21967
21967
  echo ""
21968
+ echo "For the UI, run 'loki' (opens the Control Plane) or 'loki control serve'."
21969
+ echo ""
21968
21970
  echo "Options:"
21969
21971
  echo " --host HOST Bind host (default: 127.0.0.1)"
21970
21972
  echo " --port PORT Bind port (default: 57374)"
@@ -33938,14 +33940,14 @@ cmd_outcomes() {
33938
33940
  LOKI_DIR="${LOKI_DIR:-.loki}" python3 "$lib" "$@"
33939
33941
  }
33940
33942
 
33941
- # loki control -- D56 control plane (preview). The live route is the Bun CLI
33943
+ # loki control -- D56 control plane (on by default). The live route is the Bun CLI
33942
33944
  # (loki-ts/src/commands/control.ts); this is the LOKI_LEGACY_BASH / no-shim
33943
- # fallback. It keeps the gate and help in bash and hands the work to Bun.
33945
+ # fallback. It keeps the off switch and help in bash and hands the work to Bun.
33944
33946
  cmd_control() {
33945
33947
  local sub="${1:-}"
33946
33948
  case "$sub" in
33947
33949
  ""|-h|--help|help)
33948
- echo "Usage: loki control <command> [options] (preview, requires LOKI_CONTROL=1)"
33950
+ echo "Usage: loki control <command> [options] (on by default; LOKI_CONTROL=0 turns it off; requires bun)"
33949
33951
  echo ""
33950
33952
  echo "Commands:"
33951
33953
  echo " serve [--port N] [--db PATH] Run the control plane + UI on 127.0.0.1"
@@ -33954,8 +33956,8 @@ cmd_control() {
33954
33956
  return 0
33955
33957
  ;;
33956
33958
  esac
33957
- if [ "${LOKI_CONTROL:-}" != "1" ]; then
33958
- echo "loki control is in preview. Enable it with: export LOKI_CONTROL=1"
33959
+ if [ "${LOKI_CONTROL:-}" = "0" ]; then
33960
+ echo "loki control is off (LOKI_CONTROL=0). Unset it to turn the Control Plane back on."
33959
33961
  return 0
33960
33962
  fi
33961
33963
  local cli="$SKILL_DIR/loki-ts/dist/loki.js"
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "10.6.9"
10
+ __version__ = "10.6.10"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -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.6.9
5
+ **Version:** v10.6.10
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
 
@@ -7,7 +7,7 @@ This document shows how all Loki Mode tools work together to create a unified au
7
7
  | Tool | Entry Point | Purpose | Communication |
8
8
  |------|-------------|---------|---------------|
9
9
  | **CLI** | `loki` | User interface for all operations | File-based state |
10
- | **API** | `loki serve` | Remote control, SSE events | HTTP/REST |
10
+ | **API** | `loki api start` | Remote control, SSE events (dashboard API, not the Control Plane UI) | HTTP/REST |
11
11
  | **VS Code** | Extension | IDE integration | API client |
12
12
  | **MCP** | Claude tools | Claude Code integration | STDIO/MCP protocol |
13
13
  | **SKILL** | SKILL.md | Autonomy rules and behavior | File reads |
@@ -71,8 +71,8 @@ loki stop
71
71
  loki memory index
72
72
  loki memory retrieve "authentication"
73
73
 
74
- # Manage API server (enables VS Code, dashboard)
75
- loki serve --port 57374
74
+ # Manage the dashboard API server (enables VS Code; not the Control Plane UI, run `loki` for that)
75
+ loki api start --port 57374
76
76
  loki api start
77
77
 
78
78
  # View dashboard (web UI)
package/docs/v10/BOARD.md CHANGED
@@ -750,8 +750,14 @@ Source: ~/git/autonomi-dev/research/2026-09-30-adoption/SWARM-PROMPT-ADOPTION.md
750
750
  | D63-C4 | BLOCKED-RESUME: loki answer closes the BLOCKED loop | features/blocked_answer.ts, cli.ts, control-plane answer.ts, docs | MEDIUM | merged@2026-10-03T03:55Z | TL APPROVE 7b24ed66b + bdd5018d7; cherry-picked into train 85 (dist 52c3b0e02). |
751
751
  | D63-C3 | BASH-FLIPS: bare loki opens the Control Plane; workspace gate flips | autonomy/loki, tests/test-ui-bare-loki.sh, docs/dashboard-guide.md | MEDIUM | approved@2026-10-03T03:55Z | TL APPROVE e41381751 + C3-F 362e9c501 (URL path/query/userinfo reject, [::1] leg, 20/0). Train 86 with C2. |
752
752
  | D63-C11a | E2E-HARNESS: stub-provider E2E harness, legs 1-4 | scripts/e2e-d65.sh, scripts/e2e-d65/ | MEDIUM | approved@2026-10-03T03:55Z | TL APPROVE 50a75bcfa (legs 1-2 PASS, positive control rc 1; legs 3-4 fail on known C2/C5 bugs). BUG-C slack --port 0 for C6 follow-up. Train 86. |
753
- | D63-C11b | E2E-LEGS: stub-provider E2E legs 5-9 (Jira, contract, multi-repo, MCP, containers) and E2E-D65.md section 6 | scripts/e2e-d65/legs/05-09, docs/v10/E2E-D65.md | MEDIUM | building@2026-10-03T05:33Z | Sonnet builder dispatched from main 158d977ba; deps C5, C7-C10 on main. |
753
+ | D63-C11b | E2E-LEGS: stub-provider E2E legs 5-9 (Jira, contract, multi-repo, MCP, containers) and E2E-D65.md section 6 | scripts/e2e-d65/legs/05-09, docs/v10/E2E-D65.md | MEDIUM | merged@2026-10-03T05:53Z | Built c32e7c06c: legs 1-6, 8 PASS; 7 FAIL (BUG-5), 9 FAIL (BUG-6); force-fail rc 1; shellcheck clean. Sonnet TL review dispatched. TL APPROVE (leg 6 PASS, force-fail fails=1, shellcheck 0); cherry-picked. Doc table needs a refresh after BUG-5/BUG-6 land. |
754
+ | D65-BUG5 | Installed package lacks schemas/loki-yaml.schema.json (package.json files), so `loki workspace run` fails rc=2 outside a source checkout | package.json, a packaged-files test, CHANGELOG | LOW | merged@2026-10-03T05:55Z | Found by C11b leg 7. Builder dispatched from 3c47d0f1a. Fix e2abb9d8f (packaged test 14/1 -> 15/0); TL APPROVE (3 packaging suites green); cherry-picked. |
755
+ | D65-BUG6 | Dockerfile.control-plane omits loki-ts sources imported by packages/control-plane ingest.ts, so docker build fails Could not resolve | Dockerfile.control-plane, .dockerignore, CHANGELOG | MEDIUM | merged@2026-10-03T05:54Z | Found by C11b leg 9. Builder dispatched from 3c47d0f1a. Fix 33e6508c7; TL APPROVE (rebuilt image, /ready 200, test-control-plane 17/0); cherry-picked. Follow-up D65-BUG6-G: static guard that every loki-ts import in packages/control-plane is COPYed by the Dockerfile. |
756
+ | D65-BUG6-G | Guard: every loki-ts/src path imported by packages/control-plane/src appears in a Dockerfile.control-plane COPY | an existing control-plane shell test | LOW | merged@2026-10-03T05:58Z | TL non-blocking note on D65-BUG6. Built 31076e369 (guard red on missing redact.ts COPY, green restored, control plane 18/0, shellcheck 0); TL review dispatched. TL APPROVE (red/green reproduced, 11 import shapes, 18/0, shellcheck 0); non-blocking: dynamic import() and same-line second import not detected. |
754
757
  | P0-SPAWN-ENV-SPEED | Train 86 Coverage red: spawn_env_guard flags features/speed/already_done_async.ts execFile whose env arrives via an opts spread; inline env in the call | loki-ts/src/features/speed/already_done_async.ts | LOW | merged@2026-10-03T05:40Z | gh run 37099794381: 3070 pass 1 fail, (fail) spawn env guard > no spawn under loki-ts/src omits env. Runtime env is passed; source scan cannot see the spread. Blocks train 86 promote; fix rides train 87. Fix 191e5c6d2 (red 1 fail, green 2/0); dist 6cbdd32e0, dist guard 13/0; main full loki-ts bun test 3072 pass 0 fail. |
758
+ | P0-TC-SUPERSEDE | train-cycle Phase A superseded green unpromoted train/87 with train/88 and Phase B only evaluates the newest train; hold a green unpromoted train so Phase B promotes it first | scripts/train-cycle.sh, tests/test-train-cycle.sh | MEDIUM | merged@2026-10-03T06:18Z | Incident 06:13Z, RM promoted 87 by SHA by hand. Fix 5abab1f2c (red 47/3, green 50/0, shellcheck 0). TL APPROVE: A and B share REQUIRED_TRAIN and success rule; gh/fetch failures fail open; non-fast-forward train not held; mutation 47/3. Cherry-pick bd686b7c9. |
759
+ | D65-UI-NAMING | One UI command: loki serve --help points to loki / loki control serve; README control row and TOOL-INTEGRATION.md stop presenting loki serve or a LOKI_CONTROL=1 preview as the UI | autonomy/loki, README.md, docs/TOOL-INTEGRATION.md, CHANGELOG.md | LOW | merged@2026-10-03T06:25Z | Peer finding 06:20Z. Fix 5708413dd; serve routing unchanged. TL APPROVE (bash -n ok, serve --help exits 0 and binds nothing, wording matches control.ts LOKI_CONTROL=="0"). Follow-up D65-UI-NAMING-2 for bash fallback and cli.ts help. |
760
+ | D65-UI-NAMING-2 | Bash fallback cmd_control and loki-ts cli.ts help still say preview, needs LOKI_CONTROL=1; align with bun route (on by default, LOKI_CONTROL=0 off) | autonomy/loki, loki-ts/src/cli.ts, loki-ts/dist, tests, CHANGELOG.md | LOW | merged@2026-10-03T06:33Z | Fix 15f631fae (red: preview line rc=0 under LOKI_CONTROL=0; green: off line rc=0, no bun names bun rc=1). TL APPROVE: OFF_LINE byte-identical to control.ts:12, delegation unchanged, control plane 19/0, dist guard 13/0, shellcheck no new findings. Cherry-pick e564d2423 (CHANGELOG conflict resolved keeping both lines). Non-blocking: no-bun assertion depends on bun absent from /usr/bin:/bin. |
755
761
  | D63-C6 | SLACK: two-way Slack on by default | features/slack_inbound.ts, docs/slack.md, README | HIGH | merged@2026-10-03T04:15Z | Opus round 2 APPROVE; cherry-picked 1acd2a9a2,4b2c242bd,f02609175, dist fc10b503c |
756
762
  | D63-C6-F | SLACK follow-up: sender allowlist, 64 KB task cap, no local paths in replies, strict --port | features/slack_inbound.ts, docs/slack.md | MEDIUM | merged@2026-10-03T04:25Z | TL APPROVE e8837ffa4 (3 mutations red); cherry-picked 2a404421a, dist 7ad4a44e9 |
757
763
  | P0-CORE-BUDGET | Core engine10 at 5001 lines after D61-13 (budget.test.ts needs < 5000); remove dead core code | loki-ts/src/engine10 | MEDIUM | building@2026-10-03T04:31Z | Blocks train 86 |
@@ -554,3 +554,8 @@ The $20.00 default per-run cap stays. It is a hard stop on priced sessions only;
554
554
  - D61-12 is parked. D61 ships without an integrator: parallel units stay behind their flag and the integrator is not in the shipped feature set. Named in the handoff as not shipped.
555
555
  - Next window: redesign around per-resolution-commit containment (B at R^1, X at R, H at HEAD) and a revert guard for covered units, as the reviewer proposed.
556
556
 
557
+
558
+ ## D74: gitleaks job timeout 15 -> 30 min (CoS under D69, 07:25Z 2026-10-03)
559
+ - Evidence: the gitleaks full-history scan took 8-15 min on trains 83-87 and was cancelled at the 15 min limit on trains 86, 88, 89 and 90 ("gitleaks scan (all reachable history) ##[error]The operation was canceled", run 37104195817 attempt 2). Every other Security Audit job passed.
560
+ - Decision: raise timeout-minutes to 30. Same scan, same config, same blocking posture; nothing is narrowed or skipped, so this is not a gate weakening.
561
+ - Follow-up slice: make the scan scale (incremental scan against a reviewed baseline commit) before history doubles again. Any change to scan scope needs a CTO pass.
@@ -85,3 +85,31 @@ grep -rIl -E 'sk-ant-|oat01-' "$HOME/loki-ci-logs/real-repo-gate-e2e.logs" || ec
85
85
  ```
86
86
 
87
87
  Pass criteria per repo are in `scripts/real-repo-gate.repos` (expected outcome, allowed diff paths, max seconds); evidence to record for the log: exit code, wall seconds, Outcome line, receipt path, `loki verify` verdict.
88
+
89
+ ## 6. Stub E2E (`scripts/e2e-d65.sh`)
90
+
91
+ Hermetic run on loki-mode 10.6.8 (tree 158d977ba plus the C11b legs), 2026-10-03. The script runs `npm pack`, installs the tarball into a run-owned temp prefix (throwaway `HOME` and npm cache), puts a stub `claude` on PATH and drives the INSTALLED `loki` under `env -i` with an allowlist: no `*_API_KEY`, no `*_TOKEN` (only fake values such as `JIRA_API_TOKEN=e2e-fake-token`). Command: `LOKI_NO_BROWSER=1 timeout 600 bash scripts/e2e-d65.sh`; total 19 s, script rc=1 (two FAIL legs, both named product bugs below).
92
+
93
+ BUG-2 (the v10 engine ignored the stub `claude`) is resolved by `LOKI_E10_INVOKER=cli` plus `LOKI_CLAUDE_CLI=<stub>`, which the harness sets for every leg: legs 1, 2, 5 and 6 each produced a receipt with run rc=0 and no `Not logged in`.
94
+
95
+ | Leg | Result | Wall | rc line (from the run) |
96
+ |---|---|---|---|
97
+ | 1 D61 speed | PASS | 1 s | `loki quick rc=0 run=e10-20261003T053414Z-f543` |
98
+ | 2 Visual evidence | PASS | 1 s | `loki quick rc=0 run=e10-20261003T053416Z-13df`; NOT PROVEN line present |
99
+ | 3 Control Plane | PASS | 1 s | `blocked run rc=4 run=e10-20261003T053417Z-a324`; `POST answer ... -> 200` |
100
+ | 4 Slack | PASS | 1 s | signed `url_verification` returned the challenge; bad signature 401; no outbound connection |
101
+ | 5 Jira | PASS | 1 s | `loki quick jira:ABC-1 rc=0 run=e10-20261003T053418Z-d497`, `issue.json has source=jira`; `no-credentials rc=2 in 0s`, names `JIRA_EMAIL`/`JIRA_API_TOKEN` |
102
+ | 6 Spec to contract | PASS | 1 s | `loki quick rc=0 run=e10-20261003T053419Z-7afd`; receipt has the `contract` section with AC-1 |
103
+ | 7 Multi-repo | FAIL | 1 s | `loki workspace run rc=2`, `receipts=0 integration.json=none` (BUG-5) |
104
+ | 8 MCP | PASS | 0 s | `python rc=0`; `v10_status` done/VERIFIED, `v10_verify` `exit_code` 0 on leg 6's repo |
105
+ | 9 Containers | FAIL | 3 s | deploy files present; docker daemon answered; `docker build` failed (BUG-6) |
106
+
107
+ SKIP legs: none in this run. Leg 8 would SKIP if leg 6 had not produced a run, and leg 9 SKIPs with `SKIP(docker unavailable)` when `docker` is missing or `docker info` does not answer within 10 s; it never passes without a real `/ready` 200 probe on a random host port.
108
+
109
+ Positive control: `E2E_LEGS=6 E2E_FORCE_FAIL=6 bash scripts/e2e-d65.sh` prints `FAIL leg 6 ... forced by E2E_FORCE_FAIL=6 (positive control)` and exits 1. After each run the recorded PIDs (control-plane servers, the fake Jira `http.server`, the Slack proxy trap) are stopped by PID and the run directory is removed; nothing outside the run dir was touched.
110
+
111
+ New bugs found by this run (product code is not changed by this slice):
112
+
113
+ BUG-5 (P1, packaging): the npm package omits `schemas/`, so `loki workspace` fails on every installed copy. `package.json` `files` has no `schemas/` entry, while `autonomy/lib/loki_yaml.py:23` reads `schemas/loki-yaml.schema.json` relative to the package root. Repro: install the tarball, put a `workspaces:` block in `loki.yaml`, run `loki workspace run <name> <task>`; output `workspace: cannot read loki.yaml: [Errno 2] No such file or directory: '.../node_modules/loki-mode/autonomy/lib/../../schemas/loki-yaml.schema.json'`, rc=2. Leg 7 stays FAIL until `schemas/loki-yaml.schema.json` ships; the two-runs and `integration.json` assertions were therefore not reached.
114
+
115
+ BUG-6 (P1, container): `Dockerfile.control-plane` cannot build. Its build stage copies only `packages/control-plane/`, but `packages/control-plane/src/server/ingest.ts:3` and `:5` import `../../../../loki-ts/src/engine10/events.ts` and `../../../../loki-ts/src/util/redact.ts`. Repro: `docker build -f Dockerfile.control-plane .` fails at `RUN bun run build:all` with `error: Could not resolve: "../../../../loki-ts/src/engine10/events.ts"` and `.../util/redact.ts`. The `/ready` probe was therefore not reached and leg 9 is FAIL, not PASS.
@@ -1961,3 +1961,16 @@ The swarm is stopped: .loki/V10-STOP exists, the loop has no wake-ups, and the c
1961
1961
  - Train 86 first push failed: gitleaks github-pat on the synthetic token fixture tests/workspace/80-comment.sh:7 (D51-B11). Fingerprint baselined with a reason line in .gitleaksignore (acb4ee58f). Rerun: TRAIN_PUSHED train/86 at acb4ee58f, 05:25:53Z; CI pending.
1962
1962
  - In flight: P0-CORE-BUDGET TL r2, D61-11 test fix, D61-04-F leak fixes (MEDIUM, new BOARD row).
1963
1963
  - Carry-forward reviewer notes: P0-CONTROL-LINUX wants a frozen-lockfile install for packages/control-plane in CI; D50-F4b invalid-base reason unreachable in supervisor; D61-04 child env carries OLDPWD (informational).
1964
+
1965
+ ## 2026-10-03T06:15Z tick (CoS)
1966
+ - Train 86 red: spawn_env_guard flagged already_done_async.ts (env passed via spread) and the gitleaks shape pin drifted after acb4ee58f. Fixed by P0-SPAWN-ENV-SPEED (env inline, bun suite 3072/0) and the shape pin 3c47d0f1a (31/0).
1967
+ - Train 87 (3c47d0f1a) all six checks green (Tests 37101104493, Coverage, Security Audit, Bun Parity, Tier A, First-run). Promoted by SHA to main at 06:14Z (fast-forward from d95095d9d); Phase C waits on main Tests.
1968
+ - Incident: train-cycle Phase A pushed train/88 before Phase B evaluated green train/87, and Phase B only looks at the newest train, so a green train was skipped. Promoted 87 by hand with the same RM push Phase B uses. Guard slice wanted: Phase A must not supersede a green unpromoted train.
1969
+ - Train 88 (c127f5e9f) pushed: C11b E2E legs 5-9, D65-BUG5 (schemas/ shipped), D65-BUG6 (Dockerfile COPYs), D65-BUG6-G (TL APPROVE, 18/0), D61-04-F.
1970
+ - In flight: P0-CORE-BUDGET TL r2, D61-11 test fix. E2E-D65 section 6 table refresh due after train 88.
1971
+
1972
+ ## 2026-10-03T06:31Z tick (CoS)
1973
+ - v10.6.9 released (tag 48dadd05c). Release run all 10 jobs success; publish-npm logged "+ loki-mode@10.6.9" at 06:24:51Z. Registry at 06:30Z still reads latest=next=10.6.8 with no time entry; not announced as latest until npm view shows it (peer finding accepted).
1974
+ - Peer finding: `loki serve` is the deprecated alias of `loki api start`, not the Control Plane; docs and help disagreed. D65-UI-NAMING (62b592031) and D65-UI-NAMING-2 (e564d2423, bash fallback honors LOKI_CONTROL=0 and names bun) merged, both TL APPROVE.
1975
+ - P0-TC-SUPERSEDE merged (bd686b7c9): train-cycle now holds a green unpromoted train so Phase B promotes it first.
1976
+ - Train 88 was cut before the v10.6.9 release commit, so it is not a fast-forward of main. Merged origin/main into local main (7ad91e03f, no conflicts, dist rebuilt unchanged, dist guard 13/0) and pushed train 89 (8576564a7) carrying C11b, D65-BUG5, D65-BUG6, D65-BUG6-G, D61-04-F, P0-TC-SUPERSEDE, D65-UI-NAMING and -2.
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var K80=Object.create;var{getPrototypeOf:Y80,defineProperty:fH,getOwnPropertyNames:V80}=Object;var z80=Object.prototype.hasOwnProperty;function W80($){return this[$]}var q80,G80,H80=($,Z,Q)=>{var X=$!=null&&typeof $==="object";if(X){var J=Z?q80??=new WeakMap:G80??=new WeakMap,K=J.get($);if(K)return K}Q=$!=null?K80(Y80($)):{};let Y=Z||!$||!$.__esModule?fH(Q,"default",{value:$,enumerable:!0}):Q;for(let V of V80($))if(!z80.call(Y,V))fH(Y,V,{get:W80.bind($,V),enumerable:!0});if(X)J.set($,Y);return Y};var cK=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var B80=($)=>$;function U80($,Z){this[$]=B80.bind(null,Z)}var N0=($,Z)=>{for(var Q in Z)fH($,Q,{get:Z[Q],enumerable:!0,configurable:!0,set:U80.bind(Z,Q)})};var _=($,Z)=>()=>($&&(Z=$($=0)),Z);var p4=import.meta.require;var yI={};N0(yI,{lokiDir:()=>F0,homeLokiDir:()=>z4,findRepoRootForVersion:()=>hH,REPO_ROOT:()=>y0});import{resolve as d4,dirname as vH}from"path";import{fileURLToPath as O80}from"url";import{existsSync as lK}from"fs";import{homedir as N80}from"os";function M80(){let $=bI;for(let Z=0;Z<6;Z++){if(lK(d4($,"VERSION"))&&lK(d4($,"autonomy/run.sh")))return $;let Q=vH($);if(Q===$)break;$=Q}return d4(bI,"..","..","..")}function hH($){let Z=$;for(let Q=0;Q<6;Q++){if(lK(d4(Z,"VERSION"))&&lK(d4(Z,"autonomy/run.sh")))return Z;let X=vH(Z);if(X===Z)break;Z=X}return d4($,"..","..","..")}function F0(){return process.env.LOKI_DIR??d4(process.cwd(),".loki")}function z4(){return d4(N80(),".loki")}var bI,y0;var $8=_(()=>{bI=vH(O80(import.meta.url));y0=M80()});import{readFileSync as L80}from"fs";import{resolve as j80,dirname as A80}from"path";import{fileURLToPath as C80}from"url";function c4(){if(s7!==null)return s7;let $="10.6.9";if(typeof $==="string"&&$.length>0)return s7=$,s7;try{let Z=A80(C80(import.meta.url)),Q=hH(Z);s7=L80(j80(Q,"VERSION"),"utf-8").trim()}catch{s7="unknown"}return s7}var s7=null;var r$=_(()=>{$8()});var uI={};N0(uI,{runOrThrow:()=>v80,run:()=>I0,readStreamCapped:()=>iK,commandVersion:()=>g80,commandExists:()=>N9,ShellError:()=>mH,MAX_STDOUT_BYTES:()=>mI});async function iK($,Z=mI){let Q=$.getReader(),X=new TextDecoder,J="",K=0;try{while(K<Z){let{done:Y,value:V}=await Q.read();if(Y)break;if(!V)continue;if(K+=V.byteLength,K>Z){let z=V.byteLength-(K-Z);J+=X.decode(V.subarray(0,z),{stream:!0});break}J+=X.decode(V,{stream:!0})}J+=X.decode()}finally{try{await Q.cancel()}catch{}Q.releaseLock()}return J}async function I0($,Z={}){let Q=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Z.env?{...process.env,...Z.env}:process.env,cwd:Z.cwd}),X,J;if(Z.timeoutMs&&Z.timeoutMs>0)X=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}J=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},Z.timeoutMs);try{let[K,Y,V]=await Promise.all([iK(Q.stdout),new Response(Q.stderr).text(),Q.exited]);return{stdout:K,stderr:Y,exitCode:V}}finally{if(X)clearTimeout(X);if(J)clearTimeout(J)}}async function v80($,Z={}){let Q=await I0($,Z);if(Q.exitCode!==0)throw new mH(`command failed (${Q.exitCode}): ${$.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function N9($){let Z=h80($),Q=await I0(["sh","-c",`command -v ${Z}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function h80($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function g80($,Z="--version"){if(!await N9($))return null;let X=await I0([$,Z],{timeoutMs:5000});if(X.exitCode!==0)return null;return((X.stdout||X.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var mI=16777216,mH;var K9=_(()=>{mH=class mH extends Error{message;exitCode;stdout;stderr;constructor($,Z,Q,X){super($);this.message=$;this.exitCode=Z;this.stdout=Q;this.stderr=X;this.name="ShellError"}}});function l4($){return m80?"":$}var m80,k0,w8,d0,Gz8,K8,j8,Y9,c;var s5=_(()=>{m80=(process.env.NO_COLOR??"").length>0;k0=l4("\x1B[0;31m"),w8=l4("\x1B[0;32m"),d0=l4("\x1B[1;33m"),Gz8=l4("\x1B[0;34m"),K8=l4("\x1B[0;36m"),j8=l4("\x1B[1m"),Y9=l4("\x1B[2m"),c=l4("\x1B[0m")});import{accessSync as s80,constants as r80,existsSync as t80,statSync as e80}from"fs";async function r5(){if(t$!==void 0)return t$;let $="/opt/homebrew/bin/python3.12";if(t80($))return t$=$,$;let Z=await N9("python3.12");if(Z)return t$=Z,Z;let Q=await N9("python3");return t$=Q,Q}async function R6($,Z={}){let Q=await r5();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return I0([Q,"-c",$],Z)}async function cI(){let $=(process.env.PATH??"").split(":").filter((Z)=>Z.startsWith("/"));for(let Z of[...Z90,...$.map((Q)=>`${Q}/python3`)])try{if(!e80(Z).isFile())continue;if(s80(Z,r80.X_OK),(await I0([Z,"-I","-S","-c",""],{timeoutMs:1e4})).exitCode===0)return Z}catch{}return null}var t$,$90,Z90;var P6=_(()=>{K9();$90=["/usr/bin/python3","/bin/python3"],Z90=$90});var zD={};N0(zD,{runStatus:()=>R90});import{existsSync as V9,readFileSync as M2,readdirSync as $D,statSync as ZD}from"fs";import{resolve as p8,basename as M90}from"path";import{homedir as L90}from"os";function QD($){let Z=Math.trunc($);if(Z>=1e6)return`${(Math.trunc(Z/1e6*10)/10).toFixed(1)}M`;if(Z>=1000)return`${(Math.trunc(Z/1000*10)/10).toFixed(1)}K`;return String(Z)}function XD($,Z,Q){if(Z===0)return null;let X=Math.trunc($*100/Z),J=Math.trunc($*oK/Z);if(J>oK)J=oK;let K=oK-J,Y=w8;if(X>=80)Y=k0;else if(X>=50)Y=d0;let V="=".repeat(Math.max(0,J))+" ".repeat(Math.max(0,K)),z=QD($),W=QD(Z);return` ${j8}${Q}${c} ${Y}[${V}]${c} ${X}% (${z} / ${W})`}async function A90(){if(await N9("jq"))return!0;return process.stdout.write(`${k0}Error: jq is required but not installed.${c}
2
+ var K80=Object.create;var{getPrototypeOf:Y80,defineProperty:fH,getOwnPropertyNames:V80}=Object;var z80=Object.prototype.hasOwnProperty;function W80($){return this[$]}var q80,G80,H80=($,Z,Q)=>{var X=$!=null&&typeof $==="object";if(X){var J=Z?q80??=new WeakMap:G80??=new WeakMap,K=J.get($);if(K)return K}Q=$!=null?K80(Y80($)):{};let Y=Z||!$||!$.__esModule?fH(Q,"default",{value:$,enumerable:!0}):Q;for(let V of V80($))if(!z80.call(Y,V))fH(Y,V,{get:W80.bind($,V),enumerable:!0});if(X)J.set($,Y);return Y};var cK=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var B80=($)=>$;function U80($,Z){this[$]=B80.bind(null,Z)}var N0=($,Z)=>{for(var Q in Z)fH($,Q,{get:Z[Q],enumerable:!0,configurable:!0,set:U80.bind(Z,Q)})};var _=($,Z)=>()=>($&&(Z=$($=0)),Z);var p4=import.meta.require;var yI={};N0(yI,{lokiDir:()=>F0,homeLokiDir:()=>z4,findRepoRootForVersion:()=>hH,REPO_ROOT:()=>y0});import{resolve as d4,dirname as vH}from"path";import{fileURLToPath as O80}from"url";import{existsSync as lK}from"fs";import{homedir as N80}from"os";function M80(){let $=bI;for(let Z=0;Z<6;Z++){if(lK(d4($,"VERSION"))&&lK(d4($,"autonomy/run.sh")))return $;let Q=vH($);if(Q===$)break;$=Q}return d4(bI,"..","..","..")}function hH($){let Z=$;for(let Q=0;Q<6;Q++){if(lK(d4(Z,"VERSION"))&&lK(d4(Z,"autonomy/run.sh")))return Z;let X=vH(Z);if(X===Z)break;Z=X}return d4($,"..","..","..")}function F0(){return process.env.LOKI_DIR??d4(process.cwd(),".loki")}function z4(){return d4(N80(),".loki")}var bI,y0;var $8=_(()=>{bI=vH(O80(import.meta.url));y0=M80()});import{readFileSync as L80}from"fs";import{resolve as j80,dirname as A80}from"path";import{fileURLToPath as C80}from"url";function c4(){if(s7!==null)return s7;let $="10.6.10";if(typeof $==="string"&&$.length>0)return s7=$,s7;try{let Z=A80(C80(import.meta.url)),Q=hH(Z);s7=L80(j80(Q,"VERSION"),"utf-8").trim()}catch{s7="unknown"}return s7}var s7=null;var r$=_(()=>{$8()});var uI={};N0(uI,{runOrThrow:()=>v80,run:()=>I0,readStreamCapped:()=>iK,commandVersion:()=>g80,commandExists:()=>N9,ShellError:()=>mH,MAX_STDOUT_BYTES:()=>mI});async function iK($,Z=mI){let Q=$.getReader(),X=new TextDecoder,J="",K=0;try{while(K<Z){let{done:Y,value:V}=await Q.read();if(Y)break;if(!V)continue;if(K+=V.byteLength,K>Z){let z=V.byteLength-(K-Z);J+=X.decode(V.subarray(0,z),{stream:!0});break}J+=X.decode(V,{stream:!0})}J+=X.decode()}finally{try{await Q.cancel()}catch{}Q.releaseLock()}return J}async function I0($,Z={}){let Q=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Z.env?{...process.env,...Z.env}:process.env,cwd:Z.cwd}),X,J;if(Z.timeoutMs&&Z.timeoutMs>0)X=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}J=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},Z.timeoutMs);try{let[K,Y,V]=await Promise.all([iK(Q.stdout),new Response(Q.stderr).text(),Q.exited]);return{stdout:K,stderr:Y,exitCode:V}}finally{if(X)clearTimeout(X);if(J)clearTimeout(J)}}async function v80($,Z={}){let Q=await I0($,Z);if(Q.exitCode!==0)throw new mH(`command failed (${Q.exitCode}): ${$.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function N9($){let Z=h80($),Q=await I0(["sh","-c",`command -v ${Z}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function h80($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function g80($,Z="--version"){if(!await N9($))return null;let X=await I0([$,Z],{timeoutMs:5000});if(X.exitCode!==0)return null;return((X.stdout||X.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var mI=16777216,mH;var K9=_(()=>{mH=class mH extends Error{message;exitCode;stdout;stderr;constructor($,Z,Q,X){super($);this.message=$;this.exitCode=Z;this.stdout=Q;this.stderr=X;this.name="ShellError"}}});function l4($){return m80?"":$}var m80,k0,w8,d0,Gz8,K8,j8,Y9,c;var s5=_(()=>{m80=(process.env.NO_COLOR??"").length>0;k0=l4("\x1B[0;31m"),w8=l4("\x1B[0;32m"),d0=l4("\x1B[1;33m"),Gz8=l4("\x1B[0;34m"),K8=l4("\x1B[0;36m"),j8=l4("\x1B[1m"),Y9=l4("\x1B[2m"),c=l4("\x1B[0m")});import{accessSync as s80,constants as r80,existsSync as t80,statSync as e80}from"fs";async function r5(){if(t$!==void 0)return t$;let $="/opt/homebrew/bin/python3.12";if(t80($))return t$=$,$;let Z=await N9("python3.12");if(Z)return t$=Z,Z;let Q=await N9("python3");return t$=Q,Q}async function R6($,Z={}){let Q=await r5();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return I0([Q,"-c",$],Z)}async function cI(){let $=(process.env.PATH??"").split(":").filter((Z)=>Z.startsWith("/"));for(let Z of[...Z90,...$.map((Q)=>`${Q}/python3`)])try{if(!e80(Z).isFile())continue;if(s80(Z,r80.X_OK),(await I0([Z,"-I","-S","-c",""],{timeoutMs:1e4})).exitCode===0)return Z}catch{}return null}var t$,$90,Z90;var P6=_(()=>{K9();$90=["/usr/bin/python3","/bin/python3"],Z90=$90});var zD={};N0(zD,{runStatus:()=>R90});import{existsSync as V9,readFileSync as M2,readdirSync as $D,statSync as ZD}from"fs";import{resolve as p8,basename as M90}from"path";import{homedir as L90}from"os";function QD($){let Z=Math.trunc($);if(Z>=1e6)return`${(Math.trunc(Z/1e6*10)/10).toFixed(1)}M`;if(Z>=1000)return`${(Math.trunc(Z/1000*10)/10).toFixed(1)}K`;return String(Z)}function XD($,Z,Q){if(Z===0)return null;let X=Math.trunc($*100/Z),J=Math.trunc($*oK/Z);if(J>oK)J=oK;let K=oK-J,Y=w8;if(X>=80)Y=k0;else if(X>=50)Y=d0;let V="=".repeat(Math.max(0,J))+" ".repeat(Math.max(0,K)),z=QD($),W=QD(Z);return` ${j8}${Q}${c} ${Y}[${V}]${c} ${X}% (${z} / ${W})`}async function A90(){if(await N9("jq"))return!0;return process.stdout.write(`${k0}Error: jq is required but not installed.${c}
3
3
  `),process.stdout.write(`Install with:
4
4
  `),process.stdout.write(` brew install jq (macOS)
5
5
  `),process.stdout.write(` apt install jq (Debian/Ubuntu)
@@ -1783,7 +1783,7 @@ Phase 2 ported (Bun-native, fast):
1783
1783
  wiki <subcmd> Auto-generated, cited codebase wiki + Q&A
1784
1784
  (subcmds: generate | show [section] | ask "<question>")
1785
1785
  answer [run] [--text] Resume a BLOCKED run with an answer (--text, or the Control Plane answer file)
1786
- control <subcmd> Control plane (preview, needs LOKI_CONTROL=1)
1786
+ control <subcmd> Control plane (on by default; LOKI_CONTROL=0 turns it off)
1787
1787
  (subcmds: serve [--port N] [--db PATH] | backfill [DIR] | status)
1788
1788
 
1789
1789
  All other commands fall through to the bash CLI (autonomy/loki).
@@ -1796,4 +1796,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
1796
1796
  `),2}case"start":{let{runStart:X}=await Promise.resolve().then(() => (wn(),Pn));return X(Q)}case"slack":{let{runSlackCli:X}=await Promise.resolve().then(() => (tn(),rn));return X(Q)}case"answer":{let{runAnswerCli:X}=await Promise.resolve().then(() => (d00(),p00));return X(Q)}case"engine10":{let{runEngine10:X}=await Promise.resolve().then(() => (s00(),n00)),{registryLoader:J}=await Promise.resolve().then(() => (RH(),k00));return X(Q,J)}default:return process.stderr.write(`Unknown command: ${Z}
1797
1797
  `),process.stderr.write(r00),2}}tI();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var aV8=await iV8(Bun.argv.slice(2));process.exit(aV8);
1798
1798
 
1799
- //# debugId=24017A20D37F6B8B773A8947A1B1126E
1799
+ //# debugId=7901C720C8EA5639478E8C6E5BF2B4F6
package/mcp/__init__.py CHANGED
@@ -75,4 +75,4 @@ try:
75
75
  except ImportError:
76
76
  __all__ = ['mcp']
77
77
 
78
- __version__ = '10.6.9'
78
+ __version__ = '10.6.10'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "loki-mode",
3
3
  "mcpName": "io.github.asklokesh/loki-mode",
4
- "version": "10.6.9",
4
+ "version": "10.6.10",
5
5
  "description": "An autonomous software factory that knows what it is supposed to deliver, and proves it did.",
6
6
  "keywords": [
7
7
  "agent",
@@ -79,6 +79,7 @@
79
79
  "skills/",
80
80
  "references/",
81
81
  "docs/**/*.md",
82
+ "schemas/",
82
83
  "bin/",
83
84
  "bin/loki",
84
85
  "loki-ts/dist/",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "loki-mode",
4
4
  "displayName": "Loki Mode",
5
- "version": "10.6.9",
5
+ "version": "10.6.10",
6
6
  "description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 8 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
7
7
  "author": {
8
8
  "name": "Autonomi",
@@ -0,0 +1,71 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://autonomi.dev/loki-mode/schemas/features.schema.json",
4
+ "title": "Loki Migration Features",
5
+ "description": "Validates features.json produced by the migration engine understand phase.",
6
+ "oneOf": [
7
+ {
8
+ "type": "array",
9
+ "items": { "$ref": "#/definitions/Feature" }
10
+ },
11
+ {
12
+ "type": "object",
13
+ "properties": {
14
+ "features": {
15
+ "type": "array",
16
+ "items": { "$ref": "#/definitions/Feature" }
17
+ }
18
+ },
19
+ "required": ["features"],
20
+ "additionalProperties": false
21
+ }
22
+ ],
23
+ "definitions": {
24
+ "Feature": {
25
+ "type": "object",
26
+ "properties": {
27
+ "id": {
28
+ "type": "string",
29
+ "description": "Unique identifier for the feature."
30
+ },
31
+ "category": {
32
+ "type": "string",
33
+ "default": "",
34
+ "description": "Feature category grouping."
35
+ },
36
+ "description": {
37
+ "type": "string",
38
+ "description": "Human-readable description of the feature."
39
+ },
40
+ "verification_steps": {
41
+ "type": "array",
42
+ "items": { "type": "string" },
43
+ "default": [],
44
+ "description": "Steps to verify the feature works after migration."
45
+ },
46
+ "passes": {
47
+ "type": "boolean",
48
+ "default": false,
49
+ "description": "Whether the feature currently passes verification."
50
+ },
51
+ "characterization_test": {
52
+ "type": "string",
53
+ "default": "",
54
+ "description": "Path or name of the characterization test for this feature."
55
+ },
56
+ "risk": {
57
+ "type": "string",
58
+ "default": "low",
59
+ "description": "Risk level associated with migrating this feature."
60
+ },
61
+ "notes": {
62
+ "type": "string",
63
+ "default": "",
64
+ "description": "Additional notes about the feature."
65
+ }
66
+ },
67
+ "required": ["id", "description", "passes"],
68
+ "additionalProperties": false
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,123 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://autonomi.dev/schemas/loki-yaml.schema.json",
4
+ "title": "loki.yaml",
5
+ "description": "One config file for the Loki UI and the headless CLI (D51). Looked up in the repo root, then ~/.loki/loki.yaml (first found wins, no merging). Precedence: CLI flag > environment > loki.yaml > default. Secrets are never stored here: every credential key holds the NAME of an environment variable.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "provider": {
10
+ "description": "Default provider. Env override: LOKI_PROVIDER.",
11
+ "type": "string",
12
+ "enum": ["claude", "codex", "cline", "aider", "opencode"]
13
+ },
14
+ "models": {
15
+ "type": "object",
16
+ "additionalProperties": false,
17
+ "properties": {
18
+ "default": {
19
+ "description": "Default (development) model. Env override: LOKI_MODEL_DEVELOPMENT.",
20
+ "type": "string",
21
+ "minLength": 1
22
+ },
23
+ "cheap": {
24
+ "description": "Cheap/fast model. Env override: LOKI_MODEL_FAST.",
25
+ "type": "string",
26
+ "minLength": 1
27
+ }
28
+ }
29
+ },
30
+ "git": {
31
+ "type": "object",
32
+ "additionalProperties": false,
33
+ "properties": {
34
+ "token_env": {
35
+ "description": "NAME of the env var holding a GitHub PAT (never the token). Env override: LOKI_GIT_TOKEN_ENV.",
36
+ "type": "string",
37
+ "pattern": "^[A-Z_][A-Z0-9_]*$",
38
+ "x-secret-ref": true
39
+ }
40
+ }
41
+ },
42
+ "repos": {
43
+ "description": "owner/repo list the UI offers and headless runs may target.",
44
+ "type": "array",
45
+ "items": {
46
+ "type": "string",
47
+ "pattern": "^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$"
48
+ }
49
+ },
50
+ "concurrency": {
51
+ "description": "Max backlog runs in parallel (default 2). Env override: LOKI_BACKLOG_CONCURRENCY.",
52
+ "type": "integer",
53
+ "minimum": 1,
54
+ "maximum": 32,
55
+ "default": 2
56
+ },
57
+ "budgets": {
58
+ "type": "object",
59
+ "additionalProperties": false,
60
+ "properties": {
61
+ "per_run_usd": {
62
+ "description": "USD cap forwarded to each run as LOKI_BUDGET_LIMIT. Env override: LOKI_BUDGET_PER_RUN_USD.",
63
+ "type": "number",
64
+ "exclusiveMinimum": 0
65
+ },
66
+ "per_day_usd": {
67
+ "description": "USD per calendar day; backlog stops launching new runs once reached (BUDGET_STOP). Env override: LOKI_BUDGET_PER_DAY_USD.",
68
+ "type": "number",
69
+ "exclusiveMinimum": 0
70
+ }
71
+ }
72
+ },
73
+ "knowledge_sources": {
74
+ "description": "Local paths of knowledge to give runs. Parsed and validated only; consumed by a later slice.",
75
+ "type": "array",
76
+ "items": { "type": "string", "minLength": 1 }
77
+ },
78
+ "workspaces": {
79
+ "description": "Named groups of repos for cross-repo runs (`loki workspace run`). Accepted unconditionally; runtime behavior is gated by LOKI_WORKSPACES=1.",
80
+ "type": "object",
81
+ "additionalProperties": {
82
+ "type": "object",
83
+ "additionalProperties": false,
84
+ "properties": {
85
+ "repos": {
86
+ "type": "array",
87
+ "items": {
88
+ "type": "object",
89
+ "additionalProperties": false,
90
+ "properties": {
91
+ "repo": { "type": "string", "pattern": "^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$" },
92
+ "path": { "type": "string", "minLength": 1 },
93
+ "setup": { "type": "string", "minLength": 1 },
94
+ "after": { "type": "array", "items": { "type": "string" } }
95
+ }
96
+ }
97
+ },
98
+ "integration": {
99
+ "type": "object",
100
+ "additionalProperties": false,
101
+ "properties": {
102
+ "command": { "type": "string", "minLength": 1 },
103
+ "timeout_s": { "type": "integer", "minimum": 1 }
104
+ }
105
+ },
106
+ "integration_files": { "type": "array", "items": { "type": "string", "minLength": 1 } }
107
+ }
108
+ }
109
+ },
110
+ "notifications": {
111
+ "type": "object",
112
+ "additionalProperties": false,
113
+ "properties": {
114
+ "slack_webhook_env": {
115
+ "description": "NAME of the env var holding the Slack webhook URL (never the URL). Env override: LOKI_SLACK_WEBHOOK_ENV.",
116
+ "type": "string",
117
+ "pattern": "^[A-Z_][A-Z0-9_]*$",
118
+ "x-secret-ref": true
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
@@ -0,0 +1,77 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://autonomi.dev/loki-mode/schemas/manifest.schema.json",
4
+ "title": "Loki Migration Manifest",
5
+ "description": "Validates manifest.json that tracks overall migration state.",
6
+ "type": "object",
7
+ "properties": {
8
+ "id": {
9
+ "type": "string",
10
+ "default": "",
11
+ "description": "Unique migration identifier."
12
+ },
13
+ "created_at": {
14
+ "type": "string",
15
+ "default": "",
16
+ "description": "ISO 8601 timestamp of when the migration was created."
17
+ },
18
+ "source_info": {
19
+ "type": "object",
20
+ "default": {},
21
+ "description": "Information about the source codebase (language, framework, etc.)."
22
+ },
23
+ "target_info": {
24
+ "type": "object",
25
+ "default": {},
26
+ "description": "Information about the target codebase or migration target."
27
+ },
28
+ "phases": {
29
+ "type": "object",
30
+ "default": {},
31
+ "description": "Phase results keyed by phase name (understand, guardrail, migrate, verify).",
32
+ "additionalProperties": {
33
+ "type": "object",
34
+ "description": "Phase result data."
35
+ }
36
+ },
37
+ "feature_list_path": {
38
+ "type": "string",
39
+ "default": "",
40
+ "description": "Path to the features.json file."
41
+ },
42
+ "migration_plan_path": {
43
+ "type": "string",
44
+ "default": "",
45
+ "description": "Path to the migration-plan.json file."
46
+ },
47
+ "checkpoints": {
48
+ "type": "array",
49
+ "items": { "type": "string" },
50
+ "default": [],
51
+ "description": "List of checkpoint identifiers created during migration."
52
+ },
53
+ "status": {
54
+ "type": "string",
55
+ "default": "pending",
56
+ "description": "Current overall migration status."
57
+ },
58
+ "progress_pct": {
59
+ "type": "integer",
60
+ "minimum": 0,
61
+ "maximum": 100,
62
+ "default": 0,
63
+ "description": "Overall migration progress percentage (0-100)."
64
+ },
65
+ "updated_at": {
66
+ "type": "string",
67
+ "default": "",
68
+ "description": "ISO 8601 timestamp of the last update."
69
+ },
70
+ "source_path": {
71
+ "type": "string",
72
+ "default": "",
73
+ "description": "Absolute path to the source codebase."
74
+ }
75
+ },
76
+ "additionalProperties": false
77
+ }