Status: Accepted -- Phases 1-5 shipped; Phase 6 (bash sunset) gated on 30-day clean soak Date: 2026-04-25 (proposed) / 2026-04-29 (status updated for v7.5.7) Last reviewed: 2026-04-29 against v7.5.7
| Phase | Description | Status | Shipped in |
|---|---|---|---|
| 1 | Scaffold loki-ts/, ts-version POC, CI matrix |
DONE | v7.0.x |
| 2 | Read-only sub-commands ported (provider show, status, stats, memory list) | DONE | v7.1.x |
| 3 | Build/release tooling on Bun (bun publish, bun build, bun test) |
DONE | v7.2.0 |
| 4 | build_prompt + run_autonomous outer loop ported; LOKI_LEGACY_BASH=1 fallback live |
DONE | v7.3.0 |
| 5 | council_should_stop, run_code_review ported; side-by-side parity verified |
DONE | v7.3.0 -- v7.4.x |
| 6 | Sunset bash: remove LOKI_LEGACY_BASH, delete autonomy/run.sh + autonomy/loki |
GATED | Pending 30-day clean soak from v7.3.0 GA |
Phase 6 entry criteria (per founder call 2026-04-25, release_strategy memory):
- 30 consecutive days with zero parity-diff regressions on the Bun route
- All 14 CLI tests passing on both routes (
tests/test-cli-commands.sh) - Bun-parity matrix green on every workflow (added after v7.4.18 doctor-text drift bug)
- No
LOKI_LEGACY_BASH=1fallback invocations observed in telemetry over the soak window - Local CI gate (
scripts/local-ci.sh) green on every push
When all criteria are met, Phase 6 PR (#159 per release_strategy) opens for council review.
Decision driver: autonomy/run.sh is 11,327 lines of bash and autonomy/loki is 22,304 lines. Both are fragile, hard to refactor, untyped, and the upstream RARV-C audit (v6.81 plan) flagged them as the single biggest architectural debt.
YES, verified. Anthropic acquired Bun (Oven, Inc.) in December 2025. Bun remains MIT-licensed and open-source. Anthropic is positioning Bun as the runtime infrastructure for Claude Code, the Claude Agent SDK, and future AI coding products.
Sources:
- Bun Blog: Bun is joining Anthropic
- Anthropic: Anthropic acquires Bun as Claude Code reaches $1B milestone
Two-layer answer with REAL benchmarks.
| Runtime | Cold start mean | vs bash |
|---|---|---|
| Go binary (compiled) | 1.8 ms | 2.5x faster |
| bash hello-world | 4.5 ms | baseline |
Bun binary (bun build --compile) |
6.9 ms | 1.5x slower |
Bun script (bun foo.ts) |
7.6 ms | 1.7x slower |
| Python3 script | 20.3 ms | 4.5x slower |
| Node.js script | 45.2 ms | 10x slower |
For a trivial 1-line script, bash beats Bun by ~3 ms.
| Runtime | loki version mean |
vs bash |
|---|---|---|
| bash autonomy/loki version | 106.71 ms (min 96.54, max 125.35) | baseline |
| bun loki-ts/src/cli.ts version | 12.36 ms (min 11.63, max 13.52) | 8.63x FASTER |
This is the finding that flips the analysis. When the bash script is 22,304 lines (the actual autonomy/loki), bash re-parses the entire AST every invocation. That parse cost dwarfs Bun's runtime startup cost by ~10x. Bun is 8.6x faster than actual Loki bash.
The user's premise ("Bun is faster than bash, no speed compromise") is correct for actual Loki workloads, even though it's false for hello-world.
Why the gap: bash has no bytecode cache. Every loki version invocation re-parses 22k lines of shell. Bun parses TypeScript once at install (or even at compile time with --compile), then executes machine code. The asymmetry grows with script size:
| Script size | Bash startup | Bun startup |
|---|---|---|
| 1 line | 4.5 ms | 7.6 ms (1.7x slower) |
22,304 lines (real autonomy/loki) |
106.71 ms | 12.36 ms (8.63x FASTER) |
So: for hello-world bash wins; for our actual codebase Bun wins decisively, by an order of magnitude.
User constraint: "people use npm, I want to keep it the same way."
| Runtime | npm distribution path | Complexity |
|---|---|---|
| Bash (today) | package.json bin field points to shell script |
Trivial; current state |
| 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 |
| Bun compiled binary | bun build --compile → 60 MB binary per platform; npm postinstall downloads correct binary (esbuild model) |
Medium; per-platform binaries |
| Go binary | Same model as Bun compiled — npm postinstall downloads platform binary (esbuild, biome, vite-rust, swc all use this) | Medium; mature pattern |
| Python | npm postinstall would shell out to pip install or bundle Python — fragile, two package managers |
High; do not recommend |
| Node.js | Native — no postinstall needed | Trivial; but Node is 10x slower than bash on cold start |
All three viable options (Bun runtime, Bun compiled, Go binary) keep the npm install -g loki-mode UX. Users see no change.
Pro:
- Only language that strictly beats bash. 2.5x faster cold-start (1.8 ms vs 4.5 ms). User's "no speed compromise" requirement is met without caveats.
- Single static binary, ~2.4 MB (vs 60 MB Bun binary).
- Mature CLI ecosystem (Docker, kubectl, Terraform, Helm all use Go).
- Strict typing prevents whole class of bash quoting bugs.
- Cross-compile to all platforms from any platform.
Con:
- Loki team has zero Go in the codebase today.
- Anthropic does NOT own Go; less strategic alignment.
- Rewriting 33,000+ lines of bash to idiomatic Go is a 3-6 month effort.
- Goroutines/channels are different mental model than bash + Python orchestration.
Distribution via npm: Same pattern as esbuild — npm postinstall downloads the right platform binary. Mature, ~5 MB compressed per arch.
Pro:
- Anthropic owns Bun. Strategic alignment with the company that owns the model we depend on.
- Native shell built in (
Bun.$\echo hello``) — minimal friction porting bash idioms. - Bun's
npm installis 20-40x faster than npm — every CI run faster. - TypeScript: types catch bugs bash can't.
- Anthropic-funded development means Bun improvements specifically target AI agent workloads.
- 98% Node.js compatibility — npm packages work directly.
Con:
- 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.
- Bun runtime must be installed separately OR shipped via postinstall (60 MB if compiled).
- Less mature than Node (Bun 1.3 in 2026; some npm packages still hit edge cases).
Distribution via npm: Either (a) declare Bun as a peer dep and prompt user npm install -g bun; (b) ship --compile binary via postinstall.
Pro:
- Keep tiny scripts in bash (where it wins by 3 ms):
loki version,loki status, anything <100 LOC. - Migrate the 11k-line orchestrator (
run.sh) and 22k-line CLI (autonomy/loki) to Bun TypeScript — where compiled+typed wins. - Keep
memory/,providers/,mcp/in Python — they're already mature, no reason to rewrite. - Anthropic alignment via Bun for the parts that matter.
- No speed regression for trivial commands; large gains for orchestrator.
Con:
- Three runtimes in the codebase (bash + Bun + Python) — operational complexity.
- Cross-runtime debugging harder than monorepo.
Distribution: Bun shipped via npm postinstall as compiled binary; bash remains as-is; Python unchanged.
Option B (Bun runtime + TypeScript) — full migration, not hybrid.
Reasons:
- The Layer 2 benchmark inverts the speed argument. Bun is 8.6x FASTER than actual Loki bash because
autonomy/lokiis 22,304 lines that re-parse every invocation. The user's "no speed compromise" rule is met decisively, with margin. - Anthropic strategic alignment. Anthropic owns Bun. Loki uses Claude. Aligning runtime and model owner reduces dependency-versioning friction over time.
- 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).
- 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.
- 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.
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.
- Create
loki-ts/directory parallel toautonomy/ package.jsonwith Bun as engine, TypeScript config- Port ONE simple command:
loki ts-version(proves the toolchain) - Add Bun to CI matrix (alongside existing Node/Python)
- No user-visible change. All existing commands route to bash.
- Migrate read-only commands:
loki provider show,loki status,loki stats,loki memory list - Each migrated command goes through
loki-ts/with bash as fallback flag - Performance benchmark each: must be ≤ 2x bash cold start
- Replace npm publish with
bun publishin CI - Replace dashboard-ui esbuild with
bun build(already 4-5x faster) - Replace pytest where possible with
bun testfor non-Python tests - Measure: full CI wall time, npm install time
- Port
build_prompt(the 360-line bash function) to TypeScript - Port
run_autonomousouter loop - Keep all Python subprocess invocations untouched (they're already fine)
- Side-by-side validation: same prompt output character-by-character
- Fallback flag:
LOKI_LEGACY_BASH=truereverts
- Port
council_should_stopandrun_code_reviewto TypeScript - Same validation discipline
- Remove
LOKI_LEGACY_BASHflag - Delete
autonomy/run.shandautonomy/loki(keep in git history) - Bash -> Bun migration complete
- Status (2026-04-29): awaiting 30-day clean soak. Soak clock started with v7.3.0 GA. See "Phase status" table at top of this ADR for entry criteria.
| Today | Tomorrow | Win |
|---|---|---|
npm publish (45-60 sec) |
bun publish |
~5x faster CI publish |
npm install -g loki-mode for users |
Same UX, bun install under the hood when available |
20-40x faster install (verified) |
Tests via npm test (Node 20-25 sec) |
bun test for non-Python |
~10x faster test runs |
| Dashboard build with esbuild (122 ms) | bun build |
2-4x faster |
| Per-iteration cold start in run.sh: bash 4.5ms × N | Compiled Bun start once, run 100s | Net negative if iteration count low; net positive for sessions >5 iterations |
Python mcp/server.py |
Stays Python (already good) | No change |
- Migration drift: TS port may behave subtly differently from bash. Mitigation: side-by-side test harness comparing outputs.
- Bun beta-feature churn: Even though Bun 1.3 is stable, Anthropic may push it in directions that break us. Mitigation: pin Bun version in
package.jsonengines. - 60 MB binary if we ship
--compile. Half a Loki Docker image. Mitigation: ship runtime peer dep instead of compiled binary in v8. - Three-runtime codebase is real cognitive overhead for new contributors. Mitigation: clear
CONTRIBUTING.mdtable of "what runtime owns what." - Bun's npm shipping pattern is less proven than Go's. Mitigation: keep npm registry as primary distribution; add Homebrew (already exists) as a Bun-bundled alternative.
- Scaffold
loki-ts/withpackage.json,tsconfig.json,src/cli.ts(this PR) - Port
cmd_versiontoloki-ts/src/commands/version.ts(proof of concept) - Add
bun-test.ymlGitHub workflow alongside existingtest.yml - Set acceptance criteria: every Phase 2+ command must benchmark within 2x of bash cold-start AND be type-checked via
bun typecheck - Ship Phase 1 as v8.0.0-alpha.1 (pre-release, opt-in) — does not affect default users
Hyperfine 100 runs, 5 warmup, hello-world equivalent:
bash /tmp/loki-bench-bash.sh 4.5 ± 0.4 ms baseline
bun-compiled-binary 6.9 ± 0.4 ms 1.53x slower
bun /tmp/loki-bench-bun.ts 7.6 ± 0.4 ms 1.69x slower
node /tmp/loki-bench-node.js 45.2 ± 1.0 ms 10.04x slower
python3 /tmp/loki-bench-py.py 20.3 ± 0.5 ms 4.51x slower
go-compiled-binary 1.8 ± 0.3 ms 2.5x FASTER
Local versions:
- bash 5.x (macOS shipped /bin/bash 3.2 + brew bash)
- Bun 1.3.13
- Node v25.9.0
- Python 3.x
- Go 1.26.1
These are real numbers from this exact Mac, not from a vendor blog. Run hyperfine yourself to reproduce.
Layer 2 (real Loki workload, 50 runs via loki-ts/scripts/bench.ts):
bash autonomy/loki version 106.71 ms (min 96.54, max 125.35)
bun loki-ts/src/cli.ts version 12.36 ms (min 11.63, max 13.52)
bun is 8.63x FASTER than bash on the actual Loki entry point
The 22,304-line autonomy/loki re-parses every invocation. Bun parses TS once, executes machine code thereafter. The asymmetry is the core argument for migration.