loki-mode 8.1.0 → 8.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,142 @@
1
+ # Evaluating Loki Mode
2
+
3
+ For someone deciding whether to trust an autonomous coding agent with a real
4
+ codebase. Every claim below has a command next to it. Run them; do not take our
5
+ word for it.
6
+
7
+ We have deliberately not written a feature grid scoring ourselves against ten
8
+ competitors. Those grids are written by the vendor being scored, the criteria
9
+ are chosen by the vendor, and no reader can check a single cell. This page only
10
+ makes claims you can falsify in a terminal.
11
+
12
+ ---
13
+
14
+ ## 1. The agent hands you a receipt, and it admits what it did not verify
15
+
16
+ ```bash
17
+ npx loki-mode tour # no install, no API key, no spend, no network
18
+ ```
19
+
20
+ Output includes:
21
+
22
+ ```
23
+ Headline: VERIFIED WITH GAPS
24
+
25
+ | Files changed | 8 |
26
+ | Diff sha256 | c2be6fff3e774c387f276277b25fc424f07b667… |
27
+ | Tests | verified (node-test) |
28
+ | Build | not_run |
29
+ | Security | findings |
30
+ | Cost | $10.3218 |
31
+ ```
32
+
33
+ **What to notice:** the headline is not "SUCCESS". Build was not run. Security
34
+ has findings. The receipt says so on its own front page.
35
+
36
+ **Why that is the product.** Every coding agent reports its own completion, and
37
+ self-reporting is the thing they are structurally worst at. The receipt
38
+ separates deterministic FACTS (diff hash, test result, cost) from AI
39
+ ASSESSMENTS, because only four of our eight quality gates are agent-independent
40
+ and a receipt implying otherwise would be marketing.
41
+
42
+ **Check it yourself:** recompute the diff sha256 over the same range and confirm
43
+ it matches. If it does not, the receipt is worthless and you should not use us.
44
+
45
+ ---
46
+
47
+ ## 2. Verification runs air-gapped
48
+
49
+ Deterministic verification makes zero network calls, so it runs inside a
50
+ perimeter on code that may never leave the building.
51
+
52
+ ```bash
53
+ bash tests/test-airgap-verify.sh
54
+ ```
55
+
56
+ That test blackholes every proxy variable, strips the environment, and asserts a
57
+ real verdict still comes back. Measured: **8.43 ms**.
58
+
59
+ **Scope, stated honestly:** verification is air-gapped. **Generation is not.**
60
+ Every provider we ship calls a hosted API, and local-weight generation needs
61
+ models you would supply. We are not claiming the generation half, and any vendor
62
+ who claims a fully air-gapped LLM agent without shipping weights is worth a
63
+ second question.
64
+
65
+ ---
66
+
67
+ ## 3. On an existing codebase, the read-only path is genuinely read-only
68
+
69
+ Brownfield is the harder problem, and the reason to distrust an agent near it is
70
+ obvious. So the entry point writes nothing:
71
+
72
+ ```bash
73
+ loki modernize heal ./your-repo --assess
74
+ git status # clean. no scratch files, no .loki/, no commits.
75
+ ```
76
+
77
+ **Enforced, not promised:**
78
+
79
+ ```bash
80
+ bash tests/test-brownfield-assess-readonly.sh
81
+ ```
82
+
83
+ That test hashes every file before and after, compares HEAD, and requires a
84
+ clean working tree. It is content-addressed, so it does not care *how* a write
85
+ might happen.
86
+
87
+ ---
88
+
89
+ ## 4. The harness is model-invariant (and we do not overclaim it)
90
+
91
+ ```bash
92
+ cat benchmarks/results/cross-model-eval.json
93
+ ```
94
+
95
+ - **Claimed:** the same gates run, the same acceptance is checked, and the same
96
+ receipt semantics apply regardless of which model is behind it.
97
+ - **Explicitly NOT claimed:** identical quality or identical speed across
98
+ models. That is not deliverable and we do not assert it.
99
+
100
+ Measured runs are in that file with wall-clock and iteration counts. Two runs is
101
+ two runs; it is not a benchmark suite, and the file says so.
102
+
103
+ ---
104
+
105
+ ## 5. Verification is fast enough to embed
106
+
107
+ ```bash
108
+ python3 autonomy/lib/fast_verify.py --path . --diff-base HEAD~1
109
+ ```
110
+
111
+ Measured on this repository, 1,932 tracked source files: **11,040 ms before,
112
+ 19 ms diff-scoped** (298 ms cold, 87 ms warm). That is the difference between a
113
+ check you run at the end and a check something else can call as a dependency.
114
+
115
+ ---
116
+
117
+ ## What we do not have
118
+
119
+ Stating this plainly, because you will find it out anyway and it is cheaper for
120
+ both of us if you find it here.
121
+
122
+ - **No published enterprise case studies.** We have adoption signal (fork ratio
123
+ well above the norm for a tool this size) but no named enterprise references.
124
+ - **No independent third-party benchmark placement.** The SWE-bench Verified
125
+ leaderboard is months stale and every entry on it is self-reported, ours would
126
+ be too.
127
+ - **No audit of the closed-source products.** We have verified that seven open
128
+ harnesses (OpenHands, Cline, Aider, SWE-agent, Roo-Code, OpenCode, Continue)
129
+ publish no machine-checkable completion artifact. Cursor, Devin, Replit Agent
130
+ and Claude Code we have **not** audited feature by feature, so treat the
131
+ receipt as "unclaimed as far as we can verify", not as a proven first.
132
+ - **Generation is not air-gapped.** See section 2.
133
+
134
+ ---
135
+
136
+ ## The one question worth asking any agent vendor
137
+
138
+ > When your agent says it finished, what artifact can I check that does not come
139
+ > from the agent's own narrative?
140
+
141
+ Ours is the Evidence Receipt, and section 1 is a two-minute test of whether the
142
+ answer holds up. Ask the same question everywhere else.
package/events/emit.sh CHANGED
@@ -71,6 +71,26 @@ safe_append_event_jsonl() {
71
71
  local max_attempts=100 # ~1s at 10ms sleep
72
72
  local stale_after=30
73
73
  while ! mkdir "$lock_dir" 2>/dev/null; do
74
+ # COUNT EVERY ITERATION, before any `continue` can skip the increment.
75
+ #
76
+ # This was the v8.1.0 fix's blind spot and it kept the P0 alive. Both
77
+ # `continue` paths below (lock vanished mid-stat; stale lock reclaimed)
78
+ # jumped PAST the increment that used to live at the bottom of the loop,
79
+ # so `max_attempts` was unreachable on those paths and the loop spun
80
+ # forever. Under concurrent emits the stale-reclaim path fires over and
81
+ # over, which is precisely the pathological case.
82
+ #
83
+ # MEASURED 2026-07-30, AFTER the v8.1.0 fix shipped: 63 orphaned
84
+ # emit.sh processes, oldest alive 10h51m, each burning ~5% CPU, machine
85
+ # at load 63 on 14 cores. Every orphan started after the fix landed.
86
+ # An unbounded wait whose only exit is a counter must increment that
87
+ # counter on EVERY path, or the bound is decorative.
88
+ attempts=$((attempts + 1))
89
+ if [ "$attempts" -ge "$max_attempts" ]; then
90
+ # Give up fast -- best-effort write so observability never blocks.
91
+ printf '%s\n' "$line" >> "$events_path" 2>/dev/null || true
92
+ return 0
93
+ fi
74
94
  # Check staleness EVERY iteration, not only after exhausting attempts.
75
95
  # The old code waited for all 500 attempts before its first staleness
76
96
  # check, so a stale lock cost ~5s AND ~500 forked sleep helpers per
@@ -90,12 +110,8 @@ safe_append_event_jsonl() {
90
110
  rmdir "$lock_dir" 2>/dev/null || rm -rf "$lock_dir" 2>/dev/null || true
91
111
  continue
92
112
  fi
93
- attempts=$((attempts + 1))
94
- if [ "$attempts" -ge "$max_attempts" ]; then
95
- # Give up fast -- best-effort write so observability never blocks.
96
- printf '%s\n' "$line" >> "$events_path" 2>/dev/null || true
97
- return 0
98
- fi
113
+ # (attempt counting and the give-up branch moved to the TOP of the loop
114
+ # so no `continue` can bypass them)
99
115
  # Sleep ~10ms WITHOUT forking when the shell supports fractional sleep
100
116
  # (bash's `read -t` needs no external process). perl/sleep are fallbacks.
101
117
  read -r -t 0.01 _unused_ < /dev/null 2>/dev/null \
@@ -117,6 +133,50 @@ fi
117
133
 
118
134
  set -euo pipefail
119
135
 
136
+ #-----------------------------------------------------------------------------
137
+ # SELF-REAPER: telemetry must never outlive the thing it observes.
138
+ #-----------------------------------------------------------------------------
139
+ # WHY A WATCHDOG AND NOT ANOTHER LOCK FIX. v8.1.0 fixed a specific unbounded
140
+ # wait (bare `flock -x`, and a staleness check that ran only after 500 attempts).
141
+ # It was a real fix and it was not sufficient: MEASURED 2026-07-30, AFTER that
142
+ # release, 63 orphaned emit.sh processes were alive on this machine, the oldest
143
+ # 10h51m, each burning ~5% CPU, contributing to load 63 on 14 cores. Every one
144
+ # of them started AFTER the fix landed, so whatever wedges emit.sh is not (only)
145
+ # the path that was fixed.
146
+ #
147
+ # The lesson is that patching each discovered hang is an arms race we keep
148
+ # losing, because a hang anywhere in this script has the same user-visible cost.
149
+ # emit.sh is FIRE-AND-FORGET telemetry: nothing waits on its result, and a
150
+ # dropped event is strictly cheaper than a wedged process. So instead of proving
151
+ # no path can block, we cap the lifetime of EVERY path.
152
+ #
153
+ # A background timer SIGKILLs this process after LOKI_EMIT_MAX_SECONDS (default
154
+ # 10). It is deliberately blunt: no cleanup hook, no graceful drain, because the
155
+ # failure mode being defended against is precisely "graceful paths did not run".
156
+ # The killer is disowned so it never becomes a job the parent shell waits on,
157
+ # and it exits immediately when the main process finishes normally.
158
+ #
159
+ # Set LOKI_EMIT_MAX_SECONDS=0 to disable (useful only when debugging emit.sh
160
+ # itself -- an operator who disables it is choosing the orphan risk knowingly).
161
+ _emit_max="${LOKI_EMIT_MAX_SECONDS:-10}"
162
+ case "$_emit_max" in ''|*[!0-9]*) _emit_max=10 ;; esac
163
+ if [ "$_emit_max" -gt 0 ]; then
164
+ _emit_target=$$
165
+ (
166
+ # Poll rather than one long sleep so the watchdog exits promptly on the
167
+ # normal path instead of lingering for the full window.
168
+ _waited=0
169
+ while [ "$_waited" -lt "$_emit_max" ]; do
170
+ sleep 1
171
+ kill -0 "$_emit_target" 2>/dev/null || exit 0
172
+ _waited=$((_waited + 1))
173
+ done
174
+ kill -9 "$_emit_target" 2>/dev/null || true
175
+ ) >/dev/null 2>&1 &
176
+ # Disown so the watchdog is not a tracked job of the caller's shell.
177
+ disown 2>/dev/null || true
178
+ fi
179
+
120
180
  # Configuration
121
181
  LOKI_DIR="${LOKI_DIR:-.loki}"
122
182
  EVENTS_DIR="$LOKI_DIR/events/pending"