loki-mode 10.6.14 → 10.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -5
- package/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/acp-agent.py +128 -0
- package/autonomy/docker-run.sh +8 -0
- package/autonomy/issue-parser.sh +7 -7
- package/autonomy/issue-providers.sh +159 -1
- package/autonomy/lib/engine10-push.sh +4 -1
- package/autonomy/lib/review_risk.py +91 -0
- package/autonomy/loki +209 -19
- package/autonomy/mobile-verify.sh +66 -0
- package/autonomy/run.sh +44 -2
- package/completions/_loki +2 -0
- package/completions/loki.bash +1 -1
- package/dashboard/__init__.py +1 -1
- package/dashboard/api_runs_v1.py +80 -0
- package/dashboard/server.py +2 -0
- package/docs/INSTALLATION.md +5 -1
- package/docs/acp-editors.md +29 -0
- package/docs/api-runs-v1.md +12 -0
- package/docs/dev/architecture-reference.md +4 -0
- package/docs/merge-queue.md +13 -0
- package/docs/mobile-verify.md +11 -0
- package/docs/sentry-intake.md +13 -0
- package/docs/v10/BOARD.md +31 -6
- package/docs/v10/CONTROL-PLANE.md +7 -0
- package/docs/v10/CP-ENTERPRISE-UI.md +276 -0
- package/docs/v10/D61-SPEED.md +4 -0
- package/docs/v10/DECISIONS.md +115 -0
- package/docs/v10/ENGINE-LAWS.md +155 -0
- package/docs/v10/FAILURE-CLASSES.md +145 -0
- package/docs/v10/FOUNDER-QUEUE.md +1 -0
- package/docs/v10/GAP-RESEARCH-1003.md +32 -0
- package/docs/v10/GUIDE.md +4 -2
- package/docs/v10/L0-WAVE1.md +81 -0
- package/docs/v10/MORNING-BRIEF-1003.md +25 -0
- package/docs/v10/OPERATING-MODEL.md +1 -0
- package/docs/v10/PROGRESS.md +99 -0
- package/docs/v10/SWARM.md +32 -0
- package/docs/visual-evidence.md +5 -0
- package/loki-ts/dist/loki.js +805 -777
- package/loki-ts/package.json +1 -0
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/packages/control-plane/dist/server.js +549 -21
- package/packages/control-plane/drizzle/0002_tiresome_fixer.sql +7 -0
- package/packages/control-plane/drizzle/0003_integrity.sql +4 -0
- package/packages/control-plane/drizzle/meta/0002_snapshot.json +409 -0
- package/packages/control-plane/drizzle/meta/0003_snapshot.json +437 -0
- package/packages/control-plane/drizzle/meta/_journal.json +14 -0
- package/packages/control-plane/src/db/migrate.ts +6 -2
- package/packages/control-plane/src/db/prune.ts +91 -0
- package/packages/control-plane/src/db/schema.ts +13 -0
- package/packages/control-plane/src/server/actions.ts +60 -0
- package/packages/control-plane/src/server/app.ts +59 -4
- package/packages/control-plane/src/server/integrity.ts +147 -0
- package/packages/control-plane/src/server/runs.ts +46 -4
- package/packages/control-plane/src/shipper/discover.ts +32 -3
- package/packages/control-plane/src/shipper/ship.ts +15 -0
- package/packages/control-plane/src/shipper/watch.ts +66 -0
- package/packages/control-plane/ui/dist/assets/index-DHDI_dHM.css +1 -0
- package/packages/control-plane/ui/dist/assets/index-DaQr0MPS.js +129 -0
- package/packages/control-plane/ui/dist/index.html +3 -3
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/web-app/dist/assets/{AdminPage-oAFMNfKH.js → AdminPage-BJSU5hY1.js} +1 -1
- package/web-app/dist/assets/{Avatar-BA2gnzyf.js → Avatar-CSOSpw9c.js} +1 -1
- package/web-app/dist/assets/{Badge-Dsluv8n1.js → Badge-COr7vj0D.js} +1 -1
- package/web-app/dist/assets/{Button-WmW8A-iG.js → Button-DGoWFERp.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-BR5o_RgL.js → CockpitPage-CBpWkNXY.js} +1 -1
- package/web-app/dist/assets/{ComparePage-3Eg-pKvO.js → ComparePage-BwT8vqrL.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-DAfrnnsQ.js → ErrorBoundary-D7SicDDA.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-wLZI4OTr.js → EvidenceReceiptPanel-bx-5liG2.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-BOuadisf.js → GitHubIssuesPanel-BAeeWLqY.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-BTVoVpB3.js → GitHubPRsPanel-CssD8lGI.js} +1 -1
- package/web-app/dist/assets/{HomePage-s3GWdNEe.js → HomePage-SL5PT3m5.js} +2 -2
- package/web-app/dist/assets/{LoginPage-BfOZ566t.js → LoginPage-C8hFOZOM.js} +1 -1
- package/web-app/dist/assets/{MagicPage-9EZ83xOt.js → MagicPage-xHbHkrPf.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-OJMOYhHP.js → MetricsPage-B_2CKFcC.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-_LoJ6KEv.js → NotFoundPage-CXwXMq35.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-Duj5LSt6.js → ProjectPage-AaisMQI-.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-BBud3JrO.js → ProjectsPage-Cej5ResX.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-C4zdgKno.js → SettingsPage-DKv4mn9H.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-Nb3ACjMR.js → ShowcasePage-Dkiyzne4.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-BDi49TDh.js → SystemSettingsPage-DaBLQ5dU.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-HkcqkjLa.js → TeamsPage-B2yUr31k.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-CK796Y1F.js → TemplatesPage-CfYiANhU.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-BkvdNuT6.js → TerminalOutput-CMXoexLM.js} +1 -1
- package/web-app/dist/assets/{activity-DFgMgETR.js → activity-B0dzoZtY.js} +1 -1
- package/web-app/dist/assets/{bell-BInGGOMZ.js → bell-DFOTaSoo.js} +1 -1
- package/web-app/dist/assets/{bot-D43Yjsj4.js → bot-Dz-WSQyP.js} +1 -1
- package/web-app/dist/assets/{check-DFAGTLM9.js → check-L1QIRueJ.js} +1 -1
- package/web-app/dist/assets/{chevron-left-Drwin7n1.js → chevron-left-1TrnIEZS.js} +1 -1
- package/web-app/dist/assets/{circle-alert-DLWdb7V9.js → circle-alert-8Bf6xEDx.js} +1 -1
- package/web-app/dist/assets/{clock-Dsbi59u5.js → clock-DB8NE6P5.js} +1 -1
- package/web-app/dist/assets/{cloud-CUU-dXTP.js → cloud-DUSL3wZS.js} +1 -1
- package/web-app/dist/assets/{code-xml-CqIh7Wui.js → code-xml-DbjryWNl.js} +1 -1
- package/web-app/dist/assets/{database-DASN5Bfh.js → database-DrezrMSs.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-ZvXzAihc.js → dollar-sign-CGbaLMzR.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-ED_gN-N8.js → file-code-corner-Dfypa-r4.js} +1 -1
- package/web-app/dist/assets/{file-plus-BmBHndXt.js → file-plus-CzV5L2Gd.js} +1 -1
- package/web-app/dist/assets/{globe-Ck_iEzO4.js → globe-BoYjTwPQ.js} +1 -1
- package/web-app/dist/assets/{hammer-B8YKMard.js → hammer-WO-HuiyJ.js} +1 -1
- package/web-app/dist/assets/{index-D7SxmjVQ.js → index-CjIOUjnd.js} +3 -3
- package/web-app/dist/assets/{layers-CGVsj3wB.js → layers-Bn6jtKNk.js} +1 -1
- package/web-app/dist/assets/{loader-circle-FIH7UJDF.js → loader-circle-gERWRnmW.js} +1 -1
- package/web-app/dist/assets/{lock-vR8HoAnK.js → lock-BIiMLJq8.js} +1 -1
- package/web-app/dist/assets/{package-mZ6LFwXp.js → package-dLvDSVys.js} +1 -1
- package/web-app/dist/assets/{plus-CtnSVu0w.js → plus-BHM3ZLhZ.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-BIapF6Gj.js → refresh-cw-BAp_alv6.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-LMkSsm21.js → rotate-ccw-CBhwq_MG.js} +1 -1
- package/web-app/dist/assets/{scroll-text-DQVlIhr9.js → scroll-text-DoS-6dfU.js} +1 -1
- package/web-app/dist/assets/{server-GqyhQxmz.js → server-5JgdDWQO.js} +1 -1
- package/web-app/dist/assets/{shield-alert-BrFTNJ-I.js → shield-alert-DjmlLT34.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-lgwAEJFW.js → thumbs-up-BtiEXl3p.js} +1 -1
- package/web-app/dist/assets/{trash-2-C1cNysK4.js → trash-2-ClsWU_Vg.js} +1 -1
- package/web-app/dist/assets/{trending-down-DQFZ6j5s.js → trending-down-DPS4M7_X.js} +1 -1
- package/web-app/dist/assets/{trending-up-BJG_Zo8V.js → trending-up-D6OJ38-V.js} +1 -1
- package/web-app/dist/assets/{upload-BOY1aTpA.js → upload-DOCzLUpF.js} +1 -1
- package/web-app/dist/assets/{usePolling-DoAmsTNy.js → usePolling-CljQTWj_.js} +1 -1
- package/web-app/dist/assets/{user-iOfCe0_v.js → user-C0G82Weu.js} +1 -1
- package/web-app/dist/index.html +1 -1
- package/packages/control-plane/ui/dist/assets/index-CFfrqCx2.css +0 -1
- package/packages/control-plane/ui/dist/assets/index-Jt31nrK-.js +0 -114
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Runs REST API (/api/v1/runs)
|
|
2
|
+
|
|
3
|
+
Served by the local dashboard (loopback by default). Auth reuses the dashboard
|
|
4
|
+
scopes: "read" for GET, "control" for POST. With auth off (default local mode)
|
|
5
|
+
no token is needed; with it on, send `Authorization: Bearer <token>`.
|
|
6
|
+
|
|
7
|
+
- `GET /api/v1/runs` - envelope `{runs, source, freshness_s, reason}`, newest first.
|
|
8
|
+
- `GET /api/v1/runs/{id}` - one run plus per-iteration detail (current run only); 404 if unknown.
|
|
9
|
+
- `POST /api/v1/runs` - start a run. Body: `{"prd_text": "..."}` or `{"prd_path": "..."}`, optional `provider`, `parallel`. Same behavior as `POST /api/control/start` (single-flight, 409 if busy).
|
|
10
|
+
- `POST /api/v1/runs/{id}/stop` - stop the run. Only the current run can be stopped (409 otherwise, 404 if unknown).
|
|
11
|
+
|
|
12
|
+
Cost and status fields come from measured records only; unmeasured values are null, never 0.
|
|
@@ -101,3 +101,7 @@ These knobs together implement the RARV-C (closure) loop: findings -> override c
|
|
|
101
101
|
## Worktree substrate (autonomy/lib/worktree_prep.py)
|
|
102
102
|
|
|
103
103
|
`prepare_worktree(source_repo, dest, branch, setup=None, base=None)` creates an isolated git worktree and returns `{path, base_sha, deps, left_out_changes}`. The start point is `origin/HEAD` after a fetch (when a remote exists), else HEAD. Uncommitted edits in the source checkout are never carried or stashed; their count is reported as `left_out_changes`. An fcntl lock at `~/.loki/repos/<slug>.lock` covers fetch and worktree add. Dependencies: a `setup` command run in the worktree, else a copy-on-write copy of ignored top-level `node_modules`, `.venv`, `venv`, `vendor` (refused as "copy unsafe, declare setup" if it holds absolute symlinks or editable finders), else `none`. CLI: `python3 autonomy/lib/worktree_prep.py SRC DEST BRANCH [--setup CMD] [--base REF]` prints the result as JSON. Not yet wired into backlog or the UI.
|
|
104
|
+
|
|
105
|
+
## Project memory across runs
|
|
106
|
+
|
|
107
|
+
extract_learnings_from_session (autonomy/run.sh) mirrors learnings and decisions into .loki/memory/learnings/project-*.jsonl. get_relevant_learnings adds a bounded newest-first project_memory list (15 entries, LOKI_PROJECT_MEMORY_MAX_CHARS, default 2000) to .loki/state/relevant-learnings.json at run start. LOKI_PROJECT_MEMORY=0 disables both. Test: tests/test-project-memory.sh.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# loki merge
|
|
2
|
+
|
|
3
|
+
Serial PR merge queue (requires the `gh` CLI, authenticated).
|
|
4
|
+
|
|
5
|
+
loki merge add 101 102 103 # queue PRs (stored in .loki/merge-queue)
|
|
6
|
+
loki merge run --dry-run # list what would happen, change nothing
|
|
7
|
+
loki merge run # merge one at a time
|
|
8
|
+
|
|
9
|
+
Rules: a PR merges (squash) only when `gh pr checks` exits 0. Pending checks are
|
|
10
|
+
polled (LOKI_MERGE_POLL_S, default 20s; LOKI_MERGE_MAX_POLLS, default 90). After
|
|
11
|
+
each merge the next PR is rebased onto the new base and must pass checks again.
|
|
12
|
+
PRs that are red, time out, or fail to rebase stay in the queue; the command
|
|
13
|
+
exits nonzero. Nothing is force-pushed and no check is bypassed.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Mobile emulator tests
|
|
2
|
+
|
|
3
|
+
`bash autonomy/mobile-verify.sh [project_dir]`
|
|
4
|
+
|
|
5
|
+
Detects React Native/Expo (package.json) or Flutter (pubspec.yaml). Looks for a booted Android emulator (`adb devices`) or iOS simulator (`xcrun simctl list devices booted`).
|
|
6
|
+
|
|
7
|
+
Test command: `LOKI_MOBILE_TEST_CMD`, else `flutter test [integration_test]`, else `npm run test:e2e` / `npm run e2e`.
|
|
8
|
+
|
|
9
|
+
Exit codes: 0 ran and passed (or not a mobile project, stated); 1 ran and failed; 3 NOT VERIFIED (no device or no e2e script). A NOT VERIFIED result must never be reported as a pass.
|
|
10
|
+
|
|
11
|
+
Timeout: `LOKI_MOBILE_TIMEOUT` seconds (default 600).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Sentry intake
|
|
2
|
+
|
|
3
|
+
`loki start` turns a Sentry issue into a task spec (error, stack trace, breadcrumbs, acceptance criteria).
|
|
4
|
+
|
|
5
|
+
Offline, from an exported JSON file (issue export, event, or `{issue, event}`):
|
|
6
|
+
|
|
7
|
+
loki start ./sentry-issue.json
|
|
8
|
+
|
|
9
|
+
From a URL (needs `SENTRY_AUTH_TOKEN`; without it nothing is fetched):
|
|
10
|
+
|
|
11
|
+
SENTRY_AUTH_TOKEN=... loki start https://sentry.io/organizations/acme/issues/4001/
|
|
12
|
+
|
|
13
|
+
The token is sent only to the Sentry host through a curl config on stdin, never on argv, and is never printed. Implementation: `autonomy/issue-providers.sh` (`normalize_sentry_json`).
|
package/docs/v10/BOARD.md
CHANGED
|
@@ -185,7 +185,7 @@ set is declared to avoid overlap with those and with each other.
|
|
|
185
185
|
| S-13 | BACKLOG 48: same-class D7 hardening -- `loki outcomes canary verify`, `proof share`/`show` heredocs, empty PATH component | autonomy/loki (the specific inline python3 sites named), its test | MEDIUM | released@2026-09-27T15:00Z | Merged bb99e675, pushed; quorum topped up 2/2 APPROVE. RED leg pins a literal parent SHA (reachability-checked, SKIP on a shallow clone) instead of HEAD, confirmed to survive being merged. `loki_verify_tool_path()` rejects any non-absolute PATH entry. Quorum reviewer confirmed all 5 hardened call sites fail closed (hard error), never silently fall back to a bare unscoped python3. Shipped in v9.56.0 (merged before the 14:16:24Z release push of b651b98d; on npm 15:00:06Z). |
|
|
186
186
|
| S-14 | BACKLOG 49: verifier stdout still says `ok: true` on ABSENT/NOT CHECKED while exit is 1/2 | autonomy/loki (`cmd_proof verify)` case), its test | MEDIUM | released@2026-09-27T15:00Z | `TAMPERED if attestation=="FAILED" or hash_ok is False`; both JSON and `--human` share one verdict computation. Unanimous 2/2 APPROVE. Reviewer 2 independently isolated the hash-only-corrupted case (a scenario reviewer 1's body-mutation approach couldn't architecturally produce, since receipt_sha256 and verification.hash are the same canonical digest by design) and confirmed the `or`'s hash_ok disjunct correctly fires TAMPERED there too. Both reviewers confirmed the `--human` residual gap is real but non-blocking (exit code and stderr both correct; a pure-stdout consumer sees a weaker finding). f8deb64a. Shipped in v9.56.0 (merged before the 14:16:24Z release push of b651b98d; on npm 15:00:06Z). |
|
|
187
187
|
| S-15 | BACKLOG 50: remote NOT CHECKED returns 0, local returns 2 -- align or document | the remote verifier path, docs/exit-codes.md | LOW | either the remote exit is changed to 2 with a test proving it, or docs/exit-codes.md documents the divergence explicitly with the reason; pick one and record which in the commit message | released@2026-09-27T15:00Z | Main since 34198ff4. Round 1 found the first draft factually wrong (missed the nopubkey unconditional-exit-1 override), corrected and re-approved. Shipped in v9.56.0 (merged before the 14:16:24Z release push of b651b98d; on npm 15:00:06Z). |
|
|
188
|
-
| S-16 | BACKLOG 22 follow-on / housekeeping: `scripts/release.sh` only bumps 3 of the 14 files CLAUDE.md's release checklist requires (VERSION, package.json, vscode-extension/package.json) | scripts/release.sh | MEDIUM | released@2026-09-27T16:40Z | Rebased to ed565709. Fixed the subshell-scoping bug (`--dry-run`/`--help` silently broken) and switched to anchored per-format sed slots for drift-safety. 2/2 reviewers ran independently: reviewer 1 (Opus) APPROVE, one non-blocking permissions note. Reviewer 2 (Sonnet) CONCERN, blocking: `apply_sed()`'s mktemp+mv silently narrows all 14 touched files from 644 to 600 on every release (mktemp always creates 600, mv keeps the temp file's mode, not the original's) -- confirmed live on a real bump run. Fix (`cp -p` after mktemp, before the sed redirect) dispatched as rework; full verification suite (subshell fix, drift-detection, idempotency, fail-closed assert, plus the new permissions check) to be re-run before a fresh quorum. Correction: stale building@ with no live agent and no commit of its own (git log --all --grep found none). Re-cut to ready. Dispatched 15:00 (workflow wf_29a75a9c-652, slice-card brief). Built 9bf1ddda (test-release-sh.sh). Reviewer dispatched 15:16 to verify the mode-preservation fix. CONCERN: tests/test-release-sh.sh is never invoked. Rework sent 15:28 (register it). Rework 12f2d681: test registered (mode fix 59fcbaa3 is in the branch). Re-review dispatched 15:40. 1/1 APPROVE (test registered; mode fix 59fcbaa3 in the branch). Train 4: this ends the D27 VERSION editor-tool exception. Cherry-picked onto main for train 4 (4 commits); D27 checks green except tests/test-select-tests.sh, which hit the 60s cap (rc=124; CI runs it in full; reviewer ran 38/38). Train 4 release commit 08d64f4e (v9.59.0) pushed 16:07:02Z, ls-remote verified. Released in v9.59.0 (Release run 36332036567 publish-npm success; v9.58.0 itself never published, superseded). |
|
|
188
|
+
| S-16 | BACKLOG 22 follow-on / housekeeping: `scripts/release.sh` only bumps 3 of the 14 files CLAUDE.md's release checklist requires (VERSION, package.json, vscode-extension/package.json) | scripts/release.sh | MEDIUM | (not recorded; see Notes) | released@2026-09-27T16:40Z | Rebased to ed565709. Fixed the subshell-scoping bug (`--dry-run`/`--help` silently broken) and switched to anchored per-format sed slots for drift-safety. 2/2 reviewers ran independently: reviewer 1 (Opus) APPROVE, one non-blocking permissions note. Reviewer 2 (Sonnet) CONCERN, blocking: `apply_sed()`'s mktemp+mv silently narrows all 14 touched files from 644 to 600 on every release (mktemp always creates 600, mv keeps the temp file's mode, not the original's) -- confirmed live on a real bump run. Fix (`cp -p` after mktemp, before the sed redirect) dispatched as rework; full verification suite (subshell fix, drift-detection, idempotency, fail-closed assert, plus the new permissions check) to be re-run before a fresh quorum. Correction: stale building@ with no live agent and no commit of its own (git log --all --grep found none). Re-cut to ready. Dispatched 15:00 (workflow wf_29a75a9c-652, slice-card brief). Built 9bf1ddda (test-release-sh.sh). Reviewer dispatched 15:16 to verify the mode-preservation fix. CONCERN: tests/test-release-sh.sh is never invoked. Rework sent 15:28 (register it). Rework 12f2d681: test registered (mode fix 59fcbaa3 is in the branch). Re-review dispatched 15:40. 1/1 APPROVE (test registered; mode fix 59fcbaa3 in the branch). Train 4: this ends the D27 VERSION editor-tool exception. Cherry-picked onto main for train 4 (4 commits); D27 checks green except tests/test-select-tests.sh, which hit the 60s cap (rc=124; CI runs it in full; reviewer ran 38/38). Train 4 release commit 08d64f4e (v9.59.0) pushed 16:07:02Z, ls-remote verified. Released in v9.59.0 (Release run 36332036567 publish-npm success; v9.58.0 itself never published, superseded). |
|
|
189
189
|
| S-17 | BACKLOG 43: council/runner test-result readers (`completion-council.sh`'s 4 `python3 -c` sites) can be shadowed by a committed `hashlib.py`/`json.py` in the agent's own repo (cwd module shadowing, honest-verdict, HIGH) | autonomy/completion-council.sh (the 4 named `python3 -c` test-results readers only, not the S-07 vote site), its test | HIGH | released@2026-09-27T15:00Z | Rebased onto current main in worktree-agent-a5422f6f162d3dd2f (now at 23025a09), NOT yet merged -- HIGH tier requires 3+1 unanimous APPROVE (D12/D13) before merge, which has not run against this diff. Found the CODE fix already shipped in 3bc40efb (all 43 inline python3 sites in this file, including all 4 named readers, already have the D7 pattern) -- this slice is test-coverage-only, no production code changed. Extended tests/moat/p2-honest-verdict.sh's existing P2.council-readers-not-shadowed case to drive the 3 previously-untested readers (council_heuristic_review, council_evaluate_member, council_devils_advocate_review) via mutation-cycle verification (stripped each site's filter, confirmed shadow fired/verdict flipped, restored, reconfirmed clean). No cases.txt/pending.txt change (no new case ID). Solo-verified (not a substitute for quorum): moat matches main (3 of 9, no rule failed), shellcheck clean (one pre-existing unrelated SC2034 warning). Full 4-reviewer HIGH-tier quorum: 3/4 APPROVE, 1/4 CONCERN -- NOT unanimous, rework needed. Reviewer 3 (Opus) found a real, more severe, OUT-OF-SCOPE bypass in the SAME file's reader hardening (bucket-(b) per D21, not a veto on this test-coverage-only slice): the readers' `python3 -E -c` calls have no `-I`/`-S`/fixed-path resolution, lighter than BACKLOG 129's equivalent fix; reproduced live via a planted `.pth` flipping a genuinely-failing verdict to CONFIRMED_COMPLETE. Filed as BACKLOG 134. Reviewer 4 (Sonnet) CONCERN, blocking, reproduced live: the 3 new call sites (`tests/moat/p2-honest-verdict.sh:802-804`) discard rc/stdout and rely only on a shared marker file staying empty -- a typo'd function name (verified: renaming `council_heuristic_review` to a nonexistent name) still reports PASS, since a nonexistent-function call never touches the marker either. Fix: assert rc/vote-text differs between the fail and green legs for each of the 3 new calls (reviewer already confirmed each site's distinct fail/green vote text: council_heuristic_review -> VOTE:REJECT/VOTE:APPROVE; council_evaluate_member -> CONTINUE.../COMPLETE...; council_devils_advocate_review -> OVERRIDE_CONTINUE/CONFIRMED_COMPLETE). Same reviewer also found a 6th reader, `council_managed_should_stop` (already D7-hardened, gated behind 3 default-false experimental flags, not currently exploitable) not covered by this case -- filed as BACKLOG 135, non-blocking follow-up, not part of this rework. Rework commit 4df70b2d (rebased): `council_call_args` now captures and asserts each call's actual vote-text output against the pattern the file's pre-existing 2-reader loop already uses, matching each site's real fail-leg/green-leg strings verified against completion-council.sh source directly. Also fixed a subtler fixture-contamination bug found during rework: `council_heuristic_review`'s original fixture file independently drove REJECT via a separate grep check regardless of whether the D7-guarded reader even ran; switched to a neutral empty file so the assertion depends only on the reader under test. Typo-reproduction re-verified for all 3 sites (before: silent PASS; after: loud FAIL naming the broken site). Full mutation cycle re-verified. Fresh 4-reviewer HIGH-tier quorum: reviewer 1/4 (Opus) APPROVE, independently confirmed the typo test both ways (renamed the test's call AND separately renamed the production function), verified every expected vote string against completion-council.sh source directly, independently reproduced that the neutral-fixture fix is genuinely necessary (the original evidence file's own text content drives REJECT via the role's own grep check, masking a stripped D7 filter at the heuristic reader specifically), and ran the full mutation cycle per-site and combined. No blocking findings. Reviewer 3/4 (Opus) also APPROVE: confirmed the vote-text comparison is exact-match (not a fooled-by-prefix risk), found one genuine limit (the devil's-advocate result-WRITER site at completion-council.sh:4058 is uncaptured stdout, so a decoy vote there could theoretically slip past the vote-text check alone -- but confirmed via its own mutation that the marker check independently catches this case, proving the two checks are complementary, not redundant), reproduced the typo test on 2 of 3 sites, and confirmed the case's own claims stay within what it actually tests (does not overclaim coverage of the separate BACKLOG 134 gap). Flagged (and I confirmed clean, transient) a worktree hygiene note: other review agents' own scratch scripts briefly appeared in this shared worktree's tests/moat/ directory during concurrent review, causing a spurious DUPLICATE SCRIPT moat failure for one reviewer -- verified via git status that nothing persisted or got tracked. Reviewer 4/4 (Sonnet, the original round-1 CONCERN-finder re-checking their own finding) also APPROVE: reproduced the original bug fresh against the pre-rework file for all 3 functions (confirmed the gap was not limited to just one), confirmed all 3 typos now fail loudly against the reworked file, and went further than the original ask by testing a stronger variant not explicitly claimed by the commit -- swapping one function's definition to occupy ANOTHER's name (wrong-function-called-instead-of-missing) -- and confirmed the assertion catches that too, since all 3 sites' vote vocabularies are pairwise distinct. Reviewer 2/4 (Sonnet) also APPROVE: confirmed the 6th-reader scope from BACKLOG 135 still holds and is unchanged, found a real but genuinely out-of-scope bypass (a stub function redefined inside the test harness's own subshell can fool the vote-text check -- requires editing the test itself, not achievable via the actual PYTHONPATH-shadow threat model this test defends against), and caught its own FIRST mutation-cycle attempt was too weak (only proved the marker fired, not the vote-text check specifically) -- consulted the advisor, redid it per-site, and confirmed all 3 vote-text brackets genuinely fire on their own, not just the marker. **Unanimous 4/4 APPROVE. Merged to main (410046ce).** Shipped in v9.56.0 (merged before the 14:16:24Z release push of b651b98d; on npm 15:00:06Z). |
|
|
190
190
|
| S-18 | BACKLOG 149 (escalated from BACKLOG 44, real production gap not just test-coverage): the GH CLI's own `hosts.yml` credential file is completely unprotected by Rule-of-Two's env-var withhold -- an injected prompt can just run real `gh`, which resolves credentials from `$HOME` regardless of the withheld env vars | autonomy/run.sh (the withhold call site), loki-ts/src/runner/github_token.ts (Bun equivalent), tests/moat/p9-rule-of-two.sh | HIGH | released@2026-09-28T01:11Z | **ROUND 2 REJECT (new reviewer), a different and more severe bypass than round 1**: round 1's fix (env sentinel + GH_CONFIG_DIR + git credential.helper reset via GIT_CONFIG_COUNT/KEY/VALUE) correctly closes both round-1-confirmed bypasses -- verified independently by BOTH round-2 reviewers (one APPROVE, one REJECT, but the REJECT's own verification of the round-1 fixes is itself a clean pass). The REJECT is for a THIRD, previously undisclosed and unhandled vector: **SSH transport is completely unhandled**. Every round-1 mechanism (token sentinel, GH_CONFIG_DIR, credential.helper reset) covers only HTTPS-based git/gh credential resolution -- none touch SSH_AUTH_SOCK, GIT_SSH_COMMAND, core.sshCommand, or ~/.ssh. Reproduced live, read-only: `ssh-add -l` exits 0 (the provider session's live, untouched $HOME/env always has a reachable SSH agent by the fix's own design), and `ssh -T git@github.com` completes full auth as the real account, completely unaffected by every round-1 mitigation. An agent can simply `git remote set-url origin git@github.com:<owner>/<repo>.git && git push` and authenticate exactly as an unrestricted session -- simpler than the already-disclosed `gh auth token -u <username>` gap (no username lookup, no keychain tooling, just the operator's normal always-on ssh-agent). The P9 test's own PASS assertion text is unqualified and false for this case. Fix path per the reviewer: extend the existing capture/apply/restore/depth-counter architecture (already correct for the HTTPS vars) to also sentinel SSH_AUTH_SOCK and override GIT_SSH_COMMAND/core.sshCommand for the withheld session -- a bounded addition to an already-sound design, not a redesign. Two secondary non-blocking findings folded into the rework: (1) `env -u GH_TOKEN -u GITHUB_TOKEN gh auth token` is an undisclosed sibling of the already-disclosed username-lookup gap, needs naming; (2) the Bun/TS route has no git-version floor check the bash route already added, silently no-oping the credential.helper reset on git < 2.31 with no operator signal. Per the founder's D25 directive, this does NOT block the current release train -- the vulnerability this slice fixes (both round-1 and this newly-found SSH gap) is already live in published v9.55.0 either way; S-18 ships in its own train the moment its review reaches unanimous APPROVE. Rework dispatched. Round 3 built 3af8cdac (stack 6e38257c, 94f8b26a, b8c0eccf): SSH_AUTH_SOCK unset and GIT_SSH_COMMAND=false in the withheld window with a trusted re-grant, Bun git-floor warning, P9 SSH tier mutation-tested. Disclosed residual: direct ssh -i <key>. 2 opus HIGH reviewers dispatched 14:26. Ships in its own train once unanimous (D25). Round 3 HIGH reviewer 1: SSH blocker CLOSED (synthetic agent), re-grant/depth/login shells verified; REJECT for a new reproduced Bun-route bypass: 5 bare git spawns (council.ts:178,:190,:401, prd_reuse.ts:161-175) inherit the startup env with real GH_TOKEN/SSH_AUTH_SOCK, so an agent core.fsmonitor script runs with operator creds. Round 4 sent 14:43. Round 4 9cb330cb: Bun start-env spawn leak, nested run fails closed, SSH re-grant test. 2 HIGH reviewers dispatched 15:05. Round 4 closed all round-3 findings, but both HIGH reviewers REJECT: the trusted push in on_run_complete (default on) and create_session_pr runs an agent-planted pre-push hook or core.sshCommand with every withheld channel restored (reproduced with synthetic creds). Round 5 sent 15:16: push from a Loki-owned temp repo. CEO decision pending: a Loki-spawned nested run fails closed and cannot push. Round 5 7d5b7fb4: the push goes from a fresh private repo (origin validated as github.com), gh runs from / with GH_REPO; new 38-check test and P9 planted scenario with a positive control; mutation red. Incidents during the build: a glob rm in the shared scratchpad root and 4 synthetic insteadOf lines written to the real ~/.gitconfig (removed; grep of ~/.gitconfig for loki-test/insteadOf found none at 15:40). 2 HIGH reviewers dispatched 15:40. Round 5: reviewer A APPROVE (no plant saw a credential; fetch runs withheld; URL validator rejects 14 attack forms); reviewer B CONCERN: proof-check.sh:208 `gh repo view` ignores GH_REPO from /, so the opt-in check-run never posts (reproduced). Round 6 sent 15:51 with shallow, alias and warning fixes. Round 6 e84f1136: proof-check uses _loki_trusted_repo, explicit --repo, --update-shallow, visible refusals, case-insensitive host, origin pinned (F1). trusted-push 54/54, P9 4/4. HIGH re-review dispatched 16:01. Train 5 (release 1cde81a7, v9.60.0, pushed 16:22:51Z, ls-remote verified) on the founder instruction "just release everything asap, no more tests for development work completed so far": round 6 was not re-reviewed. Follow-up S-100. Released v9.80.1 (npm view loki-mode time: 2026-09-28T01:11:53Z). |
|
|
191
191
|
| S-41 | BACKLOG 139 (top-ranked GF-3 follow-up): shipped composite GitHub Actions (`.github/actions/issue-to-pr/action.yml`, root `action.yml`) still put `GH_TOKEN` in the SAME step as the agent invocation -- an agent can read another process's environment via `/proc/<ppid>/environ` on hosted Linux regardless of its own env | .github/actions/issue-to-pr/action.yml, root action.yml | MEDIUM | released@2026-09-27T15:00Z | Root action.yml was already correct (3 agent-invoking steps never had GH_TOKEN); the real violation was `.github/actions/issue-to-pr/action.yml`'s single fetch-and-run step, split into a token-holding fetch step (writes a PRD file via `gh issue view`) and a token-free `loki start <file>` step (file-mode). Also blanks all 4 token vars on root action.yml's 3 agent steps as defense-in-depth. Unanimous 2/2 APPROVE, both fully independent and adversarial (output-tampering, argument-injection, PRD-content-leak angles all checked clean). One non-blocking follow-up filed: an owner/repo parsing divergence on refs with extra slashes (cosmetic, `gh` rejects either way). 8a714c73 (cherry-picked onto local main, pending push). Shipped in v9.56.0 (merged before the 14:16:24Z release push of b651b98d; on npm 15:00:06Z). |
|
|
@@ -200,9 +200,9 @@ set is declared to avoid overlap with those and with each other.
|
|
|
200
200
|
| S-24 | BACKLOG 70: the snapshot/hash state lives in agent-writable `.loki/state` -- an adversarial agent can add entries (hide/uncommit files) or delete the hash file (suppress preexisting_modified disclosure) | autonomy/run.sh (snapshot/hash file location and read/write guards only), its test | HIGH | released@2026-09-27T15:00Z | Merged c983c4fc + the awk-bypass fix c315cbe9, both pushed; quorum now 4/4 APPROVE on the awk fix. In-memory seal, checked at 3 read sites; a mismatch forces the existing fail-closed "commit nothing" path. Two rounds of adversarial review found and closed two real bypasses (`.pth`-file hijack, then a relocated `awk`-on-PATH bypass in the fix for the first). Digest computation now uses only fixed-path system tools and pure shell string handling, with hex validation. 51/51 regression, moat unchanged. BACKLOG 129/130 track the remaining follow-ups (writer/reader paths still bare python3 -E, audit-log digest values, session-created.z unsealed); BACKLOG 129's writer/reader hardening (merge 3e374500) now at full 4/4 HIGH-tier APPROVE quorum. Both bypass classes independently re-reproduced and re-confirmed closed by the top-up reviewers (.pth in Homebrew's own site-packages, fake git on PATH); legitimate-case output confirmed byte-identical pre/post fix. Non-blocking: BACKLOG 131 corrected for an undercounted/misattributed git-call inventory and a missing core.worktree mention; BACKLOG 132 opened for a bash-3.2-only mutant-detection gap in the shadow-write fix's own test (unrelated slice, found during the same top-up pass). Shipped in v9.56.0 (merged before the 14:16:24Z release push of b651b98d; on npm 15:00:06Z). |
|
|
201
201
|
| S-26 | Founder directive: `scripts/v10-pulse.sh`, the anti-drift status/violation reporter (docs/v10/CONTROL.md). See docs/v10/BACKLOG.md for the full spec. | scripts/v10-pulse.sh (new), tests/test-v10-pulse.sh (new), tests/run-all-tests.sh (registration) | MEDIUM | released@2026-09-27T15:00Z | Rework commit 169d7cbb (worktree-agent-a612cc8e14bb1265a, rebased onto current main) addresses all 3 original CONCERN findings: (1) git calls now explicitly pinned to `$PULSE_MAIN_REF` (6 call sites, verified by grep -- no bare git describe/log/show/rev-parse remain that should be pinned); (2) `--first-parent` added to the tag..MAIN_REF walk, verified against real repo history (128 commits without vs. 80 with, ~32min difference from swarm merge patterns) and a synthetic backdated-branch fixture; (3) MOAT_REGRESSION redesigned around `PULSE_MOAT_RESULT` (a file path to a captured `tests/moat/run.sh` output) as the sole trusted source -- a live suite FAIL is now always a violation regardless of count, a count-only drop fires separately, and with no result supplied the check reports UNKNOWN rather than a false clean. Real behavior change, disclosed by the builder: a default run with no `PULSE_MOAT_RESULT` can no longer exit 0 for this specific check. 31/31 own tests pass (both bash and real bash 3.2.57), shellcheck clean. Re-review: 2/2 APPROVE. Reviewer 2/2 (Sonnet) independently verified all 3 fixes via mutation testing (reverting each fix flips exactly its own test(s)), fed PULSE_MOAT_RESULT 5 different input shapes (real output, hand-crafted fixture, garbage, empty, nonexistent path) all degrading correctly to UNKNOWN or a true parse, confirmed the diff is scoped exactly to the 3 fixes with no regression elsewhere (31/31 full suite, bash -n and shellcheck clean on both bash versions, exit-code/BOARD/CONTROL.md checks all still correct against the real repo), and found one non-blocking documentation-precision nit (header comment doesn't mention the deliberate COULD-NOT-CHECK exclusion, though the actual code and its test T16b handle it correctly). Reviewer 1/2 (Opus) independently confirmed all 3 fixes with its own live/synthetic fixtures (cloned repo with HEAD pinned to an older tag to prove MAIN_REF pinning; a backdated-branch-merged-later fixture for --first-parent; a real `bash tests/moat/run.sh` run fed through PULSE_MOAT_RESULT showing the true 2-of-9-FAIL state where the original code claimed 3-of-9-clean) and flagged one good forward-looking note (the moat-result file isn't yet tied to a commit SHA -- tracked as BACKLOG 133 for the hook-wiring work, not blocking this merge). Unanimous 2/2 APPROVE. **Merged to main (3c3da457).** Shipped in v9.56.0 (merged before the 14:16:24Z release push of b651b98d; on npm 15:00:06Z). |
|
|
202
202
|
| S-27 | BACKLOG 125 B-1: P7 scanner reassignment-fallback bypass -- `let rows = data; if (!rows.length) rows = [rows]; setRows(rows);` -- `DECL_ARR` only matches the declaration form, never a later bare `x = [` assignment | tests/moat/p7-no-fabricated-data.sh (scanner rule + a new red/green case; never weaken an existing arm) | MEDIUM | released@2026-09-27T15:00Z | New `REASSIGN_ARR` regex + `DECL_KEYWORD` guard catches a fabricated array reassigned after declaration. Unanimous 2/2 APPROVE, both reviewers independently reproduced the bypass with their own fixtures. Non-blocking flag for whoever merges S-28 second: on a destructuring/parameter-default fixture that ALSO flows to a setter (untested by either slice today), whichever arm runs first wins the finding's MESSAGE (correct detection either way, just message-attribution -- "reassigned" vs "parameter default"). Recommend reordering DEFAULT_ARR ahead of REASSIGN_ARR when S-28 merges. 94137535. Shipped in v9.56.0 (merged before the 14:16:24Z release push of b651b98d; on npm 15:00:06Z). |
|
|
203
|
-
| S-28 | BACKLOG 125 B-2: P7 scanner destructuring/parameter-default bypass -- `const { rows = [rows] } = data;` or `function load(rows = [rows]) {}` -- neither is a `name = [` declaration the scanner recognizes | tests/moat/p7-no-fabricated-data.sh (scanner rule + a new red/green case; never weaken an existing arm) | MEDIUM | released@2026-09-28T01:11Z | Correction: stale building@ with no live agent and no commit of its own (git log --all --grep found none). Re-cut to ready. Dispatched 15:49 (S-29 released). Train 7 (release 9218ea04, v9.62.0, pushed 16:29:17Z, ls-remote and tag ^{} verified), unreviewed (founder "release everything"). The v9.62.0 Release run was cancelled at 16:30 (the tree carries the S-18 P9 regression). Released v9.80.1 (npm view loki-mode time: 2026-09-28T01:11:53Z). |
|
|
203
|
+
| S-28 | BACKLOG 125 B-2: P7 scanner destructuring/parameter-default bypass -- `const { rows = [rows] } = data;` or `function load(rows = [rows]) {}` -- neither is a `name = [` declaration the scanner recognizes | tests/moat/p7-no-fabricated-data.sh (scanner rule + a new red/green case; never weaken an existing arm) | MEDIUM | (not recorded; see Notes) | released@2026-09-28T01:11Z | Correction: stale building@ with no live agent and no commit of its own (git log --all --grep found none). Re-cut to ready. Dispatched 15:49 (S-29 released). Train 7 (release 9218ea04, v9.62.0, pushed 16:29:17Z, ls-remote and tag ^{} verified), unreviewed (founder "release everything"). The v9.62.0 Release run was cancelled at 16:30 (the tree carries the S-18 P9 regression). Released v9.80.1 (npm view loki-mode time: 2026-09-28T01:11:53Z). |
|
|
204
204
|
| S-29 | BACKLOG 125 B-5: P7 scanner module-level named fallback table -- `const FALLBACK_ROWS = [rows];` at column 0, referenced later via `data.length ? data : FALLBACK_ROWS` -- the column-0 exemption plus identifier-branch ternary both let it through unless the name matches sample/mock/demo/fake/placeholder | tests/moat/p7-no-fabricated-data.sh (scanner rule + a new red/green case; never weaken an existing arm) | MEDIUM | released@2026-09-27T15:00Z | Unanimous review across 6 rounds; round 6 (ab72ba3f) got a thorough final APPROVE that extended the discrimination check to 2 other call sites. Merge was non-trivial (S-29's chain predates S-27/S-32's own merges to this same file); a dedicated merge-pass agent reconciled all three lineages (5 conflict hunks, 2 mid-heredoc splices manually repaired), and a dedicated adversarial reviewer independently verified the reconciliation (read the full ~1364-line diff, confirmed heredoc balance, no duplicate definitions, all 3 lineages' fixtures intact, scanner and moat suite clean, built its own combined 3-lineage fixture confirming no shadowing). VOTE: APPROVE. Merged as 418b8f2f (a real 2-parent merge commit, content taken verbatim from the reviewed merge-pass commit cd0e5124 since main had not moved on this file since the merge-pass agent's own base -- confirmed via `git diff` before applying, avoiding a second unreviewed reconciliation attempt). Disclosed residual gap, not fixed here: an enclosing-paren confusion class (`(x || TABLE) && other` etc.), documented with a `ponytail:` comment for a future AST rewrite. Shipped in v9.56.0 (merged before the 14:16:24Z release push of b651b98d; on npm 15:00:06Z). |
|
|
205
|
-
| S-30 | BACKLOG 125 B-6: P7 scanner ternary-against-null bypass -- `const r = loading ? null : [rows];` -- `is_literal(null)` is true so the both-branches-literal exemption suppresses it; should only treat an array/object literal, never null/undefined/empty-string, as the "literal other branch" | tests/moat/p7-no-fabricated-data.sh (scanner rule + a new red/green case; never weaken an existing arm) | MEDIUM | released@2026-09-27T18:55Z | 1/1 CONCERN: fix only closes half the bypass class. `is_exempting_sibling()`'s `ABSENT` set (null/undefined/''/"") is correct but incomplete -- reviewer independently confirmed `false`/`0`/`{}`/`true` as the exempting sibling ALSO still produce zero findings, same fabrication shape, still invisible. Reviewer's suggested fix (confirmed to close all cases while preserving legitimate exemptions): require the exempting sibling itself be an array literal (`is_literal(v) and v.strip().startswith('[')`), not merely "not one of 4 named absence values." Also: line 920 (the `[rows] : X` ordering) ships with no fixture exercising `is_exempting_sibling` at all -- its own committed fixtures accidentally test the pre-existing identifier-branch path instead. Rework: switch to the array-literal-allowlist approach, add a `[rows] : null`-shaped fixture for line 920's own coverage. Sequences after S-29 per the shared-file note; S-29's own rework will need to route through whichever final helper S-30 ships (not the current is_exempting_sibling if it's replaced). Correction: stale building@ with no live agent and no commit of its own (git log --all --grep found none). Re-cut to ready. Batch 1 (build then review), dispatched 17:06. Review CONCERN/REJECT; rework plus re-review dispatched 17:49 (workflow wf_b1414df6-a66) with the reviewer findings. Rework re-review APPROVE (workflow wf_b1414df6-a66); train 6 pushed 0bd45144 at 18:10:14Z (ls-remote verified). Released in v9.67.0 (release commit 7f470727; publish-npm success). |
|
|
205
|
+
| S-30 | BACKLOG 125 B-6: P7 scanner ternary-against-null bypass -- `const r = loading ? null : [rows];` -- `is_literal(null)` is true so the both-branches-literal exemption suppresses it; should only treat an array/object literal, never null/undefined/empty-string, as the "literal other branch" | tests/moat/p7-no-fabricated-data.sh (scanner rule + a new red/green case; never weaken an existing arm) | MEDIUM | (not recorded; see Notes) | released@2026-09-27T18:55Z | 1/1 CONCERN: fix only closes half the bypass class. `is_exempting_sibling()`'s `ABSENT` set (null/undefined/''/"") is correct but incomplete -- reviewer independently confirmed `false`/`0`/`{}`/`true` as the exempting sibling ALSO still produce zero findings, same fabrication shape, still invisible. Reviewer's suggested fix (confirmed to close all cases while preserving legitimate exemptions): require the exempting sibling itself be an array literal (`is_literal(v) and v.strip().startswith('[')`), not merely "not one of 4 named absence values." Also: line 920 (the `[rows] : X` ordering) ships with no fixture exercising `is_exempting_sibling` at all -- its own committed fixtures accidentally test the pre-existing identifier-branch path instead. Rework: switch to the array-literal-allowlist approach, add a `[rows] : null`-shaped fixture for line 920's own coverage. Sequences after S-29 per the shared-file note; S-29's own rework will need to route through whichever final helper S-30 ships (not the current is_exempting_sibling if it's replaced). Correction: stale building@ with no live agent and no commit of its own (git log --all --grep found none). Re-cut to ready. Batch 1 (build then review), dispatched 17:06. Review CONCERN/REJECT; rework plus re-review dispatched 17:49 (workflow wf_b1414df6-a66) with the reviewer findings. Rework re-review APPROVE (workflow wf_b1414df6-a66); train 6 pushed 0bd45144 at 18:10:14Z (ls-remote verified). Released in v9.67.0 (release commit 7f470727; publish-npm success). |
|
|
206
206
|
| S-31 | BACKLOG 125 B-7: P7 scanner fabricated-return-from-helper bypass -- `function getRows(d) { if (!d) return [rows]; return d; } setRows(getRows(d))` -- no scanner arm follows a function's return value back to a fabricated literal | tests/moat/p7-no-fabricated-data.sh (scanner rule + a new red/green case; never weaken an existing arm) | MEDIUM | released@2026-09-28T01:11Z | Unanimous 2/2 APPROVE (mechanism + corrected comment, independently verified across two review rounds). Merge-base (10e09a98) is behind S-29's still-in-flight, much larger rework chain on this SAME file -- holding merge until S-29 lands to avoid a bad conflict, per the established shared-file sequencing convention. Will need a rebase pass onto post-S-29 main before merge, not a blind cherry-pick. Rebase onto post-S-29 main dispatched 15:49. Train 7 (release 9218ea04, v9.62.0, pushed 16:29:17Z, ls-remote and tag ^{} verified), unreviewed (founder "release everything"). The v9.62.0 Release run was cancelled at 16:30 (the tree carries the S-18 P9 regression). Released v9.80.1 (npm view loki-mode time: 2026-09-28T01:11:53Z). |
|
|
207
207
|
| S-32 | BACKLOG 125 B-8: P7 scanner `Array.from` generator bypass -- `Array.from({ length: 3 }, (_, i) => ({ id: i, action: 'Deployed', user: 'Admin' }))` invents field values inside a generator callback; the existing `Array.from` arm only checks a literal first argument | tests/moat/p7-no-fabricated-data.sh (scanner rule + a new red/green case; never weaken an existing arm) | MEDIUM | released@2026-09-27T15:00Z | New arm fires on `{length: N}` + concise-object-returning arrow, substitutes arrow params with 0 before reusing `is_literal`, requires >=1 literal string field post-substitution. Unanimous 2/2 APPROVE, both reviewers independently reproduced with distinct fixtures; reviewer 2 verified the 3-way merge onto current main via `git merge-file` before I merged it (zero conflicts, purely additive) and found a new non-blocking gap (nested Array.from generators losing an outer scope's loop variable through substitution) filed as BACKLOG 145. d49b26d7. Shipped in v9.56.0 (merged before the 14:16:24Z release push of b651b98d; on npm 15:00:06Z). |
|
|
208
208
|
| S-33 | BACKLOG 128: stale docs assert a `{"runner":"none","pass":true}` writer shape that doesn't exist (D20 corrected this; the real writer, `enforce_test_coverage` at run.sh:13250, writes `pass:"inconclusive"`, a string, never boolean true) | references/core-workflow.md, docs/VERIFIED-COMPLETION-PLAN.md, tests/test-council-devils-advocate.sh, tests/test-da-veto.sh, tests/test-council-convergence-floor.sh (fixture shapes only; do not touch any assertion logic) | LOW | released@2026-09-27T15:00Z | Not behaviorally load-bearing (harmless today since runner=='none' is unconditional at every reading site), but honesty/documentation-drift cleanup. Found and fixed a 4th documentation occurrence beyond the original bug report's scope. Confirmed a genuinely interesting residual coverage gap in test-council-convergence-floor.sh's NEGATIVE-B (correctly disclosed, not fixed -- out of this fixture-only slice's scope). 1/1 APPROVE. **Merged to main (90e26308).** Shipped in v9.56.0 (merged before the 14:16:24Z release push of b651b98d; on npm 15:00:06Z). |
|
|
@@ -433,7 +433,7 @@ set is declared to avoid overlap with those and with each other.
|
|
|
433
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 | released@2026-09-28T21:01Z | 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. Released in v10.5.0 (merge c2ae4347 is an ancestor of v10.5.0). |
|
|
434
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 | released@2026-09-28T21:01Z | 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). Built f172b9b6 (rebased onto E-91), test-v10-pulse.sh 138/0, 7 T48 subtests red on unmodified pulse first; 46 min vs 30 budget (large pulse file). Tech Lead review 19:55Z. Tech Lead APPROVE (pulse 0.61s wall, governor keys match usage-governor.py:562-591, null max is UNKNOWN); merged. Released in v10.5.0 (merge 8f93cb9f is an ancestor of v10.5.0). |
|
|
435
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 | released@2026-09-28T21:01Z | Source: founder 17:44Z. CTO (opus) authors. Billing is the founder decision. Merged as 4708cee1 (row status was stale). Released in v10.5.0 (merge 62b495a5 is an ancestor of v10.5.0). |
|
|
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 |
|
|
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 | merged@2026-10-03T13:44Z | Built 0a90538a8: dry-run default, --live needs verified `claude --cloud` (no cloud subcommand in 2.1.288), refusals 10/11/12; test 25/0, overlap mutation 3 red. Governor uncalibrated so every dispatch refuses (fail safe). Opus HIGH review running. First real --live is a founder probe. r2 building (F1-F6 + A1/A6/A7/A8). r2 11b6e1b73 (62/62 /bin/bash, red 51/62 on r1); opus re-review running. r2 opus BLOCK (R2-1: paths inside parentheses dropped from overlap). r3 building: R2-1 + leader-ancestor check, --live stub tests, mode preserve. r3 e99768c74 opus APPROVE (9 mutants red, 85/0). Merged 7982bb471..4321d1665; on main 85/0 /bin/bash, shard coverage 19/0. Advisories carded: --live is a session check not an agent check (policy: RM/CoS only); paren prose like e.g becomes a token; A2/A3/A7; after/range dependency wording. |
|
|
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
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
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 | released@2026-09-28T21:01Z | 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. Released in v10.5.0 (merge 8b41ad40 is an ancestor of v10.5.0). |
|
|
@@ -627,6 +627,12 @@ Source: ~/git/autonomi-dev/research/2026-09-30-adoption/SWARM-PROMPT-ADOPTION.md
|
|
|
627
627
|
| W1-S2 | D77 wire manifest into Wall cwd and brief; manifest_sha256 on wall.sealed | loki-ts/src/engine10/stages/wall.ts, loki-ts/tests/engine10/wall.test.ts | cwd holds only task.md, repomap.txt, wall_manifest.txt; body and implement-diff canaries never reach cwd or brief; E-54 and D42(3) tests green | HIGH | merged@2026-10-03T12:58Z | r1-r15 cherry-picked (6acdb8476..f9dc7d67b), opus HIGH r15 APPROVE (211/0, tsc 0). Combined with D61-11 it breaks the e10ext/features size budgets; P0-SIZE-BUDGET trim in flight, train held. Advisory: add a johab cookie test row. |
|
|
628
628
|
| P0-SIZE-BUDGET | Trim e10ext (1505/1500) and features (3041/3000) under budget with no behaviour change after D61-11 + W1-S2 merged | loki-ts/src/engine10/stages/wall.ts, loki-ts/tests/engine10/wall.test.ts | cwd holds only task.md, repomap.txt, wall_manifest.txt; body and implement-diff canaries never reach cwd or brief; E-54 and D42(3) tests green | HIGH | merged@2026-10-03T13:05Z | Merged 87f256642: e10ext 1433/1500, features 2931/3000; budget.test.ts 27/0, dist guard 13/0. Whitespace/comment only. |
|
|
629
629
|
| P0-T99-ROUTING | train/99 Tests red on shards 3/4/7 twice (run 37124003039 + full rerun): test-issue-to-pr acceptance import includes heading lines, test_start_run_unified URL start says no provider CLI, test-start-repo-directory (PO4) fails in 1s; all pass locally with provider CLIs | tests/cli/test-issue-to-pr.sh, tests/cli/test_start_run_unified.sh, tests/cli/test-start-repo-directory.sh, cause TBD | MEDIUM | three suites green under a CI-like PATH with no provider CLI, red before the fix | merged@2026-10-03T13:21Z | Root cause: train/99 af6b616fa+2db6d1358 registered 4 orphan tests/cli suites; GNU sed range in issue-parser.sh extract_acceptance_criteria keeps heading lines (BSD falls back, so green on macOS); 2 suites silently needed a claude CLI. Fix 060a5794c red/green under env -i and ubuntu:24.04. Tier corrected HIGH->MEDIUM (parser, not moat). TL review running. TL APPROVE (5 suites green macOS+ubuntu docker). Merged ec5cc3398. Advisory carded: switch sed \s to [[:space:]] at the root. |
|
|
630
|
+
| P0-P9-DEFAULT-PUSH | train/100 Tests red only on moat P9.injection-cannot-reach-token [default] leg: Loki post-session push never ran on the CI runner (push log: provider rejected x2). Intermittent on 8+ CI runs since 10-01. | tests/moat/p9-rule-of-two.sh, post-session push path (autonomy/run.sh or loki-ts) | HIGH | Root cause found and fixed, red before green under CI-like docker repro (M>=5); full moat run clean; pending.txt untouched | merged@2026-10-03T14:29Z | Sonnet engineer in a worktree. Opus HIGH review follows (moat). One full rerun of run 37125941522 started per D68. Root cause: printf piped to grep -q under pipefail SIGPIPE 141 refused the post-session push under load (docker 5/18 -> 0/10). opus HIGH APPROVE (equivalence 18/20, the 2 diffs are literal-correct; P2/P7 FAILs pre-existing, missing typescript prereq). On main as 84e2b585e, engine10-push 40/0, P9 4/4 PASS. Advisory: add a "drops one function, keeps anchors" rc-3 case to test-engine10-push.sh. |
|
|
631
|
+
| ADV-PUSH-RC3 | engine10-push guard testable alone: run.sh keeps its anchors but drops one of the four trusted-push functions; assert rc 3, 'region lacks', no gh, no push | tests/test-engine10-push.sh | MEDIUM | new case red when the guard is forced to pass, green on main; suite 41/0 under /bin/bash | merged@14:34Z | TL sonnet APPROVE (43/0; mutations true-match and loop-delete each 41/2; no-push via pre-receive log with positive control); main 511937aec |
|
|
632
|
+
| ADV-T99-SED | issue-parser root fix: GNU-only `\s` in sed and grep patterns becomes `[[:space:]]` so BSD and GNU agree | autonomy/issue-parser.sh, issue-parser tests | MEDIUM | a case with an indented list item and a heading parses the same on macOS and ubuntu docker; existing issue-parser suites green | merged@14:36Z | TL sonnet APPROVE (22/0 macOS; ubuntu docker commit vs parent logs identical; one-extractor BRE revert goes red 21/1; scope grew to sed -E for BSD alternation); main 4eb538b27 |
|
|
633
|
+
| ADV-SEAL-JEST-E2E | loki-seal: E2E proof that a jest or vitest red still counts while coverage is NOT VERIFIED, via a stub runner bin | packages/loki-seal/test/seal.test.js | MEDIUM | stub jest exits 1: result is red with the specific reason; a mutant that ignores the exit code goes red; suite 135+/0 | merged@14:58Z | merged 036a05281 (TL APPROVE 138/138) |
|
|
634
|
+
| T101-G04-DUPROW | train/101 shard 3 R2-3 red on GNU: test hook appended a file to itself, GNU grep refuses, so no duplicate row existed | tests/test-cloud-dispatch.sh, CHANGELOG.md | MEDIUM | R2-3 red on Linux and macOS when the writer uniqueness check is weakened | merged@14:46Z | D81; test-only; TL sonnet APPROVE (mutation len(hits)<1 gives 83/2 on ubuntu docker and macOS; 85/0 green both); main 8b314af87 |
|
|
635
|
+
| T101-SEAL-NODEFLAG | train/101 shard 2: seal.test.js:1031 fixture uses node --test-isolation=none, rejected by CI Node | packages/loki-seal/test/seal.test.js (product only if it passes the flag), CHANGELOG.md | MEDIUM | the r7 no-newline honest-run test green on the CI Node and local Node, fail-closed unchanged | merged@14:58Z | merged def612303 (TL APPROVE: node:22 127/0/7skip env-only, parent fails r7; mutation red) |
|
|
630
636
|
| W1-S3 | D77 size-tied Wall cap: 90s small, 180s normal, env override clamped to 300s | loki-ts/src/engine10/sizing.ts, loki-ts/src/engine10/stages/wall.ts, loki-ts/tests/engine10/sizing.test.ts | small 90, normal 180, 999 clamps to 300, garbage falls back; killed session copies no file; timeout never already_satisfied | MEDIUM | merged@2026-10-03T13:21Z | TL MEDIUM BLOCK: wiring test uses a small task so limitS 90 equals old value; wall.ts:168 mutation survived. r2 test-only fix requested (normal task -> 180, env 240 reaches session). Code itself passed: 300 stage ceiling safe, env parse ok. Merged 916f2d99d..615fd4745 + dist f0ece075d; engine10 1199/0, tsc 0, dist guard 13/0. |
|
|
631
637
|
| W1-S4 | D77 lift row: manifest off versus on | docs/v10/METRICS.md | augmentiq#52 plus 2 brownfield tasks, both arms; Wall timeouts, red-on-base count, completion, cost; logs under ~/loki-ci-logs | MEDIUM | ready@2026-10-03T08:52Z | Source: D77. Depends on W1-S2, W1-S3. Real-model leg: parked until Loki confirms key use. |
|
|
632
638
|
| P0-backstop-refused | A run refused at intake (dirty tracked tree) still runs backstopCommit (git add -A plus commit) on the user's own branch, landing their dirty and untracked files on main; found by the D50-F1b opus review on base 151aa563 | loki-ts/src/engine10/supervisor.ts, its tests, dist | dirty-README fixture: refusal exit, no new commit on main, README still dirty byte-identical, notes.txt untracked | HIGH | merged@2026-10-01T12:25Z 3c46a2b6 (a70f0980; red 22/1, green 953/0; train/57) | none |
|
|
@@ -737,7 +743,7 @@ Source: ~/git/autonomi-dev/research/2026-09-30-adoption/SWARM-PROMPT-ADOPTION.md
|
|
|
737
743
|
| D61-09 | D61 slice 9, decomposability check with strict-schema confirm | features/speed/decompose_check.ts, tests engine10/decompose_check.test.ts | MEDIUM | merged@2026-10-03T03:13Z | TL APPROVE; 0393c5a6b in train/83 1a63ad156. |
|
|
738
744
|
| D61-15 | D61 slice 15, live unit grid (dashboard /g/<group>, Control Plane group_id) | features/speed/group_grid.ts, engine10/dashboard, packages/control-plane runs and drizzle 0001 | MEDIUM | merged@2026-10-03T03:14Z | TL APPROVE plus should-fix (400 on bad encoding); 024a4d16b, 79eac0297 on main for train/84. Add a drizzle 0001 snapshot before the next schema change. |
|
|
739
745
|
| D61-10 | D61 slice 10, unit runner (backlog.py --dag) | autonomy/lib/backlog.py, tests/test-backlog-units.sh | MEDIUM | merged@2026-10-03T03:15Z | TL APPROVE; ad4f4b926. Follow-up D61-10-F1 1e844e066 TL APPROVE (30/0), approved@2026-10-03T03:33Z. |
|
|
740
|
-
| D61-11 | D61 slice 11, unit run mode (write-set fence, pack-only brief, unit cost cap) | features/speed/unit_mode.ts, e10ext/scope.ts, e10ext/context.ts | HIGH | merged@2026-10-03T12:52Z | 48006fdbe..a56978deb, opus HIGH r3 APPROVE (169/0, tsc 0). Fence and pack-only brief only: unitCapEnv has no caller, so no unit cost cap is enforced yet (see D61-11b). |
|
|
746
|
+
| D61-11 | D61 slice 11, unit run mode (write-set fence, pack-only brief, unit cost cap) | features/speed/unit_mode.ts, e10ext/scope.ts, e10ext/context.ts | HIGH | (not recorded; see Notes) | merged@2026-10-03T12:52Z | 48006fdbe..a56978deb, opus HIGH r3 APPROVE (169/0, tsc 0). Fence and pack-only brief only: unitCapEnv has no caller, so no unit cost cap is enforced yet (see D61-11b). |
|
|
741
747
|
| D61-11b | Wire the unit cost cap (unitCapEnv) into the real unit spawn path, fail closed with a NOT PROVEN note on a bad unit spec, read the spec at intake from outside the worktree, and state in slice 12 that FAILED units are never merged (backstopCommit runs add -A unfenced) | features/speed/unit_mode.ts, e10ext/scope.ts, e10ext/context.ts | HIGH | merged@2026-10-03T13:16Z | Merged f6dea72bd+5e6b5e9c3, dist 095f17e79. r2 opus APPROVE (18 containment cases, revert-red 22/1, supervisor rc=2 probe). Main: budget+unit_mode+features+supervisor 320/0, tsc 0, dist guard 13/0. Advisories carded: gate maybeRunGroup on !u; supervisor main() rc=2 test; win32 sep. |
|
|
742
748
|
| P1-DISCARD-PROTO | discardIfSatisfied uses `f in pre` (e10ext/discard.ts:36): prototype-named files (constructor, toString) survive the ALREADY_SATISFIED discard, so the run reports completed with a source diff (breaks D50-F1). Use Object.hasOwn plus a real-git test | loki-ts/src/e10ext/discard.ts, loki-ts/tests/e10ext/discard*.test.ts | HIGH | merged@2026-10-03T05:10Z | opus APPROVE (real-git probe: 8 prototype names incl __proto__ and a/constructor all discarded; parent code discarded 1); cherry-picked 6e6a74680, e10ext 92/0. Sibling scope.ts:20-21 hole covered by D61-11 r3 |
|
|
743
749
|
| D61-12 | D61 slice 12, integrator (ordered merges, fix units, 2-round cap) | features/speed/integrate.ts, tests features/speed/integrate.test.ts | HIGH | parked@2026-10-03T04:47Z | Round 7 opus BLOCK 5b788e895: exemption launders drops (B1,B2), context false positive (B3); round 8 is final: three-way containment, no exemption, else drop 04:47Z: round 8 opus BLOCK on 35a7b0c32 (C1-C4, S3: a dropped unit change reported merged and ready; E6 mode-only false fail). Final round spent: dropped from this window per D73; integrator design rework next window. |
|
|
@@ -808,7 +814,7 @@ Source: ~/git/autonomi-dev/research/2026-09-30-adoption/SWARM-PROMPT-ADOPTION.md
|
|
|
808
814
|
| PO-TEST-2 | Tests for scripts/check-inline-scripts.js | tests/test-check-inline-scripts.sh (new), runner and shard registration | valid exits 0, broken fixture exits 1, structural guards | LOW | merged@2026-10-03T09:01Z | merged 8b3fa5af4 (TL APPROVE; suite + shard/registration guards green)|
|
|
809
815
|
| PO-TEST-3 | Tests for scripts/clean-test-branches.sh safety rules | tests/test-clean-test-branches.sh (new), runner and shard registration | refusals proven in a throwaway repo; mutation dropping main refusal goes red; structural guards | MEDIUM | merged@2026-10-03T09:01Z | merged 75953c210 (TL APPROVE; suite + shard/registration guards green)|
|
|
810
816
|
| P7-SCALAR-PIN | Pin the P7 SCALAR_READ exclusion with honest fixtures, so a regression that flags `.length`, `[0]` or `.find(` reaching a sink (or a widening that lets a fabricated array through) goes red. | tests/moat/p7-no-fabricated-data.sh only | Add honest fixtures `const n = getRows(d).length; setCount(n);`, `setFirst(getRows(d)[0])`, `setHit(getRows(d).find(x=>x.ok))` with expected 0 findings. RED: temporarily change `if not SCALAR_READ.match(tail): return True` (line ~1243) to `return True` and run `bash tests/moat/p7-no-fabricated-data.sh` -> the new fixtures fail. GREEN: revert -> `bash tests/moat/p7-no-fabricated-data.sh` exit 0, and every existing fixture keeps its expected count. Also `bash tests/moat/run.sh` shows the P7 verdict unchanged. Do NOT touch pending.txt. No CHANGELOG line (test-only). | HIGH | merged@2026-10-03T11:25Z | d668a9cbc opus APPROVE (13 mutations, 11 caught by new fixtures); advisories: realistic ternary shape, Index/Find honest-label debate, .search gap |
|
|
811
|
-
| SEAL-FORGED-LINES | loki-seal refuses VERIFIED when the parsed passing lines disagree with the runner's own summary counts, so a test that prints forged `ok N - name` or `--- PASS:` lines cannot fake delivery. | packages/loki-seal/bin/contract.js (passing() and its caller), packages/loki-seal/test/seal.test.js, packages/loki-seal/README.md (Known limits ~44), CHANGELOG.md | RED: new seal.test.js cases: (a) TAP output with `ok 1 - x` printed by the test body plus summary `# pass 0` / `# fail 1`; (b) pytest output with `test_x PASSED` plus `1 failed, 0 passed`; (c) an id that appears both passed and failed. Each expects NOT VERIFIED with reason "runner output inconsistent". `bash packages/loki-seal/test/run.sh` fails on the new cases before the change (baseline 72/0). GREEN: after the change, `bash packages/loki-seal/test/run.sh` passes all cases (75+/0) and the existing 72 stay green. When no summary line exists, current behavior is unchanged (document this in Known limits). CHANGELOG: "loki-seal: forged runner pass lines that contradict the runner summary now give NOT VERIFIED." | HIGH |
|
|
817
|
+
| SEAL-FORGED-LINES | loki-seal refuses VERIFIED when the parsed passing lines disagree with the runner's own summary counts, so a test that prints forged `ok N - name` or `--- PASS:` lines cannot fake delivery. | packages/loki-seal/bin/contract.js (passing() and its caller), packages/loki-seal/test/seal.test.js, packages/loki-seal/README.md (Known limits ~44), CHANGELOG.md | RED: new seal.test.js cases: (a) TAP output with `ok 1 - x` printed by the test body plus summary `# pass 0` / `# fail 1`; (b) pytest output with `test_x PASSED` plus `1 failed, 0 passed`; (c) an id that appears both passed and failed. Each expects NOT VERIFIED with reason "runner output inconsistent". `bash packages/loki-seal/test/run.sh` fails on the new cases before the change (baseline 72/0). GREEN: after the change, `bash packages/loki-seal/test/run.sh` passes all cases (75+/0) and the existing 72 stay green. When no summary line exists, current behavior is unchanged (document this in Known limits). CHANGELOG: "loki-seal: forged runner pass lines that contradict the runner summary now give NOT VERIFIED." | HIGH | merged@2026-10-03T14:06Z | r7 opus BLOCK: F1 unterminated write hides real summary, F2 64MB cap drops summary; r8 builder dispatched r10 8046c2b6f opus BLOCK: 4 reproduced forges (.bin/node shim, self-package reporter, node_modules reporter, npm config outside project .npmrc). D80 amendment 2 adopted (spawn process.execPath, scrubbed env, builtin reporters only, jest/vitest NOT VERIFIED). r11 building. r11 42421df35 (132/132; 10 new tests red 8 on r10). Opus re-review running. r11 opus BLOCK: env-scrub mutant survives 132/0 (no NODE_OPTIONS/NODE_PATH test). Other spec points verified, 4 of 5 mutants red. r12 building: childEnv unit test + A1/A3/A4/A5. r12 431f4bafe: childEnv exported+unit/E2E tests, scrub mutant red, 134/0; opus verify-only re-review. r12 opus APPROVE (scrub mutant 132/2 red, M2a/M2b/M3 caught). 12 commits on main, 134/0 on main. Advisories: jest/vitest red-counts E2E untested; NODE_PATH E2E only via unit test. r13 98e144f21 escapes U+2713/2714/2716 for the emoji scan, 134/0. |
|
|
812
818
|
| HONEST-READ-2 | /api runs never claim "recorded no run_id" or "no per-iteration records" when the events or iteration files were unreadable or corrupt; they say unreadable, with the errno. | dashboard/api_runs.py, tests/dashboard/test_api_runs_unreadable.py (new), tests/run-all-tests.sh (run_test line), tests/shard-durations.tsv (row), CHANGELOG.md | RED: new pytest: (a) events file chmod 000 -> list_runs reason must contain "unreadable", not "no run id found"; (b) iteration dir with only corrupt JSON -> reason "unreadable or corrupt", not "no per-iteration records"; (c) missing file (ENOENT) keeps today's "no ..." wording. Skip (a) when running as root. `python3 -m pytest -q tests/dashboard/test_api_runs_unreadable.py` red before. GREEN: same command passes; `python3 -m pytest -q tests/dashboard` stays green. Register `run_test "Dashboard api_runs unreadable reads (HONEST-READ-2)" "timeout -k 10 120 python3 -m pytest -q $SCRIPT_DIR/dashboard/test_api_runs_unreadable.py"` plus the shard row `Dashboard api_runs unreadable reads (HONEST-READ-2)<TAB>5`, then run the structural guards for new test files. CHANGELOG: "Dashboard runs view reports unreadable or corrupt run records instead of claiming none were recorded." | MEDIUM | merged@2026-10-03T10:50Z | b8b30f271 on main (MEDIUM TL APPROVE) |
|
|
813
819
|
| BACKLOG-LEDGER-FAILCLOSED | `loki backlog` daily budget cap fails closed: a corrupt or unreadable spend ledger stops new units with BUDGET_STOP "ledger unreadable" instead of reading $0 spent, and add_spend never overwrites a corrupt ledger (move it aside to .corrupt-<ts>). | autonomy/lib/backlog.py (spent_today, add_spend, cap check ~383), tests/test-backlog.sh, CHANGELOG.md | RED: add a case to tests/test-backlog.sh with HOME pointing at a run-owned temp dir, `~/.loki/backlog-spend.json` containing `{not json`, a daily cap of $1, and a stub loki. Expect status "BUDGET_STOP: ... ledger unreadable" and no unit started; today the cap reads 0.0 and units run. A second case checks that after add_spend the corrupt bytes survive in backlog-spend.json.corrupt-*. `bash tests/test-backlog.sh` red before. GREEN: same passes; `bash tests/test-backlog-units.sh` stays green; a missing ledger (ENOENT) still means $0 spent. No cap configured means no behavior change. CHANGELOG: "loki backlog: a corrupt spend ledger now stops new units when a daily budget is set, instead of reading as $0 spent." | MEDIUM | merged@2026-10-03T10:50Z | 4dd5faf62 on main (MEDIUM TL APPROVE) |
|
|
814
820
|
| MCP-RUN-EXIT | MCP v10_run reports an early loki crash (exit code plus the last 20 log lines) instead of returning run_id None with no error. | mcp/v10_tools.py, mcp/tests/test_v10_tools.py | RED: new test: monkeypatch the loki binary to a stub that exits 2 immediately and writes "boom" to the log. Expect a result with `error` containing "exited 2" and "boom"; today it is `{"run_id": None, "pid":..., "log_path":...}`. `python3 -m pytest -q mcp/tests/test_v10_tools.py` red before. GREEN: same passes and `bash tests/test-mcp-server.sh` (test 13 at :204) stays green. A still-running process with no run id yet keeps today's shape. CHANGELOG: "MCP loki run now returns the exit code and log tail when loki exits before a run starts." | LOW | merged@2026-10-03T10:46Z | 01c8c0e6c cherry-picked (TL APPROVE; pytest 18/0, red 2 on revert, test-mcp-server 13/0) |
|
|
@@ -845,3 +851,22 @@ Source: ~/git/autonomi-dev/research/2026-09-30-adoption/SWARM-PROMPT-ADOPTION.md
|
|
|
845
851
|
| PO5-HELP-NOTES-BRANCHES | release-notes.sh and clean-test-branches.sh real --help | scripts/release-notes.sh, scripts/clean-test-branches.sh, tests/test-release-notes.sh, tests/test-clean-test-branches.sh | LOW | bash tests/test-release-notes.sh; bash tests/test-clean-test-branches.sh | merged@2026-10-03T12:48Z | 53d295093 |
|
|
846
852
|
| PO5-WORKSPACE-VACUOUS | test-workspace.sh fails when no assertions ran | tests/test-workspace.sh | LOW | bash tests/test-workspace.sh | merged@2026-10-03T12:48Z | 43e805cef |
|
|
847
853
|
| PO5-HELP-INSTALL-HOOKS | install-hooks.sh --help never rewrites git config | scripts/install-hooks.sh, tests/test-install-hooks.sh | LOW | bash tests/test-install-hooks.sh | merged@2026-10-03T12:48Z | fce165e70 |
|
|
854
|
+
| D82-COSTCAP | Cost cap: subscription runs no dollar cap plus one info line; API-key runs default $100; --max-cost and budgets.per_run override; BUDGET_STOP exit 3 | autonomy/ cost-cap code, docs, tests | MEDIUM | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
855
|
+
| D82-FLAGS | Default-on: visual evidence, spec-to-contract, D61 parallel, Slack two-way, MCP tools, Control Plane, workspaces; env=0 opts out; listeners loopback only; senders inert without credential | flag defaults, docs, tests | MEDIUM | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
856
|
+
| D82-A-E2E | Playwright browser e2e with video and trace attached to the PR | e2e/verify path | MEDIUM | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
857
|
+
| D82-B-MERGE | loki merge queue | new CLI subcommand | MEDIUM | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
858
|
+
| D82-C-REVIEW | loki review PR with a deterministic risk score | new CLI subcommand | MEDIUM | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
859
|
+
| D82-D-MEMORY | Project memory across runs | memory path | MEDIUM | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
860
|
+
| D82-E-CPMOBILE | Control Plane mobile layout (roles and sign-in to 10.7.1 under D12) | dashboard UI | LOW | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
861
|
+
| D82-F-EMU | Mobile emulator tests | test harness | MEDIUM | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
862
|
+
| D82-G-REST | REST API for runs (loopback) | dashboard server API | MEDIUM | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
863
|
+
| D82-H-ACP | VS Code and JetBrains via ACP | acp adapter | MEDIUM | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
864
|
+
| D82-I-SENTRY | Sentry intake to tasks | intake path | MEDIUM | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
865
|
+
| D82-J-D50 | D50 Sonnet lift fixes | per D50 | MEDIUM | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
866
|
+
| D82-GAPS | Gap research vs Devin, Factory, 8090, Vorflux, Claude Code | docs/v10 research doc | LOW | builds, own test file green, CI green | merged@15:33Z | D82 10.7.0 big train |
|
|
867
|
+
| CP-INGEST | Control Plane zero-setup ingest: backfill plus tail of .loki/runs/*/events.jsonl from loki control serve | packages/control-plane shipper | MEDIUM | own tests green | merged@15:33Z 45b0e9c83 | D82 10.7.0 big train |
|
|
868
|
+
| CP-LEGACY | loki dashboard, web, docker host side and run.sh auto-open route to the Control Plane; LOKI_LEGACY_DASHBOARD=1 restores | autonomy/loki, run.sh | MEDIUM | test-web-alias-consistency 7/7 | merged@15:33Z 7b701d238 | D82 10.7.0 big train |
|
|
869
|
+
| CP-UI-LIVE | Control Plane live run view, overview and landing | packages/control-plane ui | LOW | live.test.tsx green | merged@15:33Z c5b9e700a | D82 10.7.0 big train |
|
|
870
|
+
| CP-UI-SHELL | Control Plane shell, brand, import, loopback-only start endpoint | packages/control-plane ui and server | HIGH | opus APPROVE r2, suite 68/0 | merged@15:33Z f88c18a6b | D82 10.7.0 big train |
|
|
871
|
+
| D82-WALL0 | Empty Wall seal is NOT PROVEN; nested Wall files collected | loki-ts engine10 wall and seal | HIGH | opus APPROVE r2, wall+seal 101/0 | merged@15:33Z 9b87e50c8 | D82 10.7.0 big train |
|
|
872
|
+
| D83-CPE | Enterprise Control Plane UI rebuild, slices CPE-01..26 per docs/v10/CP-ENTERPRISE-UI.md, integrating on branch cpe-base | packages/control-plane, loki-ts engine10 run_pid | HIGH | per-slice Wall checks, opus on 04/07/09/14 | building@15:33Z (01,03,05,21 on cpe-base; 04,07 in opus review; 02,09 building) | D83 10.8.0 |
|
|
@@ -46,6 +46,7 @@ Architect design, 2026-10-01, base 1dfc87103. Design only. Flag: `LOKI_CONTROL=1
|
|
|
46
46
|
- events.jsonl is the spool. The shipper never writes to it (the supervisor treats outside writes as tamper). Its acked cursor lives in `.loki/runs/<id>/ship.json {acked_seq, url}`, written atomically.
|
|
47
47
|
- Started by the supervisor next to the log (one hook line, skipped when `LOKI_CONTROL=0`; the url comes from `LOKI_CONTROL_URL` or local discovery, section 6), it uses `tail()` (events.ts:155), batches up to 200 events or 1 s, and POSTs. Backoff 1, 2, 4 ... 60 s with jitter. It never blocks or fails the run: on supervisor exit it flushes for at most 5 s, then leaves the rest for replay.
|
|
48
48
|
- Every string in `data` goes through `redactSecrets` before sending.
|
|
49
|
+
- Cleanup: `loki control prune --repo OWNER/NAME` and/or `--before ISO_DATE` (`--dry-run` previews) deletes matching runs, their events and orphaned sources in one transaction, direct on the SQLite file (WAL, 5 s busy timeout), so it works with the server up or down. `DELETE /v1/runs/:source/:run` (JSON content type, same-host Origin, bearer when a token is set) removes one run and writes an `audit` row first; the UI Run detail page has a Remove button with a confirm step.
|
|
49
50
|
- Replay: `loki control backfill [--repo DIR]` and every `loki` start ship each run whose ship.json acked_seq is below its last seq. Backfill of old .loki/runs uses the same code path.
|
|
50
51
|
|
|
51
52
|
## 6. Local discovery (on by default)
|
|
@@ -111,3 +112,9 @@ A run blocked on a spec conflict shows its question in the run view with an answ
|
|
|
111
112
|
`loki answer [<run-id>] [--text "..."]` reads the run's task and question from `.loki/runs/<run>/events.jsonl` and the answer from `--text` or the answer file above, then launches `bin/loki "<task>\n\nClarification answering \"<question>\": <answer>"` and prints the new run id. The default run is the newest BLOCKED run in the current repo. The child env drops every `SLACK_*` variable and `LOKI_CONTROL_TOKEN` and sets `LOKI_NO_BROWSER=1`. A run that is not BLOCKED, or has no answer, exits 2 with the reason.
|
|
112
113
|
|
|
113
114
|
`LOKI_CONTROL_DEFAULT=1` (off by default) makes `loki dashboard` open the Control Plane.
|
|
115
|
+
|
|
116
|
+
### Integrity and the display verdict (D86, FC-08)
|
|
117
|
+
|
|
118
|
+
Ingest runs a pure verifier (`src/server/integrity.ts`) over every stored run and persists `tampered`, `attested`, `sig_checked` and `integrity_reasons`. Only the sealed prefix (events through `log.sealed`) supplies the verdict; a second `run.completed`, or any verdict-bearing event after `log.sealed`, is TAMPERED. The `log.sealed` kid must equal the signed receipt kid, and with keys configured an unknown kid is TAMPERED.
|
|
119
|
+
|
|
120
|
+
Display verdicts (`effective_verdict`, mirrored by `ui/src/api.ts`): TAMPERED; UNVERIFIED (a VERIFIED claim that is not attested, or a log redacted before ingest); "VERIFIED (signature not checked)" (attested, but no key in `LOKI_CP_RECEIPT_PUBKEYS` checked the seal signature); VERIFIED (attested and signature-checked). With no keys configured nothing can be plain VERIFIED. Choice for the list filter: `?verdict=VERIFIED` lists signature-checked runs only; `?verdict=VERIFIED (signature not checked)` lists the rest. ALREADY_SATISFIED is a success outcome and needs a seal exactly like VERIFIED (same UNVERIFIED and signature-not-checked rules). Any other verdict on an unattested run shows `<verdict> (unattested)`, so an edited or redacted FAILED or PARTIAL never reads as plain. The Overview VERIFIED tile counts only plain VERIFIED; a separate tile counts signature-not-checked runs. Rows are recomputed at boot in chunks (one transaction each) when attested is NULL or the stored key-set fingerprint (`integrity_key_fp`) differs from the configured one; rows whose events are gone are marked unattested once and not retried.
|