loki-mode 10.6.13 → 10.7.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 (110) hide show
  1. package/README.md +8 -5
  2. package/SKILL.md +3 -3
  3. package/VERSION +1 -1
  4. package/autonomy/acp-agent.py +128 -0
  5. package/autonomy/completion-council.sh +3 -3
  6. package/autonomy/docker-run.sh +8 -0
  7. package/autonomy/issue-parser.sh +8 -7
  8. package/autonomy/issue-providers.sh +159 -1
  9. package/autonomy/lib/engine10-push.sh +4 -1
  10. package/autonomy/lib/review_risk.py +91 -0
  11. package/autonomy/loki +225 -31
  12. package/autonomy/mobile-verify.sh +66 -0
  13. package/autonomy/quickstart.sh +44 -4
  14. package/autonomy/run.sh +44 -2
  15. package/completions/_loki +2 -0
  16. package/completions/loki.bash +1 -1
  17. package/dashboard/__init__.py +1 -1
  18. package/dashboard/api_runs_v1.py +80 -0
  19. package/dashboard/server.py +2 -0
  20. package/docs/COMPETITOR-DEPLOYMENT-MODELS.md +3 -3
  21. package/docs/INSTALLATION.md +5 -1
  22. package/docs/acp-editors.md +29 -0
  23. package/docs/api-runs-v1.md +12 -0
  24. package/docs/architecture/ADR-001-runtime-migration.md +13 -13
  25. package/docs/dev/architecture-reference.md +6 -2
  26. package/docs/merge-queue.md +13 -0
  27. package/docs/mobile-verify.md +11 -0
  28. package/docs/sentry-intake.md +13 -0
  29. package/docs/v10/BOARD.md +66 -12
  30. package/docs/v10/CP-ENTERPRISE-UI.md +276 -0
  31. package/docs/v10/D61-SPEED.md +4 -0
  32. package/docs/v10/DECISIONS.md +85 -0
  33. package/docs/v10/FOUNDER-QUEUE.md +1 -0
  34. package/docs/v10/GAP-RESEARCH-1003.md +32 -0
  35. package/docs/v10/MORNING-BRIEF-1003.md +39 -0
  36. package/docs/v10/PROGRESS.md +107 -0
  37. package/docs/v10/SWARM.md +32 -0
  38. package/docs/visual-evidence.md +5 -0
  39. package/loki-ts/dist/loki.js +766 -624
  40. package/mcp/__init__.py +1 -1
  41. package/package.json +1 -1
  42. package/packages/control-plane/dist/server.js +263 -9
  43. package/packages/control-plane/src/server/actions.ts +60 -0
  44. package/packages/control-plane/src/server/app.ts +39 -3
  45. package/packages/control-plane/src/shipper/watch.ts +64 -0
  46. package/packages/control-plane/ui/dist/assets/index-CUQ65vJY.css +1 -0
  47. package/packages/control-plane/ui/dist/assets/index-CwwGfp6E.js +129 -0
  48. package/packages/control-plane/ui/dist/index.html +3 -3
  49. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  50. package/skills/healing.md +2 -2
  51. package/tools/proof-passport.py +1 -1
  52. package/web-app/dist/assets/{AdminPage-CVEdde3t.js → AdminPage-BQPb5rc5.js} +1 -1
  53. package/web-app/dist/assets/{Avatar-D1r8n_Da.js → Avatar-Cttco6FC.js} +1 -1
  54. package/web-app/dist/assets/{Badge-BAPyJ97M.js → Badge-CPb6kpbH.js} +1 -1
  55. package/web-app/dist/assets/{Button-C-GCctTq.js → Button-caTL28a4.js} +1 -1
  56. package/web-app/dist/assets/{CockpitPage-CV9MhyuV.js → CockpitPage-bEbLx6ph.js} +1 -1
  57. package/web-app/dist/assets/{ComparePage-D1R5Lxmy.js → ComparePage-DNtJSij-.js} +1 -1
  58. package/web-app/dist/assets/{ErrorBoundary-CFvJx4vV.js → ErrorBoundary-BrgC3K44.js} +1 -1
  59. package/web-app/dist/assets/{EvidenceReceiptPanel-9I7dfPz0.js → EvidenceReceiptPanel-Q-mSrUUQ.js} +1 -1
  60. package/web-app/dist/assets/{GitHubIssuesPanel-8YH6WkTh.js → GitHubIssuesPanel-DbmYl_Er.js} +1 -1
  61. package/web-app/dist/assets/{GitHubPRsPanel-BZvEHBTF.js → GitHubPRsPanel-C6PCHM4B.js} +1 -1
  62. package/web-app/dist/assets/{HomePage-DhjWTo8R.js → HomePage-7zsL_k_e.js} +2 -2
  63. package/web-app/dist/assets/{LoginPage-BwNGyWxP.js → LoginPage-Cl4ON8RQ.js} +1 -1
  64. package/web-app/dist/assets/{MagicPage-Dg9z7deq.js → MagicPage-BNEAhTqH.js} +1 -1
  65. package/web-app/dist/assets/{MetricsPage-DLF1F6XC.js → MetricsPage-DyBH-88q.js} +1 -1
  66. package/web-app/dist/assets/{NotFoundPage-CZClMI3s.js → NotFoundPage-CIVr21yL.js} +1 -1
  67. package/web-app/dist/assets/{ProjectPage-CnAvyHDJ.js → ProjectPage-BMeVYocF.js} +3 -3
  68. package/web-app/dist/assets/{ProjectsPage-D33VGyVL.js → ProjectsPage-D-H2WRVU.js} +1 -1
  69. package/web-app/dist/assets/{SettingsPage-DQtlpXPe.js → SettingsPage-o0kR9RAt.js} +1 -1
  70. package/web-app/dist/assets/{ShowcasePage-CAitzJlY.js → ShowcasePage-DtfMDMjp.js} +1 -1
  71. package/web-app/dist/assets/{SystemSettingsPage-CV49UjwU.js → SystemSettingsPage-CkXdpZ_T.js} +1 -1
  72. package/web-app/dist/assets/{TeamsPage-5EKrbkN3.js → TeamsPage-Cu5H9cQ0.js} +1 -1
  73. package/web-app/dist/assets/{TemplatesPage-BRsrm00y.js → TemplatesPage-3wdbVwil.js} +1 -1
  74. package/web-app/dist/assets/{TerminalOutput-DgEnMwnQ.js → TerminalOutput-CWn301xh.js} +1 -1
  75. package/web-app/dist/assets/{activity-hXTYu4Zb.js → activity-YGaAt4zJ.js} +1 -1
  76. package/web-app/dist/assets/{bell-D5QkmMjg.js → bell-C28q0GO7.js} +1 -1
  77. package/web-app/dist/assets/{bot-CGOzPami.js → bot-DLcQGI92.js} +1 -1
  78. package/web-app/dist/assets/{check-HxPvzPXm.js → check-w0sBNlcm.js} +1 -1
  79. package/web-app/dist/assets/{chevron-left-D7HYUp4T.js → chevron-left-W7O0vC_m.js} +1 -1
  80. package/web-app/dist/assets/{circle-alert-BdufMh8P.js → circle-alert-Cxjq9fxB.js} +1 -1
  81. package/web-app/dist/assets/{clock-DMcS0xjR.js → clock-C8EqzmNl.js} +1 -1
  82. package/web-app/dist/assets/{cloud-Bt-0bh9m.js → cloud-xNgp4g3Y.js} +1 -1
  83. package/web-app/dist/assets/{code-xml-DRtDKt4_.js → code-xml-B-lyNDLJ.js} +1 -1
  84. package/web-app/dist/assets/{database-B0ChKZQ4.js → database-DoW5lmWc.js} +1 -1
  85. package/web-app/dist/assets/{dollar-sign-st_8sF_M.js → dollar-sign-BcARA5sC.js} +1 -1
  86. package/web-app/dist/assets/{file-code-corner-UdiLz5N6.js → file-code-corner-CehcII0J.js} +1 -1
  87. package/web-app/dist/assets/{file-plus-De1dimur.js → file-plus-DI9Zo5hP.js} +1 -1
  88. package/web-app/dist/assets/{globe-rrbXmytb.js → globe-CiZWBk3H.js} +1 -1
  89. package/web-app/dist/assets/{hammer-CBtNZi-S.js → hammer-3qv_T2N-.js} +1 -1
  90. package/web-app/dist/assets/{index-D3YvZaMV.js → index-gF9grAz-.js} +3 -3
  91. package/web-app/dist/assets/{layers-BmthCdkO.js → layers-CN7d0By9.js} +1 -1
  92. package/web-app/dist/assets/{loader-circle-C_sXFJUa.js → loader-circle-DywcM-im.js} +1 -1
  93. package/web-app/dist/assets/{lock-DT6V3D97.js → lock-_hdSmkU4.js} +1 -1
  94. package/web-app/dist/assets/{package-D86K1oU6.js → package-BV5zgqxJ.js} +1 -1
  95. package/web-app/dist/assets/{plus-Dwkssum8.js → plus-CU_Hh4-x.js} +1 -1
  96. package/web-app/dist/assets/{refresh-cw-DhRlqf1F.js → refresh-cw-DMK-fNl-.js} +1 -1
  97. package/web-app/dist/assets/{rotate-ccw-EvA5ZJVL.js → rotate-ccw-CEB3_v5_.js} +1 -1
  98. package/web-app/dist/assets/{scroll-text-D4ABo43E.js → scroll-text-BSdXxcRN.js} +1 -1
  99. package/web-app/dist/assets/{server-BAAdr_fD.js → server-CAMlP1yJ.js} +1 -1
  100. package/web-app/dist/assets/{shield-alert-DJPLy9t8.js → shield-alert-B-r1Dt3h.js} +1 -1
  101. package/web-app/dist/assets/{thumbs-up-D07JqmoS.js → thumbs-up-CYfxw9o4.js} +1 -1
  102. package/web-app/dist/assets/{trash-2-BJYwlHzl.js → trash-2-DX3nGPS8.js} +1 -1
  103. package/web-app/dist/assets/{trending-down-Bo8txoOw.js → trending-down-Bt-hSntd.js} +1 -1
  104. package/web-app/dist/assets/{trending-up-Bb13tkln.js → trending-up-DVSlvQp8.js} +1 -1
  105. package/web-app/dist/assets/{upload-D60DiVNZ.js → upload-D45RRHAP.js} +1 -1
  106. package/web-app/dist/assets/{usePolling-DJmgDiio.js → usePolling-fq_Xj8iw.js} +1 -1
  107. package/web-app/dist/assets/{user-BmXCbSJm.js → user-BWcJkLlr.js} +1 -1
  108. package/web-app/dist/index.html +1 -1
  109. package/packages/control-plane/ui/dist/assets/index-CFfrqCx2.css +0 -1
  110. package/packages/control-plane/ui/dist/assets/index-Jt31nrK-.js +0 -114
@@ -5,7 +5,7 @@ _loki_completion() {
5
5
  _init_completion || return
6
6
 
7
7
  # Main subcommands (must match autonomy/loki main case statement)
8
- local main_commands="start backlog quick monitor demo tour welcome init stop pause resume steer status next ship dashboard web serve api sandbox notify import github issue intent config provider reset memory compound checkpoint council dogfood projects enterprise secrets cockpit secure own handoff doctor watchdog audit metrics syslog onboard share proof receipt outcomes explain plan report cost estimate kpis stats test ci watch telemetry agent context ctx code run export review optimize heal modernize migrate cluster worktree wt trigger failover remote deploy docker mcp magic assets analyze compliance crash control workspace open otel preview quickstart rc rollback self-update sentrux setup-skill spec state template trust trust-metrics ultracode update verify voice why wiki bench cleanup logs grill docs cp version completions help keys answer"
8
+ local main_commands="start backlog quick monitor demo tour welcome init stop pause resume steer status next ship dashboard web serve api sandbox notify import github issue intent config provider reset memory compound checkpoint council dogfood projects enterprise secrets cockpit secure own handoff doctor watchdog audit metrics syslog onboard share proof receipt outcomes explain plan report cost estimate kpis stats test ci watch telemetry agent context ctx code run export review optimize heal modernize migrate cluster worktree wt trigger failover remote deploy docker mcp magic assets analyze compliance crash control workspace open otel preview quickstart rc rollback merge self-update sentrux setup-skill spec state template trust trust-metrics ultracode update verify voice why wiki bench cleanup logs grill docs cp version completions help keys answer acp"
9
9
 
10
10
  # 1. If we are on the first argument (subcommand)
11
11
  if [[ $cword -eq 1 ]]; then
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "10.6.13"
10
+ __version__ = "10.7.0"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -0,0 +1,80 @@
1
+ """REST API for runs: /api/v1/runs.
2
+
3
+ A thin, stable surface over code that already exists:
4
+ GET /api/v1/runs -> api_runs.list_runs (envelope kept intact)
5
+ GET /api/v1/runs/{id} -> api_runs.get_run (404 when the run is unknown)
6
+ POST /api/v1/runs -> the existing /api/control/start handler
7
+ POST /api/v1/runs/{id}/stop -> the existing /api/control/stop handler,
8
+ only when {id} is the current run
9
+
10
+ Auth is the dashboard's own scope check: "read" for GETs, "control" for POSTs.
11
+ The dashboard binds loopback by default; nothing here opens a listener.
12
+ """
13
+ import os
14
+ from typing import Optional
15
+
16
+ from fastapi import APIRouter, Depends, HTTPException, Request
17
+ from pydantic import BaseModel, Field
18
+
19
+ from . import auth
20
+
21
+ router = APIRouter(prefix="/api/v1/runs", tags=["runs-v1"])
22
+ _READ = [Depends(auth.require_scope("read"))]
23
+ _CONTROL = [Depends(auth.require_scope("control"))]
24
+
25
+
26
+ def _loki_dir() -> str:
27
+ try:
28
+ from . import server
29
+ return str(server._get_loki_dir())
30
+ except Exception:
31
+ return os.environ.get("LOKI_DIR") or os.path.join(os.getcwd(), ".loki")
32
+
33
+
34
+ class RunStartIn(BaseModel):
35
+ prd_text: Optional[str] = Field(default=None, max_length=1_048_576)
36
+ prd_path: Optional[str] = None
37
+ provider: str = "claude"
38
+ parallel: bool = False
39
+
40
+
41
+ async def _start_impl(request: Request, body: RunStartIn):
42
+ from . import server
43
+ return await server.start_build(request, server.StartBuildRequest(**body.model_dump()))
44
+
45
+
46
+ async def _stop_impl(request: Request):
47
+ from . import server
48
+ return await server.stop_session(request)
49
+
50
+
51
+ @router.get("", dependencies=_READ)
52
+ def list_runs_v1():
53
+ from . import api_runs
54
+ return api_runs.list_runs(_loki_dir())
55
+
56
+
57
+ @router.get("/{run_id}", dependencies=_READ)
58
+ def get_run_v1(run_id: str):
59
+ from . import api_runs
60
+ env = api_runs.get_run(_loki_dir(), run_id)
61
+ if env.get("run") is None:
62
+ raise HTTPException(status_code=404, detail=env.get("reason") or "run not found")
63
+ return env
64
+
65
+
66
+ @router.post("", dependencies=_CONTROL)
67
+ async def start_run_v1(request: Request, body: RunStartIn):
68
+ return await _start_impl(request, body)
69
+
70
+
71
+ @router.post("/{run_id}/stop", dependencies=_CONTROL)
72
+ async def stop_run_v1(run_id: str, request: Request):
73
+ from . import api_runs
74
+ env = api_runs.get_run(_loki_dir(), run_id)
75
+ row = env.get("run")
76
+ if row is None:
77
+ raise HTTPException(status_code=404, detail=env.get("reason") or "run not found")
78
+ if not row.get("current"):
79
+ raise HTTPException(status_code=409, detail="only the current run can be stopped")
80
+ return await _stop_impl(request)
@@ -1362,6 +1362,8 @@ else:
1362
1362
  # D51 Phase A: first-run onboarding + backlog API and its /start page.
1363
1363
  from .api_start import router as api_start_router, START_HTML as _START_HTML
1364
1364
  app.include_router(api_start_router)
1365
+ from .api_runs_v1 import router as api_runs_v1_router
1366
+ app.include_router(api_runs_v1_router)
1365
1367
 
1366
1368
 
1367
1369
  @app.get("/start", include_in_schema=False, dependencies=[Depends(auth.require_scope("read"))])
@@ -213,10 +213,10 @@ verbatim:
213
213
  MCP server, https://docs.replit.com/platforms/mcp-server (accessed 2026-08-08).
214
214
  This is the programmatic trigger. Documented tools:
215
215
 
216
- - `create_app_from_prompt` — "Create a new Replit App from a natural language
216
+ - `create_app_from_prompt` - "Create a new Replit App from a natural language
217
217
  description. Replit Agent immediately starts building the app."
218
- - `update_app_using_prompt` — "Make changes to an existing Replit App."
219
- - `ask_question` — "Ask Replit Agent about the current app."
218
+ - `update_app_using_prompt` - "Make changes to an existing Replit App."
219
+ - `ask_question` - "Ask Replit Agent about the current app."
220
220
 
221
221
  An Enterprise Admin API exists
222
222
  (https://docs.replit.com/teams/admin-api) but is scoped to account usage,
@@ -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.13
5
+ **Version:** v10.7.0
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
 
@@ -434,11 +434,15 @@ runs any loki command inside the published `asklokesh/loki-mode` image with zero
434
434
  config:
435
435
 
436
436
  ```bash
437
+ loki docker start owner/repo#17 # work a GitHub issue or PR in Docker (primary path)
437
438
  loki docker start prd.md # full local experience in Docker
438
439
  loki docker status # any loki command works
439
440
  loki docker --dry-run start prd.md # print the docker command, do not run
440
441
  ```
441
442
 
443
+ On macOS, pass your GitHub login for PRs with
444
+ `GH_TOKEN=$(gh auth token) loki docker start owner/repo#17`.
445
+
442
446
  It bind-mounts the current folder to `/workspace`, so `.loki/` state (memory,
443
447
  session, queue, checkpoints) persists on the host and resume and continuity
444
448
  behave exactly like the local `loki` CLI. Auth is auto-detected:
@@ -0,0 +1,29 @@
1
+ # Loki in VS Code and JetBrains via ACP
2
+
3
+ `loki acp` speaks the Agent Client Protocol (newline-delimited JSON-RPC over
4
+ stdio). It supports `initialize`, `session/new`, `session/prompt` and
5
+ `session/cancel`. Each prompt runs `loki quick "<prompt>"` in the session's
6
+ working directory and streams the output back. A non-zero exit is reported as
7
+ "NOT VERIFIED"; nothing is claimed that did not run. Loki never receives editor
8
+ credentials, and no network listener is opened.
9
+
10
+ ## JetBrains (AI Assistant with ACP support)
11
+
12
+ Edit `~/.jetbrains/acp.json`:
13
+
14
+ {"agent_servers": {"Loki": {"command": "loki", "args": ["acp"]}}}
15
+
16
+ ## Zed
17
+
18
+ In settings.json:
19
+
20
+ {"agent_servers": {"Loki": {"command": "loki", "args": ["acp"]}}}
21
+
22
+ ## VS Code
23
+
24
+ Use any ACP client extension and register a custom agent with command `loki`
25
+ and args `acp`.
26
+
27
+ ## Smoke test
28
+
29
+ printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1}}' | loki acp
@@ -0,0 +1,12 @@
1
+ # Runs REST API (/api/v1/runs)
2
+
3
+ Served by the local dashboard (loopback by default). Auth reuses the dashboard
4
+ scopes: "read" for GET, "control" for POST. With auth off (default local mode)
5
+ no token is needed; with it on, send `Authorization: Bearer <token>`.
6
+
7
+ - `GET /api/v1/runs` - envelope `{runs, source, freshness_s, reason}`, newest first.
8
+ - `GET /api/v1/runs/{id}` - one run plus per-iteration detail (current run only); 404 if unknown.
9
+ - `POST /api/v1/runs` - start a run. Body: `{"prd_text": "..."}` or `{"prd_path": "..."}`, optional `provider`, `parallel`. Same behavior as `POST /api/control/start` (single-flight, 409 if busy).
10
+ - `POST /api/v1/runs/{id}/stop` - stop the run. Only the current run can be stopped (409 otherwise, 404 if unknown).
11
+
12
+ Cost and status fields come from measured records only; unmeasured values are null, never 0.
@@ -81,9 +81,9 @@ User constraint: "people use npm, I want to keep it the same way."
81
81
  | **Bash** (today) | `package.json` `bin` field points to shell script | Trivial; current state |
82
82
  | **Bun runtime** | `npm install -g loki-mode` ships TS, requires Bun installed via `npm install -g bun` (peer) OR Bun standalone in postinstall | Medium; peer dependency convention |
83
83
  | **Bun compiled binary** | `bun build --compile` → 60 MB binary per platform; npm postinstall downloads correct binary (esbuild model) | Medium; per-platform binaries |
84
- | **Go binary** | Same model as Bun compiled — npm postinstall downloads platform binary (esbuild, biome, vite-rust, swc all use this) | Medium; mature pattern |
85
- | **Python** | npm postinstall would shell out to `pip install` or bundle Python — fragile, two package managers | High; do not recommend |
86
- | **Node.js** | Native — no postinstall needed | Trivial; but Node is 10x slower than bash on cold start |
84
+ | **Go binary** | Same model as Bun compiled - npm postinstall downloads platform binary (esbuild, biome, vite-rust, swc all use this) | Medium; mature pattern |
85
+ | **Python** | npm postinstall would shell out to `pip install` or bundle Python - fragile, two package managers | High; do not recommend |
86
+ | **Node.js** | Native - no postinstall needed | Trivial; but Node is 10x slower than bash on cold start |
87
87
 
88
88
  All three viable options (Bun runtime, Bun compiled, Go binary) keep the `npm install -g loki-mode` UX. Users see no change.
89
89
 
@@ -104,17 +104,17 @@ All three viable options (Bun runtime, Bun compiled, Go binary) keep the `npm in
104
104
  - Rewriting 33,000+ lines of bash to idiomatic Go is a 3-6 month effort.
105
105
  - Goroutines/channels are different mental model than bash + Python orchestration.
106
106
 
107
- **Distribution via npm:** Same pattern as esbuild — npm postinstall downloads the right platform binary. Mature, ~5 MB compressed per arch.
107
+ **Distribution via npm:** Same pattern as esbuild - npm postinstall downloads the right platform binary. Mature, ~5 MB compressed per arch.
108
108
 
109
109
  ### Option B: Bun runtime + TypeScript
110
110
 
111
111
  **Pro:**
112
112
  - **Anthropic owns Bun.** Strategic alignment with the company that owns the model we depend on.
113
- - Native shell built in (`Bun.$\`echo hello\``) — minimal friction porting bash idioms.
114
- - Bun's `npm install` is 20-40x faster than npm — every CI run faster.
113
+ - Native shell built in (`Bun.$\`echo hello\``) - minimal friction porting bash idioms.
114
+ - Bun's `npm install` is 20-40x faster than npm - every CI run faster.
115
115
  - TypeScript: types catch bugs bash can't.
116
116
  - Anthropic-funded development means Bun improvements specifically target AI agent workloads.
117
- - 98% Node.js compatibility — npm packages work directly.
117
+ - 98% Node.js compatibility - npm packages work directly.
118
118
 
119
119
  **Con:**
120
120
  - **1.7x SLOWER than bash on trivial cold-start** (7.6 ms vs 4.5 ms). The user explicitly said "no speed compromise". This is a genuine compromise, even if 3 ms is humanly invisible.
@@ -127,20 +127,20 @@ All three viable options (Bun runtime, Bun compiled, Go binary) keep the `npm in
127
127
 
128
128
  **Pro:**
129
129
  - Keep tiny scripts in bash (where it wins by 3 ms): `loki version`, `loki status`, anything <100 LOC.
130
- - Migrate the 11k-line orchestrator (`run.sh`) and 22k-line CLI (`autonomy/loki`) to Bun TypeScript — where compiled+typed wins.
131
- - Keep `memory/`, `providers/`, `mcp/` in Python — they're already mature, no reason to rewrite.
130
+ - Migrate the 11k-line orchestrator (`run.sh`) and 22k-line CLI (`autonomy/loki`) to Bun TypeScript - where compiled+typed wins.
131
+ - Keep `memory/`, `providers/`, `mcp/` in Python - they're already mature, no reason to rewrite.
132
132
  - Anthropic alignment via Bun for the parts that matter.
133
133
  - No speed regression for trivial commands; large gains for orchestrator.
134
134
 
135
135
  **Con:**
136
- - Three runtimes in the codebase (bash + Bun + Python) — operational complexity.
136
+ - Three runtimes in the codebase (bash + Bun + Python) - operational complexity.
137
137
  - Cross-runtime debugging harder than monorepo.
138
138
 
139
139
  **Distribution:** Bun shipped via npm postinstall as compiled binary; bash remains as-is; Python unchanged.
140
140
 
141
141
  ## Recommendation
142
142
 
143
- **Option B (Bun runtime + TypeScript) — full migration, not hybrid.**
143
+ **Option B (Bun runtime + TypeScript) - full migration, not hybrid.**
144
144
 
145
145
  Reasons:
146
146
 
@@ -148,7 +148,7 @@ Reasons:
148
148
  2. **Anthropic strategic alignment.** Anthropic owns Bun. Loki uses Claude. Aligning runtime and model owner reduces dependency-versioning friction over time.
149
149
  3. **TypeScript pays the maintainability dividend** that 33k lines of bash will never deliver. Type checking catches whole classes of bugs (the kind we hit in v6.81-v7.2 cycles).
150
150
  4. **Hybrid is now harder to justify.** When bash loses by 8.6x on the actual workload, keeping it for 3 ms theoretical wins on hello-world is bad engineering.
151
- 5. **Go would still be 2-4x faster than Bun** in absolute cold-start, but: zero existing Go in the codebase, no Anthropic alignment, larger rewrite cost, no JS ecosystem reuse. Unless Loki specifically targets the sub-millisecond CLI category (which it doesn't — every command runs in a multi-second/minute autonomous loop), the absolute speed delta doesn't justify the strategic cost.
151
+ 5. **Go would still be 2-4x faster than Bun** in absolute cold-start, but: zero existing Go in the codebase, no Anthropic alignment, larger rewrite cost, no JS ecosystem reuse. Unless Loki specifically targets the sub-millisecond CLI category (which it doesn't - every command runs in a multi-second/minute autonomous loop), the absolute speed delta doesn't justify the strategic cost.
152
152
 
153
153
  **If user explicitly wants the absolute fastest:** Go (Option A) is 2.5x faster than Bun. But for orchestrator-heavy work where most time is spent waiting on Claude API calls, the difference is invisible.
154
154
 
@@ -214,7 +214,7 @@ Reasons:
214
214
  2. Port `cmd_version` to `loki-ts/src/commands/version.ts` (proof of concept)
215
215
  3. Add `bun-test.yml` GitHub workflow alongside existing `test.yml`
216
216
  4. Set acceptance criteria: every Phase 2+ command must benchmark within 2x of bash cold-start AND be type-checked via `bun typecheck`
217
- 5. Ship Phase 1 as v8.0.0-alpha.1 (pre-release, opt-in) — does not affect default users
217
+ 5. Ship Phase 1 as v8.0.0-alpha.1 (pre-release, opt-in) - does not affect default users
218
218
 
219
219
  ---
220
220
 
@@ -25,10 +25,10 @@ model explicitly rather than inherit the session model.
25
25
  - **Inspired by**: Amazon AGI Lab's "How Agentic AI Helps Heal Systems We Can't Replace"
26
26
  - **CLI**: `loki heal <path> [--phase archaeology|stabilize|isolate|modernize|validate]` (`autonomy/loki` `cmd_heal`)
27
27
  - **Principles**: Friction-as-semantics, failure-first learning, universal adapters, incremental healing, institutional knowledge preservation
28
- - **Artifacts**: `.loki/healing/` (friction-map.json, failure-modes.json, institutional-knowledge.md)
28
+ - **Artifacts**: `.loki/healing/` (friction-map.json, failure-modes.json, institutional-knowledge.md). `loki heal` seeds failure-modes.json as `{"modes":[]}` and the prompt asks the agent to fill it; no code appends to it (NOT WIRED, issue #200)
29
29
  - **Review**: `legacy-healing-auditor` specialist added to code review pool (gated)
30
30
  - **Gate**: backward-compatibility / legacy-healing auditor (healing mode; not one of the 8 numbered gates) blocks removal of unclassified friction
31
- - **Hooks**: `hook_pre_healing_modify()` (`autonomy/hooks/migration-hooks.sh:283`), `hook_post_healing_modify()` (`:328`), `hook_healing_phase_gate()` (`:386`)
31
+ - **Hooks**: `hook_pre_healing_modify()` (`autonomy/hooks/migration-hooks.sh:348`), `hook_post_healing_modify()` (`:576`), `hook_healing_phase_gate()`. NOT WIRED (issue #200): the pre/post modify hooks are defined and unit-tested but have no production caller, so the snapshot/revert pairing contract and the failure-modes.json append inside them are not enforced in a real heal run
32
32
  - **Memory**: `FrictionPoint` and `FailureMode` schemas for healing-specific memory entries
33
33
  - **Skill**: `skills/healing.md` | **Reference**: `references/legacy-healing-patterns.md`
34
34
 
@@ -101,3 +101,7 @@ These knobs together implement the RARV-C (closure) loop: findings -> override c
101
101
  ## Worktree substrate (autonomy/lib/worktree_prep.py)
102
102
 
103
103
  `prepare_worktree(source_repo, dest, branch, setup=None, base=None)` creates an isolated git worktree and returns `{path, base_sha, deps, left_out_changes}`. The start point is `origin/HEAD` after a fetch (when a remote exists), else HEAD. Uncommitted edits in the source checkout are never carried or stashed; their count is reported as `left_out_changes`. An fcntl lock at `~/.loki/repos/<slug>.lock` covers fetch and worktree add. Dependencies: a `setup` command run in the worktree, else a copy-on-write copy of ignored top-level `node_modules`, `.venv`, `venv`, `vendor` (refused as "copy unsafe, declare setup" if it holds absolute symlinks or editable finders), else `none`. CLI: `python3 autonomy/lib/worktree_prep.py SRC DEST BRANCH [--setup CMD] [--base REF]` prints the result as JSON. Not yet wired into backlog or the UI.
104
+
105
+ ## Project memory across runs
106
+
107
+ extract_learnings_from_session (autonomy/run.sh) mirrors learnings and decisions into .loki/memory/learnings/project-*.jsonl. get_relevant_learnings adds a bounded newest-first project_memory list (15 entries, LOKI_PROJECT_MEMORY_MAX_CHARS, default 2000) to .loki/state/relevant-learnings.json at run start. LOKI_PROJECT_MEMORY=0 disables both. Test: tests/test-project-memory.sh.
@@ -0,0 +1,13 @@
1
+ # loki merge
2
+
3
+ Serial PR merge queue (requires the `gh` CLI, authenticated).
4
+
5
+ loki merge add 101 102 103 # queue PRs (stored in .loki/merge-queue)
6
+ loki merge run --dry-run # list what would happen, change nothing
7
+ loki merge run # merge one at a time
8
+
9
+ Rules: a PR merges (squash) only when `gh pr checks` exits 0. Pending checks are
10
+ polled (LOKI_MERGE_POLL_S, default 20s; LOKI_MERGE_MAX_POLLS, default 90). After
11
+ each merge the next PR is rebased onto the new base and must pass checks again.
12
+ PRs that are red, time out, or fail to rebase stay in the queue; the command
13
+ exits nonzero. Nothing is force-pushed and no check is bypassed.
@@ -0,0 +1,11 @@
1
+ # Mobile emulator tests
2
+
3
+ `bash autonomy/mobile-verify.sh [project_dir]`
4
+
5
+ Detects React Native/Expo (package.json) or Flutter (pubspec.yaml). Looks for a booted Android emulator (`adb devices`) or iOS simulator (`xcrun simctl list devices booted`).
6
+
7
+ Test command: `LOKI_MOBILE_TEST_CMD`, else `flutter test [integration_test]`, else `npm run test:e2e` / `npm run e2e`.
8
+
9
+ Exit codes: 0 ran and passed (or not a mobile project, stated); 1 ran and failed; 3 NOT VERIFIED (no device or no e2e script). A NOT VERIFIED result must never be reported as a pass.
10
+
11
+ Timeout: `LOKI_MOBILE_TIMEOUT` seconds (default 600).
@@ -0,0 +1,13 @@
1
+ # Sentry intake
2
+
3
+ `loki start` turns a Sentry issue into a task spec (error, stack trace, breadcrumbs, acceptance criteria).
4
+
5
+ Offline, from an exported JSON file (issue export, event, or `{issue, event}`):
6
+
7
+ loki start ./sentry-issue.json
8
+
9
+ From a URL (needs `SENTRY_AUTH_TOKEN`; without it nothing is fetched):
10
+
11
+ SENTRY_AUTH_TOKEN=... loki start https://sentry.io/organizations/acme/issues/4001/
12
+
13
+ The token is sent only to the Sentry host through a curl config on stdin, never on argv, and is never printed. Implementation: `autonomy/issue-providers.sh` (`normalize_sentry_json`).