loki-mode 11.3.9 → 11.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -18
- package/SKILL.md +3 -3
- package/VERSION +1 -1
- package/agents/custom_agents.py +280 -0
- package/autonomy/council-v2.sh +22 -1
- package/autonomy/edit.sh +242 -0
- package/autonomy/lib/chat.sh +315 -0
- package/autonomy/lib/engine10-push.sh +19 -1
- package/autonomy/lib/help-core.sh +164 -0
- package/autonomy/lib/json-output.sh +38 -0
- package/autonomy/lib/proof-generator.py +23 -5
- package/autonomy/lib/proof-verify.py +607 -5
- package/autonomy/lib/run-summary.sh +112 -0
- package/autonomy/lib/setup-requirements.json +35 -0
- package/autonomy/loki +337 -46
- package/autonomy/provider-offer.sh +95 -47
- package/autonomy/route.sh +302 -0
- package/autonomy/run.sh +48 -14
- package/autonomy/setup-wizard.sh +170 -0
- package/autonomy/verify.sh +62 -3
- package/bin/loki +73 -18
- package/completions/_loki +58 -1
- package/completions/loki.bash +57 -5
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-CORE-VERBS.md +112 -0
- package/docs/CLI-REFERENCE.md +9 -1
- package/docs/COMPARE-OPENCODE.md +94 -0
- package/docs/COMPONENTS.md +1 -0
- package/docs/EVALUATING.md +27 -0
- package/docs/HARNESS-INTELLIGENCE-PLAN.md +20 -0
- package/docs/INSTALLATION.md +56 -12
- package/docs/KNOWN-ISSUES.md +8 -9
- package/docs/PROOF-PASSPORT.md +114 -0
- package/docs/QUICKSTART.md +108 -0
- package/docs/alternative-installations.md +103 -0
- package/docs/cost-controls.md +139 -0
- package/docs/environment-variables.md +45 -2
- package/docs/exit-codes.md +129 -12
- package/docs/spec-first-intent.md +29 -0
- package/docs/v10/CLI-MODERN.md +11 -5
- package/docs/v10/ENGINE.md +32 -0
- package/docs/v10/GUIDE.md +270 -44
- package/docs/v10/OPENCODE-PARITY-PLAN.md +84 -0
- package/loki-ts/data/model-pricing.json +1 -0
- package/loki-ts/dist/loki.js +1065 -978
- package/mcp/__init__.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +1829 -715
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/plugins/loki-mode/README.md +41 -1
- package/plugins/loki-mode/commands/handoff.md +12 -0
- package/plugins/loki-mode/commands/loki-verify.md +9 -2
- package/plugins/loki-mode/commands/start.md +20 -0
- package/plugins/loki-mode/hooks/hooks.json +11 -0
- package/plugins/loki-mode/scripts/loki-stop-verify.sh +84 -0
- package/providers/claude.sh +16 -2
- package/providers/model_route_exec.sh +22 -0
- package/providers/model_routes.sh +188 -0
- package/skills/providers.md +13 -0
- package/templates/agents/planner.md +10 -0
- package/templates/agents/reviewer.md +10 -0
- package/templates/agents/tester.md +10 -0
- package/web-app/dist/assets/{AdminPage-QK-i_x-O.js → AdminPage-Cbu3pXL8.js} +1 -1
- package/web-app/dist/assets/{Avatar-DblkLNjB.js → Avatar-DGqGGcGx.js} +1 -1
- package/web-app/dist/assets/{Badge-DIV2ny5H.js → Badge-Bhlipt6v.js} +1 -1
- package/web-app/dist/assets/{Button--rePJOlQ.js → Button-CpN2sO61.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-BZlKxpGy.js → CockpitPage-BqeDJwdL.js} +1 -1
- package/web-app/dist/assets/{ComparePage-3_INSVux.js → ComparePage-DUieA2ba.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-DHG63CNr.js → ErrorBoundary-DTWsYrOm.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-DFsBnLlO.js → EvidenceReceiptPanel-BU_B9X19.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-phPGah98.js → GitHubIssuesPanel-DEZoLOsP.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-T7KQqJmx.js → GitHubPRsPanel-BEsnrq7Y.js} +1 -1
- package/web-app/dist/assets/{HomePage-DFjGUF5I.js → HomePage-BoUVuq7h.js} +2 -2
- package/web-app/dist/assets/{LoginPage-CorUid_5.js → LoginPage-CmOED7vb.js} +1 -1
- package/web-app/dist/assets/{MagicPage-DofbSxKD.js → MagicPage-DATZitrZ.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-qzrhhfLC.js → MetricsPage-DGL1v0I-.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-BAZR0mMb.js → NotFoundPage-C2WgOjZd.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-BOSUzG9J.js → ProjectPage-BMi1tepj.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-Ba0YLtzD.js → ProjectsPage-vc3y5YPh.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-Cr10Ue2K.js → SettingsPage-kbq0Ftvi.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-Czn655fe.js → ShowcasePage-Bn6Q8Kbg.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-Dwjnw6Ob.js → SystemSettingsPage-Basmhs_b.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-D8nc69Be.js → TeamsPage-BTqOc4TR.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-DHsaCDGv.js → TemplatesPage-2P9002VL.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-DBejni2a.js → TerminalOutput-CAoSPBrg.js} +1 -1
- package/web-app/dist/assets/{activity-B2VsBl1C.js → activity-BcWVWCqU.js} +1 -1
- package/web-app/dist/assets/{bell-CT77Fq2H.js → bell-CYRqqgZ6.js} +1 -1
- package/web-app/dist/assets/{bot-DfaWgF4H.js → bot-CU7gdn3g.js} +1 -1
- package/web-app/dist/assets/{check-D1yp7Ndv.js → check-DLlCpz9V.js} +1 -1
- package/web-app/dist/assets/{chevron-left-B6Pa8IOX.js → chevron-left-CE9Cb30C.js} +1 -1
- package/web-app/dist/assets/{circle-alert-D5jrL_Y7.js → circle-alert-uou4bjua.js} +1 -1
- package/web-app/dist/assets/{clock-DIsY_fa_.js → clock-C_dSJcDX.js} +1 -1
- package/web-app/dist/assets/{cloud-eGwLh1As.js → cloud-DZ22ITF6.js} +1 -1
- package/web-app/dist/assets/{code-xml-CGDIcZ3m.js → code-xml-BrJS0hhS.js} +1 -1
- package/web-app/dist/assets/{database-CWpdaykI.js → database-D2HOmxtl.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-DZEuTCs6.js → dollar-sign-CQ1vK_6q.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-BHBW6m9v.js → file-code-corner-w2vpGm5d.js} +1 -1
- package/web-app/dist/assets/{file-plus-D4h1jZSR.js → file-plus-DlF6wjkD.js} +1 -1
- package/web-app/dist/assets/{globe-CXdqKgwd.js → globe-Dy3lBJg1.js} +1 -1
- package/web-app/dist/assets/{hammer-B3YuuYI_.js → hammer-C3xIiRXN.js} +1 -1
- package/web-app/dist/assets/{index-BLEnboSv.js → index-4t-_IW2y.js} +3 -3
- package/web-app/dist/assets/{layers-Dvp5nFtw.js → layers-Y8Fs8qXI.js} +1 -1
- package/web-app/dist/assets/{loader-circle-DodDmIZ3.js → loader-circle-CxgN1v4m.js} +1 -1
- package/web-app/dist/assets/{lock-EiuaH1Ep.js → lock-DFFNbXDs.js} +1 -1
- package/web-app/dist/assets/{package-Cx4m2hFg.js → package-5e6qCTUg.js} +1 -1
- package/web-app/dist/assets/{plus-D-Sd5rpH.js → plus-C0Go_ytj.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-C0w1cdmF.js → refresh-cw-D4i-NW3o.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-C_qk6MTT.js → rotate-ccw-YlKkiUW6.js} +1 -1
- package/web-app/dist/assets/{scroll-text-DSxiFtkc.js → scroll-text-4qXOHTap.js} +1 -1
- package/web-app/dist/assets/{server-NTJt7I8M.js → server-BB6zXNp9.js} +1 -1
- package/web-app/dist/assets/{shield-alert-HBxMQOvH.js → shield-alert-D4tzjB1H.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-DEgsHzSD.js → thumbs-up-DZiRwdFj.js} +1 -1
- package/web-app/dist/assets/{trash-2-px46FnTD.js → trash-2-Dv_LkRIK.js} +1 -1
- package/web-app/dist/assets/{trending-down-CBosVGKa.js → trending-down-BJYp9PQe.js} +1 -1
- package/web-app/dist/assets/{trending-up-Dbd7zrQj.js → trending-up-BTcXLklK.js} +1 -1
- package/web-app/dist/assets/{upload-nhdFKAs1.js → upload-fcHqwOxr.js} +1 -1
- package/web-app/dist/assets/{usePolling-BgaGdinh.js → usePolling-BeJYw_4L.js} +1 -1
- package/web-app/dist/assets/{user-CzIihUy9.js → user-BcDwUCsO.js} +1 -1
- package/web-app/dist/index.html +1 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Core verbs (CLI reference)
|
|
2
|
+
|
|
3
|
+
The commands most people use, with their main flags. The complete generated
|
|
4
|
+
command table is `docs/CLI-REFERENCE.md` (do not edit that file by hand).
|
|
5
|
+
`loki help` prints the grouped summary; `loki help all` prints every command;
|
|
6
|
+
`loki help <topic>` prints a topic (start, models, providers, agents, verify,
|
|
7
|
+
exit-codes, config); `loki help <command>` runs `<command> --help`. Scripts that
|
|
8
|
+
parse the old default `loki help` output must switch to `loki help all`.
|
|
9
|
+
|
|
10
|
+
`loki start` is the primary path. Everything else is a shortcut, a check, or an
|
|
11
|
+
alternative surface for the same engine. Claude Code is the default Tier-1
|
|
12
|
+
provider; other providers and model routes are additions selected with
|
|
13
|
+
`--provider` or `LOKI_MODEL_ROUTE`.
|
|
14
|
+
|
|
15
|
+
## Start
|
|
16
|
+
|
|
17
|
+
| Command | What it does |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `loki start [SPEC]` | The primary path. Build from a PRD file, an issue (`owner/repo#N`, issue URL, `PROJ-1`), a quoted task or a one-word brief. Alias: `run`. Shorthand: `loki "<task>"`, `loki owner/repo#N` |
|
|
20
|
+
| `loki edit "<change>"` | One targeted change to the current repo in one pass. No PRD, plan, council, PR or branch switch |
|
|
21
|
+
| `loki quick "<task>"` | One small task with a verify loop, no PR |
|
|
22
|
+
| `loki chat` | Interactive alternative to `loki start` (Plan and Build modes, slash commands) |
|
|
23
|
+
|
|
24
|
+
`start` flags: `--no-pr`, `--deep`, `--provider NAME`, `--max-cost USD`
|
|
25
|
+
(aliases `--budget`, `--budget-limit`), `--session-model TIER`, `-v` (verbose),
|
|
26
|
+
`--quiet`, `--json`, `--engine legacy|engine10`, `--explain-route`. Flags that
|
|
27
|
+
only the previous loop honors (`--simple`, `--complex`, `--parallel`,
|
|
28
|
+
`--isolation`, `--sandbox`, `--max-iterations`, `--compliance`, ...) send that
|
|
29
|
+
one call to the previous loop with a one-line notice.
|
|
30
|
+
|
|
31
|
+
Spend cap: `--max-cost`, else `budgets.per_run` in `loki.yaml`, else $100 when
|
|
32
|
+
`ANTHROPIC_API_KEY` or `OPENAI_API_KEY` is set, else no dollar cap
|
|
33
|
+
(subscription). Model routes: `LOKI_MODEL_ROUTE=ollama/qwen3-coder loki start prd.md`.
|
|
34
|
+
|
|
35
|
+
### loki edit
|
|
36
|
+
|
|
37
|
+
`loki edit [paths...] "<change>"` with `--verify` (fast verifier), `--receipt`
|
|
38
|
+
(unsigned receipt in `.loki/edit-receipts/`), `--commit` (only touched files, by
|
|
39
|
+
name; skipped when verify failed) and `--dry-run` (plan only). `LOKI_EDIT_MODEL`
|
|
40
|
+
overrides the model. Claude provider only for now.
|
|
41
|
+
|
|
42
|
+
### loki chat
|
|
43
|
+
|
|
44
|
+
Needs a TTY (otherwise exit 2; use `loki quick`). Starts in Plan mode
|
|
45
|
+
(read-only); `/plan` and `/build` switch. Slash commands: `/plan`, `/build`,
|
|
46
|
+
`/run <prd|brief>` (starts a normal `loki start` run with the chat's model and
|
|
47
|
+
provider), `/quick`, `/edit`, `/verify`, `/receipt`, `/cost`, `/diff`, `/undo`,
|
|
48
|
+
`/model <id>`, `/provider <name>`, `/help`, `/exit`. `loki chat --attach` joins a
|
|
49
|
+
running or the last `loki start` session (`/status`, `/steer`, `/diff`,
|
|
50
|
+
`/verify`, `/receipt`, `/stop`). `loki chat --tui` launches the Claude Code TUI
|
|
51
|
+
with Loki context. Bare `loki` does not open chat.
|
|
52
|
+
|
|
53
|
+
## Check
|
|
54
|
+
|
|
55
|
+
| Command | What it does |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| `loki status [--json]` | Current run status |
|
|
58
|
+
| `loki verify [--fast] [--json] [--pubkey FILE]` | Deterministic verification with CI-gate exit codes |
|
|
59
|
+
| `loki receipt` (alias of `proof`) | Inspect the proof-of-run receipt |
|
|
60
|
+
| `loki diff` / `loki undo <run> [--plan]` | Show what a run changed; plan or apply an undo |
|
|
61
|
+
| `loki route [start\|quick] <args> [--json]` | Print the engine, provider, model, input type and reason without running |
|
|
62
|
+
|
|
63
|
+
Every run ends with one unified summary on both engines: `Result:`, `Files:`,
|
|
64
|
+
`Cost:` (marked `(estimated)` or `not measured`), `Elapsed:`, `Receipt:` and a
|
|
65
|
+
`next:` line. `--quiet` prints only that block; `--json` adds a `summary`
|
|
66
|
+
object; `NO_COLOR=1` disables color.
|
|
67
|
+
|
|
68
|
+
## Configure
|
|
69
|
+
|
|
70
|
+
| Command | What it does |
|
|
71
|
+
| --- | --- |
|
|
72
|
+
| `loki setup [--yes] [--check]` | First-run wizard: tools, Claude login, provider, model route, spend cap. Flags: `--provider`, `--model`, `--budget USD`, `--global` |
|
|
73
|
+
| `loki doctor [--fix] [--json]` | Check prerequisites, providers and login. `--fix` creates state dirs and a default config and prints exact commands for the rest; never runs sudo |
|
|
74
|
+
| `loki config list\|get\|set\|path\|show\|validate` | Settings; `config list --json` for machines |
|
|
75
|
+
| `loki models [--local] [--json]` | Model routes (openrouter, ollama, lmstudio, llamacpp, vllm, custom); `--local` probes local runtimes and prints ready-to-paste values |
|
|
76
|
+
| `loki agents list\|new\|show\|export --claude` | Custom child agents in `.loki/agents/*.md` (project) or `~/.config/loki/agents/` (user). `loki agent` (singular) is the unchanged built-in agent-type command |
|
|
77
|
+
| `loki provider list\|set NAME` | Providers and install status |
|
|
78
|
+
|
|
79
|
+
## --json
|
|
80
|
+
|
|
81
|
+
`status`, `doctor`, `verify`, `config list` and `models` accept `--json`.
|
|
82
|
+
`status`, `doctor` and `models` emit native JSON. `verify` and `config list`
|
|
83
|
+
emit one object from the shared helper `autonomy/lib/json-output.sh`:
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{"command": "verify", "exit_code": 0, "ok": true, "output": "..."}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The process exit code equals `exit_code`.
|
|
90
|
+
|
|
91
|
+
## Exit codes
|
|
92
|
+
|
|
93
|
+
| Code | Meaning |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| 0 | Success |
|
|
96
|
+
| 1 | Failure |
|
|
97
|
+
| 2 | Usage error for an unknown command, or setup error |
|
|
98
|
+
| 3 | Missing component, or verifier error |
|
|
99
|
+
| 64 | Usage error for `verify`, `quick` and `start` (unknown option, missing task) |
|
|
100
|
+
|
|
101
|
+
Severity rises with the code. `loki verify` exits 0 VERIFIED, 1 CONCERNS, 2
|
|
102
|
+
BLOCKED or not a git directory, 3 verifier error or empty diff, 64 usage error.
|
|
103
|
+
Gate CI with `loki verify || fail` and treat any code of 2 or higher as worse
|
|
104
|
+
than CONCERNS. From 11.4.0 this is a breaking change for scripts that tested
|
|
105
|
+
`rc == 1` on an empty diff or a non-git directory. Per-command detail:
|
|
106
|
+
`docs/exit-codes.md`.
|
|
107
|
+
|
|
108
|
+
## Unknown commands
|
|
109
|
+
|
|
110
|
+
An unknown command prints a "Did you mean" suggestion (edit distance), points
|
|
111
|
+
to `loki help` and `loki help all`, and exits 2. A bare one-word `loki <word>`
|
|
112
|
+
is the command namespace; use `loki start <word>` for a one-word brief.
|
package/docs/CLI-REFERENCE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CLI reference
|
|
2
2
|
|
|
3
|
-
Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.
|
|
3
|
+
Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.5.1. Do not edit by hand.
|
|
4
4
|
Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for the full inventory.
|
|
5
5
|
|
|
6
6
|
| Command | Description |
|
|
@@ -12,6 +12,8 @@ Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for th
|
|
|
12
12
|
| `loki provider show` | Show current provider |
|
|
13
13
|
| `loki provider list` | List providers and install status |
|
|
14
14
|
| `loki provider set` | Switch the active provider |
|
|
15
|
+
| `loki provider info` | Provider details; --json prints the capability contract |
|
|
16
|
+
| `loki provider matrix` | Capability matrix per provider and engine |
|
|
15
17
|
| `loki memory` | Cross-project learnings |
|
|
16
18
|
| `loki memory list` | All learnings |
|
|
17
19
|
| `loki memory index` | Show or rebuild the memory index |
|
|
@@ -74,6 +76,11 @@ Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for th
|
|
|
74
76
|
| `loki engine10 dashboard` | v10 dashboard |
|
|
75
77
|
| `loki engine10 modernize` | v10 modernize |
|
|
76
78
|
| `loki help` | Show help |
|
|
79
|
+
| `loki chat` | Interactive chat with the active provider |
|
|
80
|
+
| `loki edit` | Make one small scoped edit |
|
|
81
|
+
| `loki diff` | Show what the last run changed |
|
|
82
|
+
| `loki models` | Show per-provider model routes |
|
|
83
|
+
| `loki setup` | Guided first-run setup wizard |
|
|
77
84
|
| `loki quick` | One small task |
|
|
78
85
|
| `loki quickstart` | Guided first build |
|
|
79
86
|
| `loki init` | Scaffold from a template |
|
|
@@ -90,6 +97,7 @@ Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for th
|
|
|
90
97
|
| `loki dashboard open` | Open in browser |
|
|
91
98
|
| `loki config` | Manage configuration |
|
|
92
99
|
| `loki config show` | Show config |
|
|
100
|
+
| `loki config list` | List config (alias of show) |
|
|
93
101
|
| `loki config init` | Create config |
|
|
94
102
|
| `loki config edit` | Edit config |
|
|
95
103
|
| `loki config path` | Print config path |
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Loki Mode and opencode: an honest comparison
|
|
2
|
+
|
|
3
|
+
opencode is a general-purpose interactive coding agent. Loki is an autonomous
|
|
4
|
+
delivery system that works from a task to a verified, receipted result.
|
|
5
|
+
They overlap in the terminal and differ in intent, so this page scores them
|
|
6
|
+
category by category and says where opencode is ahead. It describes opencode
|
|
7
|
+
from its public behavior as of this writing; check its docs for current detail.
|
|
8
|
+
Loki can also drive opencode as a provider (`loki start --provider opencode`).
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
| Category | Loki Mode (11.4.0) | opencode | Edge |
|
|
13
|
+
|---|---|---|---|
|
|
14
|
+
| Everyday UX | `loki start` with one unified summary; `loki chat` for interactive use | Polished TUI as the main surface | opencode for interactive feel; Loki for hands-off runs |
|
|
15
|
+
| Install and onboarding | npm install, `loki setup`, `loki doctor --fix`; needs Node, Python, git, jq, curl and a model | Single binary or npm, provider login flow | opencode lighter; Loki now guided |
|
|
16
|
+
| Learning curve | Few core verbs (`loki help`), one route for every input, `loki route` explains it | Learn one TUI | Roughly even |
|
|
17
|
+
| Interactive coding | `loki chat`: Plan/Build modes, slash commands, `--attach` | Full TUI with sessions and rich editing flow | opencode |
|
|
18
|
+
| Small changes | `loki edit` (one pass, diff, opt-in verify and receipt) | Prompt in the TUI or `opencode run` | Even |
|
|
19
|
+
| Provider flexibility | Claude default; codex, cline, aider, opencode; OpenRouter and local routes | Very wide provider catalog, first-class | opencode |
|
|
20
|
+
| Local models | `loki models --local`, `LOKI_MODEL_ROUTE=ollama/...`, lmstudio, llamacpp, vllm, custom URL | Local providers via config | Even |
|
|
21
|
+
| Multi-agent | Role agents, council review, custom agents in `.loki/agents/*.md`, export to Claude Code subagents | Configurable agents and subagents | Even; Loki adds council |
|
|
22
|
+
| Docs consistency | One routing story, one cap rule, generated CLI table | Single product surface | Even |
|
|
23
|
+
| Predictability | Order-independent routing, documented exit-code contract, spend cap | Interactive, user-driven | Loki for unattended use |
|
|
24
|
+
|
|
25
|
+
## Per category
|
|
26
|
+
|
|
27
|
+
**Everyday UX.** In opencode you work inside one TUI and watch each step. In
|
|
28
|
+
Loki you hand over a task with `loki start` and read one summary at the end:
|
|
29
|
+
Result, Files, Cost, Elapsed, Receipt and a `next:` command. If you want to
|
|
30
|
+
watch and steer, `loki chat --attach` joins the run. opencode's interactive
|
|
31
|
+
experience is more mature.
|
|
32
|
+
|
|
33
|
+
**Install and onboarding.** opencode installs as one tool and logs in to a
|
|
34
|
+
provider. Loki needs Node.js 18+, Python 3.8+, git, jq, curl and a model:
|
|
35
|
+
Claude Code is the default and needed for the default path; other CLIs are
|
|
36
|
+
optional. `loki setup` walks through it and `loki doctor --fix` repairs state
|
|
37
|
+
safely, printing exact commands for the rest. More prerequisites than opencode.
|
|
38
|
+
|
|
39
|
+
**Learning curve.** `loki help` shows grouped core verbs (Start, Check,
|
|
40
|
+
Configure); `loki help all` and `loki help <topic>` go deeper. Flag order and
|
|
41
|
+
input form never change the engine, and `loki route` or `--explain-route`
|
|
42
|
+
prints the engine, provider, model and reason. Unknown commands suggest the
|
|
43
|
+
nearest match and exit 2.
|
|
44
|
+
|
|
45
|
+
**Interactive coding.** `loki chat` has Plan mode (read-only for Claude) and
|
|
46
|
+
Build mode, slash commands (`/run`, `/quick`, `/edit`, `/verify`, `/receipt`,
|
|
47
|
+
`/diff`, `/undo`, `/model`, `/provider`) and `--tui` for the Claude Code TUI.
|
|
48
|
+
It is newer and smaller than opencode's TUI. Its advantage is the handoff: `/run`
|
|
49
|
+
starts a real `loki start` run and `--attach` joins one in progress.
|
|
50
|
+
|
|
51
|
+
**Small changes.** `loki edit "<change>"` is one pass with no plan, council or
|
|
52
|
+
PR, then diff stat, diff, cost and time. `--verify`, `--receipt`, `--commit`
|
|
53
|
+
and `--dry-run` are opt-in. Claude provider only for now.
|
|
54
|
+
|
|
55
|
+
**Provider flexibility.** opencode has the broader provider catalog. Loki's
|
|
56
|
+
Tier-1 provider is Claude Code; codex, cline, aider and opencode are optional.
|
|
57
|
+
On those, the Loki 10 engine now measures cost (parsed or estimated, flagged
|
|
58
|
+
`estimated`) so `--max-cost` applies, and enforces the wall-clock limit,
|
|
59
|
+
`BUDGET_LIMIT` kill and a post-iteration guard scan. Kill blocking is still
|
|
60
|
+
Claude-only and receipts say so (`kill blocking not enforced`).
|
|
61
|
+
|
|
62
|
+
**Local models.** `loki models --local` probes Ollama, LM Studio, llama.cpp and
|
|
63
|
+
vLLM and prints ready-to-paste values. `LOKI_MODEL_ROUTE=<kind>/<id>` runs a
|
|
64
|
+
local or OpenRouter model through the Claude harness, so Loki's controls still
|
|
65
|
+
apply. Small local models can fail tool use; that limit is the model's.
|
|
66
|
+
|
|
67
|
+
**Multi-agent.** Loki has built-in roles and a council. You can add your own
|
|
68
|
+
as markdown with frontmatter (model, provider, tools, deny, permission) in
|
|
69
|
+
`.loki/agents/`, manage them with `loki agents list|new|show|export --claude`,
|
|
70
|
+
and council reviewers use a matching agent automatically.
|
|
71
|
+
|
|
72
|
+
**Docs consistency.** The prerequisites, the spend cap ($100 with an API key,
|
|
73
|
+
none on a subscription), routing and the provider table are stated once and
|
|
74
|
+
match the code on this branch.
|
|
75
|
+
|
|
76
|
+
**Predictability.** One execution path for every input form, a documented
|
|
77
|
+
exit-code contract (`loki verify` 0 to 3, usage errors 64) and a spend cap
|
|
78
|
+
that applies on every engine10 provider.
|
|
79
|
+
|
|
80
|
+
## What Loki adds
|
|
81
|
+
|
|
82
|
+
- **Autonomy.** A task, PRD or issue goes to a pull request without turn-by-turn
|
|
83
|
+
prompting, with a stop-and-ask when the contract cannot be met.
|
|
84
|
+
- **Receipts.** A signed receipt per run that `loki verify` re-checks and that
|
|
85
|
+
lists what was NOT PROVEN.
|
|
86
|
+
- **Verification.** Checks written from the task before code, a deterministic
|
|
87
|
+
`loki verify` for CI, and test-weakening detection.
|
|
88
|
+
- **Council.** Specialist review selected from the changed files and diff.
|
|
89
|
+
|
|
90
|
+
## When to pick which
|
|
91
|
+
|
|
92
|
+
Pick opencode for hands-on interactive coding across many providers. Pick Loki
|
|
93
|
+
when you want to delegate a task and get back a verified, receipted result, or
|
|
94
|
+
to gate CI on `loki verify`. They compose: run opencode as a Loki provider.
|
package/docs/COMPONENTS.md
CHANGED
|
@@ -166,6 +166,7 @@ capability degradation.
|
|
|
166
166
|
- `cline.sh` - Cline (Tier 2: reduced parallelism).
|
|
167
167
|
- `codex.sh` - OpenAI Codex CLI (Tier 3: degraded, sequential).
|
|
168
168
|
- `aider.sh` - Aider (Tier 3: degraded).
|
|
169
|
+
- Non-Claude engine10 sessions run under `loki-ts/src/providers/provider_guard.ts` (timeout, budget stop, post-iteration diff scan with revert).
|
|
169
170
|
- `loader.sh` - Provider loader utility.
|
|
170
171
|
- `models.sh`, `model_catalog.json` - Model name registry and catalog.
|
|
171
172
|
- `managed.py` - Managed provider client.
|
package/docs/EVALUATING.md
CHANGED
|
@@ -184,6 +184,33 @@ per-call cost was not recorded.
|
|
|
184
184
|
|
|
185
185
|
---
|
|
186
186
|
|
|
187
|
+
## 8. Harness attribution: what Loki adds to the same model
|
|
188
|
+
|
|
189
|
+
Question: what does Loki add to the same underlying coding agent, and is the benefit worth its cost? Status: pilot. Six tasks, small n. A pilot reports variance; it is not proof of superiority. Running it is a separate, paid step.
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
loki bench attribution --dry-run # validate task set, print plan, no model call
|
|
193
|
+
loki bench attribution --model <model-id> --execute # run, spends API budget
|
|
194
|
+
loki bench attribution --report <result.json> # re-render the markdown report
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Source checkout only. Implementation: `benchmarks/bench/attribution.py`, reusing `runner._apply_overlay`, `report._median` and `benchmarks/bench/adapters` (process-tree reaping, the Claude JSON parser, the Loki adapter and its cost collection). Options: `--tasks id,id`, `--repeats N` (default 1), `--model ID` (default `claude-sonnet-5`, or `LOKI_BENCH_MODEL`), `--budget-usd X` (default 5), `--timeout SECONDS` (default 900, capped by each task's `agent_timeout_s`), `--out-dir DIR`, `--tasks-dir DIR`. Without `--execute` it only prints the plan and never spawns `claude` or `loki`.
|
|
198
|
+
|
|
199
|
+
Arms and controls: `raw_claude` runs `claude -p <prompt> --output-format json --model M --dangerously-skip-permissions --max-budget-usd B`; `loki` runs `loki start <prompt-file> --provider claude --no-dashboard --yes` with `LOKI_SESSION_MODEL=M` and `LOKI_BUDGET_LIMIT=B`. Both get a byte-identical seed in a fresh git repo with one fixed "seed" commit, the same prompt text (the PRD file for Loki is kept outside the workspace), the same wall-clock cap with the process tree reaped on timeout, separate scratch directories, a scoped child environment and `LOKI_NO_BROWSER=1`. The arm that goes first alternates per task and repeat. Every result JSON pins `claude --version`, `loki version`, the Loki commit SHA, Python version, model, budget, timeout, repeats, and per task the sha256 of the seed tree, acceptance tree and prompt. Disclosed difference: Loki runs its own planning, review and verification loop; that overhead is what is measured. Provider comparisons are out of scope so model and harness effects are not mixed.
|
|
200
|
+
|
|
201
|
+
Tasks live under `benchmarks/attribution/tasks/<id>/` (2 bug fixes, 2 features, 1 refactor, 1 integration): `task.json`, `prompt.md` (the only instruction either arm sees), `seed/` (workspace), `acceptance/` (hidden test, copied in only after the run, overwriting same-named files) and `reference/` (known-good overlay, used only by tests). Exit code 0 from `acceptance.cmd` means accepted. The loader rejects a task whose acceptance test also appears in the seed. Neither arm grades itself: no council, RARV-C or LLM judge takes part in scoring.
|
|
202
|
+
|
|
203
|
+
Metrics, per arm and per task class, computed by `compute_metrics`; failures, timeouts and harness errors stay in every denominator:
|
|
204
|
+
|
|
205
|
+
- Acceptance rate: accepted / assigned, with a 95% Wilson interval.
|
|
206
|
+
- False-completion rate: (reported success and not accepted) / reported success; null when nothing reported success. Reported success means `claude -p` exits 0 with `is_error` false, or `loki start` exits 0.
|
|
207
|
+
- Cost per accepted task: total measured spend across all attempts / accepted. Null (`undefined_no_accepted`) when none accepted. A run with no cost figure is `unmeasured`, never zero: some unmeasured gives `partial_lower_bound` (per-accepted null, lower bound only), all unmeasured gives `unmeasured`. Cost is API-dollar accounting; subscription use is not converted.
|
|
208
|
+
- Elapsed time: median over accepted runs, with completion rate, timeout count and error count; median over all runs is also given.
|
|
209
|
+
|
|
210
|
+
Not measured: human effort, recovery success, review quality. Output: `--out-dir` (default `benchmarks/attribution/results/`) receives `attribution-<UTC stamp>.json` and the matching `.md`. Publish failures, timeouts and exclusions with the report; do not drop rows. Do not claim superiority from overlapping intervals on a handful of runs; use the pilot to size a larger run with `--repeats` above 1. Tests: `python3 benchmarks/bench/tests/test_attribution.py` (no model call).
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
187
214
|
## What we do not have
|
|
188
215
|
|
|
189
216
|
Stating this plainly, because you will find it out anyway and it is cheaper for
|
|
@@ -133,6 +133,26 @@ Cap overrides (only meaningful when feature 8 is on):
|
|
|
133
133
|
Profile knobs: `LOKI_REPO_PROFILE_TTL_SECONDS` (86400),
|
|
134
134
|
`LOKI_REPO_PROFILE_MAX_CHARS` (2000).
|
|
135
135
|
|
|
136
|
+
## Repo commands and baseline (REPOMEM, same module)
|
|
137
|
+
|
|
138
|
+
`loki-ts/src/runner/repo_profile.ts` also owns the commands profile the engine10 path uses (`loki start`). The goal: the user never explains how the repo builds and tests, and a failure that was already there never blocks the run. It is not gated by `LOKI_REPO_PROFILE`; disable it with `LOKI_REPO_BASELINE=0`. Both profiles share one manifest hash (`manifestHash`: sha256 over name and content of package.json, requirements.txt, Makefile, pyproject.toml, tox.ini, pytest.ini, setup.cfg, go.mod, Cargo.toml and `.github/workflows/*.yml`).
|
|
139
|
+
|
|
140
|
+
Artifact: `.loki/state/repo-profile.json` (version 1, `CommandProfile`), written by engine10 intake.
|
|
141
|
+
|
|
142
|
+
- `revision`: HEAD the baseline ran on. `manifest_hash`: as above.
|
|
143
|
+
- `commands[]`: `{kind: test|lint|typecheck|build, cmd, source, validated, exit_code, duration_s, failing_ids}`. `validated` is true only when the command ran to completion on the untouched tree, false when it could not run (missing, timed out), null when discovered but not executed. Only the first test command is executed.
|
|
144
|
+
- `baseline`: `{ran, command, exit_code, duration_s, timed_out, failing_ids, attributable, reason?}`. `attributable` means exit 0, or non-zero with parseable failing ids (`failIds`).
|
|
145
|
+
|
|
146
|
+
Lifecycle:
|
|
147
|
+
|
|
148
|
+
1. Intake (after the dirty-tree refusal and the `.loki/` exclude, before any agent edit): same manifest hash and HEAD reuses the file; same hash and a new HEAD keeps the commands and re-runs only the baseline; a changed hash rediscovers and re-runs (`ensureProfile`).
|
|
149
|
+
2. Baseline: `sh -c <test cmd>` in the repo, 60s timeout (SIGKILL), scoped env (`plainTestEnv`, `PYTHONDONTWRITEBYTECODE=1`, `CI=1`). Untracked files the run created are removed so the diff stays the agent's.
|
|
150
|
+
3. Implementer brief (`briefContext`, e10ext/context.ts): a "Repo commands" block and the known-red test ids (`profileBrief`). Bytes depend only on the profile content (no timestamps).
|
|
151
|
+
4. Verify (`verifyStage`): `attribute()` marks a failing check pre-existing only when the profile revision equals the run base sha, the baseline was attributable, the check is neither a Wall/task-named target nor in a file the diff touched, and every one of its failing ids is in the baseline. Those join `pre_red` and `pre_red_checks`. Everything else that fails is introduced and blocks as before; a check with no parsed ids is introduced. Verify data gains `baseline_line` (`baseline: N pre-existing failing check(s) (not blocking), M introduced (blocking)`) and `introduced_checks`; seal lists the line under NOT PROVEN only when a baseline failure was excused.
|
|
152
|
+
5. Surface: `loki doctor --repo` (and `--repo --json`) prints the profile, read-only, from the current directory.
|
|
153
|
+
|
|
154
|
+
`e10ext/repomemory.ts` still holds the last verified command, flaky list and failure causes (dynamic per-repo cache data, not discovery).
|
|
155
|
+
|
|
136
156
|
## Acceptance
|
|
137
157
|
|
|
138
158
|
1. With all flags unset, `bun test tests/parity/` stays 60/60 byte-exact.
|
package/docs/INSTALLATION.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Loki Mode, by [Autonomi](https://www.autonomi.dev/), turns a spec or an issue into a verified pull request with a receipt you can check. This page covers installing it, a first run, and the options around it.
|
|
4
4
|
|
|
5
|
-
**Version:** v11.
|
|
5
|
+
**Version:** v11.5.1
|
|
6
6
|
|
|
7
|
-
**Engine note:** `loki "<task>"`, `loki owner/repo#N` and `loki quick` run the Loki 10 engine
|
|
7
|
+
**Engine note:** `loki start` is the primary command. `loki start`, `loki "<task>"`, `loki owner/repo#N` and `loki quick` all run the Loki 10 engine, whatever the flag order or input form (PRD file, issue ref, task or one-word brief). The previous loop runs only on `--engine legacy`, `LOKI_ENGINE=legacy`, or for one call when a flag Loki 10 cannot honor is present. See the [user guide](v10/GUIDE.md) and the [5-minute quickstart](QUICKSTART.md).
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -51,19 +51,52 @@ loki --version # prints the installed version
|
|
|
51
51
|
loki doctor # checks providers, Bun, skill links and prerequisites
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
## Prerequisites
|
|
55
|
+
|
|
56
|
+
Required (`loki doctor` fails without them):
|
|
57
|
+
|
|
58
|
+
| Tool | Minimum |
|
|
59
|
+
|------|---------|
|
|
60
|
+
| Node.js | 18 (20+ recommended, 22 LTS is the CI target) |
|
|
61
|
+
| Python 3 | 3.8 |
|
|
62
|
+
| git | any recent version |
|
|
63
|
+
| jq | any |
|
|
64
|
+
| curl | any |
|
|
65
|
+
|
|
66
|
+
Plus a way to reach a model. Claude Code (`claude`) is the default provider and the only one with every feature, so the default path needs it installed and logged in: `npm install -g @anthropic-ai/claude-code`, then `claude auth login`. The bundled Claude Agent SDK with `ANTHROPIC_API_KEY` can stand in for the CLI on the engine10 path. `loki edit` and `loki chat` call the `claude` CLI directly. Every other provider CLI (`codex`, `cline`, `aider`, `opencode`) is optional.
|
|
67
|
+
|
|
68
|
+
Optional: Bun 1.3+ (bundled by the npm package), bash 4+ (recommended), Ollama or an OpenRouter key for non-Claude model routes.
|
|
69
|
+
|
|
70
|
+
One command checks and configures all of this:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
loki setup # wizard: tools, Claude login, provider, model route, spend cap
|
|
74
|
+
loki setup --yes # non-interactive, accept defaults
|
|
75
|
+
loki setup --check # report only
|
|
76
|
+
loki doctor --fix # apply safe fixes; prints exact commands for the rest
|
|
77
|
+
loki config list # show settings; also: loki config get|set|path
|
|
78
|
+
loki doctor --json # machine-readable
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`loki doctor --fix` creates state directories and a default config. It never installs system packages or runs sudo; it prints those commands instead.
|
|
55
82
|
|
|
56
83
|
---
|
|
57
84
|
|
|
58
85
|
## First run
|
|
59
86
|
|
|
60
87
|
```bash
|
|
61
|
-
loki
|
|
62
|
-
loki
|
|
63
|
-
loki
|
|
64
|
-
loki
|
|
88
|
+
loki setup # first-run wizard
|
|
89
|
+
loki start "add a /health route" # the primary path: build, verify, seal a receipt
|
|
90
|
+
loki start prd.md # same, from a PRD file
|
|
91
|
+
loki start owner/repo#42 # same, from a GitHub, GitLab or Jira issue
|
|
92
|
+
loki edit "rename fooBar to foo_bar" # one small change, no loop
|
|
93
|
+
loki chat # interactive alternative (Plan/Build modes)
|
|
94
|
+
loki welcome # what Loki is and what to do next
|
|
95
|
+
loki quickstart # guided first build: setup check, idea, template, plan, go
|
|
65
96
|
```
|
|
66
97
|
|
|
98
|
+
The shorter forms `loki "<task>"` and `loki owner/repo#42` run the same engine. The spend cap defaults to $100 when `ANTHROPIC_API_KEY` or `OPENAI_API_KEY` is set and to no dollar cap on a subscription login; change it with `--max-cost <usd>`, `budgets.per_run` in `loki.yaml`, or `loki setup --budget`. A quick walkthrough is in [QUICKSTART.md](QUICKSTART.md).
|
|
99
|
+
|
|
67
100
|
`loki quickstart` asks four questions and shows the plan before anything runs. Press Enter at every step to build the sample Todo app. Add `--dry-run --json` to preview the plan without writing files.
|
|
68
101
|
|
|
69
102
|
Every finished run leaves a receipt. Check a branch the same way CI does:
|
|
@@ -93,14 +126,25 @@ See [control-plane-migration.md](control-plane-migration.md) and [control-plane-
|
|
|
93
126
|
|
|
94
127
|
| Provider | Notes |
|
|
95
128
|
|----------|-------|
|
|
96
|
-
| `claude` | Default. Full feature set. |
|
|
97
|
-
| `cline` | Full feature set; small local models may fail tool use. |
|
|
98
|
-
| `codex` | Sequential only. |
|
|
99
|
-
| `aider` | Sequential only; `ollama_chat/<model>` works for local models. |
|
|
100
|
-
| `opencode` | Sequential only. Install with `npm install -g opencode-ai`. |
|
|
129
|
+
| `claude` | Default (Tier 1). Full feature set. |
|
|
130
|
+
| `cline` | Full feature set; small local models may fail tool use. Engine10 cost parsed or estimated, guardrail scan. |
|
|
131
|
+
| `codex` | Sequential only. Engine10 cost parsed or estimated, guardrail scan, `--sandbox workspace-write`. |
|
|
132
|
+
| `aider` | Sequential only; `ollama_chat/<model>` works for local models. Engine10 cost reported or estimated, guardrail scan, `--no-auto-commits`. |
|
|
133
|
+
| `opencode` | Sequential only. Supported in engine10 (`--provider opencode`); cost not measured. Install with `npm install -g opencode-ai`; model via `LOKI_OPENCODE_MODEL=provider/model`. |
|
|
101
134
|
|
|
102
135
|
When `LOKI_PROVIDER` is unset, Loki uses the first installed CLI in this order: `claude`, `cline`, `codex`, `aider`, `opencode`. An explicit `LOKI_PROVIDER` or `--provider NAME` always wins.
|
|
103
136
|
|
|
137
|
+
### Model routes and local models
|
|
138
|
+
|
|
139
|
+
Run OpenRouter or a local model through the Claude harness with `LOKI_MODEL_ROUTE=<kind>/<id>`, where kind is `openrouter`, `ollama`, `lmstudio`, `llamacpp`, `vllm` or `custom` (custom needs `LOKI_MODEL_BASE_URL`):
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
loki models --local # discover local models, print ready-to-paste values
|
|
143
|
+
LOKI_MODEL_ROUTE=ollama/qwen3-coder loki start prd.md
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
OpenRouter reads `OPENROUTER_API_KEY`. The route applies to the Claude child process only and every Loki control (cost, kill blocking, receipts) still applies. Details: [user guide](v10/GUIDE.md).
|
|
147
|
+
|
|
104
148
|
---
|
|
105
149
|
|
|
106
150
|
## Configuration
|
package/docs/KNOWN-ISSUES.md
CHANGED
|
@@ -2,16 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Issues in the current release that are known and not yet fixed. Report new ones with `loki crash` or at https://github.com/asklokesh/loki-mode/issues.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Which engine runs
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|---|---|---|---|
|
|
9
|
-
| Empty diff (a git repo with no changes vs base) | `loki verify` | 1 (CONCERNS) | 3 |
|
|
10
|
-
| Not a git directory | `loki verify` | 1 (CONCERNS) | 2 |
|
|
11
|
-
| Unknown flag | `loki verify` with a flag it does not know | 3 | 64 |
|
|
7
|
+
From 11.4.0, `loki start`, `loki "<task>"`, `loki owner/repo#N` and `loki quick` run the Loki 10 engine whatever the flag order or input form. The previous loop runs only on `--engine legacy`, `LOKI_ENGINE=legacy`, for a provider with no Loki 10 invoker, for a PRD over 100000 bytes, or for one call when a flag Loki 10 cannot honor is present (`--simple`, `--parallel`, `--sandbox`, ...). Check with `loki route start <args> --json`: it reports `engine`, `adapter`, `reason` and `capability_differences`. The full table is in the Routing contract section of `docs/exit-codes.md`.
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
## Exit codes
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
The exit code of every command is listed in `docs/exit-codes.md`. Two things are kept as they are for compatibility:
|
|
16
12
|
|
|
17
|
-
|
|
13
|
+
- `loki run` (deprecated alias of `loki start <issue-ref>`) exits 1 on an unknown option, not 64.
|
|
14
|
+
- `loki start` without `LOKI_DURABLE_STATE=1` has no finer run-outcome signal than 0 versus nonzero.
|
|
15
|
+
|
|
16
|
+
An empty diff has a distinct exit code only for `loki verify` (3). `loki quick`, `loki start` and `loki run` do not define one.
|
package/docs/PROOF-PASSPORT.md
CHANGED
|
@@ -29,3 +29,117 @@ trust limitations, but no repository or machine-specific paths.
|
|
|
29
29
|
Proof Passport does not currently sign the passport itself. Receipt signature
|
|
30
30
|
status is reported separately and must not be interpreted as a passport
|
|
31
31
|
signature.
|
|
32
|
+
|
|
33
|
+
## Verification record
|
|
34
|
+
|
|
35
|
+
Status: v1 (schema_version 1). Closes review finding LM-005: a passing outcome label could be misread when checks were not performed.
|
|
36
|
+
|
|
37
|
+
Implementation: the verification-record section of `autonomy/lib/proof-verify.py` (CLI: `proof-verify.py <label|summary|json> <file>`). Both routes of `loki verify` and `loki proof show` use this one module, so the bash and Bun paths cannot drift.
|
|
38
|
+
|
|
39
|
+
### Why three properties
|
|
40
|
+
|
|
41
|
+
A single "verified" word hides three different questions. The record answers each one separately and never lets one stand in for another.
|
|
42
|
+
|
|
43
|
+
1. **Integrity.** Is this record the one that was written, unaltered?
|
|
44
|
+
2. **Execution validity.** Did the checks run against the code in front of you, and in what environment?
|
|
45
|
+
3. **Requirement coverage.** Do the checks that ran actually cover what was asked for?
|
|
46
|
+
|
|
47
|
+
A signature alone proves neither execution validity nor requirement coverage. A signed record can describe checks run on a different commit, on a dirty tree, or against only some of the requirements. The signature says the bytes are unchanged. It says nothing about whether the claims in those bytes are current or complete.
|
|
48
|
+
|
|
49
|
+
### Property 1: integrity
|
|
50
|
+
|
|
51
|
+
| status | meaning |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| `valid` | `verification.hash` matches the canonical bytes, gpg (when present) verifies, the recorded headline matches the headline re-derived from the facts, and the cost claim is coherent. |
|
|
54
|
+
| `invalid` | Any of the above failed. The label becomes `NOT VERIFIED (integrity failed ...)` regardless of what the checks say. |
|
|
55
|
+
| `not_recorded` | The record carries no hash. `.loki/verify/evidence.json` is always in this state: it is unhashed and unsigned. |
|
|
56
|
+
| `unchecked` | The integrity code could not run. |
|
|
57
|
+
|
|
58
|
+
The Ed25519 attestation is reported as present but is not verified inside the record. Use `loki proof verify --jwks` for that.
|
|
59
|
+
|
|
60
|
+
### Property 2: execution validity
|
|
61
|
+
|
|
62
|
+
Recorded with every receipt:
|
|
63
|
+
|
|
64
|
+
- `git.head_sha` and `git.dirty` (dirty ignores `.loki/`), plus `git.tree_sha256` when the generator computed it.
|
|
65
|
+
- `environment`: os, machine, python, node, bun and git versions, as found.
|
|
66
|
+
|
|
67
|
+
Status:
|
|
68
|
+
|
|
69
|
+
| status | meaning |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| `fresh` | Recorded HEAD equals live HEAD and the tree digest (or clean flag) still matches. |
|
|
72
|
+
| `stale` | HEAD moved, or the working tree changed since the checks ran. Every previously passed check is reported as `stale`, and the label is `STALE (...)`. |
|
|
73
|
+
| `unknown` | Not enough was recorded to compare (older receipts, no git tree). Unknown is never promoted to fresh. The label carries `revision freshness unknown`. |
|
|
74
|
+
|
|
75
|
+
### Property 3: requirement coverage
|
|
76
|
+
|
|
77
|
+
Read from `.loki/state/requirements-map.json`:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{"requirements": [{"id": "R1", "text": "...", "checks": ["lint"], "status": "covered"}]}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
| status | meaning |
|
|
84
|
+
| --- | --- |
|
|
85
|
+
| `recorded` | `total`, `covered`, `uncovered` and `uncovered_ids` are filled in. Uncovered requirements appear in the label. |
|
|
86
|
+
| `not_recorded` | No map exists. Coverage is unknown, not zero. Counts are `null`. |
|
|
87
|
+
| `unreadable` | The file exists but is not a valid map. Counts are `null`. |
|
|
88
|
+
|
|
89
|
+
`covered_but_check_not_passed` lists covered requirements whose named check did not pass. Matching check ids to gate names is best effort.
|
|
90
|
+
|
|
91
|
+
### Per-check status
|
|
92
|
+
|
|
93
|
+
Every check is exactly one of: `passed`, `failed`, `skipped`, `not_run`, `stale`.
|
|
94
|
+
|
|
95
|
+
Recorded words map as follows: pass-like words (`pass`, `passed`, `verified`, `ok`, `success`) become `passed`; fail-like words (`fail`, `failed`, `blocked`, `weakened`, `error`) become `failed`; `skipped` and `disabled` become `skipped`; `stale` stays `stale`. Everything else, including `inconclusive` and empty, becomes `not_run`. A check that did not reach a conclusion never reads as passed.
|
|
96
|
+
|
|
97
|
+
### Label rules
|
|
98
|
+
|
|
99
|
+
Evaluated in this order, first match wins:
|
|
100
|
+
|
|
101
|
+
1. Integrity `invalid`: `NOT VERIFIED (integrity failed: ...)`.
|
|
102
|
+
2. Any `failed` check: `NOT VERIFIED (failed: <ids>)`. A failed check never yields a passing label.
|
|
103
|
+
3. Record has no facts or no base verdict: `INCOMPLETE (...)`.
|
|
104
|
+
4. Base verdict is not `VERIFIED` or `VERIFIED WITH GAPS`: that verdict, unchanged.
|
|
105
|
+
5. Execution `stale`: `STALE (...)`.
|
|
106
|
+
6. Anything not run, recorded gaps, uncovered requirements, modified tests or unknown freshness: `VERIFIED (scoped: 5 of 7 checks ran; not run: lint, e2e)` with the applicable clauses.
|
|
107
|
+
7. Otherwise `VERIFIED`.
|
|
108
|
+
|
|
109
|
+
The bare word `VERIFIED` therefore means: integrity not failed, no failed checks, every check ran and passed, tree fresh, no uncovered requirements, no modified tests.
|
|
110
|
+
|
|
111
|
+
### Modified tests
|
|
112
|
+
|
|
113
|
+
`modified_tests` lists existing test files the change modified, deleted, renamed or type-changed, derived from `git diff --name-status` between the recorded base and head. Added test files are not listed. Status is `measured` or `unknown` (no base recorded or diff not computable). Modified tests appear in the label and in the summary because an implementer who edits the tests that judge the change weakens the evidence.
|
|
114
|
+
|
|
115
|
+
### Record shape
|
|
116
|
+
|
|
117
|
+
`loki proof show <id> --json` keeps the full proof. The verification record is produced by `proof-verify.py json`, embedded as `verification` in `.loki/verify/evidence.json`, and added as `verification` to the `loki proof verify` JSON. Fields are added, never renamed.
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"schema_version": 1,
|
|
122
|
+
"kind": "proof | evidence",
|
|
123
|
+
"label": "VERIFIED (scoped: ...)",
|
|
124
|
+
"base_verdict": "VERIFIED",
|
|
125
|
+
"integrity": {"status": "valid", "hash_ok": true, "signature": "none", "detail": "..."},
|
|
126
|
+
"execution": {"status": "fresh", "reason": "", "recorded": {}, "current": {}, "environment": {}},
|
|
127
|
+
"requirements": {"status": "recorded", "total": 3, "covered": 1, "uncovered": 2, "uncovered_ids": []},
|
|
128
|
+
"checks": [{"id": "lint", "status": "skipped", "detail": ""}],
|
|
129
|
+
"counts": {"passed": 1, "failed": 0, "skipped": 1, "not_run": 0, "stale": 0, "total": 2, "ran": 1},
|
|
130
|
+
"modified_tests": {"status": "measured", "files": [{"path": "tests/a.py", "change": "modified"}]},
|
|
131
|
+
"complete": true,
|
|
132
|
+
"record_path": ""
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Human output
|
|
137
|
+
|
|
138
|
+
`loki verify` (banner), `loki proof show <id>` and `loki proof verify <id> --human` print a compact summary of about 12 lines: the label, revision and freshness, environment, integrity, check counts with the checks that did not pass, requirement coverage, modified tests, and the signature caveat. Pass `--json` to `loki proof show` for the full record.
|
|
139
|
+
|
|
140
|
+
### Compatibility
|
|
141
|
+
|
|
142
|
+
- Exit codes are unchanged: `loki verify` keeps its verdict-based codes; `loki proof verify` keeps 0 clean, 1 tamper or drift, 2 unusable.
|
|
143
|
+
- Existing JSON fields are untouched. `verification` is additive.
|
|
144
|
+
- Receipts written before this contract lack `facts.environment` and `facts.git.dirty`. They report environment `not recorded` and may report freshness `unknown`.
|
|
145
|
+
- `loki proof show <id>` used to print the raw JSON. Scripts that parsed it must now pass `--json`.
|