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.
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/completion-council.sh +79 -15
- package/autonomy/loki +9 -4
- package/autonomy/run.sh +22 -3
- package/dashboard/__init__.py +1 -1
- package/docs/dev/architecture-reference.md +99 -0
- package/docs/dev/project-structure.md +134 -0
- package/docs/dev/release-checklist.md +157 -0
- package/docs/dev/research-foundation.md +29 -0
- package/docs/dev/tmp-cleanup.md +157 -0
- package/docs/v10/BOARD.md +95 -76
- package/docs/v10/DECISIONS.md +14 -0
- package/docs/v10/METRICS.md +33 -0
- package/docs/v10/OPERATING-MODEL.md +47 -0
- package/docs/v10/PROGRESS.md +173 -0
- package/docs/v10/SWARM.md +24 -0
- package/loki-ts/dist/loki.js +2 -2
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
package/docs/v10/DECISIONS.md
CHANGED
|
@@ -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.
|
package/docs/v10/METRICS.md
CHANGED
|
@@ -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.
|
package/docs/v10/PROGRESS.md
CHANGED
|
@@ -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
|
package/loki-ts/dist/loki.js
CHANGED
|
@@ -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.
|
|
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=
|
|
1352
|
+
//# debugId=BE3483EEAD4BDCD4D66273ADAB0A2BC0
|
package/mcp/__init__.py
CHANGED
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.
|
|
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.
|
|
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",
|