loki-mode 9.56.0 → 9.59.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.
@@ -195,3 +195,17 @@ One entry per decision: context, choice, why, how to reverse. Newest last.
195
195
  - Choice: build guards 1-3 now as slices through the normal review process (per the founder's own instruction: "each as a slice through normal review"), without interrupting or pushing anything onto the currently-frozen release train (train 1 remains frozen at `c31cb1e8` until Tests/Bun Parity/Security Audit are all green there). Guards 4-7 are process/documentation changes that also queue as slices, cut alongside 1-3, but are not blocking the reply the founder asked for (the founder's own instruction is to reply once guards 1-3 are live).
196
196
  - Why: this directive is itself direct, textbook evidence for guard 5's own thesis -- this session has repeatedly found and disclosed the SAME classes of near-miss (an agent spending disproportionate time/tokens on trivial work, a stuck background classification process, a BOARD.md edit that could have dropped rows, self-inflicted CI cancellation) as one-off narrative corrections in PROGRESS.md's drift audits, without ever converting any of them into a structural guard that makes the mistake mechanically non-repeatable. The founder's framing ("prompts drift; guards do not") is the correct fix for a pattern this session's own turn-102/120/132/138/144 audits kept re-discovering piecemeal.
197
197
  - Reverse: continue relying on per-turn discipline and drift-audit self-correction without codifying guards. Not chosen -- directly countermanded, and this session's own history is the founder's strongest evidence against it.
198
+
199
+ ## D27. 2026-09-27: Loki directive -- speed: a train every 20 minutes, CI replaces local gates, trains pipelined
200
+
201
+ - Context: train 2 sat unpushed for more than 89 minutes. The local-ci fast tier took more than 10 minutes under swarm load (90 of 173 checks at the 600s cap, EXIT=124), and the pre-push hook's serial pytest alone exceeded 10 minutes. The first push attempt was killed by its own timeout. The second reported success through a pipe while `git ls-remote` still showed b651b98d. Loki directed: push train 2 now with PRE_PUSH_SKIP=1 (Loki-authorized; CI is the gate), never pipe git push, and verify each push by ls-remote.
202
+ - Choice (Loki approved):
203
+ 1. The "Local CI Before Every Push" mandate (2026-07-31) is retired. Before a push, run only syntax checks (`bash -n`, `py_compile`) plus the slice's own tests, capped at 60 seconds. GitHub CI (Tier B) is the release gate.
204
+ 2. `.githooks/pre-push` becomes identity check + `bash -n` + red-main warning only (no pytest), target under 5 seconds; a LOW slice in train 3 (S-97).
205
+ 3. A push is done only when `git ls-remote origin refs/heads/main` equals `git rev-parse HEAD`; recorded as evidence and enforced by a guard (S-98).
206
+ 4. Train 3 carries the release-speed fixes first as each is approved (Part C items 1-7: S-79, S-80, S-84, S-81, the needs:gate removal inside S-84, S-82, S-83); other approved slices ride along but never delay a train.
207
+ 5. Trains are pipelined: a train counts as released when publish-npm succeeds. The next train opens immediately, without waiting for npm's availability lag, Docker or Homebrew; train N+1 can run Tier B while train N publishes.
208
+ 6. Cadence: push a train every 20 minutes whenever at least one merged slice exists, even a single one. New pulse violation TRAIN_LATE: more than 25 minutes since the last train push while merged-unreleased commits exist (S-98).
209
+ - Release Manager exception, disclosed: until S-16 makes `scripts/release.sh` bump every checklist file without prompting or pushing, the Release Manager bumps VERSION with the editor tool (not a shell command) as part of the release commit. v9.57.0 (5332bfc3) was bumped this way. This is the only permitted VERSION write outside release.sh, and it ends when S-16 merges.
210
+ - Evidence: train 2 push, `PRE_PUSH_SKIP=1 git push origin main` at 15:48:18Z: rc=0; `git rev-parse HEAD` = `git ls-remote origin refs/heads/main` = 89e350bd641a4b659faa405587a9db5bb7bcc201. Release push at 15:50:09Z: rc=0; both = 5332bfc35ccf801bdf8c67bff9fc07537ac4240f. The per-SHA concurrency from S-80 held on its first real push: Tests on 89e350bd kept running (`in_progress`) after 5332bfc3 was pushed.
211
+ - Reverse: keep local CI as a precondition. Not chosen: it cannot finish inside the 10-minute command cap under swarm load, and it duplicates GitHub CI.
@@ -123,3 +123,36 @@ ratchet-ordering deadlock: GF-4 cannot promote `P4.three-setups-resolve`
123
123
  out of pending.txt until S-19's stricter pass bar is also in the tree, or
124
124
  the merge itself becomes a ratchet regression. S-19 promoted to the
125
125
  critical path and reviewed immediately.
126
+
127
+ ## CI: Tests workflow shell-tests sharding (S-81, supersedes S-70)
128
+
129
+ S-70 resharded shell-tests 4 -> 8 with a plain `idx % n` split and measured
130
+ the real per-suite cost of doing so (see its commit, c6000cb9). S-81 keeps
131
+ n=8 but replaces the index split with a deterministic greedy longest-first
132
+ (LPT) bin-packing over measured per-suite durations, so the 8 shards are
133
+ balanced by real cost instead of by coincidence of registration order.
134
+
135
+ BEFORE numbers are measured from a real completed GitHub Actions run. AFTER
136
+ numbers are **projected from measured per-suite durations**, not measured --
137
+ this sandbox cannot trigger a real push, so nothing below claims to be a live
138
+ CI wall clock for the new packing until a real run confirms it.
139
+
140
+ | Metric | Value | Method |
141
+ |---|---|---|
142
+ | BEFORE: measured per-suite durations, source | real run 36319020918 (2026-09-27), 4 shard job logs, S-44's START/END lines | `gh run view --job <id> --log`, grepped for `END: ` |
143
+ | BEFORE: suites with a real measured row | 496 of 496 registered suites (100%; no suite needed the default) | exact-name join against `tests/run-all-tests.sh`'s `run_test` registrations |
144
+ | Deliberate override, not a measurement | `test-ci-json-argmax.sh` measured 1186s in that run; a parallel BACKLOG 25 slice is shrinking its fixture, so `tests/shard-durations.tsv` assumes ~60s post-fix and uses 60, not 1186 | documented in the table's own header comment |
145
+ | BEFORE (projected from measured per-suite durations): max shard at n=4, plain `idx % 4` (current main, pre-S-70/S-81) | 451s test-time (~7.5min) | `idx % 4` replay against `tests/shard-durations.tsv`'s same measured rows (single source run, n=1) |
146
+ | BEFORE (projected from measured per-suite durations): max shard at n=8, plain `idx % 8` (S-70's scheme) | 346s test-time (~5.8min) | same replay, `idx % 8` -- matches S-70's own commit projection (c6000cb9) of "~346s (~5.8min)" once argmax is fixed, cross-checked independently here |
147
+ | AFTER (projected from measured per-suite durations): max shard at n=8, LPT-packed (S-81, this change) | 197s test-time (~3.3min) -- every shard lands at exactly 197s, because 1576s total / 8 divides evenly against this suite set | replay of the actual `tests/run-all-tests.sh` LPT logic via `LOKI_TEST_SHARD=i/8 LOKI_TEST_LIST=1`, summed against `tests/shard-durations.tsv` |
148
+ | AFTER (projected from measured per-suite durations): max shard including ~29s job setup (checkout/pip/npm/bun, per S-70's measurement) | about 226s (about 3.8min), under the 6-minute target | same table + S-70's measured setup overhead |
149
+ | Named suites land in 5 distinct shards (required) | trust-core-detect -> shard 1, review-assurance-tail -> shard 0, e2e-features -> shard 4, shellcheck -> shard 2, no-unreachable -> shard 3 | same LPT replay |
150
+ | Partition proof | `tests/test-shard-coverage.sh`: n in [2, 3, 4, 6, 8] each give union=496, 0 duplicates, 0 missing, no empty shard -- driven through the real runtime path (`LOKI_TEST_LIST=1`), not a second copy of the packing algorithm | `bash tests/test-shard-coverage.sh` |
151
+
152
+ **What still needs real-CI verification** (cannot be done from this sandbox):
153
+ an actual GitHub Actions run of the updated `test.yml` at n=8 with the new
154
+ packing, to confirm the real wall clock lands near the ~3.8min projection
155
+ rather than something job-setup variance or GitHub's own queueing missed, and
156
+ that `test-ci-json-argmax.sh` actually lands near 60s once its BACKLOG 25
157
+ fixture fix ships (until then this table's 60s row is an assumption, not a
158
+ measurement, as stated in `tests/shard-durations.tsv`'s own header).
@@ -0,0 +1,47 @@
1
+ # Loki company operating model (always loaded; never exceed 90 lines)
2
+
3
+ The CEO is Lokesh Mure (Loki), the founder. Everyone else is an agent. The company ships Loki Mode v10 per docs/V10-VISION.md. Order when goals conflict: moat > Seal accuracy > delivered accuracy > cost > speed. Velocity target: 30-60 releases per day.
4
+
5
+ ## Roles and models (pin every agent's model explicitly, D13)
6
+ - Chief of Staff (the main session, opus): runs the operating rhythm, owns BOARD.md dispatch, keeps every seat busy, escalates only to Loki, never writes product code.
7
+ - CTO (opus, advisor): architecture and quality calls, approves any change to the moat, gates or release policy.
8
+ - Project Managers (opus, advisors): flow, bottlenecks, staffing. Each PM owns one workstream and its board rows.
9
+ - Architects (opus): split every large task into 10-40 independent slices with non-overlapping file sets and Wall checks. They design; they do not implement.
10
+ - Product Owners (sonnet): backlog ranking, slice cards (60 lines max: goal, file set, Wall checks, commands, budget, tier).
11
+ - Tech Leads (sonnet): LOW and MEDIUM reviews, unanimous (D12).
12
+ - Reviewers for HIGH-tier work (opus): moat, verifier, Seal, auth, security. Unanimous; a reproduced blocking finding always blocks (D12).
13
+ - Software Engineers (sonnet): one slice each, worktree isolation, single writer, red-then-green tests.
14
+ - Release Manager (sonnet, exactly one): the only role that pushes main, bumps VERSION, tags or publishes.
15
+
16
+ ## Leadership lock (one company per repo)
17
+ - The leader holds .loki/v10-leader (PID and start time). A session becomes leader only if that file is missing or its PID is dead (kill -0 fails).
18
+ - Non-leader sessions act as extra engineers or reviewers on BOARD.md slices, or answer Loki. They never push, bump VERSION, release or rewrite BOARD.md.
19
+
20
+ ## Nobody sits idle
21
+ - The Chief of Staff keeps 8-16 engineers busy whenever ready slices exist. When anyone finishes, the next slice is assigned in the same turn.
22
+ - The ready queue never drops below 2x the number of engineers; PMs and POs refill it.
23
+ - Idle seats while work exists, or an empty ready queue, is a P0 violation.
24
+
25
+ ## Time limits (anything slower gets redesigned, not waited on)
26
+ - Budgets: trivial ops use scripts, never agents (target under 10s). LOW engineer 15 min, MEDIUM 30 min. Reviewers 30 min, HIGH adversarial reviewer 60 min.
27
+ - Any shell command: timeout 10 min max; target under 2 min.
28
+ - An agent or command over budget is stopped, recorded in METRICS.md, and re-sliced smaller.
29
+
30
+ ## Release pipeline
31
+ - Tier A fast gate on every change (target 60-120s): syntax checks, changed-file shellcheck, diff-selected tests, moat suite split per property. It is feedback, not release authority.
32
+ - Tier B full verification on every main commit (target 5-6 min, hard 10 min per job, never cancelled on main).
33
+ - Release = a lookup: publish a commit whose tree already has a Tier B pass. A VERSION-only bump reuses its parent's verdict. Target: 2 min from verified to npm.
34
+ - Trains: the Release Manager batches merged slices; one push per train; releases when verified; the next train opens immediately. Never hold a train for one HIGH slice.
35
+ - If Tier B fails on main: stop releases, open a P0 fix-forward slice. Never unpublish; npm deprecate is allowed.
36
+
37
+ ## Large tasks (for example "rebuild the dashboard")
38
+ - The Architect splits the task into 10-40 slices behind a feature flag.
39
+ - Engineers build them in parallel; each merges and releases behind the flag as soon as it is green.
40
+ - The flag flips when the Wall checks for the whole feature pass.
41
+ - Releases never pause for a big task.
42
+
43
+ ## Discipline
44
+ - Evidence or it did not happen: every claim cites a command plus its exit code or output line.
45
+ - Every incident becomes a guard with a test (docs/v10/GUARDS.md, D26).
46
+ - The pulse block (scripts/v10-pulse.sh) is injected every turn. Act on the top VIOLATION first.
47
+ - Never kill by name or pattern, force-push, git add -A, or bypass branch protection.
@@ -1035,3 +1035,176 @@ else should take priority over.
1035
1035
  mean the SAME OS family as the failing CI job, not just "my own
1036
1036
  machine" -- a macOS-only local repro is not sufficient evidence to
1037
1037
  rule out a Linux-specific regression, ever.
1038
+
1039
+ - 2026-09-27T14:13Z: Tests rerun of shard 0 on `c31cb1e8` completed
1040
+ success (`gh run view 36321857199 --json status,conclusion` ->
1041
+ `completed success`). Train 1 verified: Tests and Bun Parity green on
1042
+ the frozen SHA.
1043
+ - 2026-09-27T14:16:24Z: pushed release commit `b651b98d` (v9.56.0,
1044
+ `c31cb1e8..b651b98d`). Only version strings, CHANGELOG and a fresh
1045
+ deterministic dist build on top of docs-only commits. Release run
1046
+ 36325316189, Tests 36325316218, Bun Parity 36325316184, Security
1047
+ Audit 36325316176 all started on `b651b98d`. Main frozen until publish.
1048
+ - Found while releasing: the committed loki-ts/dist was not a fresh
1049
+ build of src (a second local build was byte-identical to the first,
1050
+ so the build is deterministic; after normalizing minified identifiers
1051
+ the only semantic difference is the version string). Shipped the
1052
+ fresh build.
1053
+
1054
+ ## Drift audit, turn 174
1055
+
1056
+ **Matched:** the CEO directive's Part A shipped first: train 1 was
1057
+ verified on its frozen SHA and released as v9.56.0 before any Part C
1058
+ work merged. Leader lock taken (`.loki/v10-leader`, PID 74619). 6
1059
+ engineers and 10 reviewers dispatched in parallel on the named items;
1060
+ pulse `Active builder worktrees` rose from 5 to 19, clearing
1061
+ IDLE_BUILDERS. Trivial ops (committing finished builds, BOARD edits,
1062
+ version bump) were done directly, not by agents (D26 guard 2).
1063
+
1064
+ **Drifted, self-caught:** two builders (S-74, S-82) stopped short of
1065
+ committing and asked for approval, following the global
1066
+ approve-before-commit rule the repo's standing authorization waives.
1067
+ Fixed by committing their work directly; S-78 (CLAUDE.md trim) is the
1068
+ real fix, since it moves the operating model into every session.
1069
+ The release also surfaced a stale committed loki-ts/dist that no gate
1070
+ caught on train 1's own commit; the fast-tier dist-freshness check
1071
+ exists but the train skipped local-ci. Correction: run
1072
+ `bash scripts/local-ci.sh` (fast tier) on every train's freeze commit
1073
+ before pushing it, not only on release commits.
1074
+
1075
+ ## Drift audit, turn 180
1076
+
1077
+ **Near-miss caught, becomes a GUARDS.md entry (S-76):** S-72's
1078
+ worktree cleanup used "directory modified in the last 90 minutes" as
1079
+ its liveness signal. Its own `git -C <wt> status` calls refresh each
1080
+ worktree's index and touch mtimes (pulse jumped to "Active builder
1081
+ worktrees: 123 of 129"), so the signal went dead, and a live agent
1082
+ that has not yet committed or written a file looks safe by every
1083
+ other rule. Caught before any removal (agent reported "0 worktrees
1084
+ removed so far"). Fix applied: an explicit exclusion list of live and
1085
+ approved-unmerged worktrees, plus `.git` file birth time (`stat -f %B`)
1086
+ as the recency signal. Guard to build: the worktree-cleanup tool must
1087
+ take the live-agent list as input and must not use mtime.
1088
+
1089
+ **Matched:** trains stay frozen while v9.56.0 waits on Tests at
1090
+ b651b98d; all wave-2 slices build in parallel; every review that
1091
+ found a blocker went back to the same engineer with the reviewers'
1092
+ exact reproductions (S-73, S-74, S-75), not to a fresh agent.
1093
+
1094
+ ## Drift audit, turn 186
1095
+
1096
+ **Matched:** three reworks (S-74 round 2, S-75, S-18 round 3) came
1097
+ back within their budgets and each went straight to re-review with the
1098
+ prior reviewers' exact reproductions as the checklist. Reviews are
1099
+ finding real defects (S-73 x2 REJECT, S-74 CONCERN x2, S-75 REJECT),
1100
+ which is the review gate working, not noise.
1101
+
1102
+ **Drifted, recurring:** a third builder (S-85) stopped short of
1103
+ committing to "wait for approval" (S-74, S-82 did the same). Root cause
1104
+ is the old CLAUDE.md commit workflow text that every subagent loads;
1105
+ S-78's trim removes it. Until S-78 merges, slice cards should say
1106
+ "commit when done, you are authorized" explicitly.
1107
+
1108
+ ## Drift audit, turn 192
1109
+
1110
+ **Matched:** release train 1 is one job from publishing (only Tests
1111
+ shard 0, the argmax shard, still running on b651b98d); the two slices
1112
+ that remove that shard's cost (S-79 fixture shrink, S-81 balanced
1113
+ sharding) are built or nearly built. S-72 freed 12 GB with zero forced
1114
+ removals.
1115
+
1116
+ **Watch item:** a builder reported an unusually clean number (all 8
1117
+ shards projected at exactly 197 s). Reviewers are instructed to
1118
+ recompute it from the raw table rather than trust the report. Clean
1119
+ numbers get the same evidence bar as alarming ones.
1120
+
1121
+ ## Drift audit, turn 198
1122
+
1123
+ **Recurrence (guard review rule, D26 item 7):** the "temp file then
1124
+ replace narrows mode 644 -> 600" defect appeared twice this session:
1125
+ S-16 (scripts/release.sh, mktemp + mv) and now S-74 (v10-ops.sh,
1126
+ mkstemp + os.replace). Both were caught only by review. A recurrence
1127
+ means the fix-per-slice approach is wrong; the guard belongs in
1128
+ GUARDS.md (S-76): a shared helper for atomic in-place rewrite that
1129
+ copies mode and resolves symlinks, plus a fixture that asserts mode is
1130
+ preserved, and a lint that flags bare mkstemp/mktemp followed by a
1131
+ replace without a mode copy.
1132
+
1133
+ **Second recurring class:** locating a table cell by value shape
1134
+ instead of by header (S-74's Status-cell finder). The pulse's own
1135
+ BOARD parser (S-75) uses a position-independent shape scan too;
1136
+ S-75's reviewers found it safe because it requires a known token plus
1137
+ a full timestamp. Same rule should be written down once for every
1138
+ BOARD reader and writer.
1139
+
1140
+ **Matched:** release still gated only on Tests shard 0 at b651b98d;
1141
+ every finished build this turn went straight to review; three
1142
+ engineers again stopped short of committing, committed directly.
1143
+
1144
+ - 2026-09-27T14:42Z: Tests on b651b98d completed success (run
1145
+ 36325316218); Bun Parity (36325316184) and Security Audit
1146
+ (36325316176) also success. required-ci passed.
1147
+ - 2026-09-27T14:43:50Z: GitHub Release v9.56.0 published
1148
+ (`gh release view v9.56.0` publishedAt).
1149
+ - 2026-09-27T14:44:53Z: publish-npm job step "Publish to npm" success
1150
+ (`gh api .../jobs/108641497036`). At 14:45:06Z the registry still
1151
+ returned 404 for loki-mode@9.56.0: propagation window, re-checking.
1152
+ Docker publish still running.
1153
+
1154
+ ## Drift audit, turn 204
1155
+
1156
+ **Train 1 measured:** freeze push 13:17:07Z -> Tests green 14:13Z (one
1157
+ flaky-shard rerun) -> release commit push 14:16:24Z -> gates green
1158
+ 14:42Z -> GitHub Release 14:43:50Z -> npm publish step 14:44:53Z. About
1159
+ 26 min from release push to publish, almost all of it Tests on the
1160
+ release SHA re-running what c31cb1e8 had already verified. That is
1161
+ exactly the cost S-84 (verdict reuse) removes.
1162
+
1163
+ **Matched:** the release did not wait for any HIGH slice (S-18 is in
1164
+ round 4 and did not block, per D25).
1165
+
1166
+ ## Drift audit, turn 210
1167
+
1168
+ **npm propagation, not assumed:** 5 minutes after the publish-npm step
1169
+ ("npm publish --access public", exit 0 at 14:44:53Z) the registry still
1170
+ returns 404 for loki-mode@9.56.0 (curl registry.npmjs.org, bypassing
1171
+ the npm client cache; dist-tag latest 9.55.0). npm publish only exits 0
1172
+ after the registry accepts the package, so this is CDN or packument
1173
+ caching; memory records one prior case where six agreeing probes read a
1174
+ stale packument. Not republishing (the version would be rejected as a
1175
+ duplicate anyway). Re-checking; if still absent at +15 min, investigate
1176
+ with npm support channels, never republish or bump.
1177
+
1178
+ **Reviews keep finding real defects in fixes-to-fixes:** S-74 round 3
1179
+ fixed two bugs and introduced a third (short rows refused), caught
1180
+ because the reviewer measured the real board's row shapes instead of
1181
+ trusting a first-row-only test. Rule for slice cards touching BOARD.md
1182
+ tooling: test against every row of a copy of the real board, not a
1183
+ sample.
1184
+
1185
+ ## Turn 216 drift audit (2026-09-27T14:58Z)
1186
+ - Train 1 npm: publish-npm logged `+ loki-mode@9.56.0` and "being processed" at 14:44:51Z; registry still 404 at 14:57 (13 min). Not republishing; per the stale-packument lesson, repeated reads share one CDN cache and are not independent. publish-docker still in_progress (run 36325316189).
1187
+ - Pulse NO_RECENT_RELEASE reads npm, so it stays red until 9.56.0 is visible there. That is correct: npm is the channel users install from.
1188
+ - Drift caught: two MEDIUM builders (S-87, S-91) ran past 30 min without check-in. The newly merged S-75 pulse flagged them within minutes of landing. Guard 3 works.
1189
+ - Train 2 assembled on main: S-71, S-75, S-78, S-80, S-86, S-90 (8 commits). S-81 is held for S-79 (same runner file, and the argmax suite duration decides its packing); S-82 is held for shard times under 10 min.
1190
+
1191
+ ## Train 1 shipped to npm (2026-09-27T15:00Z)
1192
+ - npm: `curl registry.npmjs.org/loki-mode` gives dist-tags latest 9.56.0, time["9.56.0"] = 2026-09-27T15:00:06.452Z. publish-npm reported acceptance at 14:44:51Z, so npm took 15m15s to make it available. The 404s in between were npm's processing delay, not a failed publish; not republishing was correct.
1193
+ - publish-docker is still in_progress at 15:08 (run 36325316189).
1194
+ - Measurement for the Part C release-lookup target (2 min verified-to-npm): GitHub Release to npm availability was 16m16s, of which about 15 min is npm-side processing we do not control. The S-84 reuse only shortens required-ci.
1195
+
1196
+ ## Turn 240 drift audit (2026-09-27T15:24Z)
1197
+ - Near-miss, false green: the train 2 background push "completed (exit code 0)", but `git ls-remote origin refs/heads/main` still returned b651b98d. `timeout 600 git push ... | tail -5` reported tail's status, not the push's. The first attempt had already been killed by a 120s timeout during the pre-push hook's serial pytest. Correction: after every push, compare `git ls-remote` with `git rev-parse HEAD`; never trust a piped exit code. GUARDS.md candidate (S-76 follow-up): a push helper in scripts/v10-ops.sh that asserts remote == local.
1198
+ - The local-ci fast tier took more than 10 min under swarm load (90 of 173 checks at 600s, EXIT=124). Its one real failure (CLAUDE.md tool count after S-78) was fixed in 6f1e68eb. This conflicts with the 10-min command cap; S-91 (Tier A) is the planned replacement. Until then, release on GitHub CI plus the packaging checks run by hand (npm pack contents: 938 entries, 9/9 required).
1199
+ - Standing drift check: slices finished inside workflows leave BOARD rows at building until the orchestrator reads the result, which fed 5 false AGENT_OVER_BUDGET hits at 15:15. Read workflow results the same turn they complete.
1200
+
1201
+ ## Trains 2 and 3 under D27 (2026-09-27)
1202
+ | Time (UTC) | Event | Evidence |
1203
+ |---|---|---|
1204
+ | 15:36 | Train 2 assembled (12 slices); third push attempt still in the pre-push serial pytest | push-train2 log |
1205
+ | 15:47 | Loki directive D27 received; background push stopped (TaskStop bw1fgezxd) | |
1206
+ | 15:48:18-21 | Train 2 pushed: PRE_PUSH_SKIP=1 git push origin main, rc=0 | HEAD = ls-remote = 89e350bd641a4b659faa405587a9db5bb7bcc201 |
1207
+ | 15:50:09-12 | Train 2 release commit v9.57.0 pushed, rc=0 | HEAD = ls-remote = 5332bfc35ccf801bdf8c67bff9fc07537ac4240f |
1208
+ | 15:50 | S-80 verified on a real push: Tests on 89e350bd stayed in_progress after 5332bfc3 landed | gh run list |
1209
+ | 15:53:23-26 | Train 3 (S-79, S-81, S-82, S-83, S-85) plus release commit v9.58.0 pushed, rc=0 | HEAD = ls-remote = c2eccb21c1273b27a385aa785fedee3269c4f605 |
1210
+ - Next: each train counts as released when its publish-npm job succeeds. Train 4 opens now: S-84 (Part C items 3 and 5) once approved, plus S-97 and S-98 (D27 hook and cadence guard). Target push by 16:13 (20-minute cadence).
package/docs/v10/SWARM.md CHANGED
@@ -223,6 +223,30 @@ queue. Never unpublishes or deletes a version.
223
223
  agent-authored slices never combine untrusted input, an agent, and push
224
224
  rights either.
225
225
 
226
+ ## Slice card template
227
+
228
+ Binding: the orchestrator dispatches every builder and reviewer from a slice
229
+ card below, never from conversation history or its own recall of prior
230
+ turns -- the card is the sole source of scope for that agent. While the
231
+ swarm runs, the orchestrator's own live view stays limited to
232
+ `docs/v10/CONTROL.md`, the pulse block, and `docs/v10/BOARD.md`; it does not
233
+ re-derive scope from scrollback.
234
+
235
+ <!-- SLICE-CARD-TEMPLATE:START -->
236
+ Slice: S-<id>
237
+ Goal: <one sentence, the acceptance condition for this slice>
238
+ Tier: LOW | MEDIUM | HIGH
239
+ Model: <pinned model, e.g. opus, sonnet -- never inherited, see D13>
240
+ Budget: <minutes>
241
+ Files:
242
+ - <path>
243
+ - <path>
244
+ Wall checks:
245
+ - <command or assertion that must pass before review>
246
+ Commands:
247
+ - <exact shell command(s) the builder runs>
248
+ <!-- SLICE-CARD-TEMPLATE:END -->
249
+
226
250
  ## Metrics (appended to METRICS.md after every wave)
227
251
 
228
252
  - releases in the last 24h
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var ct=Object.create;var{getPrototypeOf:lt,defineProperty:OG,getOwnPropertyNames:it}=Object;var at=Object.prototype.hasOwnProperty;function ot($){return this[$]}var st,nt,rt=($,X,Q)=>{var z=$!=null&&typeof $==="object";if(z){var Z=X?st??=new WeakMap:nt??=new WeakMap,K=Z.get($);if(K)return K}Q=$!=null?ct(lt($)):{};let J=X||!$||!$.__esModule?OG(Q,"default",{value:$,enumerable:!0}):Q;for(let q of it($))if(!at.call(J,q))OG(J,q,{get:ot.bind($,q),enumerable:!0});if(z)Z.set($,J);return J};var Zq=($,X)=>()=>(X||$((X={exports:{}}).exports,X),X.exports);var tt=($)=>$;function et($,X){this[$]=tt.bind(null,X)}var B1=($,X)=>{for(var Q in X)OG($,Q,{get:X[Q],enumerable:!0,configurable:!0,set:et.bind(X,Q)})};var s=($,X)=>()=>($&&(X=$($=0)),X);var w5=import.meta.require;var HR={};B1(HR,{lokiDir:()=>h0,homeLokiDir:()=>GQ,findRepoRootForVersion:()=>LG,REPO_ROOT:()=>O1});import{resolve as h2,dirname as jG}from"path";import{fileURLToPath as $e}from"url";import{existsSync as Kq}from"fs";import{homedir as Xe}from"os";function Qe(){let $=UR;for(let X=0;X<6;X++){if(Kq(h2($,"VERSION"))&&Kq(h2($,"autonomy/run.sh")))return $;let Q=jG($);if(Q===$)break;$=Q}return h2(UR,"..","..","..")}function LG($){let X=$;for(let Q=0;Q<6;Q++){if(Kq(h2(X,"VERSION"))&&Kq(h2(X,"autonomy/run.sh")))return X;let z=jG(X);if(z===X)break;X=z}return h2($,"..","..","..")}function h0(){return process.env.LOKI_DIR??h2(process.cwd(),".loki")}function GQ(){return h2(Xe(),".loki")}var UR,O1;var k1=s(()=>{UR=jG($e(import.meta.url));O1=Qe()});import{readFileSync as ze}from"fs";import{resolve as Ze,dirname as Ke}from"path";import{fileURLToPath as Je}from"url";function L9(){if(t3!==null)return t3;let $="9.56.0";if(typeof $==="string"&&$.length>0)return t3=$,t3;try{let X=Ke(Je(import.meta.url)),Q=LG(X);t3=ze(Ze(Q,"VERSION"),"utf-8").trim()}catch{t3="unknown"}return t3}var t3=null;var Jq=s(()=>{k1()});var jR={};B1(jR,{runOrThrow:()=>Te,run:()=>X1,readStreamCapped:()=>qq,commandVersion:()=>Fe,commandExists:()=>g5,ShellError:()=>CG,MAX_STDOUT_BYTES:()=>OR});async function qq($,X=OR){let Q=$.getReader(),z=new TextDecoder,Z="",K=0;try{while(K<X){let{done:J,value:q}=await Q.read();if(J)break;if(!q)continue;if(K+=q.byteLength,K>X){let V=q.byteLength-(K-X);Z+=z.decode(q.subarray(0,V),{stream:!0});break}Z+=z.decode(q,{stream:!0})}Z+=z.decode()}finally{try{await Q.cancel()}catch{}Q.releaseLock()}return Z}async function X1($,X={}){let Q=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:X.env?{...process.env,...X.env}:process.env,cwd:X.cwd}),z,Z;if(X.timeoutMs&&X.timeoutMs>0)z=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}Z=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},X.timeoutMs);try{let[K,J,q]=await Promise.all([qq(Q.stdout),new Response(Q.stderr).text(),Q.exited]);return{stdout:K,stderr:J,exitCode:q}}finally{if(z)clearTimeout(z);if(Z)clearTimeout(Z)}}async function Te($,X={}){let Q=await X1($,X);if(Q.exitCode!==0)throw new CG(`command failed (${Q.exitCode}): ${$.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function g5($){let X=De($),Q=await X1(["sh","-c",`command -v ${X}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function De($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function Fe($,X="--version"){if(!await g5($))return null;let z=await X1([$,X],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var OR=16777216,CG;var y8=s(()=>{CG=class CG extends Error{message;exitCode;stdout;stderr;constructor($,X,Q,z){super($);this.message=$;this.exitCode=X;this.stdout=Q;this.stderr=z;this.name="ShellError"}}});function g2($){return Re?"":$}var Re,p0,$5,Z1,y61,A1,f1,m5,n;var e7=s(()=>{Re=(process.env.NO_COLOR??"").length>0;p0=g2("\x1B[0;31m"),$5=g2("\x1B[0;32m"),Z1=g2("\x1B[1;33m"),y61=g2("\x1B[0;34m"),A1=g2("\x1B[0;36m"),f1=g2("\x1B[1m"),m5=g2("\x1B[2m"),n=g2("\x1B[0m")});import{existsSync as fe}from"fs";async function Z2(){if(BQ!==void 0)return BQ;let $="/opt/homebrew/bin/python3.12";if(fe($))return BQ=$,$;let X=await g5("python3.12");if(X)return BQ=X,X;let Q=await g5("python3");return BQ=Q,Q}async function I4($,X={}){let Q=await Z2();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return X1([Q,"-c",$],X)}var BQ;var m2=s(()=>{y8()});var hR={};B1(hR,{runStatus:()=>J00});import{existsSync as u5,readFileSync as T9,readdirSync as xR,statSync as kR}from"fs";import{resolve as A5,basename as re}from"path";import{homedir as te}from"os";function SR($){let X=Math.trunc($);if(X>=1e6)return`${(Math.trunc(X/1e6*10)/10).toFixed(1)}M`;if(X>=1000)return`${(Math.trunc(X/1000*10)/10).toFixed(1)}K`;return String(X)}function yR($,X,Q){if(X===0)return null;let z=Math.trunc($*100/X),Z=Math.trunc($*Yq/X);if(Z>Yq)Z=Yq;let K=Yq-Z,J=$5;if(z>=80)J=p0;else if(z>=50)J=Z1;let q="=".repeat(Math.max(0,Z))+" ".repeat(Math.max(0,K)),V=SR($),Y=SR(X);return` ${f1}${Q}${n} ${J}[${q}]${n} ${z}% (${V} / ${Y})`}async function $00(){if(await g5("jq"))return!0;return process.stdout.write(`${p0}Error: jq is required but not installed.${n}
2
+ var ct=Object.create;var{getPrototypeOf:lt,defineProperty:OG,getOwnPropertyNames:it}=Object;var at=Object.prototype.hasOwnProperty;function ot($){return this[$]}var st,nt,rt=($,X,Q)=>{var z=$!=null&&typeof $==="object";if(z){var Z=X?st??=new WeakMap:nt??=new WeakMap,K=Z.get($);if(K)return K}Q=$!=null?ct(lt($)):{};let J=X||!$||!$.__esModule?OG(Q,"default",{value:$,enumerable:!0}):Q;for(let q of it($))if(!at.call(J,q))OG(J,q,{get:ot.bind($,q),enumerable:!0});if(z)Z.set($,J);return J};var Zq=($,X)=>()=>(X||$((X={exports:{}}).exports,X),X.exports);var tt=($)=>$;function et($,X){this[$]=tt.bind(null,X)}var B1=($,X)=>{for(var Q in X)OG($,Q,{get:X[Q],enumerable:!0,configurable:!0,set:et.bind(X,Q)})};var s=($,X)=>()=>($&&(X=$($=0)),X);var w5=import.meta.require;var HR={};B1(HR,{lokiDir:()=>h0,homeLokiDir:()=>GQ,findRepoRootForVersion:()=>LG,REPO_ROOT:()=>O1});import{resolve as h2,dirname as jG}from"path";import{fileURLToPath as $e}from"url";import{existsSync as Kq}from"fs";import{homedir as Xe}from"os";function Qe(){let $=UR;for(let X=0;X<6;X++){if(Kq(h2($,"VERSION"))&&Kq(h2($,"autonomy/run.sh")))return $;let Q=jG($);if(Q===$)break;$=Q}return h2(UR,"..","..","..")}function LG($){let X=$;for(let Q=0;Q<6;Q++){if(Kq(h2(X,"VERSION"))&&Kq(h2(X,"autonomy/run.sh")))return X;let z=jG(X);if(z===X)break;X=z}return h2($,"..","..","..")}function h0(){return process.env.LOKI_DIR??h2(process.cwd(),".loki")}function GQ(){return h2(Xe(),".loki")}var UR,O1;var k1=s(()=>{UR=jG($e(import.meta.url));O1=Qe()});import{readFileSync as ze}from"fs";import{resolve as Ze,dirname as Ke}from"path";import{fileURLToPath as Je}from"url";function L9(){if(t3!==null)return t3;let $="9.59.0";if(typeof $==="string"&&$.length>0)return t3=$,t3;try{let X=Ke(Je(import.meta.url)),Q=LG(X);t3=ze(Ze(Q,"VERSION"),"utf-8").trim()}catch{t3="unknown"}return t3}var t3=null;var Jq=s(()=>{k1()});var jR={};B1(jR,{runOrThrow:()=>Te,run:()=>X1,readStreamCapped:()=>qq,commandVersion:()=>Fe,commandExists:()=>g5,ShellError:()=>CG,MAX_STDOUT_BYTES:()=>OR});async function qq($,X=OR){let Q=$.getReader(),z=new TextDecoder,Z="",K=0;try{while(K<X){let{done:J,value:q}=await Q.read();if(J)break;if(!q)continue;if(K+=q.byteLength,K>X){let V=q.byteLength-(K-X);Z+=z.decode(q.subarray(0,V),{stream:!0});break}Z+=z.decode(q,{stream:!0})}Z+=z.decode()}finally{try{await Q.cancel()}catch{}Q.releaseLock()}return Z}async function X1($,X={}){let Q=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:X.env?{...process.env,...X.env}:process.env,cwd:X.cwd}),z,Z;if(X.timeoutMs&&X.timeoutMs>0)z=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}Z=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},X.timeoutMs);try{let[K,J,q]=await Promise.all([qq(Q.stdout),new Response(Q.stderr).text(),Q.exited]);return{stdout:K,stderr:J,exitCode:q}}finally{if(z)clearTimeout(z);if(Z)clearTimeout(Z)}}async function Te($,X={}){let Q=await X1($,X);if(Q.exitCode!==0)throw new CG(`command failed (${Q.exitCode}): ${$.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function g5($){let X=De($),Q=await X1(["sh","-c",`command -v ${X}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function De($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function Fe($,X="--version"){if(!await g5($))return null;let z=await X1([$,X],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var OR=16777216,CG;var y8=s(()=>{CG=class CG extends Error{message;exitCode;stdout;stderr;constructor($,X,Q,z){super($);this.message=$;this.exitCode=X;this.stdout=Q;this.stderr=z;this.name="ShellError"}}});function g2($){return Re?"":$}var Re,p0,$5,Z1,y61,A1,f1,m5,n;var e7=s(()=>{Re=(process.env.NO_COLOR??"").length>0;p0=g2("\x1B[0;31m"),$5=g2("\x1B[0;32m"),Z1=g2("\x1B[1;33m"),y61=g2("\x1B[0;34m"),A1=g2("\x1B[0;36m"),f1=g2("\x1B[1m"),m5=g2("\x1B[2m"),n=g2("\x1B[0m")});import{existsSync as fe}from"fs";async function Z2(){if(BQ!==void 0)return BQ;let $="/opt/homebrew/bin/python3.12";if(fe($))return BQ=$,$;let X=await g5("python3.12");if(X)return BQ=X,X;let Q=await g5("python3");return BQ=Q,Q}async function I4($,X={}){let Q=await Z2();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return X1([Q,"-c",$],X)}var BQ;var m2=s(()=>{y8()});var hR={};B1(hR,{runStatus:()=>J00});import{existsSync as u5,readFileSync as T9,readdirSync as xR,statSync as kR}from"fs";import{resolve as A5,basename as re}from"path";import{homedir as te}from"os";function SR($){let X=Math.trunc($);if(X>=1e6)return`${(Math.trunc(X/1e6*10)/10).toFixed(1)}M`;if(X>=1000)return`${(Math.trunc(X/1000*10)/10).toFixed(1)}K`;return String(X)}function yR($,X,Q){if(X===0)return null;let z=Math.trunc($*100/X),Z=Math.trunc($*Yq/X);if(Z>Yq)Z=Yq;let K=Yq-Z,J=$5;if(z>=80)J=p0;else if(z>=50)J=Z1;let q="=".repeat(Math.max(0,Z))+" ".repeat(Math.max(0,K)),V=SR($),Y=SR(X);return` ${f1}${Q}${n} ${J}[${q}]${n} ${z}% (${V} / ${Y})`}async function $00(){if(await g5("jq"))return!0;return process.stdout.write(`${p0}Error: jq is required but not installed.${n}
3
3
  `),process.stdout.write(`Install with:
4
4
  `),process.stdout.write(` brew install jq (macOS)
5
5
  `),process.stdout.write(` apt install jq (Debian/Ubuntu)
@@ -1349,4 +1349,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
1349
1349
  `),2}case"start":{let{runStart:z}=await Promise.resolve().then(() => (ut(),mt));return z(Q)}default:return process.stderr.write(`Unknown command: ${X}
1350
1350
  `),process.stderr.write(dt),2}}PR();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var N61=await B61(Bun.argv.slice(2));process.exit(N61);
1351
1351
 
1352
- //# debugId=AF4E056DAC4D3D5B742E33E3BB5AEAB7
1352
+ //# debugId=BE3483EEAD4BDCD4D66273ADAB0A2BC0
package/mcp/__init__.py CHANGED
@@ -75,4 +75,4 @@ try:
75
75
  except ImportError:
76
76
  __all__ = ['mcp']
77
77
 
78
- __version__ = '9.56.0'
78
+ __version__ = '9.59.0'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "loki-mode",
3
3
  "mcpName": "io.github.asklokesh/loki-mode",
4
- "version": "9.56.0",
4
+ "version": "9.59.0",
5
5
  "description": "Loki Mode by Autonomi. Autonomous spec-to-product system: takes a PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief to a deployed app via the RARV-C closure loop with 8 quality gates. Provider-agnostic (Claude Code, OpenAI Codex, Cline, Aider, opencode).",
6
6
  "keywords": [
7
7
  "agent",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "loki-mode",
4
4
  "displayName": "Loki Mode",
5
- "version": "9.56.0",
5
+ "version": "9.59.0",
6
6
  "description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 8 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
7
7
  "author": {
8
8
  "name": "Autonomi",