loki-mode 10.3.1 → 10.4.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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/bin/loki +28 -0
- package/dashboard/__init__.py +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/docs/v10/BOARD.md +18 -7
- package/docs/v10/GUARDS.md +45 -2
- package/docs/v10/MEDIUM-ANALYSIS.md +181 -0
- package/docs/v10/PROGRESS.md +8 -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/web-app/dist/assets/{AdminPage-Cbw_ElCY.js → AdminPage-DXFriVML.js} +1 -1
- package/web-app/dist/assets/{Avatar-BIPSPAq_.js → Avatar-p9ksx_eu.js} +1 -1
- package/web-app/dist/assets/{Badge-Ds9MSd7u.js → Badge-LNKA1VAh.js} +1 -1
- package/web-app/dist/assets/{Button-C0Flsmvz.js → Button-BubeNlVF.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-Bp1_2hHf.js → CockpitPage-Vmnn1kk_.js} +1 -1
- package/web-app/dist/assets/{ComparePage-BYUoDxD4.js → ComparePage-y4DEGPAX.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-2RVnleyJ.js → ErrorBoundary-DiuMh-ej.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-CsL2KIoA.js → EvidenceReceiptPanel-BTg9fL9S.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-CjtkXtH4.js → GitHubIssuesPanel-C4fuMrPb.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-Dn0MQlOl.js → GitHubPRsPanel-BdQsKH8b.js} +1 -1
- package/web-app/dist/assets/{HomePage-TK7wY27j.js → HomePage-E0Dp3m6N.js} +2 -2
- package/web-app/dist/assets/{LoginPage-IWO6iIbt.js → LoginPage-BsbNsjYW.js} +1 -1
- package/web-app/dist/assets/{MagicPage-BvXPjLPl.js → MagicPage-DGrIIo5Z.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-WB6chNRQ.js → MetricsPage-DLvKrowx.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-wHzb58is.js → NotFoundPage-B6jgGGXs.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-BvfgSuNH.js → ProjectPage-iu7achd2.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-Bc-XKOdi.js → ProjectsPage-zWcn06b3.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-BoasXtyi.js → SettingsPage-_HQ0UqwR.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-BQ3Oi2Kt.js → ShowcasePage-yAsWHQEg.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-D3mLoggO.js → SystemSettingsPage-DtZVxTJ2.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-BVO23r7A.js → TeamsPage-DDpGebPt.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-CiLaTDHP.js → TemplatesPage-BlOcIhIE.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-3DwL15aa.js → TerminalOutput-EiD6R33t.js} +1 -1
- package/web-app/dist/assets/{activity-nE9JBZE1.js → activity-DbmttG_6.js} +1 -1
- package/web-app/dist/assets/{bell-CRDj-S-l.js → bell-BVZdHdS9.js} +1 -1
- package/web-app/dist/assets/{bot-scrkkEwS.js → bot-CBpm5F9l.js} +1 -1
- package/web-app/dist/assets/{check-DB5UlEKq.js → check-NZElkYN9.js} +1 -1
- package/web-app/dist/assets/{chevron-left-DI1ZUltn.js → chevron-left-Bsj7g0Lx.js} +1 -1
- package/web-app/dist/assets/{circle-alert-DmjqpClG.js → circle-alert--R-03UOi.js} +1 -1
- package/web-app/dist/assets/{clock-CxOxLpB9.js → clock-DxURKFW-.js} +1 -1
- package/web-app/dist/assets/{cloud-Cioy4N3d.js → cloud-CwgZnGFX.js} +1 -1
- package/web-app/dist/assets/{code-xml-XGTyeaui.js → code-xml-DbI4aSEX.js} +1 -1
- package/web-app/dist/assets/{database-DxNOgRAL.js → database-DyH1aJKS.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-DkudXWee.js → dollar-sign-DcirTDYQ.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-DD1ALh56.js → file-code-corner-D25VLaas.js} +1 -1
- package/web-app/dist/assets/{file-plus-DRKBaZOM.js → file-plus-CXZAUQHR.js} +1 -1
- package/web-app/dist/assets/{globe-Cx9Kefsu.js → globe-fb7DDJvp.js} +1 -1
- package/web-app/dist/assets/{hammer-DHivTbzj.js → hammer-B0CgWTnB.js} +1 -1
- package/web-app/dist/assets/{index-CZUWd8_O.js → index-h49hpHj_.js} +2 -2
- package/web-app/dist/assets/{layers-BK9AO5zh.js → layers-D7e5s5oV.js} +1 -1
- package/web-app/dist/assets/{loader-circle-BlQhXbH7.js → loader-circle-CuJseaIc.js} +1 -1
- package/web-app/dist/assets/{lock-CUd78HQV.js → lock-AWuJecY0.js} +1 -1
- package/web-app/dist/assets/{package-DqgAeAvu.js → package-FOl48t3g.js} +1 -1
- package/web-app/dist/assets/{plus-BnNbuEwQ.js → plus-B0rvkQ0K.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-BA2qvce4.js → refresh-cw-9k6QfjLX.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-BRWuu0SG.js → rotate-ccw-BKfPqp6g.js} +1 -1
- package/web-app/dist/assets/{scroll-text-BesWiqca.js → scroll-text-VliGSgXD.js} +1 -1
- package/web-app/dist/assets/{server-BcALRvWT.js → server-CDRRtXH3.js} +1 -1
- package/web-app/dist/assets/{shield-alert-B9lelKUZ.js → shield-alert-BudxBT3Y.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-kvcd_6aB.js → thumbs-up-DG8YD2t0.js} +1 -1
- package/web-app/dist/assets/{trash-2-yVZSntnY.js → trash-2-C3OCq0ib.js} +1 -1
- package/web-app/dist/assets/{trending-down-BrJ1Rg6x.js → trending-down-DdhqjRcI.js} +1 -1
- package/web-app/dist/assets/{trending-up-B8KBS1fi.js → trending-up-DeiXF7_i.js} +1 -1
- package/web-app/dist/assets/{upload-DT3f6xVq.js → upload-TsptvdQm.js} +1 -1
- package/web-app/dist/assets/{usePolling-DqdFR9Fb.js → usePolling-CtO3JeYc.js} +1 -1
- package/web-app/dist/assets/{user-mEyKrfXr.js → user-LzUg4eFF.js} +1 -1
- package/web-app/dist/index.html +1 -1
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: Autonomous spec-driven build system with a built-in trust layer. It does not call work done until it is verified (RARV-C closure loop, 8 quality gates, completion council, verified-completion evidence gate). Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v10.
|
|
6
|
+
# Loki Mode v10.4.1
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -470,4 +470,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
|
|
|
470
470
|
|
|
471
471
|
---
|
|
472
472
|
|
|
473
|
-
**v10.
|
|
473
|
+
**v10.4.1 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
10.
|
|
1
|
+
10.4.1
|
package/bin/loki
CHANGED
|
@@ -243,6 +243,34 @@ if [ "${LOKI_LEGACY_BASH:-0}" = "1" ] || [ "${LOKI_LEGACY_BASH:-}" = "true" ]; t
|
|
|
243
243
|
exec "$BASH_CLI" "$@"
|
|
244
244
|
fi
|
|
245
245
|
|
|
246
|
+
# M-08 (docs/v10/MODERNIZE.md section 2): the NEW `loki modernize <repo> --to
|
|
247
|
+
# <target>` form always reaches the Loki 10 (Bun) modernize CLI, regardless of
|
|
248
|
+
# LOKI_ENGINE or the default engine flip. Ahead of the v10 block below so
|
|
249
|
+
# tonight's legacy default never blocks it; $1 is already "modernize" so "$@"
|
|
250
|
+
# reproduces it as the router's own first argument without a shift.
|
|
251
|
+
#
|
|
252
|
+
# `loki modernize` is ALSO an existing legacy noun (autonomy/loki cmd_modernize,
|
|
253
|
+
# `heal`/`migrate` subcommands, documented in README.md and
|
|
254
|
+
# wiki/CLI-Reference.md): a plain catch-all here broke `loki heal`/`loki
|
|
255
|
+
# migrate` forwarding parity and `modernize bogus`'s error-channel contract
|
|
256
|
+
# (tests/cli/test-alias-forwarding.sh). --to is the one flag every valid
|
|
257
|
+
# engine10 invocation requires (modernize/cli.ts: "missing --to" otherwise), so
|
|
258
|
+
# it is the routing signal: only args containing --to go to engine10; bare
|
|
259
|
+
# `modernize`, `--help`/`-h`/`help`, `heal`, `migrate`, and any other token
|
|
260
|
+
# fall through unchanged to the existing dispatch below, which already sends
|
|
261
|
+
# them to the legacy CLI today. (`--help`'s own content -- whether it should
|
|
262
|
+
# also mention heal/migrate -- is modernize/cli.ts's USAGE text, outside this
|
|
263
|
+
# arm's file set; left unchanged.)
|
|
264
|
+
if [ "${1:-}" = "modernize" ]; then
|
|
265
|
+
for _loki_mod_a in "$@"; do
|
|
266
|
+
if [ "$_loki_mod_a" = "--to" ]; then
|
|
267
|
+
command -v bun >/dev/null 2>&1 || { echo "Error: loki modernize needs bun." >&2; exit 1; }
|
|
268
|
+
exec bun "$BUN_CLI" engine10 "$@"
|
|
269
|
+
fi
|
|
270
|
+
done
|
|
271
|
+
unset _loki_mod_a
|
|
272
|
+
fi
|
|
273
|
+
|
|
246
274
|
# Loki 10 engine (D29): additive; skipped entirely unless LOKI_ENGINE=v10.
|
|
247
275
|
if [ "${LOKI_ENGINE:-}" = "v10" ]; then
|
|
248
276
|
_e10=0
|
package/dashboard/__init__.py
CHANGED
package/docs/INSTALLATION.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The flagship product of [Autonomi](https://www.autonomi.dev/). Loki Mode is a spec-driven autonomous builder with a built-in trust layer that takes any spec to a deployed product and verifies completion with evidence (quality gates plus a completion council), not just a "done" claim. Complete installation instructions for all platforms and use cases.
|
|
4
4
|
|
|
5
|
-
**Version:** v10.
|
|
5
|
+
**Version:** v10.4.1
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
package/docs/v10/BOARD.md
CHANGED
|
@@ -359,7 +359,7 @@ set is declared to avoid overlap with those and with each other.
|
|
|
359
359
|
| M-05 | SCC clustering, 1,500-line unit cap, topological waves | loki-ts/src/engine10/modernize/cluster.ts, loki-ts/tests/engine10/modernize/cluster.test.ts | MEDIUM | cd loki-ts && bun test tests/engine10/modernize/cluster.test.ts | released@2026-09-28T05:00Z | Source: MODERNIZE.md (D30). Depends on M-02. Built on branch worktree-wf_4601e7b3-4d8-4 (777f6cdd M-01, 212a7404 M-02, 6b00c05c M-05, 3d8edb5d M-06). TL CONCERN: cluster.ts tarjanSCC recursion overflows the stack on dependency chains of about 20-50k nodes (the M-28/M-29 scale); needs an iterative SCC. Wave E18 rework: iterative Tarjan, branch slice-M-05-iterative-scc. TL APPROVE (sonnet): iterative Tarjan 372ebe11, red on recursive (RangeError), 2000/2000 fuzz identical; merged f4d98c0b, `bun test tests/engine10/modernize/` 28 pass 0 fail. Released in v10.1.0 (npm publish 2026-09-28T05:00Z; every cited commit is an ancestor of the v10.1.0 tag; `git merge-base --is-ancestor`). |
|
|
360
360
|
| M-06 | Up-front estimate (cost, time, risk), --budget math, --dry-run print | loki-ts/src/engine10/modernize/estimate.ts, loki-ts/tests/engine10/modernize/estimate.test.ts | LOW | cd loki-ts && bun test tests/engine10/modernize/estimate.test.ts | released@2026-09-28T05:00Z | Source: MODERNIZE.md (D30). Depends on M-05. Built on branch worktree-wf_4601e7b3-4d8-4 (777f6cdd M-01, 212a7404 M-02, 6b00c05c M-05, 3d8edb5d M-06). TL CONCERN: cluster.ts tarjanSCC recursion overflows the stack on dependency chains of about 20-50k nodes (the M-28/M-29 scale); needs an iterative SCC. Wave E18 with M-05, branch slice-M-05-iterative-scc. Merged f4d98c0b with M-05. Released in v10.1.0 (npm publish 2026-09-28T05:00Z; every cited commit is an ancestor of the v10.1.0 tag; `git merge-base --is-ancestor`). |
|
|
361
361
|
| M-07 | modernize CLI and flag parsing; TABLE route in engine10 cli | loki-ts/src/engine10/modernize/cli.ts, loki-ts/src/engine10/cli.ts (TABLE and USAGE line only), loki-ts/tests/engine10/modernize/cli.test.ts | MEDIUM | cd loki-ts && bun test tests/engine10/modernize/cli.test.ts | merged@2026-09-28T18:25Z | Source: MODERNIZE.md (D30). Depends on M-06, E-31 merged or parked. Wave E21 (wf_39ab3f7d-8f3). TL APPROVE of 13848b53, but merged after E-66/E-61/M-24 core reads exactly 5,000 (cap is under 5,000). Next: net core delta at most -1 (offset in cli.ts or dead core code), then merge. r2 TL REJECT (reproduced): modernize/cli.ts TABLE-routed but not in registry.ts (registry.test.ts red when merged); report claimed 40/0 but 39/1; --help lost its modernize line. Next: register it, keep the USAGE line, offset core elsewhere. Wave E26 (wf_9ba5fcaf-75a). Round 4. r4 3c73b6cb honest (unsquashed) version; its only blocking finding (core 5,000) no longer reproduces after E-67 removed escalate.ts: merged 02c30314, core 4,977, budget/registry/cli tests 41 pass 0 fail, `bun test tests/engine10/` 654 pass (1 load-timeout, 35/0 alone), dist 18 passed. |
|
|
362
|
-
| M-08 | bin/loki modernize arm to engine10 regardless of default | bin/loki (modernize arm only), tests/test-modernize-dispatch.sh | MEDIUM | bash tests/test-modernize-dispatch.sh |
|
|
362
|
+
| M-08 | bin/loki modernize arm to engine10 regardless of default | bin/loki (modernize arm only), tests/test-modernize-dispatch.sh | MEDIUM | bash tests/test-modernize-dispatch.sh | merged@2026-09-28T19:13Z | Source: MODERNIZE.md (D30). Depends on M-07. Dispatched 18:58Z, sonnet engineer. Tech Lead REJECT r1 (engine10-dispatch count) and r2 (shadowed legacy modernize heal/migrate: alias-forwarding 204/9); APPROVE r3 766a493b (engine10 only when --to present). Merged; modernize-dispatch 18/0, engine10-dispatch 35/0, alias-forwarding 213/0 (main baseline), shard coverage 19/0, drift 6/0. |
|
|
363
363
|
| M-09 | py2/3 capture tracer with type-tagged JSON and branch coverage | autonomy/lib/modernize/py_capture.py, tests/test-modernize-py-capture.sh, tests/fixtures/modernize/py2/ | HIGH | bash tests/test-modernize-py-capture.sh | released@2026-09-28T14:26Z | Source: MODERNIZE.md (D30). Depends on M-01. Built a4fbf034 (branch worktree-wf_4601e7b3-4d8-5). Opus REJECT (reproduced): unsupported types (sets, Decimal, datetime, bytearray, custom classes) record as equal with no not_proven entry, so the oracle could certify unproven equivalence. Next: rework. Wave E18 rework: unsupported types yield not_proven, branch slice-M-09-not-proven-types. Opus REJECT of 3594eee5: subclasses of supported types (namedtuple, IntEnum, OrderedDict) tag as the base type with no not_proven. Rework wave E19. Rework 085bc2e0 Opus APPROVE; merged b8d40a34; `bash tests/test-modernize-py-capture.sh` Passed 50 Failed 0 Skipped 1 (no python2). Released in v10.1.1 (npm publish 2026-09-28T14:26Z; every cited commit is an ancestor of the v10.1.1 tag; `git merge-base --is-ancestor`). |
|
|
364
364
|
| M-10 | Coverage-guided input search (read-only session, plateau stop) | loki-ts/src/engine10/modernize/oracle/search.ts, loki-ts/tests/engine10/modernize/search.test.ts | HIGH | cd loki-ts && bun test tests/engine10/modernize/search.test.ts | merged@2026-09-28T17:20Z | Source: MODERNIZE.md (D30). Depends on M-09. Opus REJECT (reproduced): a failed seed capture is reported as a plateau. Next: rework. r2 d7db4fb1 Opus APPROVE; merged dc827b80 (on top of v10.2.2): full `cd loki-ts && bun test` 2277 pass 0 fail, `bash tests/test-engine10-dist.sh` 18 passed, `bash tests/test-v10-pulse.sh` 117 passed. |
|
|
365
365
|
| M-11 | Java capture: JUnit under JDK 8 with JaCoCo plus Randoop | autonomy/lib/modernize/java_capture.sh, loki-ts/src/engine10/modernize/oracle/java.ts, loki-ts/tests/engine10/modernize/java_capture.test.ts | HIGH | cd loki-ts && bun test tests/engine10/modernize/java_capture.test.ts | merged@2026-09-28T18:25Z | Source: MODERNIZE.md (D30). Depends on M-04. Opus REJECT (reproduced): multi-line java -version breaks status.json (json_escape skips newlines). Next: rework. Wave E26 (wf_9ba5fcaf-75a). Round 3. r3 e476435b opus APPROVE (every C0 byte escaped as \u00XX; malformed status.json reported as its own reason); merged locally. |
|
|
@@ -430,16 +430,27 @@ set is declared to avoid overlap with those and with each other.
|
|
|
430
430
|
| DEP-05 | npm/bun patch and minor batch from docs/v10/DEPS.md (web-app, dashboard-ui, vscode-extension, root; lockfiles regenerated and committed; 0.x packages excluded) | the package.json and lockfiles DEPS.md names for patch/minor only | LOW | npm audit: no new high or critical; hallucinated-dependency guard rc=0; full Tier B plus the moat suite on a PR run | ready@2026-09-28T17:45Z | Source: DEP-01 inventory (D35). |
|
|
431
431
|
| DEP-06 | Python patch and minor batch from docs/v10/DEPS.md (dashboard, mcp, web-app requirements, sdk/python pyproject; 0.x excluded) | those requirements*.txt and pyproject.toml | LOW | pip-audit: no new high or critical; guard rc=0; PR run of Tests conclusion success (run id cited) | ready@2026-09-28T17:45Z | Source: DEP-01 (D35). |
|
|
432
432
|
| DEP-07 | SHA-pin every remaining tag-pinned action already on its latest major (anchore/sbom-action, anthropics/claude-code-action, contributor-assistant/github-action, oven-sh/setup-bun) with a version comment | .github/workflows/*.yml (those uses: lines only) | LOW | every uses: is a full SHA with a vX comment; actionlint rc=0; PR run | ready@2026-09-28T17:45Z | Source: DEP-01 (D35). Serialize after DEP-02/DEP-03 merge (same files). |
|
|
433
|
-
| G-01 | Usage governor (D39): scripts/usage-governor.py sums usage (output, input, cache read, cache write) from ~/.claude/projects/**/*.jsonl per model, role (from workflow labels and agent types where recorded) and hour; stores founder plan-percentage readings (docs/v10/usage-readings.tsv) and fits tokens-per-percent as a labelled estimate; projects 5-hour window and weekly usage; outputs max engineers for the next hour; checks and records whether Claude Code exposes plan usage directly (statusline input rate-limit fields, /usage) and uses it when it does | scripts/usage-governor.py, docs/v10/usage-readings.tsv, tests/test-usage-governor.sh | HIGH | fixture jsonl plus readings gives a stated projection and max-engineer number; missing readings reads "uncalibrated", never a number presented as fact |
|
|
434
|
-
| G-02 | Pulse BUDGET_BURN and OPUS_SHARE violations plus an hourly METRICS.md usage section (tokens per role and model, cost per merged slice, window and weekly projections, max engineers, releases per hour, merged slices per hour and per million tokens), all from G-01 | scripts/v10-pulse.sh (two checks), tests/test-v10-pulse.sh, docs/v10/METRICS.md (section header only) | MEDIUM | fixtures: opus 31% fires OPUS_SHARE; a projection of 86% fires BUDGET_BURN; uncalibrated reads UNKNOWN |
|
|
435
|
-
| G-03 | docs/v10/SCALE.md: what the Max 20x plan sustains around the clock (from G-01 measurements and calibration), what 50 parallel engineers need (API pay-as-you-go with a rate-limit tier, or Team/Enterprise), cost per day estimates labelled as estimates, and the ramp gates (governor allows, merged slices per hour rising, merged work per token not falling) | docs/v10/SCALE.md | HIGH | every number cites a measurement or is labelled an estimate with its basis |
|
|
433
|
+
| G-01 | Usage governor (D39): scripts/usage-governor.py sums usage (output, input, cache read, cache write) from ~/.claude/projects/**/*.jsonl per model, role (from workflow labels and agent types where recorded) and hour; stores founder plan-percentage readings (docs/v10/usage-readings.tsv) and fits tokens-per-percent as a labelled estimate; projects 5-hour window and weekly usage; outputs max engineers for the next hour; checks and records whether Claude Code exposes plan usage directly (statusline input rate-limit fields, /usage) and uses it when it does | scripts/usage-governor.py, docs/v10/usage-readings.tsv, tests/test-usage-governor.sh | HIGH | fixture jsonl plus readings gives a stated projection and max-engineer number; missing readings reads "uncalibrated", never a number presented as fact | merged@2026-09-28T19:09Z | Source: founder 17:44Z. First in the queue; everything obeys it. r2 de8e1f76 opus REJECT: weekly reset 1h off across DST; fixes 2 and 4 unguarded. r3 dispatched 19:00Z. r3 fa279532 opus APPROVE (DST reset fixed; fixes 2 and 4 mutation-guarded by T14/T15); merged c2ae4347; governor 25/0, logger 16/0, run-shellcheck.sh passes, shard coverage 19/0, drift 6/0. Open non-blocking: weekly tokens counted from computed Wednesday not live resets_at-7d; no test for live-reset preference; "uncalibrated" label when idle. |
|
|
434
|
+
| G-02 | Pulse BUDGET_BURN and OPUS_SHARE violations plus an hourly METRICS.md usage section (tokens per role and model, cost per merged slice, window and weekly projections, max engineers, releases per hour, merged slices per hour and per million tokens), all from G-01 | scripts/v10-pulse.sh (two checks), tests/test-v10-pulse.sh, docs/v10/METRICS.md (section header only) | MEDIUM | fixtures: opus 31% fires OPUS_SHARE; a projection of 86% fires BUDGET_BURN; uncalibrated reads UNKNOWN | building@2026-09-28T19:09Z | Source: founder 17:44Z. Depends on G-01. Serialize after E-89..E-91 (same file). Dispatched 19:09Z, sonnet engineer (G-01 merged; goes before E-90/E-91, which rebase after). |
|
|
435
|
+
| G-03 | docs/v10/SCALE.md: what the Max 20x plan sustains around the clock (from G-01 measurements and calibration), what 50 parallel engineers need (API pay-as-you-go with a rate-limit tier, or Team/Enterprise), cost per day estimates labelled as estimates, and the ramp gates (governor allows, merged slices per hour rising, merged work per token not falling) | docs/v10/SCALE.md | HIGH | every number cites a measurement or is labelled an estimate with its basis | merged@2026-09-28T19:09Z | Source: founder 17:44Z. CTO (opus) authors. Billing is the founder decision. Merged as 4708cee1 (row status was stale). |
|
|
436
436
|
| G-04 | Cloud fan-out (HIGH, CTO-owned): dispatch ready slices with no file overlap with in-flight work as Claude Code cloud sessions that open PRs from their own branches; the Release Manager merges PRs whose checks concluded success with gh pr merge; every dispatch recorded in BOARD.md with its cloud session id; ramp 25 to 50 only when the governor allows and merged slices per hour rose | scripts/cloud-dispatch.sh, docs/v10/SWARM.md (one section), tests/test-cloud-dispatch.sh | HIGH | dry-run dispatch prints the exact command and the BOARD row it would write; refuses when the governor max is reached or file sets overlap | ready@2026-09-28T17:50Z | Source: founder 17:44Z. Depends on G-01 (governor) and G-03 (plan ceiling). Verify the real cloud-session CLI syntax before building. |
|
|
437
437
|
| G-05 | The same fan-out as loki modernize remote-worker mode (POST /jobs kind unit, Helm worker.engine v10): align G-04 with M-23 | (design note in docs/v10/MODERNIZE.md, one section) | MEDIUM | the note maps G-04 dispatch fields to the M-23 job schema | ready@2026-09-28T17:50Z | Source: founder 17:44Z. Depends on G-04 and M-17. |
|
|
438
|
-
| EV-15 | Re-run the medium tier (7 tasks, raw and v10, 2 runs each, same model) with every result file written under ~/loki-ci-logs/eval/ev15-<arm>-r<n>/ (outside any worktree) and a per-task table of which runs failed and why (hidden-test failure, timeout, no PR, cost) | eval/loki10 results (outside the repo), docs/v10/METRICS.md (one section) | HIGH | 28 rows, 0 arm_unavailable; per-task failure reasons cited from the result files |
|
|
439
|
-
| E-98 | Diagnose why v10 loses to raw on medium (EV-15 per-task failures): for each task v10 failed and raw completed, read the v10 run log and name the stage and cause (plan, Wall, implement, verify, fix rounds, cap), then cut fix slices | docs/v10/ENGINE.md (findings section) | HIGH | each finding cites a result file path and a log line |
|
|
438
|
+
| EV-15 | Re-run the medium tier (7 tasks, raw and v10, 2 runs each, same model) with every result file written under ~/loki-ci-logs/eval/ev15-<arm>-r<n>/ (outside any worktree) and a per-task table of which runs failed and why (hidden-test failure, timeout, no PR, cost) | eval/loki10 results (outside the repo), docs/v10/METRICS.md (one section) | HIGH | 28 rows, 0 arm_unavailable; per-task failure reasons cited from the result files | merged@2026-09-28T19:40Z | Source: EV-14 evidence lost (17:36Z incident) and v10 lost on all three medium axes. Governor-gated (paid run). D40 priority 1: running (wf_4af22d00-9fb), results under ~/loki-ci-logs/eval. Done 19:19Z: raw 10/14 $0.5085 p50 56s; v10 9/14, cost at least $0.788 (E-98 correction) p50 128s. Files durable under ~/loki-ci-logs/eval/ev15-*. |
|
|
439
|
+
| E-98 | Diagnose why v10 loses to raw on medium (EV-15 per-task failures): for each task v10 failed and raw completed, read the v10 run log and name the stage and cause (plan, Wall, implement, verify, fix rounds, cap), then cut fix slices | docs/v10/ENGINE.md (findings section) | HIGH | each finding cites a result file path and a log line | merged@2026-09-28T19:40Z | Source: EV-14. Depends on EV-15. CTO (opus) analysis. D40 priority 1: CTO analysis runs after EV-15 in the same workflow. docs/v10/MEDIUM-ANALYSIS.md merged d496db89. Top cause: verify hard-codes python, so 27/27 pytest checks were not_run and no fix round ever fired. Cards E-98a..f below. |
|
|
440
|
+
| E-98a | verify uses the project interpreter (.venv, venv, $VIRTUAL_ENV, python3, python); a check on a system interpreter adds a not_proven line | loki-ts/src/engine10/stages/verify.ts, loki-ts/tests/engine10/verify*.test.ts | HIGH | fixture red then green (.venv shim, no python on PATH); core +12 max | building@2026-09-28T19:40Z | Source: MEDIUM-ANALYSIS.md. Dispatched 19:40Z sonnet; opus review. |
|
|
441
|
+
| E-98b | a spec_conflict implement exit still runs verify and fix; receipt keeps SPEC_CONFLICT | loki-ts/src/engine10/machine.ts, loki-ts/tests/engine10/machine*.test.ts | HIGH | fake-stage test red on main; core +3 max | building@2026-09-28T19:40Z | Source: MEDIUM-ANALYSIS.md. Dispatched 19:40Z sonnet; opus review. |
|
|
442
|
+
| E-98c | existing test files append-only in the implement brief; impactedTests falls back to named files when relevant_files is empty | loki-ts/src/engine10/stages/implement.ts, its test | MEDIUM | unit test red then green; core +2 max | building@2026-09-28T19:40Z | Source: MEDIUM-ANALYSIS.md. Dispatched 19:40Z sonnet. |
|
|
443
|
+
| E-98d | repo map extracts Python top-level def and class names | loki-ts/src/engine10/repomap.ts, loki-ts/tests/engine10/repomap*.test.ts | MEDIUM | unit test red then green; core +4 max | building@2026-09-28T19:40Z | Source: MEDIUM-ANALYSIS.md. Dispatched 19:40Z sonnet. Offline 7-repo check runs after merge. |
|
|
444
|
+
| E-98e | a session killed at its stage limit writes a partial-stream cost record, never cost_usd null | loki-ts/src/engine10/session.ts, loki-ts/src/engine10/cost.ts, a test | MEDIUM | fake killed stream test red then green; core +10 max | building@2026-09-28T19:40Z | Source: MEDIUM-ANALYSIS.md. Dispatched 19:40Z sonnet. |
|
|
445
|
+
| E-98f | A/B eval of Wall and cascade on medium (default, WALL=0, CASCADE=0, n=3 each), then a sizing default only if a knob wins on completions without losing on cost | eval run; loki-ts/src/engine10/sizing.ts | HIGH | chosen default at or above raw 71.4% and below $0.5085 per completed; after table published in MEDIUM-ANALYSIS.md | ready@2026-09-28T19:40Z | Source: MEDIUM-ANALYSIS.md. Depends on E-98a..e merged. One combined re-run replaces the per-card re-runs (D40 cost). |
|
|
440
446
|
| E-99 | E-86 follow-ups (opus non-blocking): scan every pushed commit with the pushed tip's .gitleaksignore (what CI does) so a self-suppressing line added and removed in one push is refused; unset GITLEAKS_CONFIG and GITLEAKS_CONFIG_TOML in the hook; refuse a .gitleaks.toml change in any push (not only eval-touching ones) without LOKI_ALLOW_GITLEAKS_CONFIG_CHANGE=1; pin the installed binary sha256 in the hook | .githooks/pre-push, tests/test-pre-push-gitleaks.sh | MEDIUM | real-push fixtures for each case, failing first | merged@2026-09-28T18:58Z | Source: E-86 round-4 review C1-C3 and the forged-sidecar boundary. Opus APPROVE; merged 5ee5a630 (conflict with E-100 case 20 resolved: guard kept, E-99 message taken; gitleaks test 43/0 with binary, 19/0/24 skipped without; pre-push hook 13/0). |
|
|
441
447
|
| E-100 | P0: main Tests red on cc4992ed (run 36465466283): tests/test-pre-push-gitleaks.sh case 20 asserted a pass without the pinned gitleaks binary, which the CI runner does not have | tests/test-pre-push-gitleaks.sh | HIGH | `HOME=<empty> bash tests/test-pre-push-gitleaks.sh` 18 passed 0 failed 22 skipped; with the binary 40 passed | merged@2026-09-28T18:42Z | Built 91a47f52; the class is guarded by E-94 (changed tests re-run with an empty HOME). |
|
|
442
|
-
| E-101 | Eval results durable (D40 priority 4): run.sh and harness.py write results.jsonl to ~/loki-ci-logs/eval/<run> and a redacted copy to eval/loki10/archive/; scripts/prune-worktrees.sh never removes a worktree with a live process, a commit in the last 30 minutes, or un-archived eval results | eval/loki10/run.sh, eval/loki10/harness.py, scripts/prune-worktrees.sh, tests/test-eval-archive.sh, tests/test-prune-worktrees.sh | HIGH | fixtures: live-process and un-archived worktrees kept; a planted token never reaches the in-repo archive |
|
|
448
|
+
| E-101 | Eval results durable (D40 priority 4): run.sh and harness.py write results.jsonl to ~/loki-ci-logs/eval/<run> and a redacted copy to eval/loki10/archive/; scripts/prune-worktrees.sh never removes a worktree with a live process, a commit in the last 30 minutes, or un-archived eval results | eval/loki10/run.sh, eval/loki10/harness.py, scripts/prune-worktrees.sh, tests/test-eval-archive.sh, tests/test-prune-worktrees.sh | HIGH | fixtures: live-process and un-archived worktrees kept; a planted token never reaches the in-repo archive | merged@2026-09-28T19:40Z | Source: EV-14 results lost 17:36Z. Supersedes E-96. Reviewer APPROVE bbe83c7a (mutation-checked all 3 prune checks and redact_row); merged 21df7d4a; prune-worktrees 26/0, eval-archive 5/0. Used at 19:40Z to prune 6 finished worktrees. |
|
|
449
|
+
| E-102 | release.sh --bump-only must never leave a tree without its tracked dist: if the loki-ts build fails (for example no node_modules in a fresh worktree), exit non-zero and restore loki-ts/dist from HEAD; when the only source change is VERSION, patch the version literal in dist instead of rebuilding (no debugId or source-map path churn) | scripts/release.sh, tests/test-release-bump-dist.sh | MEDIUM | fixture: a worktree with no node_modules gives a non-zero exit with dist unchanged; a VERSION-only bump changes exactly the version literal in dist/loki.js | merged@2026-09-28T19:29Z | Source: 19:20 cut of v10.3.1: in a fresh worktree the build failed (@anthropic-ai/sdk unresolved) and deleted 4 tracked dist files; a node_modules symlink then rewrote source-map paths. Shipped by hand-patching the version literal (d811e5c3). Tech Lead APPROVE c83a07e2; merged c35d3fa7; bump-dist 7/0 (red first 3/4), bump-only 8/0, release-sh 29/0, shard coverage 19/0, drift 6/0. |
|
|
450
|
+
| E-103 | release.sh --bump-only: when the build exits 0 but dist/loki.js does not embed the new version (release.sh:475-479), restore loki-ts/dist from HEAD and exit non-zero, as the build-failure path already does | scripts/release.sh, tests/test-release-bump-dist.sh | LOW | fixture: a stub build that exits 0 without writing the version gives a non-zero exit with dist byte-identical to HEAD | merged@2026-09-28T19:31Z | Source: E-102 Tech Lead review (non-blocking note). Tech Lead APPROVE 1150af81 (shared release_bump_only_fail, no duplicated restore); bump-dist 10/0 (red 9/10 first), bump-only 8/0, release-sh 29/0. |
|
|
451
|
+
| E-104 | tests/test-verify.sh scenario 3 plants AKIAIOSFODNN7EXAMPLE, which gitleaks (8.30.1 on a dev Mac) allowlists as the AWS doc example, so the test goes VERIFIED/0 wherever gitleaks is installed and passes only where loki verify falls back to its regex scanner (CI). Plant a non-example secret shape and assert BLOCKED on both scanner paths | tests/test-verify.sh | LOW | run with gitleaks on PATH and with PATH stripped of it: BLOCKED/2 both ways | ready@2026-09-28T19:45Z | Source: 19:40 train fast tier: FAIL planted secret -> expected BLOCKED/2, got VERIFIED/0, reproduced on origin/main (CI green there). Env-conditional assertion class. |
|
|
452
|
+
| E-105 | tests/check-heredoc-dollar-digit.sh flags autonomy/run.sh:5548 (`local _var="$1" _had="$2" _val="$3"`), a function body, not a python3 -c body: false positive that keeps the fast tier red on main | tests/check-heredoc-dollar-digit.sh | LOW | the run.sh:5548 shape passes; a real $1 inside python3 -c "..." still fails (red first) | ready@2026-09-28T19:45Z | Source: 19:40 train fast tier; line unchanged for 27h, identical on origin/main. |
|
|
453
|
+
| E-106 | P0: claude-agent-sdk version drift. loki-ts/package.json is 0.3.283 (9db2a4ed) but root package.json and package-lock.json pin 0.3.267 and Dockerfile:160 installs 0.3.208, so the published package resolves an SDK older than the one the engine was evaluated on. Align all pins; add tests/test-sdk-version-sync.sh so CI (not only local-ci.sh) catches drift | package.json, package-lock.json, Dockerfile, tests/test-sdk-version-sync.sh, tests/run-all-tests.sh, tests/shard-durations.tsv | MEDIUM | new test red on main (3 mismatches) then green; npm pack --dry-run succeeds | building@2026-09-28T19:45Z | Source: 19:40 train fast tier FAIL "Agent SDK is a resolvable root dependency"; reproduced on origin/main (root 0.3.267 vs loki-ts 0.3.283). Dispatched 19:45Z sonnet. |
|
|
443
454
|
| E-58 | Issue-ref runs: supervisor creates runDir before the fetch child writes issue.json; makes E-47 green | loki-ts/src/engine10/supervisor.ts (one line before fetchIssueToFile), E-47 test files from 544348a7 | MEDIUM | cd loki-ts && bun test tests/engine10/issue_ref_e2e.test.ts (3 pass) | released@2026-09-28T02:38Z | Source: E-47 finding (TL reproduced). Merged 646a6cd7 (train E13): engine10 388 pass 0 fail, tsc exit 0, test-engine10-dist 18/0, test-engine10-docs 26 passed, test-harness 82/0. APPROVE (6384fff9); issue_ref_e2e 3 pass. Released v9.81.0 (npm view loki-mode time: 2026-09-28T02:38:54Z). |
|
|
444
455
|
| E-59 | Receipt model and summary tokens match the provider: cost.ts takes model from the result-cost file; events.ts fold sums cache read and creation tokens; makes E-50 green | loki-ts/src/engine10/cost.ts, loki-ts/src/engine10/events.ts, E-50 test files from 716618d4 | HIGH | cd loki-ts && bun test tests/engine10/model_report.test.ts tests/engine10/output.test.ts | released@2026-09-28T02:38Z | Source: E-50 finding. Reconcile with E-44 (output.ts already folds cache tokens at render). Opus reviewer (cost numbers feed the gate). Opus CONCERN: writeResultCost writes no model, so real records still use the caller model; summary tokens at supervisor.ts still exclude cache. Rework dispatched. Merged 3ab2a8fa (train E14, rebased on main): engine10 404 pass 0 fail (402 pass 0 fail with claude removed from PATH), tsc exit 0, test-harness 86/0, test-local-ci-gitleaks 6/0, test-engine10-dist 18/0. Released v9.81.0 (npm view loki-mode time: 2026-09-28T02:38:54Z). |
|
|
445
456
|
| EV-8 | v10 cost check on 5 tasks before the full arm (CEO 23:31Z): v10 arm, same model, after E-42 and E-45 merge | eval/loki10 results (gitignored) plus docs/v10/METRICS.md block | HIGH | eval/loki10/run.sh --arm v10 --tasks <5 ids> reports completed, time to PR and provider cost per task | released@2026-09-28T02:38Z | Target cost per completed task at or below $0.2363 (raw claude -p full arm). Depends on E-42, E-45, E-38 (--tasks). Incident 01:38Z: first run 0/5 on both variants measured the wrong code. The harness default arm binary is the global loki (loki --version: v9.78.0), and the main checkout node_modules still had agent SDK 0.3.267 (package.json pins 0.3.283), whose bundled Claude Code 2.1.267 rejects claude-opus-5-5, so every session exited "error" in about 1s with 0 tokens. Fixed in 7c3dea3d: bun install (node_modules 0.3.283), repro with the harness arm_env and arm_auth now completes on claude-opus-5-5 ($0.11, 13s); dist rebuilt. Rerun started with LOKI_EVAL_LOKI_BIN=<repo>/bin/loki. Guards E-61, E-62. Rerun measured (not a code slice): A 4/5 $0.5954, B 5/5 $0.3976, C (all sonnet, no plan, no Wall) 4/5 $0.294, raw 5/5 $0.2161 (~/loki-ci-logs/ev8r-{A,B,C}/results.jsonl). Gate not met on cost; D31 and E-64, E-65 follow. Released v9.81.0 (npm view loki-mode time: 2026-09-28T02:38:54Z). |
|
package/docs/v10/GUARDS.md
CHANGED
|
@@ -615,7 +615,7 @@ previously mismarked two merged guards (S-16, S-74) as PENDING.
|
|
|
615
615
|
restore) and a clean rerun showed `Results: 6 passed, 0 failed`, exit 0.
|
|
616
616
|
Run: `bash tests/test-dep-inventory.sh`.
|
|
617
617
|
|
|
618
|
-
##
|
|
618
|
+
## 18. Hardcoded fixture ports raced concurrent runs of the same test (E-95)
|
|
619
619
|
|
|
620
620
|
- **Incident:** commit `8f2179cd`, Tests run `36453069628`,
|
|
621
621
|
`tests/test-app-runner-watchdog-health.sh` failed with "healthy fixture
|
|
@@ -657,7 +657,7 @@ previously mismarked two merged guards (S-16, S-74) as PENDING.
|
|
|
657
657
|
concurrent `test-v10-pulse.sh` copies completed clean, exit 0, over the
|
|
658
658
|
same window). `bash -n` and `shellcheck` both clean on the file.
|
|
659
659
|
|
|
660
|
-
##
|
|
660
|
+
## 19. A local pass depended on `gh` being authenticated on the dev Mac (E-94)
|
|
661
661
|
|
|
662
662
|
- **Incident:** `tests/test-dep-inventory.sh` passed locally and failed on
|
|
663
663
|
the CI runner. Root-caused to `scripts/dep-inventory.py`'s `self_test()`:
|
|
@@ -754,3 +754,46 @@ previously mismarked two merged guards (S-16, S-74) as PENDING.
|
|
|
754
754
|
directly against this worktree, found the one real in-scope change and
|
|
755
755
|
returned `hermetic-clean` in 5.6s, well inside the 60s budget. Run:
|
|
756
756
|
`bash tests/test-local-ci-hermetic.sh`.
|
|
757
|
+
|
|
758
|
+
## 20. Eval results lost when a worktree was force-removed (E-96/EV-14, E-101)
|
|
759
|
+
|
|
760
|
+
- **Incident:** `eval/loki10/results/*/results.jsonl` is gitignored
|
|
761
|
+
(`eval/loki10/.gitignore`), so it exists only inside the worktree that ran
|
|
762
|
+
the eval. The 17:36Z pruning incident (guard 5's family, PROGRESS.md)
|
|
763
|
+
force-removed 7 live builder worktrees including EV-14's; that eval's
|
|
764
|
+
per-run results were destroyed with it (METRICS.md 18:00Z note) and could
|
|
765
|
+
not be re-audited.
|
|
766
|
+
- **Root cause with evidence:** nothing ever copied `results.jsonl` outside
|
|
767
|
+
the worktree that produced it, and no existing prune tool checked for
|
|
768
|
+
un-copied results before removing a worktree.
|
|
769
|
+
- **The guard:** `eval/loki10/harness.py` `cmd_run` now writes a redacted
|
|
770
|
+
copy of every row (`redact_row`: drops the `arm_stdout`/`arm_stderr`/etc.
|
|
771
|
+
log paths and any secret-shaped string) to both
|
|
772
|
+
`${LOKI_EVAL_ARCHIVE:-$HOME/loki-ci-logs/eval}/<run-name>/results.jsonl`
|
|
773
|
+
(outside the repo) and the committed `eval/loki10/archive/<run-name>.results.jsonl`,
|
|
774
|
+
per row inside the same lock that writes the worktree-local copy, so a
|
|
775
|
+
killed run keeps what it already archived. `scripts/prune-worktrees.sh`
|
|
776
|
+
refuses to remove a worktree that has a `results.jsonl` whose `run_id`s
|
|
777
|
+
are not all present in an archived copy, and separately refuses to remove
|
|
778
|
+
one with a live process inside it (`lsof -d cwd -Fn`) or a branch commit
|
|
779
|
+
less than 30 minutes old (`git log -1 --format=%ct`) -- any check that
|
|
780
|
+
cannot run (lsof missing/broken, unparseable JSON) REFUSES rather than
|
|
781
|
+
guessing. No file-age signal (`stat`, `find -newermt`, etc.) is used
|
|
782
|
+
anywhere in it.
|
|
783
|
+
- **The test that proves it fires:** `tests/test-prune-worktrees.sh` keeps a
|
|
784
|
+
worktree with a live process inside it, keeps one whose results are not
|
|
785
|
+
yet archived, removes one whose results ARE archived (positive control),
|
|
786
|
+
and refuses everything when `lsof` is stubbed to fail. Deleting any one of
|
|
787
|
+
the three new checks from `scripts/prune-worktrees.sh` (live-process,
|
|
788
|
+
30-minute, or archived-results) turns the corresponding case red: 24
|
|
789
|
+
passed / 2 failed each time, vs. 26 passed / 0 failed with the check in
|
|
790
|
+
place. `tests/test-eval-archive.sh` plants a token
|
|
791
|
+
(`sk-ant-plantedTOKEN9999`, a GitHub-token-shaped string, and a
|
|
792
|
+
`KEY=VALUE`-shaped one) in a synthetic row and asserts none of it survives
|
|
793
|
+
`redact_row`, that the log paths are gone, that real fields (`task`,
|
|
794
|
+
`run_id`, `harness_sha`, `cost_usd`) survive intact, and that the redacted
|
|
795
|
+
rows still `summarize_rows()` correctly (an empty/over-stripped archive
|
|
796
|
+
would otherwise pass the secret check too). Replacing `redact_row` with a
|
|
797
|
+
no-op (`return dict(row)`) reproduces the incident directly: the planted
|
|
798
|
+
secret and the log paths both survive.
|
|
799
|
+
Run: `bash tests/test-prune-worktrees.sh && bash tests/test-eval-archive.sh`.
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# E-98: why v10 loses to raw `claude -p` on the medium tier (EV-15)
|
|
2
|
+
|
|
3
|
+
Source data: EV-15 (2026-09-28, harness `cc4992ed`, v10.2.5, `claude-opus-5-5`, 7 `pub-*` medium tasks, 2 runs per arm, 900s cap). The engine10 code this analysis cites is unchanged between `cc4992ed` and `origin/main` `d811e5c3` (`git diff --stat cc4992ed origin/main -- loki-ts/src/engine10` is empty).
|
|
4
|
+
All paths below are relative to `/Users/lokesh/loki-ci-logs/eval/` (called EV below). `EV/ev15-summary.md` and `EV/ev15-stage-detail.md` are the run summaries.
|
|
5
|
+
|
|
6
|
+
The founder's "12/14 vs 10/14" comes from EV-14. Its result files were lost when a worktree was force-removed (E-96/E-101). EV-15 re-ran the tier: raw 10/14, v10 9/14. The numbers here are EV-15's, and every claim cites an EV-15 file.
|
|
7
|
+
|
|
8
|
+
## 1. Outcome per task-run
|
|
9
|
+
|
|
10
|
+
| task | raw r1 | raw r2 | v10 r1 | v10 r2 | class |
|
|
11
|
+
|---|---|---|---|---|---|
|
|
12
|
+
| pub-jinja-1413 | pass | pass | **miss** | **miss** | **v10 loss (2)** |
|
|
13
|
+
| pub-werkzeug-3105 | miss | miss (hidden_pass, no push) | miss | miss | shared miss |
|
|
14
|
+
| pub-werkzeug-3271 | miss | miss | miss | pass | shared miss, one v10 win |
|
|
15
|
+
| attrs-1313, click-2869, faker-1817, werkzeug-3121 | pass | pass | pass | pass | tie (v10 slower/costlier) |
|
|
16
|
+
|
|
17
|
+
Only two task-runs were completed by raw and missed by v10: pub-jinja-1413 r1 and r2.
|
|
18
|
+
- werkzeug-3105: both arms fail the same hidden test with the same error. `EV/ev15-v10-r{1,2}/logs/pub-werkzeug-3105*/grade_hidden.stdout.log` and `EV/ev15-raw-claude-r1/logs/pub-werkzeug-3105*/grade_hidden.stdout.log` all show `FAILED tests/test_routing.py::test_no_duplicate_head_options - DuplicateRuleError: / -> a`.
|
|
19
|
+
- werkzeug-3271 r1: both arms fail with `FAILED tests/test_wrappers.py::test_user_agent - Failed: DID NOT WARN`.
|
|
20
|
+
- These are task difficulty, not v10 stage losses.
|
|
21
|
+
|
|
22
|
+
## 2. Failure table (v10 losses, with log citations)
|
|
23
|
+
|
|
24
|
+
Event logs:
|
|
25
|
+
- `EV/ev15-engine/v10-r1/pub-jinja-1413.v10.71372932a4ef/.loki/runs/e10-20260928T185044Z-5451/events.jsonl` (r1)
|
|
26
|
+
- `EV/ev15-engine/v10-r2/pub-jinja-1413.v10.78270c64e4ab/.loki/runs/e10-20260928T190755Z-60df/events.jsonl` (r2)
|
|
27
|
+
|
|
28
|
+
Hidden grade, in both runs (`EV/ev15-v10-r{1,2}/logs/pub-jinja-1413*/grade_hidden.stdout.log`):
|
|
29
|
+
- Result: `2 failed, 12 passed`.
|
|
30
|
+
- The failing tests are `TestSet::test_set_invalid` and `TestSet::test_namespace_redefined`, both `DID NOT RAISE TemplateRuntimeError`.
|
|
31
|
+
- Both tests passed at baseline (`baseline.stdout.log`: only `test_namespace_set_tuple` failed).
|
|
32
|
+
- So v10 broke the namespace runtime check. These are regressions in existing tests, not a missing feature.
|
|
33
|
+
- Raw (opus) kept the check: `EV/ev15-raw-claude-r1/logs/pub-jinja-1413*/grade_hidden.stdout.log` shows `14 passed`.
|
|
34
|
+
|
|
35
|
+
| run | stage that lost it | exact event lines | cause (one sentence) |
|
|
36
|
+
|---|---|---|---|
|
|
37
|
+
| jinja r1 | implement brief, then early exit past verify | seq21 `stage.completed implement {"exit": "spec_conflict", ..., "spec_conflict_reason": "plan step 8 requires adding tests to the existing tests/test_core_tags.py, but the rules make existing test files read-only ...", "impacted_tests": []}`; seq22 `stage.started commit` directly after it (no verify stage); seq25 `receipt.sealed ... "verdict": "SPEC_CONFLICT"` | The brief rule "existing test files are read-only" (implement.ts:33) turned a normal task into `spec_conflict`, and `earlyExit` (machine.ts:55) then skipped verify and the fix loop, so a sonnet diff that regressed two existing tests shipped untested. |
|
|
38
|
+
| jinja r2 | verify (blind), so no fix round | seq32 `stage.completed implement {"exit": "done", ..., "impacted_tests": ["examples/basic/loki_wall_test_namespace_tuple_assign.py"]}`; `test.result verify {"name": "pytest:tests/test_core_tags.py", "cmd": "python -m pytest -q tests/test_core_tags.py", "result": "not_run", "reason": "python not found on PATH"}`; no `fix` event; seq45 `run.completed {"verdict": "PARTIAL", ...}` | Verify picked the right file (`tests/test_core_tags.py` contains both regressed tests), but ran it as `python`. The host has only `python3` (`which python` prints `python not found`), and the task's own `work/.venv` was never tried, so the check was `not_run`, `failures_grouped` stayed empty, and the fix loop never started. |
|
|
39
|
+
|
|
40
|
+
What each session actually ran:
|
|
41
|
+
- jinja r2 (`.loki/logs/bash-audit.jsonl`): the implementer ran only the Wall test, with system `python3` and `PYTHONPATH=src`. It never ran `tests/test_core_tags.py`.
|
|
42
|
+
- Its log (`iteration-e10-20260928T190755Z-60df-impl.log`) says it added new tests "after `test_namespace_macro`". Seal's `weakened test: tests/test_core_tags.py` fires on any modification (seal.ts:176), not only on weakening.
|
|
43
|
+
- The two regressed tests are therefore most likely still intact in the sandbox. A working verify would then have failed them. This is likely, not proven: the EV-15 working trees are gone, so the E-98a/E-98b re-run settles it.
|
|
44
|
+
- jinja r1 needed two fixes to reach a fix round: the interpreter fix, and a verify that still runs after `spec_conflict`.
|
|
45
|
+
|
|
46
|
+
## 3. Engine-wide facts (all 14 v10 event logs)
|
|
47
|
+
|
|
48
|
+
Commands: the scripts `dump.py`, `sumall.py` and `cost.py` read every `EV/ev15-engine/v10-r*/*/.loki/runs/*/events.jsonl`.
|
|
49
|
+
|
|
50
|
+
- **Verify never ran a test.**
|
|
51
|
+
- 27 of 27 `test.result` pytest checks are `not_run` / `python not found on PATH`.
|
|
52
|
+
- 9 of 9 ruff checks are `not_run` / `ruff not found on PATH`.
|
|
53
|
+
- 0 checks passed and 0 failed.
|
|
54
|
+
- There were 0 `fix` events in 14 runs. The fix loop is gated on `failures_grouped` (machine.ts:54), which can only fill from a `fail`.
|
|
55
|
+
- **Verify was skipped in 5 of 14 runs.** Implement exited `spec_conflict` in jinja r1, werkzeug-3121 r1 and r2, and werkzeug-3271 r1 and r2.
|
|
56
|
+
- 4 of the 5 reasons cite the read-only rule for existing test files.
|
|
57
|
+
- 3121 r1 cites a Wall test that contradicts the plan.
|
|
58
|
+
- 9 verify stages completed, 5 did not start.
|
|
59
|
+
- **The implementer is never told which existing tests to run.**
|
|
60
|
+
- Implement reported `impacted_tests: []` in 9 of 14 runs. The 5 non-empty ones are faker x2 (`tests/test_proxy.py`, lean path) and 3 Wall-test-only lists.
|
|
61
|
+
- Root cause: `repomap.ts` extracts symbols only with a JS `export` regex (`SYMBOL_RE`, repomap.ts:23). Every Python repo gets `entries: []`. For example, jinja r2 `repomap.json` has 118 files and 0 entries.
|
|
62
|
+
- So `selectRelevantFiles` returns `[]` (`"relevant_files": []` in 8 of 8 plan stages).
|
|
63
|
+
- Then `impactedTests` (implement.ts:17) takes `[]` from `??` and never falls back to `namedFiles`.
|
|
64
|
+
- **Implement always ran on sonnet; raw ran on opus.**
|
|
65
|
+
- Every `session.started implement` has `"model": "claude-sonnet-5"`, because of the E-64 cascade (implement.ts:68, sizing.ts:63).
|
|
66
|
+
- Escalation to the run model happens only in a fix round with a test failure (fix.ts:60). That cannot happen while verify is blind.
|
|
67
|
+
- So on this harness the cascade is sonnet-only. This contributes to jinja, but is not proven as a cause: EV-14 v10 passed jinja 2/2.
|
|
68
|
+
- **Wall hit its 90s limit in 5 of 14 runs:** 3105 r1 and r2, 3121 r2, 3271 r2, click r2.
|
|
69
|
+
- Evidence: `stage.failed wall {"reason": "limit"}` and `session.ended wall exit=killed dur=90.0`.
|
|
70
|
+
- Wall sealed at least one test in only 3 of 14 runs (3121 r1, 3271 r1, jinja r2).
|
|
71
|
+
- The one jinja Wall test was written under `examples/basic/`. The implementer reports that it was defective: `test_recursive_loop_matches_bug_report` references an undefined `id`.
|
|
72
|
+
|
|
73
|
+
## 4. Cost: where v10 spends that raw does not
|
|
74
|
+
|
|
75
|
+
Measured from `cost` events (`usd` non-null) and from raw `arm_stdout.log` usage:
|
|
76
|
+
|
|
77
|
+
| | usd | cache read tokens | cache write tokens | output tokens |
|
|
78
|
+
|---|---|---|---|---|
|
|
79
|
+
| raw, 14 runs | $5.09 | 4.79M | 0.29M | 89k |
|
|
80
|
+
| v10 implement (sonnet), 14 | $4.91 | 9.23M | 0.41M | 137k |
|
|
81
|
+
| v10 wall (sonnet), 8 measured + 4 unmeasured | $1.11 | 0.32M | 0.15M | 40k |
|
|
82
|
+
| v10 plan (opus), 8 | $0.90 | 0.30M | 0.06M | 16k |
|
|
83
|
+
| v10 intake (sonnet, lean path), 2 | $0.17 | 0.08M | 0.03M | 1k |
|
|
84
|
+
| **v10 total measured** | **$7.09** | 9.93M | 0.66M | 195k |
|
|
85
|
+
|
|
86
|
+
- **Correction to EV-15's lower bound.** Measured v10 spend is at least $7.09, over 9 completions, so cost per completed is at least **$0.788**, not $0.5788. EV-15 summed only the 10 costed rows. It dropped the measured plan and implement dollars inside the 4 null rows ($0.32, $0.59, $0.25, $0.72 before Wall). Raw is $0.5085, so v10 is at least 55% more per completed task.
|
|
87
|
+
- **Priority-2 gap, root cause.** All 4 `cost_usd: null` rows (3105 r1 and r2, 3121 r2, 3271 r2) are runs where Wall was killed at its limit.
|
|
88
|
+
- Evidence: `cost wall usd=None ... in=0 out=0`. Only `result-cost-*-impl.json` and `result-cost-*-plan.json` exist under `.loki/metrics/` (for example 3105 r1).
|
|
89
|
+
- A killed session never receives the SDK result message, so no cost file is written. `iteration-2.json` is Wall's efficiency record.
|
|
90
|
+
- **Overhead stages.** Plan, Wall and intake cost $2.18, which is 31% of v10's measured spend. Wall bought a sealed test in 3 of 14 runs.
|
|
91
|
+
- **Latency.** Implement waits for the whole `["plan", "wall"]` group. When Wall is killed at 90s beside a 15-31s plan, that adds about 60-75s before implement starts.
|
|
92
|
+
- **Implement burns 1.9x raw's cache reads** (9.23M vs 4.79M), on a cheaper model. Most of it is in the long runs:
|
|
93
|
+
- attrs r2: 286s, 2.49M cache read, $0.97.
|
|
94
|
+
- jinja r2: 360s, 2.34M, $0.94.
|
|
95
|
+
- werkzeug-3105 r2: 1.11M, $0.47.
|
|
96
|
+
- werkzeug-3271 r2: 239s, 0.94M, $0.63.
|
|
97
|
+
- The brief gives no test to run, so the session explores instead of converging.
|
|
98
|
+
|
|
99
|
+
Completed runs where v10 was slower or costlier than raw on the same task and run:
|
|
100
|
+
- attrs r2: $1.06 and 317s vs $0.28 and 60s. Implement ran 286s.
|
|
101
|
+
- click r2: 212s vs 49s. Wall was killed at 90s, then implement ran 121s.
|
|
102
|
+
- faker r2: 128s vs 227s, a v10 win on time.
|
|
103
|
+
- 3121 r2: 141s vs 29s. Wall was killed at 90s, then implement ended in `spec_conflict`.
|
|
104
|
+
- 3271 r2: 330s, a v10 win. Wall was killed at 90s, then implement ran 239s.
|
|
105
|
+
|
|
106
|
+
In every slow case the time went to Wall hitting its limit, or to a long implement session with no test to run.
|
|
107
|
+
|
|
108
|
+
## 5. Root causes, ranked by lost completions explained
|
|
109
|
+
|
|
110
|
+
| rank | cause | lost completions explained | other effect |
|
|
111
|
+
|---|---|---|---|
|
|
112
|
+
| 1 | Verify runs pytest as bare `python`: not on PATH, and the task `.venv` is ignored (verify.ts:31) | 2 of 2 (r2 directly; r1 once cause 2 is fixed) | 27/27 checks `not_run`; 0 fix rounds; cascade escalation unreachable |
|
|
113
|
+
| 2 | `spec_conflict` early exit skips verify and fix (machine.ts:55), triggered by the "existing test files are read-only" rule (implement.ts:33) | 1 (jinja r1) | 5/14 runs unverified; 4 of the 5 caused by the read-only rule |
|
|
114
|
+
| 3 | Implementer is given no impacted tests: Python repomap has 0 entries (repomap.ts:23), and `[]` blocks the `namedFiles` fallback (implement.ts:17) | contributing to 2 (the implementer never ran `test_core_tags.py`) | 9/14 implement runs had no tests to run; long, cache-heavy sessions |
|
|
115
|
+
| 4 | Implement pinned to sonnet by the cascade, with escalation only through verify failures | contributing, unproven (EV-14 v10 passed jinja 2/2) | cheaper tokens, but 1.9x the cache reads |
|
|
116
|
+
| 5 | Wall 90s limit kills and low yield | 0 | all 4 null-cost rows; +60-75s latency; 3/14 useful |
|
|
117
|
+
|
|
118
|
+
## 6. Fix slice cards
|
|
119
|
+
|
|
120
|
+
D33: the core is 4,942 lines against a 5,000 cap, so there are 58 lines of headroom. Card deltas below total +34 or fewer. IDs are E-98a to E-98f, to avoid clashing with an E-102 that exists on a local main.
|
|
121
|
+
|
|
122
|
+
Re-running the failed tasks uses `eval/loki10/run.sh` with a separate `--out` per run. There is no `--runs` flag, so use n=3 per task: EV-14 passed jinja 2/2, so n=2 cannot tell a fix from noise. Copy each run's `work/.loki` out before cleanup (E-101), with the output under `/Users/lokesh/loki-ci-logs/eval/e98-*`.
|
|
123
|
+
|
|
124
|
+
### E-98a: verify uses the project interpreter
|
|
125
|
+
- Goal: pytest checks run on the repo's own environment, so a regression shows up as `fail` and drives a fix round.
|
|
126
|
+
- File set:
|
|
127
|
+
- `loki-ts/src/engine10/stages/verify.ts`: `runnerCmd` resolves `<repoDir>/.venv/bin/python`, then `<repoDir>/venv/bin/python`, then `$VIRTUAL_ENV/bin/python`, then `python3`, then `python`.
|
|
128
|
+
- The same file: each check records the interpreter it used. A check that ran on a system interpreter adds "tests ran on the system interpreter" to not_proven, because system `python3` imported the installed Jinja2 3.1.6, not `src/`, in jinja r2.
|
|
129
|
+
- `loki-ts/tests/engine10/verify*.test.ts`.
|
|
130
|
+
- Net core delta: at most +12.
|
|
131
|
+
- Wall check:
|
|
132
|
+
- Red first: a fixture with a `.venv/bin/python` shim and no `python` on PATH gives `not_run` before the change and `pass`/`fail` after. A second fixture with system python3 only records `interpreter: system` plus the not_proven line.
|
|
133
|
+
- Then `eval/loki10/run.sh --arm v10 --tasks pub-jinja-1413 --out /Users/lokesh/loki-ci-logs/eval/e98a-r{1,2,3}`.
|
|
134
|
+
- Expected: `test.result` for `pytest:tests/test_core_tags.py` is `pass` or `fail` (never `not_run`) in 3 of 3 runs, and completed in at least 2 of 3.
|
|
135
|
+
- Budget: 30 min. Tier: HIGH (verify).
|
|
136
|
+
|
|
137
|
+
### E-98b: spec_conflict still verifies
|
|
138
|
+
- Goal: a `spec_conflict` implement exit still runs verify and the fix loop. Only `already_satisfied` short-circuits. The receipt keeps the `SPEC_CONFLICT` verdict and reason.
|
|
139
|
+
- File set: `loki-ts/src/engine10/machine.ts` (`earlyExit`, plus the verdict carry-through only if seal needs it), `loki-ts/tests/engine10/machine*.test.ts`. Net core delta: at most +3.
|
|
140
|
+
- Wall check:
|
|
141
|
+
- A fake-stage test: implement `spec_conflict`, then verify runs, then a `fail` triggers `fix`, then seal still says `SPEC_CONFLICT`. It must fail on current main.
|
|
142
|
+
- Then re-run `pub-jinja-1413`, `pub-werkzeug-3121` and `pub-werkzeug-3271` at n=3 into `EV/e98b-*`, with E-98a merged.
|
|
143
|
+
- Expected: every run with a `spec_conflict` exit has a `stage.completed verify`. Completions are at least EV-15's on these tasks (jinja 0/2, 3121 2/2, 3271 1/2).
|
|
144
|
+
- Budget: 30 min. Tier: HIGH (moat flow).
|
|
145
|
+
|
|
146
|
+
### E-98c: brief allows adding tests; impacted tests fall back
|
|
147
|
+
- Goal: existing test files are append-only (add new test functions, never edit or delete existing ones). Wall files stay read-only and are restored as today; seal.ts:176 still reports any modification. `impactedTests` falls back to `namedFiles` when `relevant_files` is empty, not only when it is missing.
|
|
148
|
+
- File set: `loki-ts/src/engine10/stages/implement.ts` (the brief line at :33, and `impactedTests` at :17 using `?.length ?` in place of `??`), plus its test. Net core delta: at most +2.
|
|
149
|
+
- Wall check:
|
|
150
|
+
- A unit test: a brief with `relevant_files: []` and a task naming `parser.py` lists that file's tests.
|
|
151
|
+
- Re-run `pub-werkzeug-3121` and `pub-werkzeug-3271` at n=3 into `EV/e98c-*`.
|
|
152
|
+
- Expected: no run exits `spec_conflict` citing read-only existing tests (4 of 14 did in EV-15), and completions do not drop.
|
|
153
|
+
- Budget: 15 min. Tier: MEDIUM.
|
|
154
|
+
|
|
155
|
+
### E-98d: Python symbols in the repo map
|
|
156
|
+
- Goal: `buildRepoMap` extracts Python top-level `def` and `class` names, alongside the JS `export` regex, so `selectRelevantFiles` and the impacted-test map work on Python repos.
|
|
157
|
+
- File set: `loki-ts/src/engine10/repomap.ts`, `loki-ts/tests/engine10/repomap*.test.ts`. Net core delta: at most +4 (a second regex applied to `.py`).
|
|
158
|
+
- Wall check:
|
|
159
|
+
- Offline, no model: on each of the 7 medium task repos at their `repo_ref`, `relevant_files` is non-empty and contains the file the upstream refdiff touches (`eval/loki10/refdiff/`). At least 5 of 7 must pass. EV-15 had 0 of 7, 8 of 8 plan stages empty.
|
|
160
|
+
- Keyword ties across a package directory are a known ceiling. Record the rank of the upstream file.
|
|
161
|
+
- Budget: 30 min. Tier: MEDIUM.
|
|
162
|
+
|
|
163
|
+
### E-98e: killed sessions still report cost
|
|
164
|
+
- Goal: a session killed at its stage limit writes a cost record from the per-message usage already streamed, marked `source: "partial-stream"`, so the harness row is never `cost_usd: null` because Wall was killed.
|
|
165
|
+
- File set: `loki-ts/src/engine10/session.ts`, `loki-ts/src/engine10/cost.ts`, and a test. Net core delta: at most +10, or offset by deleting dead code in cost.ts.
|
|
166
|
+
- Wall check:
|
|
167
|
+
- A unit test: a fake stream killed after 2 assistant messages gives a non-null usd equal to the summed usage price.
|
|
168
|
+
- Re-run `pub-werkzeug-3105`, `pub-werkzeug-3121` and `pub-werkzeug-3271` at n=3 into `EV/e98e-*`.
|
|
169
|
+
- Expected: `cost_usd` is non-null on every row, and `eval/loki10/summarize` reports a numeric `cost_per_completed`.
|
|
170
|
+
- Budget: 30 min. Tier: MEDIUM.
|
|
171
|
+
|
|
172
|
+
### E-98f: A/B of Wall and cascade on medium (eval-first, then a sizing change)
|
|
173
|
+
- Goal: measure whether Wall (`LOKI_E10_WALL=0`) and the sonnet cascade (`LOKI_E10_CASCADE=0`) pay for themselves on medium, with E-98a to E-98c merged. Only if a knob wins on completions without losing on cost, change `sizing.ts` so that `size: "normal"` takes that path by default.
|
|
174
|
+
- File set: an eval run only, then `loki-ts/src/engine10/sizing.ts` (at most +3 core lines) and its test.
|
|
175
|
+
- Wall check:
|
|
176
|
+
- All 7 medium tasks at n=3 per arm: default, `LOKI_E10_WALL=0`, `LOKI_E10_CASCADE=0`, into `EV/e98f-{default,nowall,nocascade}-r{1,2,3}`.
|
|
177
|
+
- The chosen default must be at or above raw's EV-15 10/14 rate (71.4%) on completions, and below raw's $0.5085 on cost per completed.
|
|
178
|
+
- The results are published in this file as the "after" table.
|
|
179
|
+
- Budget: 60 min of eval, then a 15 min code change. Tier: HIGH (it changes the default flow).
|
|
180
|
+
|
|
181
|
+
Order: a, b, c, d and e in parallel (their file sets do not overlap), then f. The "after" table for the founder is the E-98f default arm next to section 1 above.
|
package/docs/v10/PROGRESS.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Progress
|
|
2
2
|
|
|
3
|
+
## 2026-09-28T19:42Z: 19:20 slot shipped (v10.3.1); medium failure explained; 7 builders on the fixes
|
|
4
|
+
- 19:20 slot: v10.3.1 cut 19:22:09Z (d811e5c3: E-99, M-30); Release 36471746478 success, publish-npm 19:30:56Z (cut to publish 8m47s), npm latest 10.3.1 gitHead d811e5c3. GitHub body came out as the placeholder "Release v10.3.1" (2 lines); backfilled from CHANGELOG (9 lines). E-88a (the enforcement) is being rebased onto E-99 now.
|
|
5
|
+
- Release blocker found at the cut: release.sh --bump-only in a fresh worktree deleted 4 tracked dist files when the build failed. Guard E-102 merged (c35d3fa7, test red 3/4 first, then 7/0) and E-103 for the build-ok-but-no-version branch (cd3d3d26, 10/0).
|
|
6
|
+
- EV-15 (medium re-run, durable files in ~/loki-ci-logs/eval/ev15-*): raw 10/14, $0.5085, p50 56s; v10 9/14, at least $0.788 per completed (E-98 correction), p50 128s. No flip.
|
|
7
|
+
- E-98 (docs/v10/MEDIUM-ANALYSIS.md, d496db89): v10's verify stage hard-codes `python`; this host has only `python3`, so 27/27 pytest and 9/9 ruff checks were not_run and no fix round fired in any of 14 runs. The only raw-won/v10-lost task (jinja-1413 x2) broke two existing tests a working verify would have caught. Other causes: spec_conflict skips verify (5/14), empty Python repo map (0 symbols, 9/14 implement runs had no tests to run), Wall killed at 90s (5/14, all 4 null-cost rows).
|
|
8
|
+
- Dispatched 19:40Z (sonnet): E-98a (verify interpreter), E-98b (spec_conflict still verifies), E-98c (append-only tests, impacted-test fallback), E-98d (Python repo map), E-98e (killed-session cost), E-88a rebase, E-91 (pulse id regex: E-98a..e and G-02 were invisible to the building count). E-98f (A/B of Wall and cascade, n=3 per arm) follows as one combined re-run.
|
|
9
|
+
- Merged locally for the 19:40 train: G-01 (governor, opus APPROVE r3 fa279532), M-08 (modernize dispatch, Tech Lead APPROVE r3 766a493b, alias-forwarding 213/0), E-102, E-103, E-101 (durable eval results plus safe prune, used to remove 6 finished worktrees). Fast tier: two failures, both pre-existing on origin/main and env-conditional (E-104 gitleaks allowlists the AWS example key; E-105 heredoc checker false positive at run.sh:5548).
|
|
10
|
+
|
|
3
11
|
## 2026-09-28T19:04Z: drift audit (turn 528)
|
|
4
12
|
- M-08 (modernize arm in bin/loki) first build would have turned test-engine10-dispatch.sh red (it counted exactly 1 engine10 line). Fixed in-slice (7feff1f8): exactly 2 exec lines, one per named arm, red on a stray third; 35/0 and 13/0. Tech Lead review running.
|
|
5
13
|
- M-30 guide: Tech Lead REJECT, the --resume example id failed MID_RE (exit 2 when copied). Rework adds a MID_RE check over every id in the guide.
|
package/loki-ts/dist/loki.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var hn=Object.create;var{getPrototypeOf:gn,defineProperty:BG,getOwnPropertyNames:mn}=Object;var un=Object.prototype.hasOwnProperty;function pn($){return this[$]}var dn,cn,ln=($,Z,Q)=>{var X=$!=null&&typeof $==="object";if(X){var J=Z?dn??=new WeakMap:cn??=new WeakMap,K=J.get($);if(K)return K}Q=$!=null?hn(gn($)):{};let Y=Z||!$||!$.__esModule?BG(Q,"default",{value:$,enumerable:!0}):Q;for(let V of mn($))if(!un.call(Y,V))BG(Y,V,{get:pn.bind($,V),enumerable:!0});if(X)J.set($,Y);return Y};var tJ=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var an=($)=>$;function on($,Z){this[$]=an.bind(null,Z)}var w0=($,Z)=>{for(var Q in Z)BG($,Q,{get:Z[Q],enumerable:!0,configurable:!0,set:on.bind(Z,Q)})};var v=($,Z)=>()=>($&&(Z=$($=0)),Z);var D7=import.meta.require;var JT={};w0(JT,{lokiDir:()=>F0,homeLokiDir:()=>k4,findRepoRootForVersion:()=>OG,REPO_ROOT:()=>d0});import{resolve as I7,dirname as UG}from"path";import{fileURLToPath as nn}from"url";import{existsSync as eJ}from"fs";import{homedir as sn}from"os";function rn(){let $=XT;for(let Z=0;Z<6;Z++){if(eJ(I7($,"VERSION"))&&eJ(I7($,"autonomy/run.sh")))return $;let Q=UG($);if(Q===$)break;$=Q}return I7(XT,"..","..","..")}function OG($){let Z=$;for(let Q=0;Q<6;Q++){if(eJ(I7(Z,"VERSION"))&&eJ(I7(Z,"autonomy/run.sh")))return Z;let X=UG(Z);if(X===Z)break;Z=X}return I7($,"..","..","..")}function F0(){return process.env.LOKI_DIR??I7(process.cwd(),".loki")}function k4(){return I7(sn(),".loki")}var XT,d0;var Z8=v(()=>{XT=UG(nn(import.meta.url));d0=rn()});import{readFileSync as tn}from"fs";import{resolve as en,dirname as $s}from"path";import{fileURLToPath as Zs}from"url";function R7(){if(x4!==null)return x4;let $="10.
|
|
2
|
+
var hn=Object.create;var{getPrototypeOf:gn,defineProperty:BG,getOwnPropertyNames:mn}=Object;var un=Object.prototype.hasOwnProperty;function pn($){return this[$]}var dn,cn,ln=($,Z,Q)=>{var X=$!=null&&typeof $==="object";if(X){var J=Z?dn??=new WeakMap:cn??=new WeakMap,K=J.get($);if(K)return K}Q=$!=null?hn(gn($)):{};let Y=Z||!$||!$.__esModule?BG(Q,"default",{value:$,enumerable:!0}):Q;for(let V of mn($))if(!un.call(Y,V))BG(Y,V,{get:pn.bind($,V),enumerable:!0});if(X)J.set($,Y);return Y};var tJ=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var an=($)=>$;function on($,Z){this[$]=an.bind(null,Z)}var w0=($,Z)=>{for(var Q in Z)BG($,Q,{get:Z[Q],enumerable:!0,configurable:!0,set:on.bind(Z,Q)})};var v=($,Z)=>()=>($&&(Z=$($=0)),Z);var D7=import.meta.require;var JT={};w0(JT,{lokiDir:()=>F0,homeLokiDir:()=>k4,findRepoRootForVersion:()=>OG,REPO_ROOT:()=>d0});import{resolve as I7,dirname as UG}from"path";import{fileURLToPath as nn}from"url";import{existsSync as eJ}from"fs";import{homedir as sn}from"os";function rn(){let $=XT;for(let Z=0;Z<6;Z++){if(eJ(I7($,"VERSION"))&&eJ(I7($,"autonomy/run.sh")))return $;let Q=UG($);if(Q===$)break;$=Q}return I7(XT,"..","..","..")}function OG($){let Z=$;for(let Q=0;Q<6;Q++){if(eJ(I7(Z,"VERSION"))&&eJ(I7(Z,"autonomy/run.sh")))return Z;let X=UG(Z);if(X===Z)break;Z=X}return I7($,"..","..","..")}function F0(){return process.env.LOKI_DIR??I7(process.cwd(),".loki")}function k4(){return I7(sn(),".loki")}var XT,d0;var Z8=v(()=>{XT=UG(nn(import.meta.url));d0=rn()});import{readFileSync as tn}from"fs";import{resolve as en,dirname as $s}from"path";import{fileURLToPath as Zs}from"url";function R7(){if(x4!==null)return x4;let $="10.4.1";if(typeof $==="string"&&$.length>0)return x4=$,x4;try{let Z=$s(Zs(import.meta.url)),Q=OG(Z);x4=tn(en(Q,"VERSION"),"utf-8").trim()}catch{x4="unknown"}return x4}var x4=null;var I$=v(()=>{Z8()});var GT={};w0(GT,{runOrThrow:()=>Ms,run:()=>T0,readStreamCapped:()=>$K,commandVersion:()=>Ls,commandExists:()=>K9,ShellError:()=>MG,MAX_STDOUT_BYTES:()=>qT});async function $K($,Z=qT){let Q=$.getReader(),X=new TextDecoder,J="",K=0;try{while(K<Z){let{done:Y,value:V}=await Q.read();if(Y)break;if(!V)continue;if(K+=V.byteLength,K>Z){let z=V.byteLength-(K-Z);J+=X.decode(V.subarray(0,z),{stream:!0});break}J+=X.decode(V,{stream:!0})}J+=X.decode()}finally{try{await Q.cancel()}catch{}Q.releaseLock()}return J}async function T0($,Z={}){let Q=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Z.env?{...process.env,...Z.env}:process.env,cwd:Z.cwd}),X,J;if(Z.timeoutMs&&Z.timeoutMs>0)X=setTimeout(()=>{try{Q.kill("SIGTERM")}catch{}J=setTimeout(()=>{try{Q.kill("SIGKILL")}catch{}},2000)},Z.timeoutMs);try{let[K,Y,V]=await Promise.all([$K(Q.stdout),new Response(Q.stderr).text(),Q.exited]);return{stdout:K,stderr:Y,exitCode:V}}finally{if(X)clearTimeout(X);if(J)clearTimeout(J)}}async function Ms($,Z={}){let Q=await T0($,Z);if(Q.exitCode!==0)throw new MG(`command failed (${Q.exitCode}): ${$.join(" ")}`,Q.exitCode,Q.stdout,Q.stderr);return Q}async function K9($){let Z=js($),Q=await T0(["sh","-c",`command -v ${Z}`],{timeoutMs:5000});if(Q.exitCode===0)return Q.stdout.trim()||null;return null}function js($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function Ls($,Z="--version"){if(!await K9($))return null;let X=await T0([$,Z],{timeoutMs:5000});if(X.exitCode!==0)return null;return((X.stdout||X.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var qT=16777216,MG;var s8=v(()=>{MG=class MG extends Error{message;exitCode;stdout;stderr;constructor($,Z,Q,X){super($);this.message=$;this.exitCode=Z;this.stdout=Q;this.stderr=X;this.name="ShellError"}}});function w7($){return As?"":$}var As,k0,P8,c0,U18,J8,L8,Y9,d;var i5=v(()=>{As=(process.env.NO_COLOR??"").length>0;k0=w7("\x1B[0;31m"),P8=w7("\x1B[0;32m"),c0=w7("\x1B[1;33m"),U18=w7("\x1B[0;34m"),J8=w7("\x1B[0;36m"),L8=w7("\x1B[1m"),Y9=w7("\x1B[2m"),d=w7("\x1B[0m")});import{accessSync as ks,constants as xs,existsSync as Ss,statSync as bs}from"fs";async function a5(){if(R$!==void 0)return R$;let $="/opt/homebrew/bin/python3.12";if(Ss($))return R$=$,$;let Z=await K9("python3.12");if(Z)return R$=Z,Z;let Q=await K9("python3");return R$=Q,Q}async function L6($,Z={}){let Q=await a5();if(!Q)return{stdout:"",stderr:"python3 not found",exitCode:127};return T0([Q,"-c",$],Z)}async function P7(){let $=(process.env.PATH??"").split(":").filter((Z)=>Z.startsWith("/"));for(let Z of[..._s,...$.map((Q)=>`${Q}/python3`)])try{if(!bs(Z).isFile())continue;if(ks(Z,xs.X_OK),(await T0([Z,"-I","-S","-c",""],{timeoutMs:1e4})).exitCode===0)return Z}catch{}return null}var R$,ys,_s;var X5=v(()=>{s8();ys=["/usr/bin/python3","/bin/python3"],_s=ys});var xT={};w0(xT,{runStatus:()=>Yr});import{existsSync as V9,readFileSync as $2,readdirSync as FT,statSync as DT}from"fs";import{resolve as u8,basename as rs}from"path";import{homedir as ts}from"os";function IT($){let Z=Math.trunc($);if(Z>=1e6)return`${(Math.trunc(Z/1e6*10)/10).toFixed(1)}M`;if(Z>=1000)return`${(Math.trunc(Z/1000*10)/10).toFixed(1)}K`;return String(Z)}function RT($,Z,Q){if(Z===0)return null;let X=Math.trunc($*100/Z),J=Math.trunc($*QK/Z);if(J>QK)J=QK;let K=QK-J,Y=P8;if(X>=80)Y=k0;else if(X>=50)Y=c0;let V="=".repeat(Math.max(0,J))+" ".repeat(Math.max(0,K)),z=IT($),W=IT(Z);return` ${L8}${Q}${d} ${Y}[${V}]${d} ${X}% (${z} / ${W})`}async function $r(){if(await K9("jq"))return!0;return process.stdout.write(`${k0}Error: jq is required but not installed.${d}
|
|
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)
|
|
@@ -1509,4 +1509,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
|
|
|
1509
1509
|
`),2}case"start":{let{runStart:X}=await Promise.resolve().then(() => (Hi(),Gi));return X(Q)}case"engine10":{let{runEngine10:X}=await Promise.resolve().then(() => (Oi(),Ui)),{registryLoader:J}=await Promise.resolve().then(() => (wq(),En));return X(Q,J)}default:return process.stderr.write(`Unknown command: ${Z}
|
|
1510
1510
|
`),process.stderr.write(kn),2}}CT();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var s28=await n28(Bun.argv.slice(2));process.exit(s28);
|
|
1511
1511
|
|
|
1512
|
-
//# debugId=
|
|
1512
|
+
//# debugId=F3DD389212F7F6B8993327E6BC5771DD
|
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": "10.
|
|
4
|
+
"version": "10.4.1",
|
|
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": "10.
|
|
5
|
+
"version": "10.4.1",
|
|
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",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-
|
|
1
|
+
import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-h49hpHj_.js";import{B as C}from"./Button-BubeNlVF.js";import{T as $e}from"./trending-up-DeiXF7_i.js";import{C as z}from"./clock-DxURKFW-.js";import{A as Be,U as ue,M as De}from"./Avatar-p9ksx_eu.js";import{A as J}from"./activity-DbmttG_6.js";import{R as pe}from"./refresh-cw-9k6QfjLX.js";import{G as ze}from"./globe-fb7DDJvp.js";import{C as Le}from"./chevron-left-Bsj7g0Lx.js";import{C as je}from"./check-NZElkYN9.js";import{D as Y}from"./dollar-sign-DcirTDYQ.js";import{U as Te}from"./user-LzUg4eFF.js";import{D as Me}from"./database-DyH1aJKS.js";import{L as Ue}from"./lock-AWuJecY0.js";import{S as Re}from"./scroll-text-VliGSgXD.js";import{S as Ie}from"./shield-alert-BudxBT3Y.js";/**
|
|
2
2
|
* @license lucide-react v0.577.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e}from"./index-
|
|
1
|
+
import{j as e}from"./index-h49hpHj_.js";import{C as r}from"./clock-DxURKFW-.js";import{C as a}from"./circle-alert--R-03UOi.js";import{C as l}from"./check-NZElkYN9.js";const i={completed:"bg-[#1FC5A8]/10 text-[#1FC5A8]",running:"bg-[#553DE9]/10 text-[#553DE9]",failed:"bg-[#C45B5B]/10 text-[#C45B5B]",started:"bg-[#D4A03C]/10 text-[#D4A03C]",empty:"bg-[#F8F4F0] text-[#6B6960]",version:"bg-[#553DE9]/10 text-[#553DE9]"};function o({status:t}){switch(t){case"completed":return e.jsx(l,{size:12});case"running":return e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"animate-ping motion-reduce:animate-none absolute inline-flex h-full w-full rounded-full bg-current opacity-75"}),e.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-current"})]});case"failed":return e.jsx(a,{size:12});case"started":return e.jsx(r,{size:12});default:return null}}function f({status:t,children:n,className:s=""}){return e.jsxs("span",{className:["inline-flex items-center gap-1 rounded-btn px-2.5 py-0.5 text-xs font-semibold",i[t],s].filter(Boolean).join(" "),children:[e.jsx(o,{status:t}),n]})}export{f as B};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as p,j as t}from"./index-
|
|
1
|
+
import{r as p,j as t}from"./index-h49hpHj_.js";const m={primary:"bg-[#553DE9] text-white hover:bg-[#4432c4] shadow-button rounded-btn",secondary:"border border-[#553DE9] text-[#553DE9] hover:bg-[#E8E4FD] bg-transparent rounded-btn",ghost:"text-[#36342E] hover:bg-[#F8F4F0] rounded-btn",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border border-[#C45B5B]/20 hover:bg-[#C45B5B]/20 rounded-btn"},b={sm:"px-3 py-1.5 text-xs",md:"px-4 py-2 text-sm",lg:"px-6 py-3 text-base"},u={sm:14,md:16,lg:18};function h({size:e}){return t.jsxs("svg",{className:"animate-spin",width:e,height:e,viewBox:"0 0 24 24",fill:"none",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]})}const B=p.forwardRef(({variant:e="primary",size:o="md",icon:n,iconRight:i,loading:r=!1,disabled:a,className:c="",children:l,...x},d)=>{const s=u[o];return t.jsxs("button",{ref:d,disabled:a||r,className:["inline-flex items-center justify-center gap-2 font-medium transition-colors",m[e],b[o],(a||r)&&"opacity-60 cursor-not-allowed",c].filter(Boolean).join(" "),...x,children:[r?t.jsx(h,{size:s}):n?t.jsx(n,{size:s}):null,l,i&&!r&&t.jsx(i,{size:s})]})});B.displayName="Button";export{B};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as $,r as l,j as e,G as we,Q as Se,F as Ce,h as Re,T as U,Z as Ee,a as S,V as Me,S as $e,Y as Te,X as Pe,P as ie,i as Ae,g as ze,C as Ie,l as Le,N as I,J as _e,K as De,O as Fe,u as Oe}from"./index-
|
|
1
|
+
import{c as $,r as l,j as e,G as we,Q as Se,F as Ce,h as Re,T as U,Z as Ee,a as S,V as Me,S as $e,Y as Te,X as Pe,P as ie,i as Ae,g as ze,C as Ie,l as Le,N as I,J as _e,K as De,O as Fe,u as Oe}from"./index-h49hpHj_.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-DiuMh-ej.js";import{C as qe,F as Ge,M as Ue,H as Ke,a as We,G as Ve,T as Qe}from"./thumbs-up-DG8YD2t0.js";import{C as oe}from"./check-NZElkYN9.js";import{C as Ye}from"./clock-DxURKFW-.js";import{D as Xe}from"./dollar-sign-DcirTDYQ.js";import{U as Ze}from"./upload-TsptvdQm.js";import{L as V}from"./loader-circle-CuJseaIc.js";/**
|
|
2
2
|
* @license lucide-react v0.577.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|