loki-mode 9.75.0 → 9.76.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/completion-council.sh +24 -6
  4. package/autonomy/lib/proof-check.sh +43 -8
  5. package/autonomy/lib/voter-agents.sh +42 -5
  6. package/autonomy/loki +3 -0
  7. package/autonomy/prd-checklist.sh +77 -16
  8. package/autonomy/run.sh +38 -3
  9. package/dashboard/__init__.py +1 -1
  10. package/docs/INSTALLATION.md +1 -1
  11. package/docs/v10/ARCHITECT-CUTS.md +359 -322
  12. package/docs/v10/BOARD.md +57 -37
  13. package/docs/v10/GUARDS.md +32 -21
  14. package/loki-ts/dist/loki.js +341 -338
  15. package/mcp/__init__.py +1 -1
  16. package/package.json +1 -1
  17. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  18. package/web-app/dist/assets/{AdminPage-CMGkmNnt.js → AdminPage-Bw8oPnII.js} +1 -1
  19. package/web-app/dist/assets/{Avatar-9mn8sJ-2.js → Avatar-BwEtc3RH.js} +1 -1
  20. package/web-app/dist/assets/{Badge-mSFLvvRX.js → Badge-C_-lfbUl.js} +1 -1
  21. package/web-app/dist/assets/{Button-B1v4CSkD.js → Button-BdDGKKeF.js} +1 -1
  22. package/web-app/dist/assets/CockpitPage-Dx9d4fEm.js +47 -0
  23. package/web-app/dist/assets/{ComparePage-C1BXuolM.js → ComparePage-BKtAhhIJ.js} +1 -1
  24. package/web-app/dist/assets/{ErrorBoundary-C2sJyBhb.js → ErrorBoundary-BuG16GpG.js} +1 -1
  25. package/web-app/dist/assets/{EvidenceReceiptPanel-a1irlBPD.js → EvidenceReceiptPanel-NATnqxKs.js} +1 -1
  26. package/web-app/dist/assets/{GitHubIssuesPanel-zM-WRxYB.js → GitHubIssuesPanel-BgOwdOpj.js} +1 -1
  27. package/web-app/dist/assets/{GitHubPRsPanel-DvRa5Rxq.js → GitHubPRsPanel-CBJyHI1c.js} +1 -1
  28. package/web-app/dist/assets/{HomePage-CNwRexp5.js → HomePage-BHj17Epq.js} +2 -2
  29. package/web-app/dist/assets/{LoginPage-HKogNiEX.js → LoginPage-Dig4H-HO.js} +1 -1
  30. package/web-app/dist/assets/{MagicPage-u1mvdkUd.js → MagicPage-w6WJ35PH.js} +1 -1
  31. package/web-app/dist/assets/{MetricsPage-CThdMJb5.js → MetricsPage-CvjSUOWn.js} +1 -1
  32. package/web-app/dist/assets/{NotFoundPage-B1v3lELS.js → NotFoundPage-PAcYmGkU.js} +1 -1
  33. package/web-app/dist/assets/{ProjectPage-hDvSsdLF.js → ProjectPage-CBkT5JyW.js} +3 -3
  34. package/web-app/dist/assets/{ProjectsPage-CRAegSM6.js → ProjectsPage-Cs6yuWEU.js} +1 -1
  35. package/web-app/dist/assets/{SettingsPage-Dt90bFxo.js → SettingsPage-BU9F40Yn.js} +1 -1
  36. package/web-app/dist/assets/{ShowcasePage-C5a9l8u_.js → ShowcasePage-jCNABTeT.js} +1 -1
  37. package/web-app/dist/assets/{SystemSettingsPage-DtqsDXbx.js → SystemSettingsPage-Crmc-ryL.js} +1 -1
  38. package/web-app/dist/assets/{TeamsPage-CooeoWxR.js → TeamsPage-DN8W-9m5.js} +1 -1
  39. package/web-app/dist/assets/{TemplatesPage-CJhTxWrw.js → TemplatesPage-WvaXwZIl.js} +1 -1
  40. package/web-app/dist/assets/{TerminalOutput-DvjfbDxb.js → TerminalOutput-Bf_do2tO.js} +1 -1
  41. package/web-app/dist/assets/{activity-DK6KBQKA.js → activity-CMl9JvHl.js} +1 -1
  42. package/web-app/dist/assets/{bell-Cd8tQpN6.js → bell-CnjqTAUX.js} +1 -1
  43. package/web-app/dist/assets/{bot-Y30w8rML.js → bot-BBprDFVS.js} +1 -1
  44. package/web-app/dist/assets/{check-B5eUl1j9.js → check-DW9Hq4y4.js} +1 -1
  45. package/web-app/dist/assets/{chevron-left-qyvpFqze.js → chevron-left-DC9pMI2E.js} +1 -1
  46. package/web-app/dist/assets/{circle-alert-DXtjVPDB.js → circle-alert-BJoll9YV.js} +1 -1
  47. package/web-app/dist/assets/{clock-dqQis2Q6.js → clock-BdHhRTHO.js} +1 -1
  48. package/web-app/dist/assets/{cloud-CzTURYO9.js → cloud-C54B7EO9.js} +1 -1
  49. package/web-app/dist/assets/{code-xml-DLbw1HTk.js → code-xml-DwQK2vpV.js} +1 -1
  50. package/web-app/dist/assets/{database-BIj38v85.js → database-DsWVFir7.js} +1 -1
  51. package/web-app/dist/assets/{dollar-sign-9bVcHIkD.js → dollar-sign-DuRPNc2M.js} +1 -1
  52. package/web-app/dist/assets/{file-code-corner-D57x6xD1.js → file-code-corner-C4j2P44-.js} +1 -1
  53. package/web-app/dist/assets/{file-plus-BXOrz3T5.js → file-plus-rnI2RZjF.js} +1 -1
  54. package/web-app/dist/assets/{globe-Cnq8h4Gt.js → globe-BbBhsaS5.js} +1 -1
  55. package/web-app/dist/assets/{hammer-iiLGlF28.js → hammer-BxcycH3E.js} +1 -1
  56. package/web-app/dist/assets/{index-uGGZ1Ij3.js → index-xGj3noKA.js} +2 -2
  57. package/web-app/dist/assets/{layers-gcGxxNEN.js → layers-CcAOhZeY.js} +1 -1
  58. package/web-app/dist/assets/{loader-circle-B4Ad11xq.js → loader-circle-DN_Xjd5e.js} +1 -1
  59. package/web-app/dist/assets/{lock-DvQNG5RI.js → lock-Dn8AMO-D.js} +1 -1
  60. package/web-app/dist/assets/{package-BtQBNbq2.js → package-uroTpCjn.js} +1 -1
  61. package/web-app/dist/assets/{plus-DKLiMXBZ.js → plus-CYJAEX02.js} +1 -1
  62. package/web-app/dist/assets/{refresh-cw-B4Gu8e2m.js → refresh-cw-BUGsMChj.js} +1 -1
  63. package/web-app/dist/assets/{rotate-ccw-DATSPLYS.js → rotate-ccw-C_4D-XGl.js} +1 -1
  64. package/web-app/dist/assets/{scroll-text-GA8EtlY4.js → scroll-text-DrAJG0H3.js} +1 -1
  65. package/web-app/dist/assets/{server-DT_3kM4V.js → server-Di6lHsM9.js} +1 -1
  66. package/web-app/dist/assets/{shield-alert-BEaqZEhO.js → shield-alert-DH1bNjkD.js} +1 -1
  67. package/web-app/dist/assets/{thumbs-up-DVvA-Fas.js → thumbs-up-Enk3ppj_.js} +1 -1
  68. package/web-app/dist/assets/{trash-2-BCyT5A9N.js → trash-2-CezqQT3x.js} +1 -1
  69. package/web-app/dist/assets/{trending-down-BLcNt39o.js → trending-down-B_ChI0U7.js} +1 -1
  70. package/web-app/dist/assets/{trending-up-BqfBp13A.js → trending-up-BtsvHd_-.js} +1 -1
  71. package/web-app/dist/assets/{upload-BxH0rjQU.js → upload-XiWa_WBM.js} +1 -1
  72. package/web-app/dist/assets/{usePolling-CokbBZIQ.js → usePolling-B6Hxwbk1.js} +1 -1
  73. package/web-app/dist/assets/{user-C_u9mNZM.js → user-oL_Oya-S.js} +1 -1
  74. package/web-app/dist/index.html +1 -1
  75. package/web-app/dist/assets/CockpitPage-BW0hYuzC.js +0 -47
@@ -1,403 +1,440 @@
1
1
 
2
2
 
3
- ## 20:12Z cut (S-194..S-213)
3
+ ## 20:59Z cut (S-214..S-233)
4
4
 
5
- **Checked before cutting.** All reads are on main at 8ba7024d (v9.73.0).
6
- - **Alternates re-read against the code.**
7
- - **A1 (BACKLOG 108) is real.** `create_session_pr`'s `LOKI_AUTO_PR=1` branch calls `_loki_trusted_push` and never reads `.loki/state/agent-committed-user-files.z`. The only references to that file are the writer comment and the writer itself, inside `_loki_untrack_agent_committed_user_files`.
8
- - **A2 (BACKLOG 17) is real.** The "Notify dashboard of active project directory" block, about 24477 today, posts to `/api/focus` behind `command -v curl` only. It has no `ENABLE_DASHBOARD` check.
9
- - **A3 is real and larger than the card says.** run.sh 211 and 239 always set PROJECT_DIR to the Loki install root. So the BACKLOG 127 "guard when unset" would do nothing. The actual defect is that `council_managed_should_stop` runs `git diff --stat` in Loki's own tree, not the target project. Its three readers are still bare `python3 -E`, and p2-honest-verdict.sh (about 858) says so.
10
- - **A4 (BACKLOG 51) is real.** `grep -c PYTHONUSERBASE autonomy/loki` prints 0. The NOT CHECKED text says "Install python3 cryptography" even to a user who installed it through PYTHONPATH or PYTHONUSERBASE, which `-E` ignores.
11
- - **A5 is split.**
12
- - BACKLOG 145 sits in the Array.from generator arm, about 1934-1994. That does not overlap S-180's helper-return arm (about 2081-2170).
13
- - BACKLOG 147 edits `HELPER_LOCAL_DECL_TMPL`, which is in S-180's region, so it is held.
14
- - **New class found: every `-E`-only verdict reader outside completion-council.sh (BACKLOG 53 and 54).** These are:
15
- - autonomy/lib/done-recognition.sh: 16 sites.
16
- - autonomy/council-v2.sh: 7 sites.
17
- - autonomy/lib/voter-agents.sh: 3 sites.
18
- - autonomy/lib/proof-check.sh: 3 sites.
19
- - autonomy/prd-checklist.sh: about 11 sites.
20
- - loki-ts/src/commands/proof.ts:606, the Bun `loki proof verify` path.
5
+ **Checked before cutting.** All reads are on main at 04af133a.
21
6
 
22
- All of them run PATH `python3 -E`. BACKLOG 134 showed that a user-site `.pth` still loads under `-E`.
7
+ **Held dependencies, checked against main.**
8
+ - **Merged:**
9
+ - S-180 (22ff5a44)
10
+ - S-179 (94035ac4)
11
+ - S-175 (6fab92ce)
12
+ - S-178 (c8b4c8c0)
13
+ - S-187 (03070f62)
14
+ - **Still in flight:** S-194, S-195, S-197, S-198.
15
+ - **What that unblocks:**
16
+ - BACKLOG 147: S-180 has merged, and S-198's region (about 1934-1994, fixture about 3301) does not overlap `HELPER_LOCAL_DECL_TMPL` (1182, used about 2186). Cut as S-214.
17
+ - dashboard/server.py items from BACKLOG 118: S-178 has merged. The council-state fallback (8638) and the notifications zero summary (8909) are already handled on main. The skill-session `running_agents: 0` is cut as S-222. The other two are held or dropped (see below).
18
+ - ProjectWorkspace phase labels and Replay Build: S-187 has merged. Cut as S-230.
19
+ - **Still held:**
20
+ - BACKLOG 36: waits for S-198.
21
+ - BACKLOG 19 and the bash `loki proof verify` interpreter: wait for S-197.
22
+ - BACKLOG 99, bash half: waits for S-194 and S-195.
23
23
 
24
- On `-S` compatibility:
25
- - The imports I read are stdlib only: swarm/sycophancy.py, autonomy/checklist-verify.py, and autonomy/lib/proof-verify.py (which adds its own directory to sys.path at line 76). So `-I -S` should hold for those.
26
- - Each builder still audits the imports of the rest of its sites, including the prd-checklist oracle heredoc.
24
+ **Found shipped on main, but the backlog text still reads open.** Future cuts can skip these:
25
+ - 35: tests/test-moat-runner.sh:653
26
+ - 37 and 60: loki-ts/src/runner/quality_gates.ts about 565-615
27
+ - 72 and 80, the base and start-sha part: run.sh 9888-9895. The warning wording is still open and is cut as S-233.
28
+ - 91: run.sh 26343-26345
29
+ - 102: run.sh 10951-10955
30
+ - 104 and 120: tests/run-all-tests.sh 965-966
31
+ - 116, the overview council gate card: loki-overview.js about 395-414
32
+ - 118:
33
+ - standalone receipt order and the VERIFIED WITH GAPS colour: build-standalone.js 2517-2531
34
+ - council-state and notifications: server.py 8638, 8909
35
+ - 150: S-79
36
+ - The memory browser's null lists (loki-memory-browser.js 448-506) and the cockpit's ChangeReview and RiskPanel errors are also handled.
27
37
 
28
- Existing tests source each of these files on their own, so each file needs the guarded helper copy. For voter-agents.sh, `.` at completion-council.sh 4245 sources it into the parent shell.
29
- - **council-v2 fails open on sycophancy.** A detector crash yields `0.000`, then `should_challenge=no`. A unanimous approve then skips the devil's advocate.
30
- - **Cockpit remainder (BACKLOG 114).**
31
- - `FinalActions` receives `git=null` after a failed status fetch (the `settle` fallback) and still says "The working tree is clean" and "Nothing to push".
32
- - A failed `getStatus` (the swallow at useCockpitState.ts:202) makes Pause, Resume and Stop read "No run in progress".
33
- - A failed `getChecklist` (the swallow at 204) renders "No gate results recorded."
34
- - **Already handled, so dropped:**
35
- - BACKLOG 31: proof-verify maps unverifiable drift to 2.
36
- - BACKLOG 38: `no_pass_recorded`.
37
- - BACKLOG 49: the `--jwks` output is patched.
38
- - BACKLOG 16 and 85: `PYTHONDONTWRITEBYTECODE` in `enforce_test_coverage`, plus the py_compile rewrite.
39
- - BACKLOG 133: `PULSE_MOAT_RESULT` carries a `.sha` sidecar.
40
- - BACKLOG 140: the environment-variables.md row names all four tokens and both routes.
41
- - BACKLOG 13: release.sh bumps INSTALLATION.md at 320.
42
- - BACKLOG 22: the resource monitor backgrounds its sleep.
43
- - BACKLOG 26: test-bun-parity-disk-tolerance.sh.
44
- - The unreadable-waivers banner in loki-checklist-viewer is already pinned in loki-unmeasured-panels-honesty.node.test.mjs:319.
45
- - The GitPanel badge on a null fetch renders nothing.
46
- - PhaseVisualizer: its only caller passes 'idle'.
47
- - **Dropped on merit: BACKLOG 69 (snapshot hash size cap).**
48
- - A size-plus-mtime fingerprint is spoofable, which weakens `preexisting_modified`.
49
- - It changes the sealed `.sha.z` entries.
50
- - Nobody has measured the stall.
38
+ **Dropped on merit.**
39
+ - **`/cost` priced at Sonnet rates with no estimate label (BACKLOG 118).**
40
+ - The Sonnet price only applies to a record that is missing `cost_usd`. No Loki writer produces one: run.sh 9121 always writes `model` and `cost_usd` (0 when unmeasured), and no Bun efficiency writer exists.
41
+ - It would close the way S-208 did.
42
+ - **Removing T6 from test-sentrux-init-rules.sh as a speed-up.**
43
+ - autonomy/loki has no `.sh` extension, so run-shellcheck.sh's `find` never lints it. T6 is its only lint.
44
+ - S-232 moves that lint rather than deleting it.
51
45
 
52
- ### S-194: LOKI_AUTO_PR pushes a branch whose history still holds user files (BACKLOG 108, A1)
53
- - Files:
54
- - autonomy/run.sh: `create_session_pr` only, from its head to the `_loki_trusted_push` call. Anchor on the function name, because S-175 shifts line numbers when it merges.
55
- - tests/test-auto-pr-agent-committed-refuse.sh (new)
56
- - Tier: HIGH (secret exposure)
57
- - Region: this does not overlap S-175 (`enforce_test_coverage`) or S-195 (the focus notify block).
58
- - Red:
59
- - With a non-empty agent-committed-user-files.z and `LOKI_AUTO_PR=1`, the stubbed `_loki_trusted_push` gets called.
60
- - The advisory path prints `git push -u` advice with no cleanup step.
61
- - Green:
62
- - When the record is non-empty:
63
- - Recompute the fork the way `_loki_untrack_agent_committed_user_files` does: the merge base with base-branch.txt, else session-start-sha.
64
- - Print `git reset --soft <fork> && git commit` before any push advice.
65
- - Under `LOKI_AUTO_PR=1`, refuse the push: `log_warn` naming the files, and return 1.
66
- - An empty or absent record leaves both paths byte-identical to today.
67
- - Gate: the builder first reproduces the stub push call on main. If it does not reproduce, the slice closes as handled.
68
- - Test rule: `cd` to scratch before sourcing run.sh, and assert that no `.loki/state/provider` appears in the repo (BACKLOG 126).
69
- - Wall: `bash tests/test-auto-pr-agent-committed-refuse.sh` exits 0. Its legs:
70
- - Auto path with a record: no push, rc 1, and the cleanup line printed.
71
- - Advisory path with a record: the cleanup line appears before `git push -u`.
72
- - Empty record: the push happens.
73
- - Removing the record read in a scratch copy fails the first leg.
74
- - `bash tests/test-trusted-push-agent-config.sh` exits 0.
46
+ **New class found: inline Python that imports from the repo under review.**
47
+ - The pattern is `python3 -` or bare `python3 -c` run with the target repo as cwd, which puts `''` first on sys.path.
48
+ - The receipt renderer in autonomy/lib/proof-pr.sh has it (it writes the PR description). So do autonomy/verify.sh's readers (`loki verify`).
49
+ - A committed `json.py` in the repo would be imported before the stdlib module. This is worse than the `.pth` class that S-200..S-205 close.
75
50
 
76
- ### S-195: the /api/focus POST fires with the dashboard disabled (BACKLOG 17, A2)
77
- - Files:
78
- - autonomy/run.sh: the "Notify dashboard of active project directory" block only.
79
- - tests/test-focus-post-dashboard-off.sh (new)
80
- - Tier: MEDIUM
81
- - Region: this does not overlap S-175 or S-194.
82
- - Red: with `ENABLE_DASHBOARD=false`, a curl shim on PATH records one POST to `/api/focus`.
83
- - Green:
84
- - Guard on the runtime `ENABLE_DASHBOARD`, which run.sh sets false at about 19288. Do not guard on `LOKI_DASHBOARD`.
85
- - Test: extract the block by its comment anchor, as test-autocapture-shadow-write-guard.sh does. No full run.sh source.
86
- - Wall: `bash tests/test-focus-post-dashboard-off.sh` exits 0.
87
- - false: the shim log is empty.
88
- - true: exactly one POST.
89
- - Removing the guard in a scratch copy fails the false leg.
51
+ **Stale timings.** shard-durations.tsv still lists trust-core at 130s, reachability at 95s and the selector at 45s. Those predate S-135, S-155 and S-136. S-211 owns the tsv, so the Captain refreshes it after S-211 merges.
90
52
 
91
- ### S-196: council_managed_should_stop reads Loki's install tree for its diff and runs -E readers (A3)
53
+ ### S-214: the P7 useMemo arm misses a factory that calls a registered fabricator (BACKLOG 147)
92
54
  - Files:
93
- - autonomy/completion-council.sh: `council_managed_should_stop` only.
94
- - tests/moat/p2-honest-verdict.sh: `case_council_readers_no_user_site_pth`, plus the about-858 comment in `case_council_readers_not_shadowed`.
95
- - tests/test-council-managed-diff-target.sh (new)
55
+ - tests/moat/p7-no-fabricated-data.sh, three regions only:
56
+ - `HELPER_LOCAL_DECL_TMPL` (about 1182) and its use (about 2186);
57
+ - the ceiling comment (about 978-986);
58
+ - one fixture beside the DECL_USEMEMO fixture (about 3138-3160).
96
59
  - Tier: HIGH (moat)
97
- - Red:
98
- - A stub `providers.managed` records `_CC_DIFF`. It shows install-tree paths, not the target project's change.
99
- - A planted user-site `.pth` forges the test_summary read.
60
+ - Region: this does not overlap S-198's Array.from arm or its fixture at about 3301. Do not append at the file tail.
61
+ - Red: `function getRows(d){ return [{ id: 1, user: 'Admin' }]; } const rows = useMemo(() => getRows(d), [d]); setRows(rows);` goes through.
100
62
  - Green:
101
- - `diff_summary` comes from `${TARGET_DIR:-.}`, the same root as `loki_dir` and `LOKI_TARGET_DIR`.
102
- - The two inline readers and the heredoc run through `_loki_snapshot_py_tool -I -S`.
103
- - If no interpreter resolves, test_summary is empty, pending is `[]`, and the function returns 1 (the Bash voting fallback). It never returns 0.
104
- - The new leg lands in the same commit as the fix, because the case is already proven.
105
- - Gate: reproduce the install-tree diff with the stub first. Reuse S-173's stub.
63
+ - Add an optional `(?:React\.)?useMemo\(\s*\(\)\s*=>\s*` prefix ahead of the fabricator-call pattern.
64
+ - The comment stops listing this shape as a ceiling.
65
+ - Branch: run the widened arm on main first.
66
+ - On any live hit in dashboard-ui or web-app, the slice becomes report-only.
67
+ - Never add an allowlist. cases.txt stays unchanged.
106
68
  - Wall:
107
- - `bash tests/moat/p2-honest-verdict.sh` prints `CASE P2.council-readers-no-user-site-pth PASS` and `CASE P2.council-readers-not-shadowed PASS`.
108
- - `bash tests/test-council-managed-diff-target.sh` exits 0: a file changed only in the target appears in `_CC_DIFF`.
109
- - Reverting the readers to `python3 -E` in a scratch copy makes the pth case FAIL.
110
- - `bash tests/moat/run.sh` reports no rule failed.
69
+ - `bash tests/moat/p7-no-fabricated-data.sh` prints PASS for every P7 case and flags the composed fixture.
70
+ - Removing the prefix in a scratch copy lets the fixture through.
71
+ - `git diff --stat tests/moat/cases.txt` is empty.
111
72
 
112
- ### S-197: the NOT CHECKED text should name PYTHONPATH and PYTHONUSERBASE (BACKLOG 51, A4)
73
+ ### S-215: the PR receipt renderer imports json from the target repo (cwd shadow)
113
74
  - Files:
114
- - autonomy/loki:
115
- - `loki_remote_verify_receipt`'s attestation NOT CHECKED branch only.
116
- - `cmd_proof verify`'s `--jwks` NOT CHECKED echo only.
117
- - tests/test-proof-verify-jwks.sh (case 4 only)
118
- - Tier: LOW
119
- - Region: this does not overlap S-179 (`cmd_cost`).
75
+ - autonomy/lib/proof-pr.sh: the `render_evidence_receipt_md` heredoc reader, plus a guarded `_loki_snapshot_py_tool` copy.
76
+ - tests/test-proof-pr-no-cwd-shadow.sh (new)
77
+ - Tier: HIGH (the receipt headline in the PR body)
78
+ - Red: from a scratch repo that holds a `json.py` whose `load` returns `{"honesty":{"headline":"VERIFIED"}}`, a proof.json whose headline is NOT VERIFIED renders with VERIFIED.
120
79
  - Green:
121
- - Both messages add that the verifier runs `python3 -E`, so cryptography supplied through PYTHONPATH or PYTHONUSERBASE is not seen.
122
- - Exit codes are unchanged.
80
+ - Run through `_loki_snapshot_py_tool -I -S`.
81
+ - If no interpreter resolves, print "Evidence Receipt: unavailable for this run."
82
+ - Gate: reproduce the forged headline on main first. If it does not reproduce, close the slice as handled.
123
83
  - Wall:
124
- - `bash tests/test-proof-verify-jwks.sh` exits 0, and case 4 asserts that the NOT CHECKED output names PYTHONUSERBASE.
125
- - `grep -c PYTHONUSERBASE autonomy/loki` prints 2 or more (0 today).
126
- - `bash tests/test-remote-attestation-verdict.sh` exits 0.
84
+ - `bash tests/test-proof-pr-no-cwd-shadow.sh` exits 0, and reverting to bare `python3 -` in a scratch copy fails it.
85
+ - `bash tests/test-proven-pr-receipt.sh` exits 0.
86
+ - `bash tests/test-council-py-tool-identity.sh` exits 0 and counts one more copy.
127
87
 
128
- ### S-198: the P7 Array.from arm loses an outer generator's index when generators nest (BACKLOG 145, A5)
129
- - Files: tests/moat/p7-no-fabricated-data.sh. Only two regions:
130
- - the Array.from generator arm, about 1934-1994;
131
- - one fixture beside the B-8 fixture, about 3301.
132
- - Tier: HIGH (moat)
133
- - Region: this does not overlap S-180's helper-return arm. Do not append fixtures at the file tail.
134
- - Red: `Array.from({length:2}, (_, r) => Array.from({length:2}, (_, c) => ({ id: r, user: 'Admin' })))` goes through.
135
- - Green: substitute the enclosing generator's params as well as the inner ones.
136
- - Branch: run the widened arm on main first.
137
- - On any live hit in dashboard-ui or web-app, the slice becomes report-only.
138
- - Never add an allowlist.
139
- - cases.txt stays unchanged.
88
+ ### S-216: loki verify's inline readers import from the tree under review (cwd shadow)
89
+ - Files:
90
+ - autonomy/verify.sh: the reader sites only (about 190, 591, 1269, 1271, 1295, 1337, 1339, 1441), plus a guarded helper copy.
91
+ - tests/test-verify-no-cwd-shadow.sh (new)
92
+ - Tier: HIGH (P2 verdict path)
93
+ - Out of scope: the `unittest` and `py_compile` runs (about 730, 921). They run the user's own code on purpose.
94
+ - Red: a planted `json.py` in the tree changes a recorded gate. Examples are the npm audit severity count read at about 1295, or the package.json test script read at about 591. The builder names the gate and its before and after status.
95
+ - Green:
96
+ - `-I -S` through the helper.
97
+ - With no interpreter, each reader returns what it returns today when python3 is absent. None of them reads as pass.
98
+ - Gate: reproduce the changed gate on main first.
99
+ - Rule: no moat case, because p2-honest-verdict.sh belongs to S-196 and S-204.
140
100
  - Wall:
141
- - `bash tests/moat/p7-no-fabricated-data.sh` prints PASS for every P7 case, and the nested fixture is flagged.
142
- - Removing the outer substitution lets the fixture through.
101
+ - `bash tests/test-verify-no-cwd-shadow.sh` exits 0, and reverting one site in a scratch copy fails it.
102
+ - `bash tests/test-verify.sh` exits 0.
103
+ - `bash tests/moat/run.sh` reports no rule failed. `P2.verify-exit-contract` stays pending.
104
+ - `bash tests/test-council-py-tool-identity.sh` exits 0.
143
105
 
144
- ### S-199: the py-tool identity test covers every guarded copy
145
- - Files: tests/test-council-py-tool-identity.sh
146
- - Tier: LOW
106
+ ### S-217: enforce_test_coverage's package.json readers load user-site .pth (BACKLOG 81)
107
+ - Files:
108
+ - autonomy/run.sh: `enforce_test_coverage`, only the `_declared_test_script` and `_ws_script` readers. Anchor on those names.
109
+ - tests/test-enforce-test-coverage-pkg-readers-pth.sh (new)
110
+ - Tier: HIGH
111
+ - Red: a user-site `.pth` under a scratch HOME empties or changes the read, and that changes the recorded test gate outcome in test-results.json. The builder names both the runner and the pass value.
147
112
  - Green:
148
- - Compare every `^_loki_snapshot_py_tool() {` body found by `git grep -l` under autonomy/ against run.sh's.
149
- - Vacuity guard: at least one copy besides run.sh, and each body at least 10 lines.
150
- - This is the only row that edits this file. S-200 to S-204 add copies and rely on it.
113
+ - Both readers go through `_loki_snapshot_py_tool -I -S`.
114
+ - With no interpreter, the record reads inconclusive, never pass.
115
+ - Gate:
116
+ - Reproduce the recorded-outcome change on main first.
117
+ - If the forged read changes nothing that gets recorded, close as handled.
118
+ - Test rule: `cd` to scratch before sourcing, and assert that no `.loki/state/provider` is left in the repo.
151
119
  - Wall:
152
- - `bash tests/test-council-py-tool-identity.sh` exits 0 and prints the number of copies compared.
153
- - A one-byte change to completion-council.sh's copy in a scratch tree exits 1.
120
+ - `bash tests/test-enforce-test-coverage-pkg-readers-pth.sh` exits 0, and reverting one reader to `-E` in a scratch copy fails it.
121
+ - `bash tests/test-honest-gate-status.sh` exits 0.
154
122
 
155
- ### S-200: done-recognition readers load user-site .pth (BACKLOG 54)
123
+ ### S-218: the snapshot's git status runs an agent-chosen core.fsmonitor command (BACKLOG 131c)
156
124
  - Files:
157
- - autonomy/lib/done-recognition.sh: every python3 site, plus a guarded helper copy.
158
- - tests/test-done-recognition-no-user-site-pth.sh (new)
125
+ - autonomy/run.sh: `_loki_untracked_status` only.
126
+ - tests/test-untracked-status-fsmonitor.sh (new)
159
127
  - Tier: HIGH
160
- - Red: a user-site `.pth` under a scratch HOME changes the verdict read (the about-703 site).
128
+ - Red: a repo whose `.git/config` sets `core.fsmonitor` to a script that writes a marker gets the marker during `_loki_untracked_status`.
161
129
  - Green:
162
- - All sites run through `_loki_snapshot_py_tool -I -S`.
163
- - The builder lists each site's result when no interpreter resolves. None of them may read as done or met.
164
- - Add a byte-identical guarded copy.
165
- - Gate: reproduce the forged read on main first.
130
+ - Add `-c core.fsmonitor=false -c core.untrackedCache=false` to that status call.
131
+ - No marker is written, and a real untracked file is still listed.
132
+ - Gate: reproduce the marker on main first.
133
+ - Test rules:
134
+ - Use S-138's isolation prelude.
135
+ - Extract the function by name. No full run.sh source.
166
136
  - Wall:
167
- - `bash tests/test-done-recognition-no-user-site-pth.sh` exits 0.
168
- - Reverting one site to `-E` in a scratch copy fails it.
169
- - `bash tests/test-done-recognition-tests-axis.sh` and `bash tests/test-reuse-done-recognition.sh` exit 0.
137
+ - `bash tests/test-untracked-status-fsmonitor.sh` exits 0, and removing the two `-c` flags in a scratch copy fails it.
138
+ - `bash tests/test-no-ambient-gitconfig-writes.sh` and `bash tests/test-branch-lifecycle.sh` exit 0.
170
139
 
171
- ### S-201: council-v2 readers load .pth, and a crashed sycophancy check skips the devil's advocate (BACKLOG 54)
140
+ ### S-219: a failed git add -A makes the session commit silently commit nothing (BACKLOG 83)
172
141
  - Files:
173
- - autonomy/council-v2.sh: its 7 python3 sites and the Step 4 and 5 fallbacks, plus a guarded helper copy.
174
- - tests/test-council-v2-no-user-site-pth.sh (new)
175
- - Tier: MEDIUM. The path is opt-in through `LOKI_COUNCIL_VERSION=2`.
176
- - Red:
177
- - A `.pth` forges a vote read.
178
- - A detector failure yields `0.000`, so a unanimous approve never challenges.
142
+ - autonomy/run.sh: `commit_session_changes`, the `git add -A` block only.
143
+ - tests/test-session-commit-add-failure.sh (new)
144
+ - Tier: MEDIUM
145
+ - Red: an embedded git repo with no commits under an un-ignored directory makes `git add -A` fail. The session ends with no commit and no "Left uncommitted" line.
179
146
  - Green:
180
- - `-I -S` on every site.
181
- - An unmeasured sycophancy score on a unanimous approve runs the devil's advocate. A resolver failure never yields "no challenge".
182
- - Gate: reproduce both on main first.
147
+ - Keep git's first stderr line.
148
+ - On a non-zero exit, reset the index, `log_warn "Left uncommitted: git add failed (<line>). Review and commit manually."`, and return 0.
149
+ - A successful add is unchanged.
150
+ - Gate: reproduce the silent no-commit on main first.
151
+ - Test rules: S-138 prelude; scratch cwd; no `.loki/state/provider` left in the repo.
183
152
  - Wall:
184
- - `bash tests/test-council-v2-no-user-site-pth.sh` exits 0, covering the `.pth` leg and the detector-failure leg.
185
- - Reverting either change fails its leg.
186
- - `bash tests/test-council-v2-quorum.sh` exits 0.
153
+ - `bash tests/test-session-commit-add-failure.sh` exits 0: the warning names the failure, and a normal repo still commits.
154
+ - Removing the rc check in a scratch copy fails leg 1.
155
+ - `bash tests/test-branch-lifecycle.sh` exits 0.
187
156
 
188
- ### S-202: voter-agents readers load user-site .pth (BACKLOG 54)
157
+ ### S-220: the untrack step's global reset drops force-staged agent files from the session commit (BACKLOG 109)
189
158
  - Files:
190
- - autonomy/lib/voter-agents.sh: its 3 python3 sites, plus a guarded helper copy.
191
- - tests/test-voter-agents-no-user-site-pth.sh (new)
192
- - Tier: HIGH
193
- - Red: a `.pth` changes a parsed voter verdict.
194
- - Green: `-I -S`. With no interpreter, the dispatch fails, so completion-council's existing fail-closed CONTINUE applies.
195
- - Gate: reproduce the changed verdict on main first.
159
+ - autonomy/run.sh: `_loki_untrack_agent_committed_user_files` only.
160
+ - tests/test-untrack-keeps-force-staged.sh (new)
161
+ - Tier: MEDIUM
162
+ - Red: the agent runs `git add -f dist/bundle.js` (an ignored path) and also commits one pre-existing user file. After the untrack step and the session commit, `dist/bundle.js` is in neither commit, and no warning is printed.
163
+ - Green:
164
+ - Commit the removal without resetting the whole index. The builder picks the shorter correct form: `git commit --only` on the removed paths, or a temporary `GIT_INDEX_FILE`.
165
+ - Other staged paths stay staged.
166
+ - Gate: reproduce the dropped file on main first.
167
+ - Size: this may run past 30 minutes.
168
+ - Test rules: S-138 prelude; scratch cwd.
196
169
  - Wall:
197
- - `bash tests/test-voter-agents-no-user-site-pth.sh` exits 0, and reverting fails it.
198
- - `bash tests/test-voter-agents-json.sh` and `bash tests/test-sdk-voter-agents.sh` exit 0.
170
+ - `bash tests/test-untrack-keeps-force-staged.sh` exits 0: `dist/bundle.js` is in the session commit, and the user file is untracked and still on disk.
171
+ - Restoring `git reset -q` in a scratch copy fails it.
172
+ - `bash tests/test-branch-lifecycle.sh` exits 0.
199
173
 
200
- ### S-203: proof-check readers load user-site .pth (BACKLOG 54)
174
+ ### S-221: audit.py verify exits 0 when it checked nothing (BACKLOG 123, audit.py half)
201
175
  - Files:
202
- - autonomy/lib/proof-check.sh: its 3 heredoc readers, plus a guarded helper copy.
203
- - tests/test-proof-check-no-user-site-pth.sh (new)
176
+ - dashboard/audit.py: the `_unified_cli` verify branch and its docstring only.
177
+ - tests/dashboard/test_audit_verify_cli_nothing_checked.py (new)
204
178
  - Tier: MEDIUM
205
- - Red: a `.pth` forges the headline read.
206
- - Green: `-I -S`. With no interpreter, the readers print empty, as they do today when python3 is absent.
207
- - Gate: reproduce the forged headline on main first.
179
+ - Red: `python3 dashboard/audit.py verify <empty dir>` exits 0.
180
+ - Green:
181
+ - `files_checked == 0` exits 2 (could not check), and the JSON is unchanged.
182
+ - `tip` and `prefix` are untouched, because src/audit/crosslink.js reads `tip`.
208
183
  - Wall:
209
- - `bash tests/test-proof-check-no-user-site-pth.sh` exits 0, and reverting fails it.
210
- - `bash tests/test-proven-pr-check.sh` exits 0.
184
+ - `python3 -m pytest -q tests/dashboard/test_audit_verify_cli_nothing_checked.py` covers:
185
+ - empty dir: 2;
186
+ - valid chain: 0;
187
+ - tampered chain: 1;
188
+ - `tip` on an empty dir: still 0.
189
+ - `bash tests/test-audit-chain-honesty.sh` and `bash tests/test-audit-js-suites.sh` exit 0.
211
190
 
212
- ### S-204: checklist verification loads user-site .pth (BACKLOG 53)
191
+ ### S-222: the skill-session WebSocket status push hardcodes running_agents 0 (BACKLOG 118)
213
192
  - Files:
214
- - autonomy/prd-checklist.sh: every python3 site, including the checklist-verify.py call and the oracle heredoc, plus a guarded helper copy.
215
- - tests/test-prd-checklist-no-user-site-pth.sh (new)
216
- - Tier: HIGH
217
- - Red: a `.pth` changes the status_token or the waiver read.
193
+ - dashboard/server.py: the skill-session broadcast payload only (about 1030-1047).
194
+ - tests/dashboard/test_skill_session_ws_running_agents.py (new)
195
+ - Tier: LOW
196
+ - Red: with no dashboard-state.json and a fresh session.json, the pushed payload carries `running_agents: 0`.
218
197
  - Green:
219
- - `-I -S`. The builder audits the oracle heredoc's imports first.
220
- - Any site that needs a non-stdlib module stays `-E` with a ponytail note.
221
- - Resolver failure: the builder lists each site's result. None reads as verified.
222
- - Gate: reproduce the changed read on main first.
198
+ - Send `running_agents: None` (unmeasured).
199
+ - The clients already read null: loki-overview.js 212, loki-session-control.js 152, and web-app StatusOverview.
200
+ - Gate: drive the branch on main first.
201
+ - If the loop cannot be driven in-process, lift the payload into one function and test that.
202
+ - If the branch is unreachable, close as handled.
223
203
  - Wall:
224
- - `bash tests/test-prd-checklist-no-user-site-pth.sh` exits 0, and reverting fails it.
225
- - `bash tests/moat/p2-honest-verdict.sh` prints `CASE P2.checklist-verify-not-shadowed PASS`.
226
- - `bash tests/test-prd-checklist-interval-w4.sh` exits 0.
204
+ - `python3 -m pytest -q tests/dashboard/test_skill_session_ws_running_agents.py` shows running_agents None.
205
+ - Restoring 0 fails it.
227
206
 
228
- ### S-205: Bun loki proof verify runs a PATH python3 -E (BACKLOG 48 class, Bun half)
207
+ ### S-223: notification triggers read "No triggers configured" after a failed read (BACKLOG 114 and 118)
229
208
  - Files:
230
- - loki-ts/src/commands/proof.ts: the verifier spawn only.
231
- - loki-ts/src/util/python.ts, only to extend the helper that already exists there.
232
- - loki-ts/tests/commands/proof_verify_interpreter.test.ts (new)
233
- - Tier: HIGH
234
- - Red: a user-site `.pth` under a scratch HOME changes verify output, or writes a marker.
209
+ - dashboard/server.py: `get_notification_triggers` only.
210
+ - dashboard-ui/components/loki-notification-center.js: `_loadTriggers` and the triggers empty branch only.
211
+ - tests/dashboard/test_notification_triggers_unreadable.py (new)
212
+ - dashboard-ui/tests/loki-notification-triggers-error.node.test.mjs (new)
213
+ - Tier: LOW
214
+ - Red:
215
+ - A corrupt triggers.json answers `{"triggers": []}`.
216
+ - A failed fetch keeps `[]`, so the panel says "No triggers configured".
235
217
  - Green:
236
- - Resolve like `_loki_snapshot_py_tool`: /usr/bin/python3 and /bin/python3 first, then absolute PATH dirs, each probed with `-I -S -c ''`. Run with `-I -S`.
237
- - If none resolves, exit 2 as NOT CHECKED.
238
- - Gate: reproduce the `.pth` effect on main first.
218
+ - The server answers `{"triggers": null, "error": "unreadable_triggers"}`, the same shape as `read_active_notifications`.
219
+ - The panel renders "Could not load triggers" and offers no toggles.
220
+ - A missing file still answers `[]`.
239
221
  - Wall:
240
- - `cd loki-ts && bun test tests/commands/proof_verify_interpreter.test.ts tests/commands/proof_verify_parity.test.ts` exits 0.
241
- - Reverting to `["python3","-E"]` fails the new test.
242
- - The Captain rebuilds loki-ts/dist.
222
+ - `python3 -m pytest -q tests/dashboard/test_notification_triggers_unreadable.py` passes.
223
+ - `node --test dashboard-ui/tests/loki-notification-triggers-error.node.test.mjs` passes: an error lacks "No triggers configured", and an empty list keeps it.
243
224
 
244
- ### S-206: cockpit actions say "working tree is clean" and "no run in progress" after a failed fetch (BACKLOG 114)
225
+ ### S-224: the web-app receipt and cost trend show a partly priced run as a complete cost (BACKLOG 118)
245
226
  - Files:
246
- - web-app/src/cockpit/FinalActions.tsx (disabled reasons only)
247
- - web-app/src/cockpit/FinalActions.reasons.test.mjs (new)
248
- - Tier: LOW
227
+ - web-app/src/components/EvidenceReceiptPanel.tsx (the Cost field only)
228
+ - web-app/src/api/client.ts (the ProofDetail `cost` type and the cost/timeline `runs` type only)
229
+ - web-app/src/pages/MetricsPage.tsx (`costTrend` only)
230
+ - web-app/src/components/EvidenceReceiptPanel.cost.test.mjs (new)
231
+ - Tier: MEDIUM
232
+ - Red: a detail with `cost: {usd: 1.2, cost_partial: true}` renders "$1.20".
249
233
  - Green:
250
- - Export a pure reasons function.
251
- - `git === null`: commit, push and PR read "Working tree status not loaded".
252
- - `status === null`: pause, resume and stop read "Run status not loaded".
253
- - Real data keeps today's copy.
234
+ - The receipt renders "at least $1.20", matching cost.html and proofs.html after S-158.
235
+ - A partial run's trend label carries "(partial)".
236
+ - `cost_partial` absent or false keeps today's text.
254
237
  - Wall:
255
- - `node --test web-app/src/cockpit/FinalActions.reasons.test.mjs` passes:
256
- - git null lacks "The working tree is clean" and "Nothing to push";
257
- - status null lacks "No run in progress";
258
- - `{ahead:0}` with no files keeps both sentences.
238
+ - `node --test web-app/src/components/EvidenceReceiptPanel.cost.test.mjs` passes.
259
239
  - `cd web-app && npx tsc -b` exits 0.
260
- - The Captain rebuilds web-app/dist.
261
240
 
262
- ### S-207: cockpit evidence says "No gate results recorded" when the checklist request failed (BACKLOG 114)
241
+ ### S-225: the standalone receipts list shows a partly priced run as a complete cost (BACKLOG 118)
263
242
  - Files:
264
- - web-app/src/cockpit/useCockpitState.ts: `getChecklist` through `settle`, plus a `checklistError` field.
265
- - web-app/src/cockpit/EvidencePanel.tsx (empty branch only)
266
- - web-app/src/cockpit/ExecutionCockpit.tsx (EvidencePanel props only)
267
- - web-app/src/cockpit/EvidencePanel.state.test.mjs (new)
243
+ - dashboard-ui/scripts/build-standalone.js (the `loadReceipts` cost cell only)
244
+ - tests/test-receipts-panel.sh (one new leg)
268
245
  - Tier: LOW
246
+ - Green:
247
+ - `cost_partial === true` renders "at least $X.XX".
248
+ - Anything else keeps today's text.
269
249
  - Wall:
270
- - `node --test web-app/src/cockpit/EvidencePanel.state.test.mjs` passes:
271
- - an error renders "Could not load gate results" and not "No gate results recorded";
272
- - `items:[]` with no error keeps that sentence.
273
- - `node web-app/src/cockpit/run-derive-view-test.mjs` exits 0.
274
- - `cd web-app && npx tsc -b` exits 0.
275
- - The Captain rebuilds web-app/dist.
250
+ - `bash tests/test-receipts-panel.sh` exits 0, and the new leg asserts the "at least" prefix only when `cost_partial` is true.
251
+ - `bash tests/test-budget-banner-dedup.sh` exits 0.
276
252
 
277
- ### S-208: trust trajectory reads any non-pass council verdict as a failure (BACKLOG 118)
253
+ ### S-226: loki stats reads unmeasured cost as $0.00 on both routes (BACKLOG 106 class)
278
254
  - Files:
279
- - autonomy/lib/trust_trajectory.py (`_verdict_is_pass` only)
280
- - tests/test_trust_trajectory_unknown_verdict.py (new)
255
+ - autonomy/loki (`cmd_stats` only)
256
+ - loki-ts/src/commands/stats.ts
257
+ - loki-ts/tests/commands/stats_unmeasured.test.ts (new)
258
+ - tests/test-stats-unmeasured-cost.sh (new)
281
259
  - Tier: MEDIUM
282
- - Red: a verdict such as "UNKNOWN" or "INCONCLUSIVE" maps to 0.0.
260
+ - Red: efficiency records where every cost and token field is 0 print "Estimated cost: $0.00", and the JSON has `tokens.cost_usd: 0.0`.
283
261
  - Green:
284
- - Only explicit fail tokens map to False. The builder enumerates them from completion-council.sh and proof-generator's writers.
285
- - Anything else maps to None, meaning the axis has no data point.
286
- - Gate: find a writer string that is neither pass nor fail. If none exists, close the slice as handled.
262
+ - A record counts when `efficiency_cost.record_is_measured` (bash) or kpis.ts `recordsMeasured` (Bun) holds.
263
+ - If none counts, the JSON sends `cost_usd: null` and the text says "not recorded".
264
+ - Budget used follows `cmd_cost`'s rule: a positive recorded `budget_used`, else the measured current cost, else null.
265
+ - Both routes produce identical output.
266
+ - Size: this may run past 30 minutes.
287
267
  - Wall:
288
- - `python3 -m pytest -q tests/test_trust_trajectory_unknown_verdict.py tests/test_trust_trajectory.py tests/dashboard/test_trust_trajectory_endpoint.py` passes.
289
- - An unknown verdict adds no data point, and REJECTED still reads 0.0.
290
- - Reverting fails the first case.
268
+ - `bash tests/test-stats-unmeasured-cost.sh` exits 0.
269
+ - `cd loki-ts && bun test tests/commands/stats.test.ts tests/commands/stats_unmeasured.test.ts` exits 0.
270
+ - `bash tests/test-bash-bun-parity.sh` exits 0.
291
271
 
292
- ### S-209: Bun codex, cline and aider get the raw prompt without the commit-hygiene line (BACKLOG 99, Bun half)
272
+ ### S-227: loki status prints Budget $0 for a run it never measured, on both routes (BACKLOG 106 class)
293
273
  - Files:
294
- - loki-ts/src/runner/providers.ts: the codex, cline and aider invokers only.
295
- - loki-ts/tests/runner/provider_commit_hygiene.test.ts (new)
296
- - loki-ts/tests/runner/providers.test.ts, only where exact-argv assertions move.
274
+ - autonomy/loki (the `cmd_status` budget block only)
275
+ - loki-ts/src/commands/status.ts (`readBudgetField` and its budget caller only)
276
+ - loki-ts/tests/commands/status.test.ts (budget legs only)
277
+ - tests/test-status-budget-unmeasured.sh (new)
297
278
  - Tier: MEDIUM
279
+ - Red: `"budget_used": 0` (what `check_budget_limit` writes when unmeasured), null, or a missing key prints "Budget: $0 / $10" on bash and "0" on Bun.
298
280
  - Green:
299
- - Prefix the prompt with the hygiene line plus a blank line, matching the bash `"$PROVIDER_COMMIT_HYGIENE"$'\n\n'"$prompt"`.
300
- - The test reads the literal from providers/codex.sh; it does not copy it.
281
+ - Only a positive recorded `budget_used` is a reading, the same rule as `cmd_cost`.
282
+ - Otherwise print "Budget: not recorded / $10" (or "Cost: not recorded (no limit)") and skip the gauge.
283
+ - Both routes produce identical output.
301
284
  - Wall:
302
- - `cd loki-ts && bun test tests/runner/provider_commit_hygiene.test.ts tests/runner/providers.test.ts` exits 0.
303
- - All three argvs carry the bash literal.
304
- - Claude's prompt is not double-prefixed.
305
- - Removing the prefix fails the three legs.
306
- - The Captain rebuilds loki-ts/dist.
285
+ - `bash tests/test-status-budget-unmeasured.sh` exits 0.
286
+ - `cd loki-ts && bun test tests/commands/status.test.ts` exits 0.
287
+ - `bash tests/test-status-cli-provider-parity.sh` exits 0.
307
288
 
308
- ### S-210: speed up the two command-probe suites (29s and 30s in shard-durations.tsv)
309
- - Files: tests/test-help-discoverability.sh, tests/test-completion-coverage.sh (the probe loops only)
289
+ ### S-228: DeployConnections pushes default "not connected" states upward after its own fetch failed (BACKLOG 121)
290
+ - Files:
291
+ - web-app/src/components/DeployConnections.tsx (the connect and disconnect handlers only)
292
+ - web-app/src/components/DeployConnections.propagate.test.mjs (new)
310
293
  - Tier: LOW
311
- - Change:
312
- - The builder captures `real_count` and the pass and fail lines first.
313
- - Then probe with `xargs -P 8`, each probe in its own scratch cwd, writing one result file per command.
314
- - Keep the captured-output (never piped) rule noted in the file.
294
+ - Red: the first fetch fails, then connecting Vercel calls `onStatusChange` with netlify and github `{connected:false}` built from the default state.
295
+ - Green: when the last fetch failed, the handlers re-fetch instead of pushing synthesized defaults.
315
296
  - Wall:
316
- - `time bash tests/test-help-discoverability.sh` and `time bash tests/test-completion-coverage.sh` each exit 0 with real time under 10s.
317
- - `real_count` and the pass counts match the pre-change capture.
318
- - The builder reports both timings.
297
+ - `node --test web-app/src/components/DeployConnections.propagate.test.mjs` passes.
298
+ - `node --test web-app/src/components/DeployConnections.state.test.mjs` passes.
299
+ - `cd web-app && npx tsc -b` exits 0.
319
300
 
320
- ### S-211: register the four suites BACKLOG 75 still leaves unrun (after S-174 merges)
321
- - Files: tests/run-all-tests.sh (four `run_test` lines only), tests/shard-durations.tsv (four lines)
322
- - Tier: LOW. **Captain-built after S-174 merges.**
323
- - Suites: tests/council/test_managed_completion_flag.sh, tests/council/test_managed_review_flag.sh, tests/test-evidence-gate-no-tests.sh, tests/test-voter-agents-json.sh.
324
- - All four appear only in comments in run-all-tests.sh, so no runner executes them.
325
- - The evidence-gate suite also appears in scripts/local-ci.sh, which is retired.
326
- - Gate:
327
- - Each suite passes 3 of 3 from a scratch cwd and leaves no `.loki/state/provider` in the repo.
328
- - A suite that fails is reported, not registered, and becomes its own fix slice (the S-110 lesson).
301
+ ### S-229: the preview header says "Detecting project type..." forever after a failed preview-info fetch (BACKLOG 114)
302
+ - Files:
303
+ - web-app/src/components/ProjectWorkspace.tsx, preview regions only: the `getPreviewInfo` call (about 839) and the "Detecting project type..." branch (about 1877).
304
+ - web-app/src/components/ProjectWorkspace.preview.test.mjs (new)
305
+ - Tier: LOW
306
+ - Green:
307
+ - Keep the error.
308
+ - Render "Could not detect project type" with the message.
309
+ - A pending request keeps "Detecting project type...".
310
+ - Wall:
311
+ - `node --test web-app/src/components/ProjectWorkspace.preview.test.mjs` passes: a rejected fetch lacks "Detecting project type...".
312
+ - `node --test web-app/src/components/ProjectWorkspace.panels.test.mjs` passes.
313
+ - `cd web-app && npx tsc -b` exits 0.
314
+
315
+ ### S-230: ProjectWorkspace labels unknown phases "building", and Replay Build can never appear (BACKLOG 115 and 118)
316
+ - Files:
317
+ - web-app/src/components/ProjectWorkspace.tsx, only the `buildPhase` memo (about 1401-1410) and the Replay Build condition (about 1488).
318
+ - web-app/src/components/ProjectWorkspace.phase.test.mjs (new)
319
+ - Tier: LOW
320
+ - Region: this does not overlap S-229's preview regions.
321
+ - Green:
322
+ - The builder lists the phase strings run.sh and the Bun runner actually write.
323
+ - Map REASON, ACT, REFLECT and VERIFY explicitly. Any other phase returns 'unknown'.
324
+ - Replay Build shows when `!isBuilding` and `sessionData.status` is completed or completion_promise_fulfilled, the same test as about 1431.
329
325
  - Wall:
330
- - `grep -c -e test_managed_completion_flag -e test_managed_review_flag -e test-evidence-gate-no-tests -e test-voter-agents-json tests/run-all-tests.sh` prints 8 (4 before registration).
331
- - `bash tests/test-shard-coverage.sh` exits 0.
326
+ - `node --test web-app/src/components/ProjectWorkspace.phase.test.mjs` passes:
327
+ - an unrecognized phase is not 'building';
328
+ - a completed idle session shows Replay Build.
329
+ - `cd web-app && npx tsc -b` exits 0.
332
330
 
333
- ### S-212: GUARDS 5, 12 and 13 still read PENDING after S-138, S-139 and S-154 landed (after S-181 merges)
334
- - Files: docs/v10/GUARDS.md (sections 5, 12 and 13 only). This does not overlap S-181's section 11.
331
+ ### S-231: the "Moat suite" CI check reads as moat proven at 0 of 9 (BACKLOG 52)
332
+ - Files: .github/workflows/test.yml (the moat-suite job `name:` only)
335
333
  - Tier: LOW
336
334
  - Green:
337
- - Section 12 names tests/test-no-ambient-gitconfig-writes.sh (S-138).
338
- - Section 13 names the RELEASED_AHEAD_OF_NPM case in tests/test-v10-pulse.sh (S-139). It states that this is a flag, not a refusal.
339
- - Section 5 names tests/test-prune-worktrees.sh only if that test asserts the no-mtime rule. Otherwise it stays PENDING and says what would close it.
335
+ - Rename the job to "Moat ratchet (no rule failed)".
336
+ - The step summary keeps its N of 9 count.
337
+ - Gate:
338
+ - First run `gh api repos/{owner}/{repo}/branches/main/protection/required_status_checks --jq .contexts`.
339
+ - If "Moat suite" is a required context, the slice becomes report-only, because renaming it would block every merge.
340
340
  - Wall:
341
- - `awk '/^## 12\./,0' docs/v10/GUARDS.md | grep -c 'PENDING, no slice cut'` prints 0.
342
- - `bash tests/test-no-ambient-gitconfig-writes.sh` and `bash tests/test-v10-pulse.sh` exit 0.
341
+ - `git grep -n "name: Moat suite" -- .github` prints nothing.
342
+ - `git grep -n "Moat suite" -- tests scripts .github` lists only the step-summary heading.
343
+ - The first push after merge shows the renamed check green.
343
344
 
344
- ### S-213: no test of their own covers the council-vote labels on cost.html and proofs.html (BACKLOG 123, tests only)
345
- - Files: dashboard-ui/tests/static-council-vote-label.node.test.mjs (new)
345
+ ### S-232: autonomy/loki is linted only inside the sentrux test; the lint suite never schedules its big files first
346
+ - Files:
347
+ - tests/run-shellcheck.sh
348
+ - tests/test-sentrux-init-rules.sh (T6 only)
349
+ - Tier: LOW (velocity plus lint placement)
350
+ - Change:
351
+ - (a) Add ./autonomy/loki to run-shellcheck.sh at `-S error`, today's bar. Delete T6.
352
+ - (b) Order the file list largest first, so run.sh and loki do not start last.
353
+ - Gate: capture the counts and real time before changing anything. Run back to back with a fixed `LOKI_SHELLCHECK_JOBS=4`.
354
+ - If (b) gains under 15%, keep only (a).
355
+ - Wall:
356
+ - `LOKI_SHELLCHECK_JOBS=4 bash tests/run-shellcheck.sh` exits 0. Its output includes "Checked ./autonomy/loki". The pass, fail and info counts equal the pre-change capture, with loki added.
357
+ - `time bash tests/test-sentrux-init-rules.sh` exits 0 with "8 passed" and real time under 10s.
358
+ - `grep -c shellcheck tests/test-sentrux-init-rules.sh` prints 0.
359
+ - The builder reports both timings.
360
+
361
+ ### S-233: a refused resume says nothing about which file blocked it or where the earlier commits are (BACKLOG 72 remainder)
362
+ - Files:
363
+ - autonomy/run.sh: the `setup_agent_branch` resume block only, around the `--no-overwrite-ignore` checkout.
364
+ - tests/test-refused-resume-warning.sh (new)
346
365
  - Tier: LOW
347
- - It pins:
348
- - proofs.html: the badge reads "council " plus the verdict, with the title "Recorded council vote, not a verification result".
349
- - cost.html: the runs header reads "Council vote".
366
+ - Red: a gitignored user file at a path the recorded branch tracks gets "could not be checked out - creating a new one", and nothing else.
367
+ - Green:
368
+ - The warning names the conflicting path or paths from git's stderr.
369
+ - It states that the earlier session's commits are still on `${recorded}`.
370
+ - Test rules: S-138 prelude; scratch cwd; no `.loki/state/provider` left in the repo.
350
371
  - Wall:
351
- - `node --test dashboard-ui/tests/static-council-vote-label.node.test.mjs` passes.
352
- - Renaming the header, or dropping the title, in a scratch copy fails it.
372
+ - `bash tests/test-refused-resume-warning.sh` exits 0, and the warning contains the file name and the branch name.
373
+ - `bash tests/test-branch-lifecycle.sh` exits 0.
353
374
 
354
- **Registration and rebuilds (Captain).**
355
- - New tests to register:
356
- - S-194 to S-198.
357
- - S-200 to S-209.
358
- - S-213.
359
- - Bundle rebuilds:
360
- - S-205 and S-209: loki-ts/dist.
361
- - S-206 and S-207: web-app/dist.
362
- - Sequencing:
363
- - S-211 builds after S-174 merges.
364
- - S-212 builds after S-181 merges.
365
- - S-194 and S-195 are the only run.sh rows. They name regions that do not overlap each other or S-175, and merge one at a time.
375
+ **Registration and rebuilds (Captain).** S-211 owns tests/run-all-tests.sh and tests/shard-durations.tsv, so no slice edits them.
376
+ - **New tests to register, after S-211 merges:**
377
+ - S-215: tests/test-proof-pr-no-cwd-shadow.sh
378
+ - S-216: tests/test-verify-no-cwd-shadow.sh
379
+ - S-217: tests/test-enforce-test-coverage-pkg-readers-pth.sh
380
+ - S-218: tests/test-untracked-status-fsmonitor.sh
381
+ - S-219: tests/test-session-commit-add-failure.sh
382
+ - S-220: tests/test-untrack-keeps-force-staged.sh
383
+ - S-221: tests/dashboard/test_audit_verify_cli_nothing_checked.py
384
+ - S-222: tests/dashboard/test_skill_session_ws_running_agents.py
385
+ - S-223: tests/dashboard/test_notification_triggers_unreadable.py and dashboard-ui/tests/loki-notification-triggers-error.node.test.mjs
386
+ - S-224: web-app/src/components/EvidenceReceiptPanel.cost.test.mjs
387
+ - S-226: tests/test-stats-unmeasured-cost.sh and loki-ts/tests/commands/stats_unmeasured.test.ts
388
+ - S-227: tests/test-status-budget-unmeasured.sh
389
+ - S-228: DeployConnections.propagate.test.mjs
390
+ - S-229: ProjectWorkspace.preview.test.mjs
391
+ - S-230: ProjectWorkspace.phase.test.mjs
392
+ - S-233: tests/test-refused-resume-warning.sh
393
+ - **Bundle rebuilds:**
394
+ - loki-ts/dist: S-226, S-227.
395
+ - web-app/dist: S-224, S-228, S-229, S-230.
396
+ - dashboard static: S-225.
397
+ - dashboard-ui dist and dashboard static: S-223.
398
+ - **Merge order:**
399
+ - run.sh: S-217, S-218, S-219, S-220 and S-233, plus S-194 and S-195 in flight. They name regions that do not overlap, anchor on function names, and merge one at a time.
400
+ - autonomy/loki: S-226 and S-227, plus S-197 in flight, one at a time.
401
+ - dashboard/server.py: S-222 and S-223.
402
+ - ProjectWorkspace.tsx: S-229 and S-230.
403
+ - S-215 and S-216 add guarded helper copies. S-199's identity test picks them up with no edit.
404
+ - **Test rules for the git-touching slices** (S-218, S-219, S-220, S-233): each uses S-138's isolation prelude, and `bash tests/test-no-ambient-gitconfig-writes.sh` must stay green.
366
405
 
367
406
  **Held, not in the 20:**
368
- - BACKLOG 147 (P7 useMemo composed form): wait for S-180.
369
- - BACKLOG 36 (P7 zero-file scan): wait for S-180 and S-198.
370
- - BACKLOG 19 (a stripped remote attestation reads UNSIGNED exit 0): same function as S-197, so wait for S-197.
371
- - The bash `loki proof verify` interpreter (autonomy/loki `cmd_proof`, `python3 -E`): wait for S-179 and S-197.
372
- - BACKLOG 99, bash half (run.sh main loop): wait for S-175, S-194 and S-195.
373
- - workspace_diff reports count 0 in a non-git directory: needs a design, because the value lands in the receipt.
374
- - dashboard/server.py items from BACKLOG 118: wait for S-178. They are:
375
- - `/cost` pricing at Sonnet rates with no estimate label;
376
- - council-state `total_votes: 0`;
377
- - notifications zero summary;
378
- - `StatusResponse` defaults;
379
- - skill-session `running_agents: 0`.
380
- - ProjectWorkspace phase labels and Replay Build: wait for S-187.
381
- - Speeding up test-autocapture-shadow-write-guard.sh: its negative legs wait on a disowned process and need a design.
382
- - Carried over: P1.verification-metadata-signed; the P2 verify renumber (CEO); BACKLOG 18, 28, 52, 121, and 123 (the audit.py half); S-112, S-114, S-115, S-117 to S-122.
407
+ - BACKLOG 36: waits for S-198.
408
+ - BACKLOG 19 and the bash `loki proof verify` interpreter: wait for S-197 (S-179 is merged, 94035ac4).
409
+ - BACKLOG 99, bash half: waits for S-194 and S-195 (S-175 is merged, 6fab92ce).
410
+ - `StatusResponse` defaults (iteration 0, provider "claude"): changing the types touches every /api/status consumer, so this needs a design.
411
+ - BACKLOG 100 (the untrack step in the interrupt path): git commits from a signal handler need a design.
412
+ - workspace_diff count 0 in a non-git directory: needs a design.
413
+ - Speeding up test-autocapture-shadow-write-guard.sh: needs a design.
414
+ - `P4.three-setups-resolve`: waits on the D10 default decision.
415
+ - BACKLOG 18: default-off decision for the founder.
416
+ - BACKLOG 28: needs per-case expected failure reasons; design.
417
+ - BACKLOG 121, the settings half: product decision.
418
+ - `P1.verification-metadata-signed`: M2 seal.v1.
419
+ - The P2 verify renumber (CEO); S-112, S-114, S-115, S-117 to S-122.
383
420
 
384
- | S-194 | BACKLOG 108: LOKI_AUTO_PR pushes a branch whose history still holds user files | autonomy/run.sh (create_session_pr only; does not overlap S-175 or S-195), tests/test-auto-pr-agent-committed-refuse.sh (new) | HIGH | bash tests/test-auto-pr-agent-committed-refuse.sh exits 0: auto path with a record makes no push, returns 1 and prints git reset --soft; advisory path prints the cleanup before git push -u; empty record pushes; removing the record read in a scratch copy fails leg 1; bash tests/test-trusted-push-agent-config.sh exits 0 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
385
- | S-195 | BACKLOG 17: /api/focus POST fires with the dashboard disabled | autonomy/run.sh (dashboard focus notify block only; does not overlap S-175 or S-194), tests/test-focus-post-dashboard-off.sh (new) | MEDIUM | bash tests/test-focus-post-dashboard-off.sh exits 0: ENABLE_DASHBOARD=false leaves the curl shim log empty, true records one POST; removing the guard in a scratch copy fails the false leg | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
386
- | S-196 | council_managed_should_stop diffs Loki's install tree and runs -E readers | autonomy/completion-council.sh (council_managed_should_stop only), tests/moat/p2-honest-verdict.sh (case_council_readers_no_user_site_pth plus the ~858 comment), tests/test-council-managed-diff-target.sh (new) | HIGH | bash tests/moat/p2-honest-verdict.sh prints CASE P2.council-readers-no-user-site-pth PASS and CASE P2.council-readers-not-shadowed PASS; bash tests/test-council-managed-diff-target.sh exits 0 with the target-only file in _CC_DIFF; reverting the readers to -E makes the pth case FAIL; bash tests/moat/run.sh reports no rule failed | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
387
- | S-197 | BACKLOG 51: NOT CHECKED text should name PYTHONPATH and PYTHONUSERBASE | autonomy/loki (loki_remote_verify_receipt attestation NOT CHECKED branch and cmd_proof --jwks NOT CHECKED echo only; does not overlap S-179), tests/test-proof-verify-jwks.sh (case 4 only) | LOW | bash tests/test-proof-verify-jwks.sh exits 0 with case 4 asserting PYTHONUSERBASE in the NOT CHECKED output; grep -c PYTHONUSERBASE autonomy/loki prints 2 or more; bash tests/test-remote-attestation-verdict.sh exits 0 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
388
- | S-198 | BACKLOG 145: P7 Array.from arm loses an outer generator's index when generators nest | tests/moat/p7-no-fabricated-data.sh (Array.from generator arm ~1934-1994 and one fixture beside the B-8 fixture ~3301 only; does not overlap S-180) | HIGH | bash tests/moat/p7-no-fabricated-data.sh prints PASS for every P7 case and flags the nested fixture; removing the outer substitution lets it through; tests/moat/cases.txt unchanged | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
389
- | S-199 | py-tool identity test covers every guarded _loki_snapshot_py_tool copy under autonomy/ | tests/test-council-py-tool-identity.sh | LOW | bash tests/test-council-py-tool-identity.sh exits 0 and prints the number of copies compared (at least 1 besides run.sh); a one-byte change to completion-council.sh's copy in a scratch tree exits 1 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
390
- | S-200 | BACKLOG 54: done-recognition readers load user-site .pth (-E only) | autonomy/lib/done-recognition.sh (python3 sites plus guarded helper copy), tests/test-done-recognition-no-user-site-pth.sh (new) | HIGH | bash tests/test-done-recognition-no-user-site-pth.sh exits 0 and reverting one site to -E in a scratch copy fails it; bash tests/test-done-recognition-tests-axis.sh and bash tests/test-reuse-done-recognition.sh exit 0 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
391
- | S-201 | BACKLOG 54: council-v2 readers load .pth; a crashed sycophancy check skips the devil's advocate | autonomy/council-v2.sh (python3 sites, Step 4 and 5 fallbacks, guarded helper copy), tests/test-council-v2-no-user-site-pth.sh (new) | MEDIUM | bash tests/test-council-v2-no-user-site-pth.sh exits 0 (pth leg and detector-failure leg run the devil's advocate on a unanimous approve); reverting either change fails its leg; bash tests/test-council-v2-quorum.sh exits 0 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
392
- | S-202 | BACKLOG 54: voter-agents readers load user-site .pth (-E only) | autonomy/lib/voter-agents.sh (3 python3 sites plus guarded helper copy), tests/test-voter-agents-no-user-site-pth.sh (new) | HIGH | bash tests/test-voter-agents-no-user-site-pth.sh exits 0 and reverting fails it; bash tests/test-voter-agents-json.sh and bash tests/test-sdk-voter-agents.sh exit 0 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
393
- | S-203 | BACKLOG 54: proof-check readers load user-site .pth (-E only) | autonomy/lib/proof-check.sh (3 heredoc readers plus guarded helper copy), tests/test-proof-check-no-user-site-pth.sh (new) | MEDIUM | bash tests/test-proof-check-no-user-site-pth.sh exits 0 and reverting fails it; bash tests/test-proven-pr-check.sh exits 0 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
394
- | S-204 | BACKLOG 53: checklist verification loads user-site .pth (-E only) | autonomy/prd-checklist.sh (python3 sites incl. checklist-verify.py call and oracle heredoc, plus guarded helper copy), tests/test-prd-checklist-no-user-site-pth.sh (new) | HIGH | bash tests/test-prd-checklist-no-user-site-pth.sh exits 0 and reverting fails it; bash tests/moat/p2-honest-verdict.sh prints CASE P2.checklist-verify-not-shadowed PASS; bash tests/test-prd-checklist-interval-w4.sh exits 0 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
395
- | S-205 | Bun loki proof verify runs a PATH python3 -E (user-site .pth reaches the verdict) | loki-ts/src/commands/proof.ts (verifier spawn only), loki-ts/src/util/python.ts (extend existing helper only if used), loki-ts/tests/commands/proof_verify_interpreter.test.ts (new) | HIGH | cd loki-ts && bun test tests/commands/proof_verify_interpreter.test.ts tests/commands/proof_verify_parity.test.ts exits 0; reverting to python3 -E fails the new test; no resolvable interpreter exits 2 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
396
- | S-206 | BACKLOG 114: cockpit actions say working tree is clean and no run in progress after a failed fetch | web-app/src/cockpit/FinalActions.tsx (disabled reasons only), web-app/src/cockpit/FinalActions.reasons.test.mjs (new) | LOW | node --test web-app/src/cockpit/FinalActions.reasons.test.mjs passes: git null lacks The working tree is clean and Nothing to push, status null lacks No run in progress, real data keeps both; cd web-app && npx tsc -b exits 0 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
397
- | S-207 | BACKLOG 114: cockpit evidence says No gate results recorded when the checklist request failed | web-app/src/cockpit/useCockpitState.ts (getChecklist via settle only), web-app/src/cockpit/EvidencePanel.tsx (empty branch only), web-app/src/cockpit/ExecutionCockpit.tsx (EvidencePanel props only), web-app/src/cockpit/EvidencePanel.state.test.mjs (new) | LOW | node --test web-app/src/cockpit/EvidencePanel.state.test.mjs passes: an error renders Could not load gate results, items [] keeps No gate results recorded; node web-app/src/cockpit/run-derive-view-test.mjs exits 0; cd web-app && npx tsc -b exits 0 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
398
- | S-208 | BACKLOG 118: trust trajectory reads any non-pass council verdict as a failure | autonomy/lib/trust_trajectory.py (_verdict_is_pass only), tests/test_trust_trajectory_unknown_verdict.py (new) | MEDIUM | python3 -m pytest -q tests/test_trust_trajectory_unknown_verdict.py tests/test_trust_trajectory.py tests/dashboard/test_trust_trajectory_endpoint.py passes: an unknown verdict adds no data point, REJECTED stays 0.0; reverting fails case 1 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
399
- | S-209 | BACKLOG 99 (Bun): codex, cline and aider get the prompt without the commit-hygiene line | loki-ts/src/runner/providers.ts (codex, cline, aider invokers only), loki-ts/tests/runner/provider_commit_hygiene.test.ts (new), loki-ts/tests/runner/providers.test.ts (argv asserts only if moved) | MEDIUM | cd loki-ts && bun test tests/runner/provider_commit_hygiene.test.ts tests/runner/providers.test.ts exits 0: all three argvs carry the providers/codex.sh literal, claude not double-prefixed; removing the prefix fails the three legs | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
400
- | S-210 | Velocity: help-discoverability (29s) and completion-coverage (30s) probe loops under 10s each | tests/test-help-discoverability.sh, tests/test-completion-coverage.sh (probe loops only) | LOW | time bash tests/test-help-discoverability.sh and time bash tests/test-completion-coverage.sh each exit 0 with real under 10s; real_count and pass counts match the pre-change capture; both timings reported | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
401
- | S-211 | BACKLOG 75: register the four suites no runner executes (Captain, after S-174 merges) | tests/run-all-tests.sh (four run_test lines only, after S-174 merges), tests/shard-durations.tsv (four lines) | LOW | grep -c -e test_managed_completion_flag -e test_managed_review_flag -e test-evidence-gate-no-tests -e test-voter-agents-json tests/run-all-tests.sh prints 8; bash tests/test-shard-coverage.sh exits 0; each suite ran 3 of 3 from a scratch cwd with no .loki/state/provider left | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
402
- | S-212 | GUARDS 5, 12 and 13 still read PENDING after S-138, S-139 and S-154 landed (after S-181 merges) | docs/v10/GUARDS.md (sections 5, 12, 13 only; does not overlap S-181 section 11) | LOW | awk '/^## 12\./,0' docs/v10/GUARDS.md piped to grep -c 'PENDING, no slice cut' prints 0; bash tests/test-no-ambient-gitconfig-writes.sh and bash tests/test-v10-pulse.sh exit 0 | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
403
- | S-213 | BACKLOG 123: cost.html and proofs.html council-vote labels have no test of their own | dashboard-ui/tests/static-council-vote-label.node.test.mjs (new) | LOW | node --test dashboard-ui/tests/static-council-vote-label.node.test.mjs passes (proofs.html council prefix and title, cost.html Council vote header); renaming the header or dropping the title in a scratch copy fails it | ready@2026-09-27T20:12Z | Source: 20:12Z cut. |
421
+ | S-214 | BACKLOG 147: P7 useMemo arm misses a factory that calls a registered fabricator | tests/moat/p7-no-fabricated-data.sh (HELPER_LOCAL_DECL_TMPL ~1182 and its use ~2186, ceiling comment ~978-986, one fixture beside the DECL_USEMEMO fixture ~3138-3160 only; does not overlap S-198) | HIGH | bash tests/moat/p7-no-fabricated-data.sh prints PASS for every P7 case and flags the composed useMemo fixture; removing the useMemo prefix in a scratch copy lets it through; git diff --stat tests/moat/cases.txt is empty | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
422
+ | S-215 | PR receipt renderer in proof-pr.sh imports json from the target repo (cwd shadow) | autonomy/lib/proof-pr.sh (render_evidence_receipt_md heredoc reader plus guarded _loki_snapshot_py_tool copy), tests/test-proof-pr-no-cwd-shadow.sh (new) | HIGH | bash tests/test-proof-pr-no-cwd-shadow.sh exits 0 (a planted json.py cannot forge the headline) and reverting to bare python3 - in a scratch copy fails it; bash tests/test-proven-pr-receipt.sh exits 0; bash tests/test-council-py-tool-identity.sh exits 0 and counts one more copy | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
423
+ | S-216 | loki verify inline readers import from the tree under review (cwd shadow) | autonomy/verify.sh (reader sites ~190, 591, 1269, 1271, 1295, 1337, 1339, 1441 plus guarded helper copy; not the unittest or py_compile runs), tests/test-verify-no-cwd-shadow.sh (new) | HIGH | bash tests/test-verify-no-cwd-shadow.sh exits 0 and reverting one site in a scratch copy fails it; bash tests/test-verify.sh exits 0; bash tests/moat/run.sh reports no rule failed; bash tests/test-council-py-tool-identity.sh exits 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
424
+ | S-217 | BACKLOG 81: enforce_test_coverage package.json readers load user-site .pth | autonomy/run.sh (enforce_test_coverage _declared_test_script and _ws_script readers only; anchor on names), tests/test-enforce-test-coverage-pkg-readers-pth.sh (new) | HIGH | bash tests/test-enforce-test-coverage-pkg-readers-pth.sh exits 0 (a .pth no longer changes the recorded test gate outcome) and reverting one reader to -E in a scratch copy fails it; no .loki/state/provider left in the repo; bash tests/test-honest-gate-status.sh exits 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
425
+ | S-218 | BACKLOG 131c: snapshot git status runs an agent-chosen core.fsmonitor command | autonomy/run.sh (_loki_untracked_status only), tests/test-untracked-status-fsmonitor.sh (new) | HIGH | bash tests/test-untracked-status-fsmonitor.sh exits 0 (no fsmonitor marker, real untracked file still listed) and removing the two -c flags in a scratch copy fails it; bash tests/test-no-ambient-gitconfig-writes.sh and bash tests/test-branch-lifecycle.sh exit 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
426
+ | S-219 | BACKLOG 83: a failed git add -A makes the session commit silently commit nothing | autonomy/run.sh (commit_session_changes git add -A block only), tests/test-session-commit-add-failure.sh (new) | MEDIUM | bash tests/test-session-commit-add-failure.sh exits 0: an empty embedded repo prints Left uncommitted naming the add failure, a normal repo still commits; removing the rc check in a scratch copy fails leg 1; bash tests/test-branch-lifecycle.sh exits 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
427
+ | S-220 | BACKLOG 109: untrack step's global reset drops force-staged agent files from the session commit | autonomy/run.sh (_loki_untrack_agent_committed_user_files only), tests/test-untrack-keeps-force-staged.sh (new) | MEDIUM | bash tests/test-untrack-keeps-force-staged.sh exits 0: git add -f dist/bundle.js lands in the session commit while the pre-existing user file stays untracked on disk; restoring git reset -q in a scratch copy fails it; bash tests/test-branch-lifecycle.sh exits 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
428
+ | S-221 | BACKLOG 123: audit.py verify exits 0 when it checked nothing | dashboard/audit.py (_unified_cli verify branch and docstring only; tip and prefix untouched), tests/dashboard/test_audit_verify_cli_nothing_checked.py (new) | MEDIUM | python3 -m pytest -q tests/dashboard/test_audit_verify_cli_nothing_checked.py: empty dir exits 2, valid chain 0, tampered 1, tip on an empty dir still 0; bash tests/test-audit-chain-honesty.sh and bash tests/test-audit-js-suites.sh exit 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
429
+ | S-222 | BACKLOG 118: skill-session WebSocket status push hardcodes running_agents 0 | dashboard/server.py (skill-session broadcast payload ~1030-1047 only), tests/dashboard/test_skill_session_ws_running_agents.py (new) | LOW | python3 -m pytest -q tests/dashboard/test_skill_session_ws_running_agents.py shows running_agents None on the skill-session push; restoring 0 fails it | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
430
+ | S-223 | BACKLOG 114/118: notification triggers read No triggers configured after a failed read | dashboard/server.py (get_notification_triggers only), dashboard-ui/components/loki-notification-center.js (_loadTriggers and triggers empty branch only), tests/dashboard/test_notification_triggers_unreadable.py (new), dashboard-ui/tests/loki-notification-triggers-error.node.test.mjs (new) | LOW | python3 -m pytest -q tests/dashboard/test_notification_triggers_unreadable.py shows triggers null with error on a corrupt file and [] on a missing one; node --test dashboard-ui/tests/loki-notification-triggers-error.node.test.mjs shows an error lacks No triggers configured and an empty list keeps it | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
431
+ | S-224 | BACKLOG 118: web-app receipt and cost trend show a partly priced run as a complete cost | web-app/src/components/EvidenceReceiptPanel.tsx (Cost field only), web-app/src/api/client.ts (ProofDetail cost type and cost/timeline runs type only), web-app/src/pages/MetricsPage.tsx (costTrend only), web-app/src/components/EvidenceReceiptPanel.cost.test.mjs (new) | MEDIUM | node --test web-app/src/components/EvidenceReceiptPanel.cost.test.mjs: cost_partial true renders at least $1.20, absent keeps $1.20, a partial run's trend label carries (partial); cd web-app && npx tsc -b exits 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
432
+ | S-225 | BACKLOG 118: standalone receipts list shows a partly priced run as a complete cost | dashboard-ui/scripts/build-standalone.js (loadReceipts cost cell only), tests/test-receipts-panel.sh (one new leg) | LOW | bash tests/test-receipts-panel.sh exits 0 with the new leg asserting at least $X.XX only when cost_partial is true; bash tests/test-budget-banner-dedup.sh exits 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
433
+ | S-226 | BACKLOG 106 class: loki stats reads unmeasured cost as $0.00 on both routes | autonomy/loki (cmd_stats only), loki-ts/src/commands/stats.ts, loki-ts/tests/commands/stats_unmeasured.test.ts (new), tests/test-stats-unmeasured-cost.sh (new) | MEDIUM | bash tests/test-stats-unmeasured-cost.sh exits 0 (all-zero records give cost_usd null and not recorded, same on both routes); cd loki-ts && bun test tests/commands/stats.test.ts tests/commands/stats_unmeasured.test.ts exits 0; bash tests/test-bash-bun-parity.sh exits 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
434
+ | S-227 | BACKLOG 106 class: loki status prints Budget $0 for a run it never measured, on both routes | autonomy/loki (cmd_status budget block only), loki-ts/src/commands/status.ts (readBudgetField and its budget caller only), loki-ts/tests/commands/status.test.ts (budget legs only), tests/test-status-budget-unmeasured.sh (new) | MEDIUM | bash tests/test-status-budget-unmeasured.sh exits 0 (budget_used 0, null or absent prints not recorded on both routes, a positive value prints as today); cd loki-ts && bun test tests/commands/status.test.ts exits 0; bash tests/test-status-cli-provider-parity.sh exits 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
435
+ | S-228 | BACKLOG 121: DeployConnections pushes default not-connected states upward after its own fetch failed | web-app/src/components/DeployConnections.tsx (connect and disconnect handlers only), web-app/src/components/DeployConnections.propagate.test.mjs (new) | LOW | node --test web-app/src/components/DeployConnections.propagate.test.mjs shows no synthesized statuses reach onStatusChange after a failed fetch; node --test web-app/src/components/DeployConnections.state.test.mjs and cd web-app && npx tsc -b exit 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
436
+ | S-229 | BACKLOG 114: preview header says Detecting project type forever after a failed preview-info fetch | web-app/src/components/ProjectWorkspace.tsx (getPreviewInfo call ~839 and Detecting project type branch ~1877 only), web-app/src/components/ProjectWorkspace.preview.test.mjs (new) | LOW | node --test web-app/src/components/ProjectWorkspace.preview.test.mjs shows a rejected fetch renders Could not detect project type and lacks Detecting project type; node --test web-app/src/components/ProjectWorkspace.panels.test.mjs and cd web-app && npx tsc -b exit 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
437
+ | S-230 | BACKLOG 115/118: ProjectWorkspace labels unknown phases building and Replay Build can never appear | web-app/src/components/ProjectWorkspace.tsx (buildPhase memo ~1401-1410 and Replay Build condition ~1488 only; does not overlap S-229), web-app/src/components/ProjectWorkspace.phase.test.mjs (new) | LOW | node --test web-app/src/components/ProjectWorkspace.phase.test.mjs shows an unrecognized phase is not building and a completed idle session shows Replay Build; cd web-app && npx tsc -b exits 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
438
+ | S-231 | BACKLOG 52: the Moat suite CI check reads as moat proven at 0 of 9 | .github/workflows/test.yml (moat-suite job name only) | LOW | gh api required_status_checks for main does not list Moat suite (else report-only); git grep -n "name: Moat suite" -- .github prints nothing; git grep -n "Moat suite" -- tests scripts .github lists only the step-summary heading; the next push shows the renamed check | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
439
+ | S-232 | autonomy/loki is linted only inside the sentrux test; the lint suite schedules big files last | tests/run-shellcheck.sh, tests/test-sentrux-init-rules.sh (T6 only) | LOW | LOKI_SHELLCHECK_JOBS=4 bash tests/run-shellcheck.sh exits 0, prints Checked ./autonomy/loki, counts match the pre-change capture plus loki; time bash tests/test-sentrux-init-rules.sh exits 0 with 8 passed under 10s; grep -c shellcheck tests/test-sentrux-init-rules.sh prints 0; both timings reported | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |
440
+ | S-233 | BACKLOG 72 remainder: refused resume does not name the blocking file or where the earlier commits are | autonomy/run.sh (setup_agent_branch resume block around the no-overwrite-ignore checkout only), tests/test-refused-resume-warning.sh (new) | LOW | bash tests/test-refused-resume-warning.sh exits 0 with the warning naming the conflicting ignored file and the recorded branch; bash tests/test-branch-lifecycle.sh exits 0 | ready@2026-09-27T20:59Z | Source: 20:59Z cut. |