loki-mode 8.5.2 → 8.6.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 +16 -0
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/loki +226 -6
- package/autonomy/run.sh +117 -9
- package/autonomy/telemetry.sh +45 -0
- package/autonomy/verify.sh +85 -19
- package/completions/_loki +1 -0
- package/completions/loki.bash +1 -1
- package/dashboard/__init__.py +1 -1
- package/docs/EVALUATING.md +28 -0
- package/docs/PRIVACY.md +25 -2
- package/docs/STRATEGY-2026-2028.md +124 -0
- package/docs/adoption-baseline-2026-07-31.md +84 -0
- package/docs/air-gapped.md +91 -0
- package/docs/brownfield.md +120 -0
- package/docs/cost-controls.md +88 -0
- package/docs/environment-variables.md +102 -0
- package/docs/exit-codes.md +130 -0
- package/docs/image-provenance.md +124 -0
- package/loki-ts/dist/loki.js +381 -372
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
package/autonomy/verify.sh
CHANGED
|
@@ -39,12 +39,23 @@
|
|
|
39
39
|
# 2 BLOCKED
|
|
40
40
|
# 3 verifier error (could not complete; never silently passes)
|
|
41
41
|
#
|
|
42
|
-
#
|
|
43
|
-
# 0=VERIFIED, 1=BLOCKED, 2=CONCERNS,
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
42
|
+
# EXIT-CODE ORDERING, RECONCILED. An early draft spec listed
|
|
43
|
+
# 0=VERIFIED, 1=BLOCKED, 2=CONCERNS, and this header used to say a human must
|
|
44
|
+
# reconcile the two before the GitHub App consumed exit codes. That is now
|
|
45
|
+
# done, in favor of THIS implementation: 0/1/2/3 =
|
|
46
|
+
# VERIFIED/CONCERNS/BLOCKED/error.
|
|
47
|
+
#
|
|
48
|
+
# Why this ordering wins. The code is authoritative and always has been
|
|
49
|
+
# (VERIFY_EXIT_* below), `loki verify --help` documents it, and
|
|
50
|
+
# wiki/CLI-Reference.md documents it. The draft spec that said otherwise is not
|
|
51
|
+
# in this repository and has no consumers. Renumbering working code to match an
|
|
52
|
+
# absent document would break every existing caller to satisfy nothing.
|
|
53
|
+
#
|
|
54
|
+
# It is also the ordering an integrator expects: severity rises with the code,
|
|
55
|
+
# so `[ $rc -ge 2 ]` means "at least blocked". The reverse would make 1 more
|
|
56
|
+
# severe than 2, which no one guesses correctly.
|
|
57
|
+
#
|
|
58
|
+
# See docs/exit-codes.md for the exit codes of every command.
|
|
48
59
|
|
|
49
60
|
set -uo pipefail
|
|
50
61
|
|
|
@@ -1810,6 +1821,7 @@ verify_emit_evidence() {
|
|
|
1810
1821
|
_VERIFY_GATES="$_VERIFY_GATES_FILE" \
|
|
1811
1822
|
_V_VERDICT="$VERIFY_VERDICT" \
|
|
1812
1823
|
_V_EXIT="$VERIFY_EXIT" \
|
|
1824
|
+
_V_JSON_STDOUT="${VERIFY_JSON:-0}" \
|
|
1813
1825
|
_V_SCHEMA="$VERIFY_SCHEMA_VERSION" \
|
|
1814
1826
|
_V_TOOLVER="$tool_version" \
|
|
1815
1827
|
_V_REPO="$repo_name" \
|
|
@@ -1833,7 +1845,7 @@ verify_emit_evidence() {
|
|
|
1833
1845
|
_V_SCOPE_MAX_FILES="${VERIFY_SCOPE_MAX_FILES:-}" \
|
|
1834
1846
|
_V_SCOPE_MAX_NET="${VERIFY_SCOPE_MAX_NET_LINES:-}" \
|
|
1835
1847
|
python3 - <<'PYEOF'
|
|
1836
|
-
import json, os, hashlib
|
|
1848
|
+
import json, os, hashlib, sys
|
|
1837
1849
|
|
|
1838
1850
|
out_dir = os.environ["_VERIFY_OUT_DIR"]
|
|
1839
1851
|
findings_file = os.environ["_VERIFY_FINDINGS"]
|
|
@@ -1959,6 +1971,27 @@ with open(ev_path, "w") as f:
|
|
|
1959
1971
|
json.dump(doc, f, indent=2)
|
|
1960
1972
|
f.write("\n")
|
|
1961
1973
|
|
|
1974
|
+
# --json emits the SAME document to stdout. Deliberately the same `doc` rather
|
|
1975
|
+
# than a second serializer: two writers of one contract drift, and the drift
|
|
1976
|
+
# shows up as a caller trusting a field the file no longer has. The evidence
|
|
1977
|
+
# file is still written either way, so --json adds a pipe without removing the
|
|
1978
|
+
# artifact.
|
|
1979
|
+
#
|
|
1980
|
+
# Written to FD 3, not stdout. The caller redirects this function's stdout to
|
|
1981
|
+
# /dev/null (it emits progress chatter the human path does not want), so a
|
|
1982
|
+
# plain stdout write here is discarded. FD 3 is opened by the caller only under
|
|
1983
|
+
# --json and routed to the real stdout.
|
|
1984
|
+
if os.environ.get("_V_JSON_STDOUT") == "1":
|
|
1985
|
+
try:
|
|
1986
|
+
with os.fdopen(os.dup(3), "w") as _jf:
|
|
1987
|
+
_jf.write(json.dumps(doc, indent=2) + "\n")
|
|
1988
|
+
except OSError:
|
|
1989
|
+
# FD 3 not open: --json was requested but the caller did not wire it.
|
|
1990
|
+
# Fail loudly rather than exit 0 having emitted nothing, which would
|
|
1991
|
+
# look to a pipeline like a verify that produced an empty document.
|
|
1992
|
+
sys.stderr.write("verify: --json requested but FD 3 is not open\n")
|
|
1993
|
+
raise SystemExit(3)
|
|
1994
|
+
|
|
1962
1995
|
# ----- Markdown report -----
|
|
1963
1996
|
def sev_rank(s):
|
|
1964
1997
|
return {"Critical": 0, "High": 1, "Medium": 2, "Low": 3, "Info": 4}.get(s, 5)
|
|
@@ -2050,6 +2083,11 @@ OPTIONS:
|
|
|
2050
2083
|
Default: critical,high (one notch looser than the
|
|
2051
2084
|
Loki build loop, which also blocks on medium).
|
|
2052
2085
|
--no-llm Accepted for forward-compat; LLM is already off in MVP.
|
|
2086
|
+
--json Emit the evidence document to stdout so it can be piped
|
|
2087
|
+
(`loki verify --json | jq .verdict`). The same document
|
|
2088
|
+
is still written to <out>/evidence.json. The human
|
|
2089
|
+
VERDICT banner moves to stderr so stdout stays valid
|
|
2090
|
+
JSON. The verdict and exit code are unchanged.
|
|
2053
2091
|
--explain Print a one-screen, skeptic-legible trust proof: every
|
|
2054
2092
|
gate that ran, its status, the runner/scanner that
|
|
2055
2093
|
produced the evidence, whether it is reproducible, plus
|
|
@@ -2093,16 +2131,16 @@ VERDICT MODEL:
|
|
|
2093
2131
|
Uncommitted working-tree changes are not verified; commit them first. An
|
|
2094
2132
|
empty diff yields CONCERNS (nothing to verify), never VERIFIED.
|
|
2095
2133
|
|
|
2096
|
-
EXIT CODES
|
|
2134
|
+
EXIT CODES:
|
|
2097
2135
|
0 VERIFIED
|
|
2098
2136
|
1 CONCERNS
|
|
2099
2137
|
2 BLOCKED
|
|
2100
2138
|
3 verifier error (could not complete; never silently passes)
|
|
2101
2139
|
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2140
|
+
Severity rises with the code, so `[ $rc -ge 2 ]` means "at least blocked".
|
|
2141
|
+
An early draft spec listed 1=BLOCKED, 2=CONCERNS; that ordering was
|
|
2142
|
+
rejected and is not used anywhere. See docs/exit-codes.md for every
|
|
2143
|
+
command's codes.
|
|
2106
2144
|
|
|
2107
2145
|
OUTPUT:
|
|
2108
2146
|
<out>/evidence.json consolidated machine-readable evidence (schema 1.0)
|
|
@@ -2620,6 +2658,8 @@ verify_main() {
|
|
|
2620
2658
|
# verify does NOT re-run gates: it reads a prior evidence.json and fails
|
|
2621
2659
|
# closed if the repo has drifted since that evidence was graded.
|
|
2622
2660
|
VERIFY_CHECK_FRESH=0
|
|
2661
|
+
# Opt-in machine-readable stdout (--json). Default 0 = exactly today.
|
|
2662
|
+
VERIFY_JSON=0
|
|
2623
2663
|
|
|
2624
2664
|
# Fail-closed defaults. These globals are read at the end of this function
|
|
2625
2665
|
# (the VERDICT banner and the function return code). verify_compute_verdict()
|
|
@@ -2644,6 +2684,16 @@ verify_main() {
|
|
|
2644
2684
|
block_on="$(printf '%s' "${2:-}" | tr '[:upper:]' '[:lower:]')"; shift 2 ;;
|
|
2645
2685
|
--no-llm)
|
|
2646
2686
|
shift ;;
|
|
2687
|
+
--json)
|
|
2688
|
+
# Emit the evidence document to STDOUT so a caller can pipe it.
|
|
2689
|
+
# The same document is still written to <out>/evidence.json --
|
|
2690
|
+
# this adds a pipe, it does not move the artifact.
|
|
2691
|
+
#
|
|
2692
|
+
# Implies --quiet-banner: stdout must be JSON and nothing else,
|
|
2693
|
+
# or `loki verify --json | jq` breaks on the human banner. The
|
|
2694
|
+
# banner still goes to stderr, so an operator watching a
|
|
2695
|
+
# terminal loses nothing.
|
|
2696
|
+
VERIFY_JSON=1; shift ;;
|
|
2647
2697
|
--explain)
|
|
2648
2698
|
# Render a one-screen, skeptic-legible trust proof: every gate
|
|
2649
2699
|
# that ran, its status, the runner/scanner that produced the
|
|
@@ -2793,10 +2843,21 @@ verify_main() {
|
|
|
2793
2843
|
|
|
2794
2844
|
completed_at="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
2795
2845
|
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2846
|
+
# stdout is discarded (the emitter's own chatter is not wanted on the human
|
|
2847
|
+
# path). Under --json, FD 3 is opened onto the REAL stdout so the emitter
|
|
2848
|
+
# can write the evidence document there while everything else stays
|
|
2849
|
+
# suppressed -- that is what keeps `loki verify --json | jq` parseable.
|
|
2850
|
+
if [ "${VERIFY_JSON:-0}" = "1" ]; then
|
|
2851
|
+
verify_emit_evidence "$out_dir" "$started_at" "$completed_at" "$block_on" 3>&1 >/dev/null || {
|
|
2852
|
+
_verify_err "failed to emit evidence document"
|
|
2853
|
+
return $VERIFY_EXIT_ERROR
|
|
2854
|
+
}
|
|
2855
|
+
else
|
|
2856
|
+
verify_emit_evidence "$out_dir" "$started_at" "$completed_at" "$block_on" >/dev/null || {
|
|
2857
|
+
_verify_err "failed to emit evidence document"
|
|
2858
|
+
return $VERIFY_EXIT_ERROR
|
|
2859
|
+
}
|
|
2860
|
+
fi
|
|
2800
2861
|
|
|
2801
2862
|
# Opt-in (--hosted): fold the embedded Autonomi Verify engine's verdict
|
|
2802
2863
|
# fields into the just-written evidence.json. Fully additive and fail-open:
|
|
@@ -2814,9 +2875,14 @@ verify_main() {
|
|
|
2814
2875
|
_verify_render_explain "$started_at" "$completed_at" "$VERIFY_VERDICT"
|
|
2815
2876
|
fi
|
|
2816
2877
|
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2878
|
+
# Under --json stdout carries the evidence document alone, so the human
|
|
2879
|
+
# banner is redirected to stderr rather than dropped: an operator watching a
|
|
2880
|
+
# terminal still sees the verdict, and `| jq` still parses.
|
|
2881
|
+
_v_banner_fd=1
|
|
2882
|
+
[ "${VERIFY_JSON:-0}" = "1" ] && _v_banner_fd=2
|
|
2883
|
+
printf 'VERDICT: %s\n' "$VERIFY_VERDICT" >&$_v_banner_fd
|
|
2884
|
+
printf 'Evidence: %s/evidence.json\n' "$out_dir" >&$_v_banner_fd
|
|
2885
|
+
printf 'Report: %s/report.md\n' "$out_dir" >&$_v_banner_fd
|
|
2820
2886
|
# --hosted only: surface the enrichment in human output so the extra signal
|
|
2821
2887
|
# is visible without parsing JSON. Printed solely when a fold succeeded;
|
|
2822
2888
|
# the default path never sets VERIFY_HOSTED_SUMMARY, so it stays byte-identical.
|
package/completions/_loki
CHANGED
|
@@ -153,6 +153,7 @@ function _loki_commands {
|
|
|
153
153
|
'memory:Memory commands'
|
|
154
154
|
'compound:Knowledge compounding commands'
|
|
155
155
|
'checkpoint:Snapshot and restore session state'
|
|
156
|
+
'cp:Snapshot and restore session state (alias of checkpoint)'
|
|
156
157
|
'council:Completion council commands'
|
|
157
158
|
'dogfood:Self-development statistics'
|
|
158
159
|
'projects:Project registry commands'
|
package/completions/loki.bash
CHANGED
|
@@ -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 quick monitor demo tour welcome init stop pause resume steer status next ship dashboard web serve api sandbox notify import github issue config provider reset memory compound checkpoint council dogfood projects enterprise secrets cockpit secure own doctor watchdog audit metrics syslog onboard share proof explain plan report cost 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 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"
|
|
8
|
+
local main_commands="start quick monitor demo tour welcome init stop pause resume steer status next ship dashboard web serve api sandbox notify import github issue config provider reset memory compound checkpoint council dogfood projects enterprise secrets cockpit secure own handoff doctor watchdog audit metrics syslog onboard share proof receipt explain plan report cost 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 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"
|
|
9
9
|
|
|
10
10
|
# 1. If we are on the first argument (subcommand)
|
|
11
11
|
if [[ $cword -eq 1 ]]; then
|
package/dashboard/__init__.py
CHANGED
package/docs/EVALUATING.md
CHANGED
|
@@ -154,6 +154,34 @@ expose something the CLI does not. If a competitor does ship output
|
|
|
154
154
|
verification, this test is how we would find out, and the claim above would be
|
|
155
155
|
corrected rather than defended.
|
|
156
156
|
|
|
157
|
+
## 7. Headless latency, five trials per tool
|
|
158
|
+
|
|
159
|
+
Same task, same machine, artifact verified by content, five trials each:
|
|
160
|
+
|
|
161
|
+
| CLI | Success | Median | Range |
|
|
162
|
+
| --- | --- | --- | --- |
|
|
163
|
+
| opencode 1.18.9 | 5/5 | 11s | 4s to 265s |
|
|
164
|
+
| codex-cli 0.146.0 | 4/5 | 69s | 48s to 80s (one 300s timeout) |
|
|
165
|
+
|
|
166
|
+
**Read the range, not just the median.** opencode's first trial took 265
|
|
167
|
+
seconds and the next four took 4 to 12. A new user experiences the 265, not the
|
|
168
|
+
11. Reporting only the median would hide the thing they will actually feel.
|
|
169
|
+
|
|
170
|
+
**The timeout is kept in.** Dropping codex's one failure would turn 4-of-5 into
|
|
171
|
+
an implied 5-of-5 and overstate reliability.
|
|
172
|
+
|
|
173
|
+
**Five trials, not one, and that is the point.** An earlier single-shot run of
|
|
174
|
+
this same codex command timed out, and publishing it would have recorded
|
|
175
|
+
"codex: timeout" as a fact about a competitor when the identical command
|
|
176
|
+
completed in 51 seconds minutes later. The spread is the finding.
|
|
177
|
+
|
|
178
|
+
**What this does not measure.** One trivial file-creation task is not a proxy
|
|
179
|
+
for build quality, multi-iteration work, or brownfield capability. It measures
|
|
180
|
+
headless invocation latency and nothing else. aider, Claude Code and
|
|
181
|
+
cursor-agent have not been run on this task; Devin and Replit Agent ship no
|
|
182
|
+
local CLI. Cost is not compared: codex ran on a free tier and opencode's
|
|
183
|
+
per-call cost was not recorded.
|
|
184
|
+
|
|
157
185
|
---
|
|
158
186
|
|
|
159
187
|
## What we do not have
|
package/docs/PRIVACY.md
CHANGED
|
@@ -114,10 +114,33 @@ it sits below the base telemetry gate, every telemetry opt-out (`loki telemetry
|
|
|
114
114
|
off` / `LOKI_TELEMETRY=off` / `DO_NOT_TRACK=1`) also disables it -- opt-out
|
|
115
115
|
always wins.
|
|
116
116
|
|
|
117
|
+
### 5. First-run blocker (anonymous, STRICT opt-in, default OFF)
|
|
118
|
+
|
|
119
|
+
A `first_run_blocked` event naming which CLASS of dependency stopped a first
|
|
120
|
+
run, sent at most ONCE per install. It sits behind the same strict second
|
|
121
|
+
opt-in as build-outcome analytics above (`LOKI_ANALYTICS=on`), so it is off by
|
|
122
|
+
default even with telemetry enabled.
|
|
123
|
+
|
|
124
|
+
It exists because we could see that a first run was ATTEMPTED and nothing about
|
|
125
|
+
whether it succeeded, which made "why does a trial not convert" unanswerable.
|
|
126
|
+
A real example we found and fixed: on a machine with no AI provider CLI, one
|
|
127
|
+
route ended with a dead end instead of pointing at `loki tour` (which needs no
|
|
128
|
+
provider, no key and no spend). Nobody could see that happening.
|
|
129
|
+
|
|
130
|
+
The ONLY field is `blocker`, clamped to this fixed enum:
|
|
131
|
+
|
|
132
|
+
no_provider | node | python3 | jq | git | curl | disk | skill_symlink | other
|
|
133
|
+
|
|
134
|
+
Anything not on that list becomes `other`. It is deliberately coarse: `node` is
|
|
135
|
+
enough to act on, and a version string or an install path would be a leak. It
|
|
136
|
+
NEVER sends paths, versions, hostnames, spec text, or command lines -- a test
|
|
137
|
+
(`tests/test-first-run-blocked-signal.sh`) feeds a filesystem path through the
|
|
138
|
+
real emitter and fails the build if anything but `other` reaches the payload.
|
|
139
|
+
|
|
117
140
|
This document and the first-run notice describe ALL paths. The model is unified:
|
|
118
141
|
opt-out always wins and disables everything; crash reporting and usage telemetry
|
|
119
|
-
opt in together (default ON for individuals); build-outcome analytics
|
|
120
|
-
|
|
142
|
+
opt in together (default ON for individuals); build-outcome analytics and the
|
|
143
|
+
first-run blocker each need an explicit second opt-in on top (default OFF).
|
|
121
144
|
|
|
122
145
|
## What is collected (the whitelist)
|
|
123
146
|
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Two-year adoption strategy
|
|
2
|
+
|
|
3
|
+
Written 2026-07-31 from measured inputs: registry download data, competitor
|
|
4
|
+
documentation fetched the same day, and benchmark results from this repository.
|
|
5
|
+
Where a claim is inference rather than measurement, it says so.
|
|
6
|
+
|
|
7
|
+
## The one number that matters
|
|
8
|
+
|
|
9
|
+
**Floor: ~94 downloads/day. Peak: 1,263.** The 13x swing tracks our own
|
|
10
|
+
release activity -- eight releases landed on 07-30. A curve that rises when we
|
|
11
|
+
publish and falls when we stop is CI and mirrors, not word of mouth.
|
|
12
|
+
|
|
13
|
+
Organic growth is a **rising floor**. Everything below is judged against that
|
|
14
|
+
single number, measured on days we ship nothing.
|
|
15
|
+
|
|
16
|
+
Two years from now the question is not "how many releases did we cut." It is
|
|
17
|
+
"what is the floor, and does it rise when we are quiet."
|
|
18
|
+
|
|
19
|
+
## What we actually sell, stated so it survives a demo
|
|
20
|
+
|
|
21
|
+
Competitor documentation, fetched 2026-07-31:
|
|
22
|
+
|
|
23
|
+
- **Lovable** runs a security scan on every publish and admins can block the
|
|
24
|
+
publish outright.
|
|
25
|
+
- **Claude Code** has a review step that checks findings against actual code
|
|
26
|
+
behavior.
|
|
27
|
+
- **Replit** says its agent tests its own work.
|
|
28
|
+
|
|
29
|
+
So **"we verify and they don't" is false**, and a founder demo against Lovable
|
|
30
|
+
would expose it. That framing is retired.
|
|
31
|
+
|
|
32
|
+
What is true and unoccupied across all seven competitors: **nobody ships a
|
|
33
|
+
persisted, portable, diff-bound artifact.** Theirs live in a dashboard --
|
|
34
|
+
Lovable's is a findings count in a dialog, Claude Code's check run is
|
|
35
|
+
deliberately non-blocking. Ours is a file: bound to a diff by `diff_sha256`,
|
|
36
|
+
recording what was NOT proven as prominently as what was, verifiable by someone
|
|
37
|
+
who never installed us.
|
|
38
|
+
|
|
39
|
+
That is the sentence. Portable, diff-bound, honest about gaps.
|
|
40
|
+
|
|
41
|
+
## The second thing we sell, now measured
|
|
42
|
+
|
|
43
|
+
**The harness carries quality, not the model.** On `hard-2-ledger`, a task
|
|
44
|
+
authored so a bare model fails it:
|
|
45
|
+
|
|
46
|
+
| arm | result | cost |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| haiku, harness off | 1/4 passed | $0.86 |
|
|
49
|
+
| haiku, harness on | 1/1 passed | $0.54 |
|
|
50
|
+
|
|
51
|
+
Same model. Same prompt. The harness is the only variable. A correct
|
|
52
|
+
implementation cost **less** than the failing ones, because a cheap failure is
|
|
53
|
+
not cheap.
|
|
54
|
+
|
|
55
|
+
Caveat, stated because it will be checked: n is small and trials are still
|
|
56
|
+
accumulating. This demonstrates the mechanism. The rate needs more trials, and
|
|
57
|
+
those are now worth buying -- before this task existed, the baseline passed
|
|
58
|
+
everything and more trials bought precision around a ceiling.
|
|
59
|
+
|
|
60
|
+
## Where we win, and where we should not fight
|
|
61
|
+
|
|
62
|
+
**Do not fight on:** hosted preview URLs, visual editing, zero-install browser
|
|
63
|
+
onboarding, managed backend primitives. Those are structural properties of a
|
|
64
|
+
hosted product. Lovable publishes to `[name].lovable.app` free at zero credit
|
|
65
|
+
balance; we cannot and should not try.
|
|
66
|
+
|
|
67
|
+
**Win on the three axes competitors structurally cannot occupy:**
|
|
68
|
+
|
|
69
|
+
1. **Air-gapped operation.** Measured with egress severed: `version`, `doctor`,
|
|
70
|
+
`plan --json`, `proof verify`, `heal --assess` all return real results. No
|
|
71
|
+
competitor can do this -- "Devin's brain always resides within Cognition's
|
|
72
|
+
Cloud." For defence, government, and regulated banking this is winnable on
|
|
73
|
+
this axis alone. One required egress (model inference), disclosed.
|
|
74
|
+
|
|
75
|
+
2. **In-place brownfield.** Lovable **cannot import an existing repository at
|
|
76
|
+
all**. Replit and Cursor import into *their* environment. For a private
|
|
77
|
+
monorepo with internal dependencies, that is frequently not permitted. We
|
|
78
|
+
run where the code already lives.
|
|
79
|
+
|
|
80
|
+
3. **Cost per correct result.** Haiku-plus-harness beat opus-baseline in the
|
|
81
|
+
aggregate at roughly an eighth the cost. If that holds under more trials, it
|
|
82
|
+
is a procurement argument, not a benchmark curiosity.
|
|
83
|
+
|
|
84
|
+
## The two-year sequence
|
|
85
|
+
|
|
86
|
+
**Year 1, first half -- earn the floor.** Every item judged by whether a first
|
|
87
|
+
run reaches a result. Ship `first_run_blocked` (done, v8.6.0), read what it
|
|
88
|
+
says, fix the top blocker, repeat. The floor is the scoreboard.
|
|
89
|
+
|
|
90
|
+
Concretely already done and testable: 43 of 112 commands were unreachable from
|
|
91
|
+
`loki help` including `loki proof`; a first-run dead end on provider-less hosts;
|
|
92
|
+
`loki proof md` so the receipt travels into a PR or Slack.
|
|
93
|
+
|
|
94
|
+
**Year 1, second half -- make the receipt the artefact people forward.** A
|
|
95
|
+
receipt in a PR is a person showing a colleague. That is the only word-of-mouth
|
|
96
|
+
mechanic available to a CLI, and it costs no infrastructure.
|
|
97
|
+
|
|
98
|
+
**Year 2 -- enterprise pull, not push.** Air-gapped + in-place brownfield +
|
|
99
|
+
signed provenance is a procurement story no competitor can match today. It sells
|
|
100
|
+
to the buyer who cannot use the others at all, and those buyers talk to each
|
|
101
|
+
other.
|
|
102
|
+
|
|
103
|
+
## What would falsify this
|
|
104
|
+
|
|
105
|
+
Stated so it is checkable rather than reassuring:
|
|
106
|
+
|
|
107
|
+
- **The floor does not rise** over the next quarter despite first-run fixes ->
|
|
108
|
+
the bottleneck is not discoverability, and this plan is wrong.
|
|
109
|
+
- **`first_run_blocked` shows trials dying on something we did not predict** ->
|
|
110
|
+
follow the data, not this document.
|
|
111
|
+
- **The harness lift does not survive more trials** -> the cost argument
|
|
112
|
+
collapses and the differentiator narrows to portability alone.
|
|
113
|
+
- **A competitor ships a portable signed receipt** -> the wedge is gone and we
|
|
114
|
+
compete on cost and air-gap only.
|
|
115
|
+
|
|
116
|
+
## What is deliberately not here
|
|
117
|
+
|
|
118
|
+
No 80-item backlog. The items that exist are the ones with a measured
|
|
119
|
+
mechanism. Padding this list to look comprehensive would be the fabrication
|
|
120
|
+
this project has already paid for once.
|
|
121
|
+
|
|
122
|
+
Release cadence is explicitly **not** a growth lever: eight releases in one day
|
|
123
|
+
produced a 1,263 spike and a 94 floor. If the floor is the goal, cadence is
|
|
124
|
+
noise.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Adoption baseline, 2026-07-31
|
|
2
|
+
|
|
3
|
+
The first numbers in this project taken from the registry rather than from
|
|
4
|
+
intuition. Recorded so the next measurement has something to compare against.
|
|
5
|
+
|
|
6
|
+
## What we actually have
|
|
7
|
+
|
|
8
|
+
**4,456 npm downloads in the last 7 days.** Daily:
|
|
9
|
+
|
|
10
|
+
| Day | Downloads |
|
|
11
|
+
|---|---|
|
|
12
|
+
| 07-24 | 863 |
|
|
13
|
+
| 07-25 | 1,160 |
|
|
14
|
+
| 07-26 | 196 |
|
|
15
|
+
| 07-27 | 94 |
|
|
16
|
+
| 07-28 | 386 |
|
|
17
|
+
| 07-29 | 494 |
|
|
18
|
+
| 07-30 | 1,263 |
|
|
19
|
+
|
|
20
|
+
Two things follow, and the second matters more than the first.
|
|
21
|
+
|
|
22
|
+
**1. We have users.** Roughly 4.5k downloads a week is not a project nobody
|
|
23
|
+
has heard of. Every strategy discussion in this repo has proceeded as though
|
|
24
|
+
adoption were hypothetical. It is not.
|
|
25
|
+
|
|
26
|
+
**2. The shape is release-driven, not organic.** The 13x swing between 07-27
|
|
27
|
+
(94) and 07-30 (1,263) tracks publishing activity -- eight releases landed on
|
|
28
|
+
07-30 alone. A curve that rises when we publish and falls when we stop is
|
|
29
|
+
mirrors and CI, not word of mouth. Organic growth would show a floor that
|
|
30
|
+
rises over time; this shows a floor near 94.
|
|
31
|
+
|
|
32
|
+
**Do not read 4,456 as 4,456 humans.** npm counts mirrors, CI, and Docker
|
|
33
|
+
layer pulls. The honest statement is that the ceiling is real and the floor is
|
|
34
|
+
what needs to move.
|
|
35
|
+
|
|
36
|
+
## Why the floor is the metric
|
|
37
|
+
|
|
38
|
+
The founder's goal is word-of-mouth growth over two years. The number that
|
|
39
|
+
measures it is the **trough**, not the peak: how many installs happen on a day
|
|
40
|
+
we publish nothing. Today that is ~94.
|
|
41
|
+
|
|
42
|
+
Peaks are bought with releases. Floors are earned by people telling other
|
|
43
|
+
people. Every adoption item should be judged against whether it moves the
|
|
44
|
+
floor.
|
|
45
|
+
|
|
46
|
+
## What we still cannot see, and what changed today
|
|
47
|
+
|
|
48
|
+
Until v8.6.0 shipped this morning, we could see that a first run was ATTEMPTED
|
|
49
|
+
and nothing about whether it succeeded. `first_run_blocked` (v8.6.0) now names
|
|
50
|
+
the class of dependency that stops a first run -- enum-clamped, once per
|
|
51
|
+
install, strict opt-in.
|
|
52
|
+
|
|
53
|
+
That data does not exist yet: the release is hours old and the telemetry is
|
|
54
|
+
off by default behind a second opt-in. It will accumulate slowly and from a
|
|
55
|
+
minority of users, which is the correct trade for not exfiltrating anyone's
|
|
56
|
+
environment.
|
|
57
|
+
|
|
58
|
+
So the sequence is: floor today ~94/day -> ship things that plausibly move it
|
|
59
|
+
-> watch the floor, not the peak.
|
|
60
|
+
|
|
61
|
+
## The three things measured this session that plausibly move it
|
|
62
|
+
|
|
63
|
+
Ranked by how directly they affect someone's first ten minutes:
|
|
64
|
+
|
|
65
|
+
1. **43 of 112 commands were unreachable from `loki help`**, including
|
|
66
|
+
`loki proof` -- the Evidence Receipt, the thing the product argues on. Fixed
|
|
67
|
+
and gated. A user who cannot find the differentiator does not repeat it to
|
|
68
|
+
anyone.
|
|
69
|
+
2. **A first-run dead end on hosts with no provider CLI.** One route named the
|
|
70
|
+
blockers and pointed at `loki tour` (no provider, no key, no spend); the
|
|
71
|
+
other said "some required prerequisites are missing" and stopped. That is
|
|
72
|
+
the exact moment an evaluator decides whether to continue.
|
|
73
|
+
3. **`loki proof md`** puts the receipt in a form a person can paste into a PR
|
|
74
|
+
or a Slack message. Competitors' verification output lives in their
|
|
75
|
+
dashboard; a file is the only artifact that travels.
|
|
76
|
+
|
|
77
|
+
None of these is proven to move the floor. They are the candidates with a
|
|
78
|
+
plausible mechanism, and the floor is now being watched.
|
|
79
|
+
|
|
80
|
+
## Reproduce
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
curl -s "https://api.npmjs.org/downloads/range/last-week/loki-mode"
|
|
84
|
+
```
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Running without egress
|
|
2
|
+
|
|
3
|
+
If your code cannot leave your network, most of this category is unavailable to
|
|
4
|
+
you regardless of what the sales conversation suggests.
|
|
5
|
+
|
|
6
|
+
## Where the tools actually stand
|
|
7
|
+
|
|
8
|
+
Verified from vendor documentation, 2026-07-31:
|
|
9
|
+
|
|
10
|
+
| Tool | Air-gapped |
|
|
11
|
+
|---|---|
|
|
12
|
+
| Devin | **No.** Single-tenant VPC via AWS PrivateLink, customer-managed KMS, a federal docs tree -- but "Devin's brain... always resides within Cognition's Cloud." |
|
|
13
|
+
| Cursor | No. Cloud service; embeddings are uploaded (obfuscated and encrypted). |
|
|
14
|
+
| Claude Code | Partly. Runs against Bedrock / Vertex / Foundry in your own cloud, so data residency is yours -- but a model endpoint is still required. |
|
|
15
|
+
| Lovable, Replit, Emergent | No. Browser products on their infrastructure. |
|
|
16
|
+
| opencode | Structurally yes (MIT, self-hostable) -- but no SOC2, SSO, audit logs, or support. |
|
|
17
|
+
|
|
18
|
+
Devin's is the strongest enterprise packaging in the category and it still
|
|
19
|
+
cannot run disconnected. That is a structural property of a hosted control
|
|
20
|
+
plane, not an oversight.
|
|
21
|
+
|
|
22
|
+
## What we measured
|
|
23
|
+
|
|
24
|
+
Executed 2026-07-31 with outbound HTTP forced through an unroutable proxy --
|
|
25
|
+
not a flag, not an assumption. Every one of these returned a real result with
|
|
26
|
+
egress severed:
|
|
27
|
+
|
|
28
|
+
| Command | Result |
|
|
29
|
+
|---|---|
|
|
30
|
+
| `loki version` | works |
|
|
31
|
+
| `loki doctor --json` | works |
|
|
32
|
+
| `loki plan <spec> --json` | works -- full cost and complexity estimate |
|
|
33
|
+
| `loki proof list` | works |
|
|
34
|
+
| `loki proof verify <id>` | works, and correctly reported `tree_drift: true` |
|
|
35
|
+
| `loki heal <repo> --assess --json` | works -- maturity, ranked targets, runtime |
|
|
36
|
+
|
|
37
|
+
The whole evaluate-before-you-buy path runs disconnected. You can assess a
|
|
38
|
+
legacy codebase, estimate what a build would cost, and verify an existing
|
|
39
|
+
receipt without a single packet leaving the machine.
|
|
40
|
+
|
|
41
|
+
`loki proof verify` deserves emphasis: an auditor can re-check a receipt against
|
|
42
|
+
the repository offline and get a genuine verdict, including detecting drift.
|
|
43
|
+
That is the property competitors' dashboard-bound verification cannot have.
|
|
44
|
+
|
|
45
|
+
## The one required egress, stated plainly
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
loki doctor --airgap
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
prints the egress inventory. Today it reports exactly one REQUIRED point:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
REQUIRED model inference -> https://api.anthropic.com
|
|
55
|
+
Set ANTHROPIC_BASE_URL to an in-network gateway, or switch to a
|
|
56
|
+
local-weights provider.
|
|
57
|
+
optional telemetry [off] disable: loki telemetry off (default off)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**We cannot run a build with no model at all.** Nobody can. What we can do is
|
|
61
|
+
let you point at a model you host: set `ANTHROPIC_BASE_URL` to an in-network
|
|
62
|
+
gateway, or run a provider with local weights. The engine abstracts over CLIs
|
|
63
|
+
rather than over one vendor's API.
|
|
64
|
+
|
|
65
|
+
Telemetry is off by default and every opt-out wins (`DO_NOT_TRACK=1`,
|
|
66
|
+
`LOKI_TELEMETRY=off`, `~/.loki/config`). The adoption instrumentation added in
|
|
67
|
+
v8.6.0 requires a second explicit opt-in on top of that -- see
|
|
68
|
+
[PRIVACY.md](./PRIVACY.md).
|
|
69
|
+
|
|
70
|
+
## Why `unknown` is the right answer offline
|
|
71
|
+
|
|
72
|
+
`loki heal --assess` reports `dependency_staleness: unknown` and always will
|
|
73
|
+
without a network call. We know your manifest pins lodash 3.x; we do not know
|
|
74
|
+
what is current upstream, and we will not guess.
|
|
75
|
+
|
|
76
|
+
That refusal is what makes the assessment trustworthy inside a disconnected
|
|
77
|
+
network. A tool that fabricates a staleness number offline is more dangerous
|
|
78
|
+
than one that declines.
|
|
79
|
+
|
|
80
|
+
## Honest limits
|
|
81
|
+
|
|
82
|
+
- **A model endpoint is required.** If you have no model at all -- not local,
|
|
83
|
+
not in-network -- we cannot build anything, and neither can anyone else.
|
|
84
|
+
- **The five mutating healing phases need a provider.** Only `--assess` is
|
|
85
|
+
genuinely zero-dependency.
|
|
86
|
+
- **Not measured here:** a full disconnected build against a local-weights
|
|
87
|
+
provider. The commands above were measured; that one was not, and this page
|
|
88
|
+
does not claim it.
|
|
89
|
+
|
|
90
|
+
See [Kubernetes air-gapped install](../deploy/helm/README.md) for the
|
|
91
|
+
cluster-side path.
|