loki-mode 11.74.2 → 11.75.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.
Files changed (166) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +2 -3
  3. package/VERSION +1 -1
  4. package/autonomy/completion-council.sh +10 -10
  5. package/autonomy/council-v2.sh +4 -4
  6. package/autonomy/grill.sh +1 -1
  7. package/autonomy/lib/browser-open.sh +1 -1
  8. package/autonomy/lib/chat.sh +1 -1
  9. package/autonomy/lib/cockpit-render.sh +1 -1
  10. package/autonomy/lib/done-recognition.sh +4 -4
  11. package/autonomy/lib/efficiency_cost.py +1 -1
  12. package/autonomy/lib/engine10-push.sh +2 -2
  13. package/autonomy/lib/prd-enrich.sh +1 -1
  14. package/autonomy/lib/proof-check.sh +1 -1
  15. package/autonomy/lib/proof-generator.py +3 -3
  16. package/autonomy/lib/proof-pr.sh +1 -1
  17. package/autonomy/lib/skill-link-heal.sh +1 -1
  18. package/autonomy/lib/voter-agents.sh +1 -1
  19. package/autonomy/loki +26 -37
  20. package/autonomy/prd-checklist.sh +1 -1
  21. package/autonomy/receipt_jwt.py +1 -1
  22. package/autonomy/run.sh +28 -28
  23. package/autonomy/trigger-schedule.py +6 -414
  24. package/autonomy/tui.sh +1 -1
  25. package/autonomy/verify.sh +4 -4
  26. package/completions/loki.bash +0 -5
  27. package/dashboard/__init__.py +1 -1
  28. package/docs/ARCHITECTURE.md +1 -2
  29. package/docs/CLI-REFERENCE.md +1 -1
  30. package/docs/COMPONENTS.md +1 -1
  31. package/docs/INSTALLATION.md +1 -1
  32. package/docs/ROUTING-EVIDENCE.md +1 -2
  33. package/docs/V10-RESEARCH.md +1 -1
  34. package/docs/dev/architecture-reference.md +3 -7
  35. package/docs/dev/project-structure.md +1 -4
  36. package/docs/dev/release-checklist.md +13 -31
  37. package/docs/research-2026-07/OBSERVABILITY-TOOL-SPEC.md +1 -1
  38. package/docs/v11/MARKET-SLICES.md +1 -1
  39. package/docs/v11/REGISTRIES.md +1 -1
  40. package/docs/v11/ROUTER-1.md +2 -2
  41. package/loki-ts/dist/loki.js +2 -2
  42. package/mcp/__init__.py +1 -1
  43. package/package.json +2 -2
  44. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  45. package/skills/extending.md +2 -3
  46. package/skills/factory-operations.md +11 -18
  47. package/skills/release-cadence.md +2 -2
  48. package/web-app/dist/assets/{AdminPage-jkjilfbl.js → AdminPage-xKgtIhk2.js} +1 -1
  49. package/web-app/dist/assets/{Avatar-bd5JWkSJ.js → Avatar-Q14AHox9.js} +1 -1
  50. package/web-app/dist/assets/{Badge-DVRit2Xw.js → Badge-yk5M-lip.js} +1 -1
  51. package/web-app/dist/assets/{Button-BNAB-pVZ.js → Button-ynznk0At.js} +1 -1
  52. package/web-app/dist/assets/{CockpitPage-DpG29h_w.js → CockpitPage-C8B765za.js} +1 -1
  53. package/web-app/dist/assets/{ComparePage-Dasg5V41.js → ComparePage-DqzmWKnf.js} +1 -1
  54. package/web-app/dist/assets/{ErrorBoundary-DJojse6b.js → ErrorBoundary-DdBPd_Lq.js} +1 -1
  55. package/web-app/dist/assets/{EvidenceReceiptPanel-Blxw7_u1.js → EvidenceReceiptPanel-jb4Tp38b.js} +1 -1
  56. package/web-app/dist/assets/{GitHubIssuesPanel-BBvSFj80.js → GitHubIssuesPanel-xJQiLcxs.js} +1 -1
  57. package/web-app/dist/assets/{GitHubPRsPanel-BCIKeSBg.js → GitHubPRsPanel-84W3Dhk_.js} +1 -1
  58. package/web-app/dist/assets/{HomePage-C7d__oNG.js → HomePage-St1Xl2tu.js} +2 -2
  59. package/web-app/dist/assets/{LoginPage-BXljL3yY.js → LoginPage-jRt0NUHb.js} +1 -1
  60. package/web-app/dist/assets/{MagicPage-Xjkts_yE.js → MagicPage-CQLFe7LR.js} +1 -1
  61. package/web-app/dist/assets/{MetricsPage-kQvVp-j2.js → MetricsPage-zzX9eTC5.js} +1 -1
  62. package/web-app/dist/assets/{NotFoundPage-D-4ZlEaO.js → NotFoundPage-DDu023SY.js} +1 -1
  63. package/web-app/dist/assets/{ProjectPage-DfzR5RXP.js → ProjectPage-D60UURaH.js} +3 -3
  64. package/web-app/dist/assets/{ProjectsPage-DFDsWzkV.js → ProjectsPage-DqVsKxlt.js} +1 -1
  65. package/web-app/dist/assets/{SettingsPage-CLPIoYT3.js → SettingsPage-G7pPKvo0.js} +1 -1
  66. package/web-app/dist/assets/{ShowcasePage-PZKkyGeY.js → ShowcasePage-CrU_aKgS.js} +1 -1
  67. package/web-app/dist/assets/{SystemSettingsPage-BsBlcnzo.js → SystemSettingsPage-ClKGQFsB.js} +1 -1
  68. package/web-app/dist/assets/{TeamsPage-BSjgNhoU.js → TeamsPage-B530vSNe.js} +1 -1
  69. package/web-app/dist/assets/{TemplatesPage-W2KeAzbg.js → TemplatesPage-COmv_Cqd.js} +1 -1
  70. package/web-app/dist/assets/{TerminalOutput-BjroTiCC.js → TerminalOutput-CufG9YzF.js} +1 -1
  71. package/web-app/dist/assets/{activity-BXZ5YYes.js → activity-Ct1Updr6.js} +1 -1
  72. package/web-app/dist/assets/{bell-D1urp5pa.js → bell-rcvhQuGr.js} +1 -1
  73. package/web-app/dist/assets/{bot-Chedf2bF.js → bot-DzeqEI-b.js} +1 -1
  74. package/web-app/dist/assets/{check-DhaCuOCV.js → check-zacnZHyC.js} +1 -1
  75. package/web-app/dist/assets/{chevron-left-D7BpQyA6.js → chevron-left-Lxnkl8Qg.js} +1 -1
  76. package/web-app/dist/assets/{circle-alert-DnGvQ_AQ.js → circle-alert-DoqSdQdB.js} +1 -1
  77. package/web-app/dist/assets/{clock-CqfxWhHM.js → clock-B7bJcVIC.js} +1 -1
  78. package/web-app/dist/assets/{cloud-BKxp5AWB.js → cloud-DdA9Bu6q.js} +1 -1
  79. package/web-app/dist/assets/{code-xml-BDQ6GBtt.js → code-xml-CAZEZ9T8.js} +1 -1
  80. package/web-app/dist/assets/{database-BmpEx1y_.js → database-Da2GkEIN.js} +1 -1
  81. package/web-app/dist/assets/{dollar-sign-DYNY9R_C.js → dollar-sign-DjDiG-37.js} +1 -1
  82. package/web-app/dist/assets/{file-code-corner-BJi0IBFd.js → file-code-corner-CSL-Jij-.js} +1 -1
  83. package/web-app/dist/assets/{file-plus-Dqyb2bcQ.js → file-plus-02DRA8pV.js} +1 -1
  84. package/web-app/dist/assets/{globe-DPh4RWfM.js → globe-CGyB90kK.js} +1 -1
  85. package/web-app/dist/assets/{hammer-B3xnuoA1.js → hammer-BaQB96TG.js} +1 -1
  86. package/web-app/dist/assets/{index-BpX8DcTr.js → index-lcoI1_Kk.js} +3 -3
  87. package/web-app/dist/assets/{layers-BRCmyCW8.js → layers-BWJBvoeg.js} +1 -1
  88. package/web-app/dist/assets/{loader-circle-n07Pky0M.js → loader-circle-CdcI0FeS.js} +1 -1
  89. package/web-app/dist/assets/{lock-BWqOuQmS.js → lock-BBkw5NJx.js} +1 -1
  90. package/web-app/dist/assets/{package-BJlB_Z-Z.js → package-BpPRO3LM.js} +1 -1
  91. package/web-app/dist/assets/{plus-oH17BZu2.js → plus-D7XbyK29.js} +1 -1
  92. package/web-app/dist/assets/{refresh-cw-CPQ476LL.js → refresh-cw-DLG3hyAi.js} +1 -1
  93. package/web-app/dist/assets/{rotate-ccw-7hLvOcnS.js → rotate-ccw-Bqau4R_S.js} +1 -1
  94. package/web-app/dist/assets/{scroll-text-BCmLauQn.js → scroll-text-BtIL3cNk.js} +1 -1
  95. package/web-app/dist/assets/{server-DfTfvW84.js → server-tZCmZ4yH.js} +1 -1
  96. package/web-app/dist/assets/{shield-alert-CaeGRq19.js → shield-alert-K5JXzFKg.js} +1 -1
  97. package/web-app/dist/assets/{thumbs-up-Dz-l2GPC.js → thumbs-up-CHCVyJdw.js} +1 -1
  98. package/web-app/dist/assets/{trash-2-B-OsDmSo.js → trash-2-DncNxVq0.js} +1 -1
  99. package/web-app/dist/assets/{trending-down-CXTFOxzq.js → trending-down-D8Bp0azX.js} +1 -1
  100. package/web-app/dist/assets/{trending-up-FQEdqr3v.js → trending-up-AixETdKR.js} +1 -1
  101. package/web-app/dist/assets/{upload-CacWSNTg.js → upload-VCbjFn2H.js} +1 -1
  102. package/web-app/dist/assets/{usePolling-cIjZ9qd2.js → usePolling-CQvKD2Jj.js} +1 -1
  103. package/web-app/dist/assets/{user-DAouWFHi.js → user-SK-YguQ6.js} +1 -1
  104. package/web-app/dist/index.html +1 -1
  105. package/autonomy/company-seats.json +0 -82
  106. package/docs/COMPETITIVE-INTEL-2026-09.md +0 -444
  107. package/docs/FOUNDER-DECISIONS-TRUST-SEMANTICS-2026-08-01.md +0 -145
  108. package/docs/FOUNDER-STATUS-AND-DECISIONS-2026-07-01.md +0 -132
  109. package/docs/LOKI-10-BUILD-PROMPT.md +0 -350
  110. package/docs/STRATEGY-2026-2028.md +0 -124
  111. package/docs/V10-VISION.md +0 -161
  112. package/docs/v10/ADOPTION-PLAN.md +0 -375
  113. package/docs/v10/ARCHITECT-CUTS.md +0 -744
  114. package/docs/v10/BACKLOG.md +0 -231
  115. package/docs/v10/BOARD.md +0 -1403
  116. package/docs/v10/CONTROL-PLANE.md +0 -120
  117. package/docs/v10/CONTROL.md +0 -36
  118. package/docs/v10/CP-ASK-PLAN.md +0 -85
  119. package/docs/v10/CP-ENTERPRISE-UI.md +0 -537
  120. package/docs/v10/D51-PHASE-B.md +0 -120
  121. package/docs/v10/D61-SPEED.md +0 -105
  122. package/docs/v10/D63-CARDS.md +0 -354
  123. package/docs/v10/DECISIONS.md +0 -915
  124. package/docs/v10/E2E-D65.md +0 -123
  125. package/docs/v10/ENGINE-LAWS.md +0 -163
  126. package/docs/v10/ENGINE-MEASURE.md +0 -69
  127. package/docs/v10/ENGINE.md +0 -743
  128. package/docs/v10/FAILURE-CLASSES.md +0 -2026
  129. package/docs/v10/FC21B-FC22-PLAN.md +0 -107
  130. package/docs/v10/FIRST-RUN-GATE.md +0 -39
  131. package/docs/v10/FOUNDER-QUEUE.md +0 -29
  132. package/docs/v10/GAP-RESEARCH-1003.md +0 -32
  133. package/docs/v10/GUARDS.md +0 -883
  134. package/docs/v10/L0-WAVE1.md +0 -81
  135. package/docs/v10/LEGACY-REMOVAL.md +0 -408
  136. package/docs/v10/MEDIUM-ANALYSIS.md +0 -346
  137. package/docs/v10/METRICS.md +0 -645
  138. package/docs/v10/MODERNIZE.md +0 -437
  139. package/docs/v10/OPENCODE-PARITY-PLAN.md +0 -84
  140. package/docs/v10/OPERATING-MODEL.md +0 -60
  141. package/docs/v10/PLAN-V12.md +0 -896
  142. package/docs/v10/PROGRESS.md +0 -2735
  143. package/docs/v10/RELEASE-11.md +0 -77
  144. package/docs/v10/RETRO-2026.md +0 -650
  145. package/docs/v10/ROADMAP-D63.md +0 -35
  146. package/docs/v10/SCALE.md +0 -140
  147. package/docs/v10/SCORECARD-PLAN.md +0 -250
  148. package/docs/v10/SWARM-PROMPT.md +0 -98
  149. package/docs/v10/SWARM.md +0 -293
  150. package/docs/v10/cp-redesign/PARITY.md +0 -188
  151. package/docs/v10/cp-redesign/legacy/INDEX.md +0 -1167
  152. package/docs/v10/roadmap-10/01-measurement.md +0 -113
  153. package/docs/v10/roadmap-10/02-cost.md +0 -75
  154. package/docs/v10/roadmap-10/03-speed.md +0 -65
  155. package/docs/v10/roadmap-10/04-first-run.md +0 -61
  156. package/docs/v10/roadmap-10/05-deploy.md +0 -61
  157. package/docs/v10/roadmap-10/06-stability.md +0 -64
  158. package/docs/v10/roadmap-10/07-quality.md +0 -57
  159. package/docs/v10/roadmap-10/08-proof.md +0 -48
  160. package/docs/v10/roadmap-10/09-safety.md +0 -74
  161. package/docs/v10/roadmap-10/README.md +0 -1464
  162. package/skills/sdlc-fleet.md +0 -170
  163. package/tools/cockpit/SPEC.md +0 -275
  164. package/tools/cockpit/index.html +0 -146
  165. package/tools/cockpit/roi-basis.json +0 -33
  166. package/tools/cockpit/server.py +0 -946
@@ -1,744 +0,0 @@
1
-
2
-
3
- ## 23:00Z cut (E-31..E-40)
4
-
5
- Every claim below comes from reading main at 84c22568. I edited no files.
6
-
7
- **What I found that shapes this cut**
8
-
9
- 1. **The engine cannot run from the npm package today.**
10
- - Root `package.json` `files` ships `loki-ts/dist/` and no `loki-ts/src`. Every source-relative path is therefore dead in an install. These break:
11
- - `machine.ts:44-55`: `optional()` checks whether `import.meta.dir/stages/<name>.ts` exists. In a bundle that file is never there, so every stage emits `stage.skipped` "module not present".
12
- - `engine10/cli.ts:54`: the default loader uses a non-literal `import(spec)`.
13
- - `output.ts:132`: dynamic import of the eta module.
14
- - `session.ts:137`: spawns `[process.execPath, [import.meta.path, "--engine10-session-child"]]`. In a bundle, `import.meta.path` is `dist/loki.js`.
15
- - `fetch_issue.ts:32` and `stages/pr.ts:49`: paths built with `new URL("../../../...", import.meta.url)`, which resolve above the package root from dist.
16
- - `util/paths.ts` already finds `REPO_ROOT` by walking up to `VERSION` + `autonomy/run.sh`, and works from dist. The fix is to reuse it.
17
- 2. **The flip breaks two merged tests.**
18
- - `tests/test-engine10-dispatch.sh` and `tests/test-engine10-legacy-contract.sh` both assert that an unset `LOKI_ENGINE` routes to legacy.
19
- - The E-30 alias assertions switch from SKIP to live only when bin/loki matches `^[[:space:]]*legacy\)`.
20
- 3. **The gate chain has a hole.** No row runs the v10 arm over the 29 tasks. EV-4 is raw claude and EV-5 is legacy. E-38 closes this, and it runs the dist build so the gate measures what actually ships.
21
- 4. **Hard limits from existing code:**
22
- - `loki-ts/src/runner/types.ts:8` has no opencode provider, and `providers.ts` is on the no-edit list. So the only honest opencode path is a clear refusal.
23
- - `autonomy/loki` is also no-edit, so the deprecation note cannot live in legacy help text.
24
- - `supervisor.ts` has no `main` yet. Its wiring arrives with E-14, so preflight wiring waits for E-14.
25
- 5. **E-TG's file set is not recorded anywhere.** PROGRESS.md:1255 names it only as a follow-up to E-07 and E-09. E-32 touches `session.ts`, so it depends on E-TG merging.
26
-
27
- **How the file sets stay separate**
28
- - **In-flight rows:** no file below appears in any ready, building or review row (E-14..E-29, EV-4, EV-5, EV-6, E-TG).
29
- - **EV-6:** it keeps `eval/loki10/summarize` and `docs/v10/METRICS.md`. E-33 builds a new generator that EV-6 runs, so the two sets stay apart.
30
- - **One planned exception:**
31
- - E-31 changes one marked line in `README.md` and one in `docs/v10/GUIDE.md` (the opt-in line that E-34 writes).
32
- - E-31 depends on E-34, so the two are never in flight together.
33
- - The Captain applies that line change in the E-31 merge commit.
34
-
35
- ### E-31: Default flip to v10, with a `LOKI_ENGINE=legacy` override and the `loki legacy` alias
36
- - **Files:**
37
- - `bin/loki`
38
- - `loki-ts/src/engine10/cli.ts` (USAGE text only)
39
- - `tests/test-engine10-default.sh` (new)
40
- - `tests/test-engine10-dispatch.sh`
41
- - `tests/test-engine10-legacy-contract.sh`
42
- - After E-34 merges: the one marked opt-in line in `README.md` and in `docs/v10/GUIDE.md`
43
- - **Tier:** HIGH.
44
- - **Gating:**
45
- - Build on a branch now.
46
- - After review, hold the row at `approved`. Merge only when the E-33 marker in `docs/v10/METRICS.md` reads `<!-- loki10-gate: met ... -->`.
47
- - If the marker does not read met by 03:00Z, the row goes to `parked` and v10.0.0 ships with legacy as the default (D29).
48
- - The test enforces the gate mechanically: the build goes red if the switch reads v10 while the marker does not read met.
49
- - **Contents:**
50
- - **One switch.** A single line in bin/loki, `_loki_engine_default="v10"`, and the v10 block tests `"${LOKI_ENGINE:-$_loki_engine_default}"`.
51
- - **Override values.**
52
- - `LOKI_ENGINE=legacy` runs today's route exactly.
53
- - Any other non-empty value except `v10` exits 2 with a one-line message, so a typo such as `legasy` fails instead of silently picking an engine.
54
- - **Alias.** A `case "${1:-}" in legacy) shift; export LOKI_ENGINE=legacy ;; esac` arm runs before the v10 block. The export keeps nested calls on legacy.
55
- - For `loki legacy`, `loki legacy --help`, `-h` or `help`, the arm first prints `autonomy/lib/engine10-legacy-notice.txt` to stderr if that file exists (E-35 owns the text).
56
- - **Precedence.** `LOKI_LEGACY_BASH=1` still wins over everything.
57
- - **No bun.**
58
- - A default v10 selection without bun prints one notice line ("v10 needs bun; running the legacy engine. Set LOKI_ENGINE=legacy to silence") and falls through to legacy.
59
- - An explicit `LOKI_ENGINE=v10` without bun still exits 1, as today.
60
- - **Help after the flip.** `loki`, `loki --help` and `loki -h` go to the engine10 USAGE. USAGE ends with `loki legacy <args> run the previous engine (deprecated)`. `--version` stays on the legacy route.
61
- - **Commands that change meaning.** `status`, `verify` and `dashboard` now mean the v10 commands. The legacy ones are reached through `loki legacy status` and so on.
62
- - **Wall:** `bash tests/test-engine10-default.sh && bash tests/test-engine10-legacy-contract.sh && bash tests/test-engine10-dispatch.sh`. The output must show 0 failed for all three, and "0 skipped" on the legacy-contract Results line.
63
- - **Red:** the default test fails because nothing flips the default, and the legacy contract reports 20 SKIP lines.
64
- - **Green:**
65
- - With `LOKI_ENGINE` unset, a task routes to engine10.
66
- - `LOKI_ENGINE=legacy` and `loki legacy <args>` each match all 20 golden routes.
67
- - `LOKI_LEGACY_BASH` wins.
68
- - With no bun, the default falls back with a notice and explicit v10 exits 1.
69
- - `LOKI_ENGINE=legasy` exits 2.
70
- - `grep -c '_loki_engine_default=' bin/loki` equals 1.
71
- - Planting a METRICS.md without the met marker turns the default test red.
72
- - **Deps:** E-30, E-32, E-33, E-34, E-35, E-38, EV-6.
73
-
74
- ### E-32: Packaging, so the engine runs from dist and the npm package
75
- - **Files:**
76
- - `loki-ts/src/engine10/registry.ts` (new)
77
- - `loki-ts/src/cli.ts` (inside the existing engine10 arm only)
78
- - `loki-ts/src/engine10/machine.ts`
79
- - `loki-ts/src/engine10/session.ts`
80
- - `loki-ts/src/engine10/output.ts`
81
- - `loki-ts/src/engine10/fetch_issue.ts`
82
- - `loki-ts/src/engine10/stages/pr.ts`
83
- - `loki-ts/tests/engine10/registry.test.ts` (new)
84
- - `tests/test-engine10-dist.sh` (new)
85
- - **Tier:** HIGH. It changes how provider sessions spawn and the path to the credentialed push child.
86
- - **Contents:**
87
- - **Registry.** `registry.ts` maps each stage and route module name to a literal lazy import, for example `wall: () => import("./stages/wall.ts")`. Only modules present on disk at build time are listed. Bun bundles literal imports, and loading stays lazy.
88
- - **Loaders.**
89
- - `machine.ts` `defaultLoader` and `output.ts`'s eta load go through the registry.
90
- - The `src/cli.ts` arm passes the registry loader to `runEngine10(rest, load)`. The string `engine10` stays inside that one arm, which `cli.test.ts` asserts.
91
- - `optional()` stays as the source fallback.
92
- - **Session child.** `session.ts` spawns the child as `[process.execPath, <bundle or src cli entry>, "engine10", "session"]`, using the `session` route that already exists in the TABLE, instead of `import.meta.path`.
93
- - **Paths.** `fetch_issue.ts` and `pr.ts` resolve `autonomy/issue-providers.sh` and `autonomy/lib/engine10-push.sh` from `REPO_ROOT` (`util/paths.ts`).
94
- - **Registration guard.** `registry.test.ts` fails when a module that the stage table or cli TABLE names exists on disk but is not registered. Slices that land after E-32 (wave 2 still building, E-24..E-29) are each one registry line, which the Captain adds at merge.
95
- - **No writes to `loki-ts/dist/`** (section 14).
96
- - **The dist test:**
97
- 1. `npm pack` into a temp dir and extract it. The result has no `loki-ts/src`.
98
- 2. `bun build` the current src into `<extract>/loki-ts/dist/loki.js`, simulating the Captain's rebuild.
99
- 3. Run `<extract>/bin/loki` with `LOKI_ENGINE=v10 LOKI_E10_INVOKER=cli LOKI_CLAUDE_CLI=<E-14 stub>` on a copy of the E-14 fixture with `--no-pr`.
100
- 4. Separately, `npm pack --dry-run --json` must list `autonomy/lib/engine10-push.sh`, `autonomy/receipt_jwt.py` and `loki-ts/dist/loki.js`.
101
- - **Wall:** `bash tests/test-engine10-dist.sh && (cd loki-ts && bun test tests/engine10/registry.test.ts)`.
102
- - **Red:** the same script on current main shows every stage `stage.skipped` with "module not present", and the session child never starts.
103
- - **Green:**
104
- - `events.jsonl` from the extracted package holds `stage.completed` for intake, implement, verify and seal.
105
- - There are 0 "module not present" skips for landed modules.
106
- - `receipt.json`, `.loki/engine.json` and an efficiency record exist.
107
- - The dry-run list contains the three files.
108
- - **Deps:** E-14, E-TG.
109
-
110
- ### E-33: gate report generator (EV-6)
111
- - **Files:** `eval/loki10/gate_report.py` (new), `eval/loki10/test-gate-report.sh` (new), `eval/loki10/fixtures/gate/` (new subdir).
112
- - **Tier:** HIGH. Its marker controls E-31.
113
- - **Contents:**
114
- - **Invocation:** `gate_report.py <results.jsonl> --metrics <path> --changelog <path>`. It reuses `harness.summarize_rows`.
115
- - **Output:**
116
- - a per-arm table (completed/evaluated, rate, p50 and p90 time to PR, cost per completed task, runs with measured cost);
117
- - four gate lines, each showing the measured number, the threshold and MET or MISSED;
118
- - every miss, as task id plus status or reason;
119
- - null cost rendered as "not measured".
120
- - **`met` requires all of:**
121
- - at least 25 evaluated tasks on each arm;
122
- - the same `model` on every row;
123
- - v10 completion at or above raw-claude;
124
- - v10 p50 of 300s or less and p90 of 600s or less;
125
- - measured cost on both arms, with v10 cost per completed task at or below raw-claude. Null cost counts as MISSED.
126
- - **Markers:** it writes `<!-- loki10-gate: met|missed n=<N> results_sha256=<sha> -->` and replaces the block between `<!-- loki10-gate:begin -->` and `<!-- loki10-gate:end -->` in both target files, so rerunning is idempotent.
127
- - **Who writes the real files:** EV-6 runs this on real results and commits METRICS.md and the CHANGELOG block. This slice never touches `summarize` or METRICS.md.
128
- - **Wall:** `bash eval/loki10/test-gate-report.sh`.
129
- - **Red:** the file is missing.
130
- - **Green:**
131
- - An all-met fixture writes the met marker.
132
- - A v10 p90 of 660s gives MISSED and lists the slow tasks.
133
- - Null v10 cost gives MISSED with "not measured".
134
- - 24 evaluated tasks gives MISSED with "fewer than 25".
135
- - A model mismatch gives MISSED.
136
- - A second run leaves exactly one block.
137
- - **Deps:** EV-1.
138
-
139
- ### E-34: v10 user docs, marked opt-in until the flip
140
- - **Files:** `README.md` (new quickstart section), `docs/v10/GUIDE.md` (new), `tests/test-engine10-docs.sh` (new).
141
- - **Tier:** LOW.
142
- - **Contents:**
143
- - **Quickstart:** `LOKI_ENGINE=v10 loki "<task>"`, issue refs, and `--no-pr`, `--deep`, and `--provider`.
144
- - **The 5-line summary,** explained line by line.
145
- - **NOT PROVEN:** what it means, including the deep checks that are always listed and "not measured" cost.
146
- - **Receipts:** `receipt.json` and `receipt.md`, `loki verify`, and UNSIGNED.
147
- - **Provider table:** claude cost is measured. For codex, cline and aider, cost is not measured and kill blocking is not enforced. opencode is not supported and is refused.
148
- - **After the flip:** `status`, `verify` and `dashboard` change meaning. `loki legacy <args>` and `LOKI_ENGINE=legacy` reach the old engine.
149
- - **The opt-in line:** one line in each file carries `<!-- loki10-default -->` and reads "Opt-in: set LOKI_ENGINE=v10". E-31 changes that line.
150
- - **Wall:** `bash tests/test-engine10-docs.sh`.
151
- - **Red:** GUIDE.md is missing.
152
- - **Green:**
153
- - Every command in the guide appears in the engine10 USAGE.
154
- - The marked line's wording matches bin/loki's current default.
155
- - README links GUIDE.md.
156
- - The docs contain no em or en dashes.
157
- - **Deps:** E-13, E-22.
158
-
159
- ### E-35: Legacy deprecation note, with no removal
160
- - **Files:** `autonomy/lib/engine10-legacy-notice.txt` (new), `CHANGELOG.md` (a "Deprecated" entry for v10.0.0), `tests/test-engine10-legacy-notice.sh` (new).
161
- - **Tier:** LOW.
162
- - **Contents:**
163
- - The notice runs three lines or fewer. It says the legacy engine is deprecated in v10.0.0 and still fully supported, that nothing is removed in this release, that `LOKI_ENGINE=legacy` pins it, and where the guide lives.
164
- - The notice avoids `autonomy/loki`, which is on the no-edit list. E-31's `legacy)` arm prints the file for help invocations only.
165
- - The CHANGELOG entry states the same facts and says no removal date is set.
166
- - **Wall:** `bash tests/test-engine10-legacy-notice.sh`.
167
- - **Red:** the file is missing.
168
- - **Green:**
169
- - The notice exists and has 3 lines or fewer.
170
- - It contains "LOKI_ENGINE=legacy" and does not contain "removed in".
171
- - The CHANGELOG has a Deprecated entry that names `loki legacy`.
172
- - Once E-31 is present, `loki legacy --help` stderr contains the first notice line. Until then that assertion prints SKIP.
173
- - **Deps:** none (the file must exist before E-31 merges).
174
-
175
- ### E-36: First-run preflight with clear errors
176
- - **Files:** `loki-ts/src/engine10/preflight.ts` (new), `loki-ts/tests/engine10/preflight.test.ts` (new), `loki-ts/src/engine10/supervisor.ts` (one call at the start of `main`, before the marker or branch).
177
- - **Tier:** MEDIUM.
178
- - **Checks:** each failure prints one line with a fix hint and exits 2 before any branch or event log exists.
179
- - **Not a repo:** the current directory is not a git work tree.
180
- - **Git identity:** `user.name` or `user.email` is unset, which would make the commit fail.
181
- - **Provider CLI:** the provider's CLI is not on PATH (`LOKI_CLAUDE_CLI`, `LOKI_CODEX_CLI` and so on are honored).
182
- - **Unsupported provider:** `--provider opencode`, or any other unknown name, gets: "the v10 engine has no opencode invoker yet; use LOKI_ENGINE=legacy loki start --provider opencode".
183
- - **Host guard:** an inherited `LOKI_HOST_GUARD=1` with a non-claude provider would throw at `providers.ts:63`, so preflight explains it first.
184
- - **GitHub CLI:** when origin is on github.com and `--no-pr` is absent, missing `gh` or a failing `gh auth status` gets a hint to use `--no-pr`. A non-GitHub origin or `--no-pr` skips the check, so the eval's local bare remote is unaffected.
185
- - **Warnings (not fatal):** `python3 -I` without `cryptography`, or no signing key, prints "receipts will be UNSIGNED".
186
- - **bun:** bin/loki already checks for bun.
187
- - **Wall:** `cd loki-ts && bun test tests/engine10/preflight.test.ts`.
188
- - **Red:** the file is missing.
189
- - **Green:**
190
- - Each fatal case gives exit 2, its exact line, and no `.loki/runs` dir.
191
- - Missing cryptography warns and continues.
192
- - `--no-pr` skips the gh check.
193
- - **Deps:** E-14.
194
-
195
- ### E-37: Non-claude provider paths through session.ts, with honest cost
196
- - **Files:** `loki-ts/tests/engine10/providers.test.ts` (new), `loki-ts/tests/engine10/fixtures/providers/` (new: stub codex, cline and aider CLIs).
197
- - **Tier:** MEDIUM.
198
- - **Contents:**
199
- - Runs the supervisor end to end with `--provider codex`, `cline` and `aider` through their stubs (`LOKI_CODEX_CLI`, `LOKI_CLINE_CLI`, `LOKI_AIDER_CLI`) and `--no-pr`.
200
- - This slice has no source files. Any red it finds becomes its own fix slice.
201
- - **Wall:** `cd loki-ts && bun test tests/engine10/providers.test.ts`.
202
- - **Red:** the file is missing.
203
- - **Green, for each non-claude provider:**
204
- - The run reaches seal.
205
- - The `cost` event has `usd: null` with tokens kept.
206
- - `cost-summary.py --json` reports `fully_measured` false.
207
- - The Cost line reads "not measured" and never "$0.00".
208
- - The receipt's `not_proven` holds "kill blocking not enforced".
209
- - With `LOKI_MODEL_OVERRIDE` set, it also holds "model override not applied".
210
- - The session child env has no `LOKI_HOST_GUARD`.
211
- - `--provider opencode` exits 2 with the E-36 line.
212
- - **Deps:** E-14, E-36.
213
-
214
- ### E-38: v10 arm gate run, with the legacy arm pinned
215
- - **Files:** `eval/loki10/harness.py` (the legacy arm sets `env["LOKI_ENGINE"]="legacy"`), `eval/loki10/test-harness.sh` (one new leg).
216
- - **Tier:** HIGH.
217
- - **Contents:**
218
- - Pinning the legacy arm keeps EV-5 results unchanged after the flip.
219
- - The v10 arm runs `--all` over the 29 tasks using the dist build from E-32 (`LOKI_TS_ENTRY` pointing at the rebuilt bundle), so the gate measures what ships.
220
- - Results stay under the gitignored `eval/loki10/results/`.
221
- - **Wall:** `bash eval/loki10/test-harness.sh && eval/loki10/run.sh --arm v10 --all`. The results must hold 29 rows, none `arm_unavailable`, and each row must carry `model`, `time_to_pr_s` and `cost_usd` (a number or null).
222
- - **Red:** the new leg fails because the legacy arm env has no `LOKI_ENGINE`, and no v10 results exist.
223
- - **Green:** the leg asserts `LOKI_ENGINE=legacy` on the legacy arm and `v10` on the v10 arm, and the 29-row v10 results file exists.
224
- - **Deps:** EV-1, E-32, E-36.
225
-
226
- ### E-39: Interrupt end to end (resume removed in A-113)
227
- - **Files:** `loki-ts/tests/engine10/resume_e2e.test.ts` (new), `loki-ts/tests/engine10/fixtures/resume/` (new).
228
- - **Tier:** MEDIUM.
229
- - **Wall:** `cd loki-ts && bun test tests/engine10/resume_e2e.test.ts`.
230
- - **Red:** the file is missing.
231
- - **Green:**
232
- - SIGINT during a sleeping implement stub exits 130. The session process group is gone and there is no `run.completed`.
233
- - (Removed in A-113: `--resume` no longer exists; `loki --resume` exits 2 with "start a new run".)
234
- - `seq` keeps increasing, and there is no second `stage.started` for intake.
235
- - `.loki/engine.json` still names the same run.
236
- - Changing the origin between runs refuses the push.
237
- - **Deps:** E-14.
238
-
239
- ### E-40: Live PR smoke on a sandbox GitHub repo
240
- - **Files:** `tests/test-engine10-live-pr.sh` (new).
241
- - **Tier:** HIGH (credentialed).
242
- - **Contents:**
243
- - Runs one real small task from the E-32 dist layout against `LOKI_E10_LIVE_REPO`.
244
- - Without the variable it prints SKIP and exits 0. SKIP never counts as done; the Wall command sets the variable.
245
- - **Wall:** `LOKI_E10_LIVE_REPO=<owner>/<sandbox> bash tests/test-engine10-live-pr.sh`. The output must show:
246
- - a PR URL;
247
- - `gh pr view --json isDraft` agreeing with the verdict;
248
- - the `loki/deep-verify` status context through `gh api`;
249
- - `loki verify <run>` exiting 0, or UNSIGNED stated;
250
- - a second run of the same task reporting `existing: true` with the same URL.
251
- - **Red:** the file is missing.
252
- - **Green:** all five assertions hold against the sandbox repo.
253
- - **Deps:** E-23, E-32, E-36.
254
-
255
- ### Recovery of an interrupted run
256
-
257
- Code: `resumeMain`, `findInterrupted`, `resumePublish`, `startRecovery` in `loki-ts/src/util/run_outputs.ts`, `phaseOf` in `events.ts`, `runOwnerAlive` in `util/run_pid.ts`, the push-skip in `autonomy/lib/engine10-push.sh`, `loki resume` in `autonomy/loki`. Tests: the RECOVERY block in `loki-ts/tests/engine10/pr.test.ts` and the recovery block in `tests/test-engine10-push.sh`.
258
-
259
- An interrupted run has an `events.jsonl` with neither `run.completed` nor `pr.opened`, and a `run.pid` that does not name a live process with the recorded start time. A run owned by a live supervisor is never resumed. The phase comes from the event log only (`phaseOf`):
260
-
261
- | Phase | Meaning | Recoverable |
262
- |-----------|-------------------------------------------------------------|-------------|
263
- | implement | no `stage.completed` for implement | No (reported) |
264
- | verify | implement completed, no `receipt.sealed` | No (reported) |
265
- | publish | `receipt.sealed` present, no `pr.opened` or `run.completed` | Yes |
266
- | done | `pr.opened` or `run.completed` present | Nothing to do |
267
-
268
- `loki resume [run-id]`, and `loki start "<same task>"` when the newest interrupted run is in the publish phase, its recorded intake task equals the new task and `--no-pr` is absent, resume the publish phase and print `resumed phase: publish (run <id>); receipt reused; PR <url>`.
269
-
270
- - The sealed receipt is reused: no second `receipt.json`, no second `receipt.sealed` event. Resume never reseals.
271
- - Events appended: `run.resumed`, `pr.opened`, `run.completed` (with `resumed: true` and the not-proven note "publish phase resumed after an interruption"), then the log seal.
272
- - Push is skipped when the remote branch is already at the local commit (GitHub: `gh api .../git/ref/heads/<branch>`; local bare origin: `git ls-remote`). A newer commit is a new revision and is pushed.
273
- - PR creation checks `gh pr list --head <branch> --state open` first and reuses an open PR, so any number of publish attempts yields one PR.
274
-
275
- For implement and verify, `loki resume` prints the phase, whether branch `loki/<run-id>` holds preserved work, and exits 4. `loki start` prints a one-line note and starts a new run. `LOKI_NO_RESUME=1` disables the `loki start` check.
276
-
277
- Exit codes of `loki-ts engine10 resume`: 0 resumed, 3 no interrupted run, 4 phase reported but not auto-resumable, 5 publish attempted and failed (the run stays resumable), 2 not in a git repository or no origin.
278
-
279
- Honest limits:
280
- - implement and verify keep stage outputs in the worker's memory; the stage machine cannot skip completed stages. Work committed on `loki/<run-id>` is preserved but the run is not continued.
281
- - A crash between `gh pr create` returning and `pr.opened` being recorded is recovered by the open-PR lookup, provided GitHub lists the PR by then.
282
- - A crash after the commit status call but before `run.completed` sets the same status again.
283
- - GitLab origins (`engine10-push-gitlab.sh`) are unchanged; push-skip and PR reuse are verified for the GitHub and local-bare paths only.
284
- - The legacy bash loop (`autonomy/run.sh`) keeps its own iteration-level resume.
285
- - Deep verify (a detached child spawned after `pr.opened`) is not re-spawned on resume.
286
-
287
- ### BOARD rows
288
-
289
- The notes start with the requested "Source: ENGINE.md 23:00Z cut." and then add dependencies, following the 21:50Z rows. If you want the notes to be only that sentence, drop the dependency part.
290
-
291
- | id | title | files | tier | wall check | status | notes |
292
- |---|---|---|---|---|---|---|
293
- | E-31 | Default flip to v10 with LOKI_ENGINE=legacy override and the loki legacy alias (merge held until the gate marker reads met) | bin/loki, loki-ts/src/engine10/cli.ts (USAGE only), tests/test-engine10-default.sh, tests/test-engine10-dispatch.sh, tests/test-engine10-legacy-contract.sh, README.md and docs/v10/GUIDE.md (marked opt-in line only, after E-34) | HIGH | bash tests/test-engine10-default.sh && bash tests/test-engine10-legacy-contract.sh && bash tests/test-engine10-dispatch.sh (0 failed; legacy contract 0 skipped) | ready@2026-09-27T23:00Z | Source: ENGINE.md 23:00Z cut. Held at approved until the METRICS.md loki10-gate marker reads met; parked if not met by 03:00Z. Depends on E-30, E-32, E-33, E-34, E-35, E-38, EV-6. |
294
- | E-32 | Packaging: engine runs from dist and the npm package (static registry, session child via cli route, REPO_ROOT paths) | loki-ts/src/engine10/registry.ts, loki-ts/src/cli.ts (engine10 arm only), loki-ts/src/engine10/machine.ts, loki-ts/src/engine10/session.ts, loki-ts/src/engine10/output.ts, loki-ts/src/engine10/fetch_issue.ts, loki-ts/src/engine10/stages/pr.ts, loki-ts/tests/engine10/registry.test.ts, tests/test-engine10-dist.sh | HIGH | bash tests/test-engine10-dist.sh && (cd loki-ts && bun test tests/engine10/registry.test.ts) | ready@2026-09-27T23:00Z | Source: ENGINE.md 23:00Z cut. Later engine slices add one registry line at merge. Depends on E-14, E-TG. |
295
- | E-33 | Gate report generator: METRICS.md and CHANGELOG blocks with every gate number, misses and the loki10-gate marker | eval/loki10/gate_report.py, eval/loki10/test-gate-report.sh, eval/loki10/fixtures/gate/ | HIGH | bash eval/loki10/test-gate-report.sh | ready@2026-09-27T23:00Z | Source: ENGINE.md 23:00Z cut. EV-6 runs it on real results and commits METRICS.md. Depends on EV-1. |
296
- | E-34 | v10 user docs: README quickstart and docs/v10/GUIDE.md (5-line summary, NOT PROVEN, receipts), opt-in until the flip | README.md, docs/v10/GUIDE.md, tests/test-engine10-docs.sh | LOW | bash tests/test-engine10-docs.sh | ready@2026-09-27T23:00Z | Source: ENGINE.md 23:00Z cut. Depends on E-13, E-22. |
297
- | E-35 | Legacy engine deprecation note for loki legacy help and CHANGELOG (no removal) | autonomy/lib/engine10-legacy-notice.txt, CHANGELOG.md, tests/test-engine10-legacy-notice.sh | LOW | bash tests/test-engine10-legacy-notice.sh | ready@2026-09-27T23:00Z | Source: ENGINE.md 23:00Z cut. Depends on none; lands before E-31. |
298
- | E-36 | First-run preflight: repo, git identity, provider CLI, opencode refusal, host guard, gh auth, UNSIGNED warning | loki-ts/src/engine10/preflight.ts, loki-ts/tests/engine10/preflight.test.ts, loki-ts/src/engine10/supervisor.ts (one call in main) | MEDIUM | cd loki-ts && bun test tests/engine10/preflight.test.ts | ready@2026-09-27T23:00Z | Source: ENGINE.md 23:00Z cut. Depends on E-14. |
299
- | E-37 | Non-claude provider paths (codex, cline, aider) through session.ts with cost not measured and NOT PROVEN entries | loki-ts/tests/engine10/providers.test.ts, loki-ts/tests/engine10/fixtures/providers/ | MEDIUM | cd loki-ts && bun test tests/engine10/providers.test.ts | ready@2026-09-27T23:00Z | Source: ENGINE.md 23:00Z cut. Test only; a red becomes its own slice. Depends on E-14, E-36. |
300
- | E-38 | v10 arm gate run over the 29 tasks from dist; legacy arm pinned to LOKI_ENGINE=legacy | eval/loki10/harness.py (legacy arm env), eval/loki10/test-harness.sh (one leg) | HIGH | bash eval/loki10/test-harness.sh && eval/loki10/run.sh --arm v10 --all (29 rows, none arm_unavailable) | ready@2026-09-27T23:00Z | Source: ENGINE.md 23:00Z cut. The missing third arm for the gate. Depends on EV-1, E-32, E-36. |
301
- | E-39 | Interrupt and resume end to end (SIGINT, no orphan, resume to seal on the same run) | loki-ts/tests/engine10/resume_e2e.test.ts, loki-ts/tests/engine10/fixtures/resume/ | MEDIUM | cd loki-ts && bun test tests/engine10/resume_e2e.test.ts | ready@2026-09-27T23:00Z | Source: ENGINE.md 23:00Z cut. Depends on E-14. |
302
- | E-40 | Live PR smoke on a sandbox GitHub repo from the dist layout | tests/test-engine10-live-pr.sh | HIGH | LOKI_E10_LIVE_REPO=<owner>/<sandbox> bash tests/test-engine10-live-pr.sh | ready@2026-09-27T23:00Z | Source: ENGINE.md 23:00Z cut. SKIP without the variable does not count as done. Depends on E-23, E-32, E-36. |
303
-
304
- **Critical path to the flip:** E-14 and E-TG → E-32 → E-36 → E-38 → EV-6 (runs E-33) → E-31. E-34 and E-35 must merge before E-31. E-37, E-39 and E-40 can run in parallel once their dependencies land.
305
-
306
-
307
- ## 20:59Z cut (S-214..S-233)
308
-
309
- **Checked before cutting.** All reads are on main at 04af133a.
310
-
311
- **Held dependencies, checked against main.**
312
- - **Merged:**
313
- - S-180 (22ff5a44)
314
- - S-179 (94035ac4)
315
- - S-175 (6fab92ce)
316
- - S-178 (c8b4c8c0)
317
- - S-187 (03070f62)
318
- - **Still in flight:** S-194, S-195, S-197, S-198.
319
- - **What that unblocks:**
320
- - 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.
321
- - 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).
322
- - ProjectWorkspace phase labels and Replay Build: S-187 has merged. Cut as S-230.
323
- - **Still held:**
324
- - BACKLOG 36: waits for S-198.
325
- - BACKLOG 19 and the bash `loki proof verify` interpreter: wait for S-197.
326
- - BACKLOG 99, bash half: waits for S-194 and S-195.
327
-
328
- **Found shipped on main, but the backlog text still reads open.** Future cuts can skip these:
329
- - 35: tests/test-moat-runner.sh:653
330
- - 37 and 60: loki-ts/src/runner/quality_gates.ts about 565-615
331
- - 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.
332
- - 91: run.sh 26343-26345
333
- - 102: run.sh 10951-10955
334
- - 104 and 120: tests/run-all-tests.sh 965-966
335
- - 116, the overview council gate card: loki-overview.js about 395-414
336
- - 118:
337
- - standalone receipt order and the VERIFIED WITH GAPS colour: build-standalone.js 2517-2531
338
- - council-state and notifications: server.py 8638, 8909
339
- - 150: S-79
340
- - The memory browser's null lists (loki-memory-browser.js 448-506) and the cockpit's ChangeReview and RiskPanel errors are also handled.
341
-
342
- **Dropped on merit.**
343
- - **`/cost` priced at Sonnet rates with no estimate label (BACKLOG 118).**
344
- - 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.
345
- - It would close the way S-208 did.
346
- - **Removing T6 from test-sentrux-init-rules.sh as a speed-up.**
347
- - autonomy/loki has no `.sh` extension, so run-shellcheck.sh's `find` never lints it. T6 is its only lint.
348
- - S-232 moves that lint rather than deleting it.
349
-
350
- **New class found: inline Python that imports from the repo under review.**
351
- - The pattern is `python3 -` or bare `python3 -c` run with the target repo as cwd, which puts `''` first on sys.path.
352
- - 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`).
353
- - 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.
354
-
355
- **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.
356
-
357
- ### S-214: the P7 useMemo arm misses a factory that calls a registered fabricator (BACKLOG 147)
358
- - Files:
359
- - tests/moat/p7-no-fabricated-data.sh, three regions only:
360
- - `HELPER_LOCAL_DECL_TMPL` (about 1182) and its use (about 2186);
361
- - the ceiling comment (about 978-986);
362
- - one fixture beside the DECL_USEMEMO fixture (about 3138-3160).
363
- - Tier: HIGH (moat)
364
- - Region: this does not overlap S-198's Array.from arm or its fixture at about 3301. Do not append at the file tail.
365
- - Red: `function getRows(d){ return [{ id: 1, user: 'Admin' }]; } const rows = useMemo(() => getRows(d), [d]); setRows(rows);` goes through.
366
- - Green:
367
- - Add an optional `(?:React\.)?useMemo\(\s*\(\)\s*=>\s*` prefix ahead of the fabricator-call pattern.
368
- - The comment stops listing this shape as a ceiling.
369
- - Branch: run the widened arm on main first.
370
- - On any live hit in legacy-ui or web-app, the slice becomes report-only.
371
- - Never add an allowlist. cases.txt stays unchanged.
372
- - Wall:
373
- - `bash tests/moat/p7-no-fabricated-data.sh` prints PASS for every P7 case and flags the composed fixture.
374
- - Removing the prefix in a scratch copy lets the fixture through.
375
- - `git diff --stat tests/moat/cases.txt` is empty.
376
-
377
- ### S-215: the PR receipt renderer imports json from the target repo (cwd shadow)
378
- - Files:
379
- - autonomy/lib/proof-pr.sh: the `render_evidence_receipt_md` heredoc reader, plus a guarded `_loki_snapshot_py_tool` copy.
380
- - tests/test-proof-pr-no-cwd-shadow.sh (new)
381
- - Tier: HIGH (the receipt headline in the PR body)
382
- - 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.
383
- - Green:
384
- - Run through `_loki_snapshot_py_tool -I -S`.
385
- - If no interpreter resolves, print "Evidence Receipt: unavailable for this run."
386
- - Gate: reproduce the forged headline on main first. If it does not reproduce, close the slice as handled.
387
- - Wall:
388
- - `bash tests/test-proof-pr-no-cwd-shadow.sh` exits 0, and reverting to bare `python3 -` in a scratch copy fails it.
389
- - `bash tests/test-proven-pr-receipt.sh` exits 0.
390
- - `bash tests/test-council-py-tool-identity.sh` exits 0 and counts one more copy.
391
-
392
- ### S-216: loki verify's inline readers import from the tree under review (cwd shadow)
393
- - Files:
394
- - autonomy/verify.sh: the reader sites only (about 190, 591, 1269, 1271, 1295, 1337, 1339, 1441), plus a guarded helper copy.
395
- - tests/test-verify-no-cwd-shadow.sh (new)
396
- - Tier: HIGH (P2 verdict path)
397
- - Out of scope: the `unittest` and `py_compile` runs (about 730, 921). They run the user's own code on purpose.
398
- - 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.
399
- - Green:
400
- - `-I -S` through the helper.
401
- - With no interpreter, each reader returns what it returns today when python3 is absent. None of them reads as pass.
402
- - Gate: reproduce the changed gate on main first.
403
- - Rule: no moat case, because p2-honest-verdict.sh belongs to S-196 and S-204.
404
- - Wall:
405
- - `bash tests/test-verify-no-cwd-shadow.sh` exits 0, and reverting one site in a scratch copy fails it.
406
- - `bash tests/test-verify.sh` exits 0.
407
- - `bash tests/moat/run.sh` reports no rule failed. `P2.verify-exit-contract` stays pending.
408
- - `bash tests/test-council-py-tool-identity.sh` exits 0.
409
-
410
- ### S-217: enforce_test_coverage's package.json readers load user-site .pth (BACKLOG 81)
411
- - Files:
412
- - autonomy/run.sh: `enforce_test_coverage`, only the `_declared_test_script` and `_ws_script` readers. Anchor on those names.
413
- - tests/test-enforce-test-coverage-pkg-readers-pth.sh (new)
414
- - Tier: HIGH
415
- - 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.
416
- - Green:
417
- - Both readers go through `_loki_snapshot_py_tool -I -S`.
418
- - With no interpreter, the record reads inconclusive, never pass.
419
- - Gate:
420
- - Reproduce the recorded-outcome change on main first.
421
- - If the forged read changes nothing that gets recorded, close as handled.
422
- - Test rule: `cd` to scratch before sourcing, and assert that no `.loki/state/provider` is left in the repo.
423
- - Wall:
424
- - `bash tests/test-enforce-test-coverage-pkg-readers-pth.sh` exits 0, and reverting one reader to `-E` in a scratch copy fails it.
425
- - `bash tests/test-honest-gate-status.sh` exits 0.
426
-
427
- ### S-218: the snapshot's git status runs an agent-chosen core.fsmonitor command (BACKLOG 131c)
428
- - Files:
429
- - autonomy/run.sh: `_loki_untracked_status` only.
430
- - tests/test-untracked-status-fsmonitor.sh (new)
431
- - Tier: HIGH
432
- - Red: a repo whose `.git/config` sets `core.fsmonitor` to a script that writes a marker gets the marker during `_loki_untracked_status`.
433
- - Green:
434
- - Add `-c core.fsmonitor=false -c core.untrackedCache=false` to that status call.
435
- - No marker is written, and a real untracked file is still listed.
436
- - Gate: reproduce the marker on main first.
437
- - Test rules:
438
- - Use S-138's isolation prelude.
439
- - Extract the function by name. No full run.sh source.
440
- - Wall:
441
- - `bash tests/test-untracked-status-fsmonitor.sh` exits 0, and removing the two `-c` flags in a scratch copy fails it.
442
- - `bash tests/test-no-ambient-gitconfig-writes.sh` and `bash tests/test-branch-lifecycle.sh` exit 0.
443
-
444
- ### S-219: a failed git add -A makes the session commit silently commit nothing (BACKLOG 83)
445
- - Files:
446
- - autonomy/run.sh: `commit_session_changes`, the `git add -A` block only.
447
- - tests/test-session-commit-add-failure.sh (new)
448
- - Tier: MEDIUM
449
- - 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.
450
- - Green:
451
- - Keep git's first stderr line.
452
- - On a non-zero exit, reset the index, `log_warn "Left uncommitted: git add failed (<line>). Review and commit manually."`, and return 0.
453
- - A successful add is unchanged.
454
- - Gate: reproduce the silent no-commit on main first.
455
- - Test rules: S-138 prelude; scratch cwd; no `.loki/state/provider` left in the repo.
456
- - Wall:
457
- - `bash tests/test-session-commit-add-failure.sh` exits 0: the warning names the failure, and a normal repo still commits.
458
- - Removing the rc check in a scratch copy fails leg 1.
459
- - `bash tests/test-branch-lifecycle.sh` exits 0.
460
-
461
- ### S-220: the untrack step's global reset drops force-staged agent files from the session commit (BACKLOG 109)
462
- - Files:
463
- - autonomy/run.sh: `_loki_untrack_agent_committed_user_files` only.
464
- - tests/test-untrack-keeps-force-staged.sh (new)
465
- - Tier: MEDIUM
466
- - 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.
467
- - Green:
468
- - 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`.
469
- - Other staged paths stay staged.
470
- - Gate: reproduce the dropped file on main first.
471
- - Size: this may run past 30 minutes.
472
- - Test rules: S-138 prelude; scratch cwd.
473
- - Wall:
474
- - `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.
475
- - Restoring `git reset -q` in a scratch copy fails it.
476
- - `bash tests/test-branch-lifecycle.sh` exits 0.
477
-
478
- ### S-221: audit.py verify exits 0 when it checked nothing (BACKLOG 123, audit.py half)
479
- - Files:
480
- - dashboard/audit.py: the `_unified_cli` verify branch and its docstring only.
481
- - tests/dashboard/test_audit_verify_cli_nothing_checked.py (new)
482
- - Tier: MEDIUM
483
- - Red: `python3 dashboard/audit.py verify <empty dir>` exits 0.
484
- - Green:
485
- - `files_checked == 0` exits 2 (could not check), and the JSON is unchanged.
486
- - `tip` and `prefix` are untouched, because src/audit/crosslink.js reads `tip`.
487
- - Wall:
488
- - `python3 -m pytest -q tests/dashboard/test_audit_verify_cli_nothing_checked.py` covers:
489
- - empty dir: 2;
490
- - valid chain: 0;
491
- - tampered chain: 1;
492
- - `tip` on an empty dir: still 0.
493
- - `bash tests/test-audit-chain-honesty.sh` and `bash tests/test-audit-js-suites.sh` exit 0.
494
-
495
- ### S-222: the skill-session WebSocket status push hardcodes running_agents 0 (BACKLOG 118)
496
- - Files:
497
- - dashboard/server.py: the skill-session broadcast payload only (about 1030-1047).
498
- - tests/dashboard/test_skill_session_ws_running_agents.py (new)
499
- - Tier: LOW
500
- - Red: with no dashboard-state.json and a fresh session.json, the pushed payload carries `running_agents: 0`.
501
- - Green:
502
- - Send `running_agents: None` (unmeasured).
503
- - The clients already read null: loki-overview.js 212, loki-session-control.js 152, and web-app StatusOverview.
504
- - Gate: drive the branch on main first.
505
- - If the loop cannot be driven in-process, lift the payload into one function and test that.
506
- - If the branch is unreachable, close as handled.
507
- - Wall:
508
- - `python3 -m pytest -q tests/dashboard/test_skill_session_ws_running_agents.py` shows running_agents None.
509
- - Restoring 0 fails it.
510
-
511
- ### S-223: notification triggers read "No triggers configured" after a failed read (BACKLOG 114 and 118)
512
- - Files:
513
- - dashboard/server.py: `get_notification_triggers` only.
514
- - legacy-ui/components/loki-notification-center.js: `_loadTriggers` and the triggers empty branch only.
515
- - tests/dashboard/test_notification_triggers_unreadable.py (new)
516
- - legacy-ui/tests/loki-notification-triggers-error.node.test.mjs (new)
517
- - Tier: LOW
518
- - Red:
519
- - A corrupt triggers.json answers `{"triggers": []}`.
520
- - A failed fetch keeps `[]`, so the panel says "No triggers configured".
521
- - Green:
522
- - The server answers `{"triggers": null, "error": "unreadable_triggers"}`, the same shape as `read_active_notifications`.
523
- - The panel renders "Could not load triggers" and offers no toggles.
524
- - A missing file still answers `[]`.
525
- - Wall:
526
- - `python3 -m pytest -q tests/dashboard/test_notification_triggers_unreadable.py` passes.
527
- - `node --test legacy-ui/tests/loki-notification-triggers-error.node.test.mjs` passes: an error lacks "No triggers configured", and an empty list keeps it.
528
-
529
- ### S-224: the web-app receipt and cost trend show a partly priced run as a complete cost (BACKLOG 118)
530
- - Files:
531
- - web-app/src/components/EvidenceReceiptPanel.tsx (the Cost field only)
532
- - web-app/src/api/client.ts (the ProofDetail `cost` type and the cost/timeline `runs` type only)
533
- - web-app/src/pages/MetricsPage.tsx (`costTrend` only)
534
- - web-app/src/components/EvidenceReceiptPanel.cost.test.mjs (new)
535
- - Tier: MEDIUM
536
- - Red: a detail with `cost: {usd: 1.2, cost_partial: true}` renders "$1.20".
537
- - Green:
538
- - The receipt renders "at least $1.20", matching cost.html and proofs.html after S-158.
539
- - A partial run's trend label carries "(partial)".
540
- - `cost_partial` absent or false keeps today's text.
541
- - Wall:
542
- - `node --test web-app/src/components/EvidenceReceiptPanel.cost.test.mjs` passes.
543
- - `cd web-app && npx tsc -b` exits 0.
544
-
545
- ### S-225: the standalone receipts list shows a partly priced run as a complete cost (BACKLOG 118)
546
- - Files:
547
- - legacy-ui/scripts/build-standalone.js (the `loadReceipts` cost cell only)
548
- - tests/test-receipts-panel.sh (one new leg)
549
- - Tier: LOW
550
- - Green:
551
- - `cost_partial === true` renders "at least $X.XX".
552
- - Anything else keeps today's text.
553
- - Wall:
554
- - `bash tests/test-receipts-panel.sh` exits 0, and the new leg asserts the "at least" prefix only when `cost_partial` is true.
555
- - `bash tests/test-budget-banner-dedup.sh` exits 0.
556
-
557
- ### S-226: loki stats reads unmeasured cost as $0.00 on both routes (BACKLOG 106 class)
558
- - Files:
559
- - autonomy/loki (`cmd_stats` only)
560
- - loki-ts/src/commands/stats.ts
561
- - loki-ts/tests/commands/stats_unmeasured.test.ts (new)
562
- - tests/test-stats-unmeasured-cost.sh (new)
563
- - Tier: MEDIUM
564
- - 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`.
565
- - Green:
566
- - A record counts when `efficiency_cost.record_is_measured` (bash) or kpis.ts `recordsMeasured` (Bun) holds.
567
- - If none counts, the JSON sends `cost_usd: null` and the text says "not recorded".
568
- - Budget used follows `cmd_cost`'s rule: a positive recorded `budget_used`, else the measured current cost, else null.
569
- - Both routes produce identical output.
570
- - Size: this may run past 30 minutes.
571
- - Wall:
572
- - `bash tests/test-stats-unmeasured-cost.sh` exits 0.
573
- - `cd loki-ts && bun test tests/commands/stats.test.ts tests/commands/stats_unmeasured.test.ts` exits 0.
574
- - `bash tests/test-bash-bun-parity.sh` exits 0.
575
-
576
- ### S-227: loki status prints Budget $0 for a run it never measured, on both routes (BACKLOG 106 class)
577
- - Files:
578
- - autonomy/loki (the `cmd_status` budget block only)
579
- - loki-ts/src/commands/status.ts (`readBudgetField` and its budget caller only)
580
- - loki-ts/tests/commands/status.test.ts (budget legs only)
581
- - tests/test-status-budget-unmeasured.sh (new)
582
- - Tier: MEDIUM
583
- - 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.
584
- - Green:
585
- - Only a positive recorded `budget_used` is a reading, the same rule as `cmd_cost`.
586
- - Otherwise print "Budget: not recorded / $10" (or "Cost: not recorded (no limit)") and skip the gauge.
587
- - Both routes produce identical output.
588
- - Wall:
589
- - `bash tests/test-status-budget-unmeasured.sh` exits 0.
590
- - `cd loki-ts && bun test tests/commands/status.test.ts` exits 0.
591
- - `bash tests/test-status-cli-provider-parity.sh` exits 0.
592
-
593
- ### S-228: DeployConnections pushes default "not connected" states upward after its own fetch failed (BACKLOG 121)
594
- - Files:
595
- - web-app/src/components/DeployConnections.tsx (the connect and disconnect handlers only)
596
- - web-app/src/components/DeployConnections.propagate.test.mjs (new)
597
- - Tier: LOW
598
- - Red: the first fetch fails, then connecting Vercel calls `onStatusChange` with netlify and github `{connected:false}` built from the default state.
599
- - Green: when the last fetch failed, the handlers re-fetch instead of pushing synthesized defaults.
600
- - Wall:
601
- - `node --test web-app/src/components/DeployConnections.propagate.test.mjs` passes.
602
- - `node --test web-app/src/components/DeployConnections.state.test.mjs` passes.
603
- - `cd web-app && npx tsc -b` exits 0.
604
-
605
- ### S-229: the preview header says "Detecting project type..." forever after a failed preview-info fetch (BACKLOG 114)
606
- - Files:
607
- - web-app/src/components/ProjectWorkspace.tsx, preview regions only: the `getPreviewInfo` call (about 839) and the "Detecting project type..." branch (about 1877).
608
- - web-app/src/components/ProjectWorkspace.preview.test.mjs (new)
609
- - Tier: LOW
610
- - Green:
611
- - Keep the error.
612
- - Render "Could not detect project type" with the message.
613
- - A pending request keeps "Detecting project type...".
614
- - Wall:
615
- - `node --test web-app/src/components/ProjectWorkspace.preview.test.mjs` passes: a rejected fetch lacks "Detecting project type...".
616
- - `node --test web-app/src/components/ProjectWorkspace.panels.test.mjs` passes.
617
- - `cd web-app && npx tsc -b` exits 0.
618
-
619
- ### S-230: ProjectWorkspace labels unknown phases "building", and Replay Build can never appear (BACKLOG 115 and 118)
620
- - Files:
621
- - web-app/src/components/ProjectWorkspace.tsx, only the `buildPhase` memo (about 1401-1410) and the Replay Build condition (about 1488).
622
- - web-app/src/components/ProjectWorkspace.phase.test.mjs (new)
623
- - Tier: LOW
624
- - Region: this does not overlap S-229's preview regions.
625
- - Green:
626
- - The builder lists the phase strings run.sh and the Bun runner actually write.
627
- - Map REASON, ACT, REFLECT and VERIFY explicitly. Any other phase returns 'unknown'.
628
- - Replay Build shows when `!isBuilding` and `sessionData.status` is completed or completion_promise_fulfilled, the same test as about 1431.
629
- - Wall:
630
- - `node --test web-app/src/components/ProjectWorkspace.phase.test.mjs` passes:
631
- - an unrecognized phase is not 'building';
632
- - a completed idle session shows Replay Build.
633
- - `cd web-app && npx tsc -b` exits 0.
634
-
635
- ### S-231: the "Moat suite" CI check reads as moat proven at 0 of 9 (BACKLOG 52)
636
- - Files: .github/workflows/test.yml (the moat-suite job `name:` only)
637
- - Tier: LOW
638
- - Green:
639
- - Rename the job to "Moat ratchet (no rule failed)".
640
- - The step summary keeps its N of 9 count.
641
- - Gate:
642
- - First run `gh api repos/{owner}/{repo}/branches/main/protection/required_status_checks --jq .contexts`.
643
- - If "Moat suite" is a required context, the slice becomes report-only, because renaming it would block every merge.
644
- - Wall:
645
- - `git grep -n "name: Moat suite" -- .github` prints nothing.
646
- - `git grep -n "Moat suite" -- tests scripts .github` lists only the step-summary heading.
647
- - The first push after merge shows the renamed check green.
648
-
649
- ### S-232: autonomy/loki is linted only inside the sentrux test; the lint suite never schedules its big files first
650
- - Files:
651
- - tests/run-shellcheck.sh
652
- - tests/test-sentrux-init-rules.sh (T6 only)
653
- - Tier: LOW (velocity plus lint placement)
654
- - Change:
655
- - (a) Add ./autonomy/loki to run-shellcheck.sh at `-S error`, today's bar. Delete T6.
656
- - (b) Order the file list largest first, so run.sh and loki do not start last.
657
- - Gate: capture the counts and real time before changing anything. Run back to back with a fixed `LOKI_SHELLCHECK_JOBS=4`.
658
- - If (b) gains under 15%, keep only (a).
659
- - Wall:
660
- - `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.
661
- - `time bash tests/test-sentrux-init-rules.sh` exits 0 with "8 passed" and real time under 10s.
662
- - `grep -c shellcheck tests/test-sentrux-init-rules.sh` prints 0.
663
- - The builder reports both timings.
664
-
665
- ### S-233: a refused resume says nothing about which file blocked it or where the earlier commits are (BACKLOG 72 remainder)
666
- - Files:
667
- - autonomy/run.sh: the `setup_agent_branch` resume block only, around the `--no-overwrite-ignore` checkout.
668
- - tests/test-refused-resume-warning.sh (new)
669
- - Tier: LOW
670
- - 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.
671
- - Green:
672
- - The warning names the conflicting path or paths from git's stderr.
673
- - It states that the earlier session's commits are still on `${recorded}`.
674
- - Test rules: S-138 prelude; scratch cwd; no `.loki/state/provider` left in the repo.
675
- - Wall:
676
- - `bash tests/test-refused-resume-warning.sh` exits 0, and the warning contains the file name and the branch name.
677
- - `bash tests/test-branch-lifecycle.sh` exits 0.
678
-
679
- **Registration and rebuilds (Captain).** S-211 owns tests/run-all-tests.sh and tests/shard-durations.tsv, so no slice edits them.
680
- - **New tests to register, after S-211 merges:**
681
- - S-215: tests/test-proof-pr-no-cwd-shadow.sh
682
- - S-216: tests/test-verify-no-cwd-shadow.sh
683
- - S-217: tests/test-enforce-test-coverage-pkg-readers-pth.sh
684
- - S-218: tests/test-untracked-status-fsmonitor.sh
685
- - S-219: tests/test-session-commit-add-failure.sh
686
- - S-220: tests/test-untrack-keeps-force-staged.sh
687
- - S-221: tests/dashboard/test_audit_verify_cli_nothing_checked.py
688
- - S-222: tests/dashboard/test_skill_session_ws_running_agents.py
689
- - S-223: tests/dashboard/test_notification_triggers_unreadable.py and legacy-ui/tests/loki-notification-triggers-error.node.test.mjs
690
- - S-224: web-app/src/components/EvidenceReceiptPanel.cost.test.mjs
691
- - S-226: tests/test-stats-unmeasured-cost.sh and loki-ts/tests/commands/stats_unmeasured.test.ts
692
- - S-227: tests/test-status-budget-unmeasured.sh
693
- - S-228: DeployConnections.propagate.test.mjs
694
- - S-229: ProjectWorkspace.preview.test.mjs
695
- - S-230: ProjectWorkspace.phase.test.mjs
696
- - S-233: tests/test-refused-resume-warning.sh
697
- - **Bundle rebuilds:**
698
- - loki-ts/dist: S-226, S-227.
699
- - web-app/dist: S-224, S-228, S-229, S-230.
700
- - dashboard static: S-225.
701
- - legacy-ui dist and dashboard static: S-223.
702
- - **Merge order:**
703
- - 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.
704
- - autonomy/loki: S-226 and S-227, plus S-197 in flight, one at a time.
705
- - dashboard/server.py: S-222 and S-223.
706
- - ProjectWorkspace.tsx: S-229 and S-230.
707
- - S-215 and S-216 add guarded helper copies. S-199's identity test picks them up with no edit.
708
- - **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.
709
-
710
- **Held, not in the 20:**
711
- - BACKLOG 36: waits for S-198.
712
- - BACKLOG 19 and the bash `loki proof verify` interpreter: wait for S-197 (S-179 is merged, 94035ac4).
713
- - BACKLOG 99, bash half: waits for S-194 and S-195 (S-175 is merged, 6fab92ce).
714
- - `StatusResponse` defaults (iteration 0, provider "claude"): changing the types touches every /api/status consumer, so this needs a design.
715
- - BACKLOG 100 (the untrack step in the interrupt path): git commits from a signal handler need a design.
716
- - workspace_diff count 0 in a non-git directory: needs a design.
717
- - Speeding up test-autocapture-shadow-write-guard.sh: needs a design.
718
- - `P4.three-setups-resolve`: waits on the D10 default decision.
719
- - BACKLOG 18: default-off decision for the founder.
720
- - BACKLOG 28: needs per-case expected failure reasons; design.
721
- - BACKLOG 121, the settings half: product decision.
722
- - `P1.verification-metadata-signed`: M2 seal.v1.
723
- - The P2 verify renumber (CEO); S-112, S-114, S-115, S-117 to S-122.
724
-
725
- | 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. |
726
- | 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. |
727
- | 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. |
728
- | 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. |
729
- | 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. |
730
- | 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. |
731
- | 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. |
732
- | 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. |
733
- | 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. |
734
- | S-223 | BACKLOG 114/118: notification triggers read No triggers configured after a failed read | dashboard/server.py (get_notification_triggers only), legacy-ui/components/loki-notification-center.js (_loadTriggers and triggers empty branch only), tests/dashboard/test_notification_triggers_unreadable.py (new), legacy-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 legacy-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. |
735
- | 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. |
736
- | S-225 | BACKLOG 118: standalone receipts list shows a partly priced run as a complete cost | legacy-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. |
737
- | 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. |
738
- | 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. |
739
- | 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. |
740
- | 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. |
741
- | 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. |
742
- | 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. |
743
- | 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. |
744
- | 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. |