loki-mode 11.3.0 → 11.3.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 (215) hide show
  1. package/README.md +68 -650
  2. package/SKILL.md +4 -4
  3. package/VERSION +1 -1
  4. package/autonomy/completion-council.sh +2 -2
  5. package/autonomy/context-tracker.py +4 -4
  6. package/autonomy/council-v2.sh +1 -1
  7. package/autonomy/grill.sh +1 -1
  8. package/autonomy/lib/done-recognition.sh +1 -1
  9. package/autonomy/lib/prd-enrich.sh +1 -1
  10. package/autonomy/lib/voter-agents.sh +1 -1
  11. package/autonomy/loki +99 -75
  12. package/autonomy/run.sh +30 -18
  13. package/autonomy/sandbox.sh +1 -1
  14. package/autonomy/tui.sh +6 -5
  15. package/autonomy/verify.sh +1 -1
  16. package/bin/loki +166 -59
  17. package/completions/_loki +2 -0
  18. package/completions/loki.bash +2 -2
  19. package/dashboard/__init__.py +1 -1
  20. package/dashboard/server.py +25 -31
  21. package/docs/ARCHITECTURE.md +337 -0
  22. package/docs/BRANDING.md +124 -0
  23. package/docs/CLI-REFERENCE.md +7 -1
  24. package/docs/COMPONENTS.md +447 -0
  25. package/docs/DEPLOYMENT.md +9 -9
  26. package/docs/DOCKER.md +469 -0
  27. package/docs/INSTALLATION.md +67 -1045
  28. package/docs/KNOWN-ISSUES.md +11 -35
  29. package/docs/TESTING.md +161 -0
  30. package/docs/air-gapped.md +1 -2
  31. package/docs/alternative-installations.md +14 -24
  32. package/docs/architecture/DECISIONS.md +333 -0
  33. package/docs/audit-logging.md +7 -7
  34. package/docs/authentication.md +3 -3
  35. package/docs/authorization.md +1 -1
  36. package/docs/certification/04-production-deployment/lab.md +6 -6
  37. package/docs/certification/04-production-deployment/lesson.md +4 -4
  38. package/docs/certification/README.md +1 -1
  39. package/docs/control-plane-container.md +2 -2
  40. package/docs/dev/real-run.md +34 -0
  41. package/docs/dev/release-checklist.md +2 -2
  42. package/docs/exit-codes.md +3 -3
  43. package/docs/git-workflow.md +3 -3
  44. package/docs/metrics.md +37 -55
  45. package/docs/network-security.md +1 -1
  46. package/docs/siem-integration.md +5 -5
  47. package/docs/v10/CLI-MODERN.md +4 -3
  48. package/docs/v10/DECISIONS.md +44 -0
  49. package/docs/v10/DEPS.md +22 -22
  50. package/docs/v10/ENGINE.md +1 -1
  51. package/docs/v10/FAILURE-CLASSES.md +118 -1
  52. package/docs/v10/FOUNDER-QUEUE.md +1 -0
  53. package/docs/v10/GUARDS.md +13 -0
  54. package/docs/v10/LEGACY-REMOVAL.md +4 -6
  55. package/docs/v10/METRICS.md +2 -2
  56. package/docs/v10/MODERNIZE.md +1 -1
  57. package/docs/v10/OPERATING-MODEL.md +2 -1
  58. package/docs/v10/PROGRESS.md +29 -0
  59. package/docs/v11/COST-HALF.md +352 -0
  60. package/docs/v11/MARKET-SLICES.md +315 -0
  61. package/docs/v11/REGISTRIES.md +730 -0
  62. package/loki-ts/data/model-pricing.json +52 -24
  63. package/loki-ts/dist/loki.js +1036 -957
  64. package/mcp/__init__.py +1 -1
  65. package/package.json +1 -1
  66. package/packages/control-plane/dist/server.js +2467 -736
  67. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  68. package/src/protocols/mcp-client.js +6 -2
  69. package/src/protocols/mcp-server.js +13 -3
  70. package/tools/audit-docs.py +1 -1
  71. package/web-app/dist/assets/{AdminPage-D_e45uTw.js → AdminPage-CMkHNJbF.js} +1 -1
  72. package/web-app/dist/assets/{Avatar-T3nIpoaf.js → Avatar-BJyjV7Zi.js} +1 -1
  73. package/web-app/dist/assets/{Badge-BKqb59pP.js → Badge-D572l0uq.js} +1 -1
  74. package/web-app/dist/assets/{Button-DjVlkh8_.js → Button-T4BnOZgl.js} +1 -1
  75. package/web-app/dist/assets/{CockpitPage-DXJgLGmh.js → CockpitPage-Cj_GFsNn.js} +1 -1
  76. package/web-app/dist/assets/{ComparePage-BRP_eVc_.js → ComparePage-A8m4ZXak.js} +1 -1
  77. package/web-app/dist/assets/{ErrorBoundary-CLjpGLjC.js → ErrorBoundary-hugCg5yg.js} +1 -1
  78. package/web-app/dist/assets/{EvidenceReceiptPanel-DX-vb4Xy.js → EvidenceReceiptPanel-CuJKDC2G.js} +1 -1
  79. package/web-app/dist/assets/{GitHubIssuesPanel-214HVHtX.js → GitHubIssuesPanel-BYGKjarC.js} +1 -1
  80. package/web-app/dist/assets/{GitHubPRsPanel-BEiZKc4t.js → GitHubPRsPanel-c7sFIJlf.js} +1 -1
  81. package/web-app/dist/assets/{HomePage-VvMHS5ga.js → HomePage-A1MIkG2P.js} +2 -2
  82. package/web-app/dist/assets/{LoginPage-5WD-v7n3.js → LoginPage-8KQMRhtR.js} +1 -1
  83. package/web-app/dist/assets/{MagicPage-DUQT_Jye.js → MagicPage-C05QW2Lx.js} +1 -1
  84. package/web-app/dist/assets/{MetricsPage-lga-z79v.js → MetricsPage-Oukv5hme.js} +1 -1
  85. package/web-app/dist/assets/{NotFoundPage-CGhBX3G1.js → NotFoundPage-DKIwsawz.js} +1 -1
  86. package/web-app/dist/assets/{ProjectPage-CdzF2GzZ.js → ProjectPage-DwFRPLCG.js} +3 -3
  87. package/web-app/dist/assets/{ProjectsPage-DRG64N8s.js → ProjectsPage-CgY4YYDX.js} +1 -1
  88. package/web-app/dist/assets/{SettingsPage-5fzW9Frb.js → SettingsPage-BpfcSjUA.js} +1 -1
  89. package/web-app/dist/assets/{ShowcasePage-DrTdxO4y.js → ShowcasePage-BqBakC4K.js} +1 -1
  90. package/web-app/dist/assets/{SystemSettingsPage-C9Mqs6Rd.js → SystemSettingsPage-CZLu5VB0.js} +1 -1
  91. package/web-app/dist/assets/{TeamsPage-CUGPdSWo.js → TeamsPage-D55S1jKz.js} +1 -1
  92. package/web-app/dist/assets/{TemplatesPage-CNraDY0F.js → TemplatesPage-D3SydvxN.js} +1 -1
  93. package/web-app/dist/assets/{TerminalOutput-BIu_6Pea.js → TerminalOutput-hNg8G1-e.js} +1 -1
  94. package/web-app/dist/assets/{activity-Bk-kgqaf.js → activity-D2C0VagO.js} +1 -1
  95. package/web-app/dist/assets/{bell-BXmUdmo8.js → bell-CMvYi36w.js} +1 -1
  96. package/web-app/dist/assets/{bot-CiuzXxUR.js → bot-BvtQ6lmo.js} +1 -1
  97. package/web-app/dist/assets/{check-BEzjXppd.js → check-B13xkXed.js} +1 -1
  98. package/web-app/dist/assets/{chevron-left-AYWCXHf8.js → chevron-left-emu6r49E.js} +1 -1
  99. package/web-app/dist/assets/{circle-alert-BNg2uSRq.js → circle-alert-CExlwjuy.js} +1 -1
  100. package/web-app/dist/assets/{clock-DTj0kkGT.js → clock-D7Uas3oL.js} +1 -1
  101. package/web-app/dist/assets/{cloud-x4nTDBLT.js → cloud-CkB4S86C.js} +1 -1
  102. package/web-app/dist/assets/{code-xml-BVh_MLrk.js → code-xml-SL9IIWIn.js} +1 -1
  103. package/web-app/dist/assets/{database-DdfBaowG.js → database-BQFkd7t1.js} +1 -1
  104. package/web-app/dist/assets/{dollar-sign-XuYFmAOY.js → dollar-sign-qHmnNYsU.js} +1 -1
  105. package/web-app/dist/assets/{file-code-corner-D4cRnmeL.js → file-code-corner-C2YUDP0K.js} +1 -1
  106. package/web-app/dist/assets/{file-plus-CyoVlHc_.js → file-plus-C_ooIkDe.js} +1 -1
  107. package/web-app/dist/assets/{globe-Y6IK2RPW.js → globe-CQ-GL485.js} +1 -1
  108. package/web-app/dist/assets/{hammer-BKzr9VZI.js → hammer-U05L_D7V.js} +1 -1
  109. package/web-app/dist/assets/{index-B20cSx5G.js → index-CooHd7I-.js} +3 -3
  110. package/web-app/dist/assets/{layers-DebNOhGS.js → layers-Buo17rjW.js} +1 -1
  111. package/web-app/dist/assets/{loader-circle-DyGbrEgd.js → loader-circle-15vK3oV1.js} +1 -1
  112. package/web-app/dist/assets/{lock-BKPpyt20.js → lock-BeXLebuJ.js} +1 -1
  113. package/web-app/dist/assets/{package-egF5Wi4y.js → package-MVh_6-6R.js} +1 -1
  114. package/web-app/dist/assets/{plus-OiEgKIc-.js → plus-Dh_nd9vS.js} +1 -1
  115. package/web-app/dist/assets/{refresh-cw-CzKvrONq.js → refresh-cw-C9cBJEAT.js} +1 -1
  116. package/web-app/dist/assets/{rotate-ccw-Bu2mII0p.js → rotate-ccw-D3PAtzST.js} +1 -1
  117. package/web-app/dist/assets/{scroll-text-CSkiyax8.js → scroll-text-DZCoXQjo.js} +1 -1
  118. package/web-app/dist/assets/{server-DlPthJFw.js → server-OCOLI5J_.js} +1 -1
  119. package/web-app/dist/assets/{shield-alert-CbpHWQQX.js → shield-alert-oVhmf1_h.js} +1 -1
  120. package/web-app/dist/assets/{thumbs-up-DgGpZe-Q.js → thumbs-up-B-kbX4vN.js} +1 -1
  121. package/web-app/dist/assets/{trash-2-BV3GlCB-.js → trash-2-EL6moveW.js} +1 -1
  122. package/web-app/dist/assets/{trending-down-Y4TJtXhD.js → trending-down-Cl3kjpsx.js} +1 -1
  123. package/web-app/dist/assets/{trending-up-DsDNoHZY.js → trending-up-DST7I6M2.js} +1 -1
  124. package/web-app/dist/assets/{upload-gkThrc_I.js → upload-CUOT780G.js} +1 -1
  125. package/web-app/dist/assets/{usePolling-jpNSeNAe.js → usePolling-Djmt90eb.js} +1 -1
  126. package/web-app/dist/assets/{user-3Zez1WOK.js → user-BRBohA6J.js} +1 -1
  127. package/web-app/dist/index.html +1 -1
  128. package/docs/ARCHITECTURE-OVERVIEW.md +0 -209
  129. package/docs/AUTONOMI-ECOSYSTEM.md +0 -107
  130. package/docs/COCKPIT-SPEC.md +0 -72
  131. package/docs/COCKPIT-UX-MANDATE.md +0 -53
  132. package/docs/COMPETITIVE-ANALYSIS.md +0 -303
  133. package/docs/COMPETITIVE-NEXT-10.md +0 -316
  134. package/docs/COMPETITIVE-RALPH-ZEROSHOT-2026-07-08.md +0 -81
  135. package/docs/DASHBOARD-9.12-EVIDENCE.md +0 -97
  136. package/docs/DASHBOARD-ARCHITECTURE.md +0 -425
  137. package/docs/DASHBOARD_V2_CHECKLIST.md +0 -243
  138. package/docs/DEMOS.md +0 -63
  139. package/docs/ENTERPRISE-IDENTITY-ROADMAP.md +0 -206
  140. package/docs/EVIDENCE-RECEIPT-BUILD-APPLICABILITY.md +0 -79
  141. package/docs/FEAT-PRDREUSE-DOCKER-PLAN.md +0 -144
  142. package/docs/GATE-FAILURE-TRIAGE.md +0 -254
  143. package/docs/HANDOFF-2026-08-03.md +0 -439
  144. package/docs/LOOP-CANDIDATE-PROPOSAL-v1.md +0 -167
  145. package/docs/LOOP-HARNESS-AUDIT.md +0 -684
  146. package/docs/MERGE-DEDUP-MAP.md +0 -420
  147. package/docs/MERGE-ROUTE-MAP.md +0 -139
  148. package/docs/MODEL-REGISTRY-PLAN.md +0 -155
  149. package/docs/OUTCOME-FRONTIER.md +0 -536
  150. package/docs/P2-SPEC-ROBUSTNESS-PLAN.md +0 -192
  151. package/docs/PLANS-INDEX.md +0 -32
  152. package/docs/PRD-REUSE-DONE-RECOGNITION-PLAN.md +0 -536
  153. package/docs/PROMPT-ABLATION-RESULT.md +0 -97
  154. package/docs/R4-TRUST-TRAJECTORY-DESIGN.md +0 -127
  155. package/docs/R5-AUTO-WIKI-DESIGN.md +0 -137
  156. package/docs/R6-ROLLBACK-CHECKPOINT-PLAN.md +0 -107
  157. package/docs/R7-ZERO-CONFIG-FIRST-RUN-PLAN.md +0 -137
  158. package/docs/R8-SHAREABLE-TEAM-ASSETS-PLAN.md +0 -129
  159. package/docs/R9-OPEN-CORE-HOOKS-PLAN.md +0 -113
  160. package/docs/RARV-C-100X-PLAN.md +0 -286
  161. package/docs/RARV-C-LOOP-EFFICIENCY-PLAN.md +0 -470
  162. package/docs/SHAREABLE-PROOF-PLAN.md +0 -194
  163. package/docs/SONNET5-DEFAULT-PLAN.md +0 -157
  164. package/docs/SPEED-AND-FIRST-PASS-PLAN.md +0 -281
  165. package/docs/STALE-STATE-AUDIT.md +0 -174
  166. package/docs/SYNERGY-TASKS.md +0 -143
  167. package/docs/TASKLIST-ACCURACY-PLAN.md +0 -355
  168. package/docs/TOP-100-BACKLOG.md +0 -159
  169. package/docs/V8-ACCEPTANCE-TRIAGE-2026-07-24.md +0 -114
  170. package/docs/V8-COMPLEXITY-AUDIT-2026-07-24.md +0 -45
  171. package/docs/V8-MAJOR-RELEASE-PLAN.md +0 -137
  172. package/docs/V8-OVERNIGHT-PLAN-2026-07-25.md +0 -82
  173. package/docs/V8-SDK-RESEARCH-RAW.md +0 -129
  174. package/docs/WELCOME-OPENER-PLAN.md +0 -106
  175. package/docs/adoption-baseline-2026-07-31.md +0 -84
  176. package/docs/architecture/bmad-integration-epic.md +0 -271
  177. package/docs/architecture/bmad-integration-review.md +0 -86
  178. package/docs/architecture/bmad-integration-validation.md +0 -249
  179. package/docs/architecture/bmad-loki-voice-agent-council-analysis.md +0 -61
  180. package/docs/auto-claude-comparison.md +0 -250
  181. package/docs/bug-fixes/agent-01-cli-fixes.md +0 -101
  182. package/docs/bug-fixes/agent-02-purplelab-fixes.md +0 -88
  183. package/docs/bug-fixes/agent-03-dashboard-fixes.md +0 -119
  184. package/docs/bug-fixes/agent-04-memory-fixes.md +0 -105
  185. package/docs/bug-fixes/agent-05-provider-fixes.md +0 -86
  186. package/docs/bug-fixes/agent-06-integration-fixes.md +0 -101
  187. package/docs/bug-fixes/agent-07-dash-run-fixes.md +0 -101
  188. package/docs/bug-fixes/agent-08-docker-fixes.md +0 -164
  189. package/docs/bug-fixes/agent-09-e2e-build-fixes.md +0 -69
  190. package/docs/bug-fixes/agent-10-e2e-fullstack-fixes.md +0 -102
  191. package/docs/bug-fixes/agent-11-e2e-session-fixes.md +0 -70
  192. package/docs/bug-fixes/agent-12-scenario-fixes.md +0 -120
  193. package/docs/bug-fixes/agent-13-enterprise-fixes.md +0 -143
  194. package/docs/bug-fixes/agent-14-uat-newuser-fixes.md +0 -88
  195. package/docs/bug-fixes/agent-15-uat-poweruser-fixes.md +0 -132
  196. package/docs/bug-fixes/agent-19-code-review.md +0 -316
  197. package/docs/bug-fixes/agent-20-architecture-review.md +0 -331
  198. package/docs/competitive/bolt-new-analysis.md +0 -579
  199. package/docs/competitive/emergence-others-analysis.md +0 -605
  200. package/docs/competitive/replit-lovable-analysis.md +0 -622
  201. package/docs/dashboard-guide.md +0 -487
  202. package/docs/enterprise/migration.md +0 -265
  203. package/docs/history/one-run-audit.md +0 -304
  204. package/docs/plans/FORGE-AUTONOMOUS-QUEUE.md +0 -312
  205. package/docs/plans/ULTRAPLAN-FORGE-BAAS.md +0 -612
  206. package/docs/plans/UT2-6-LSP-DIAGNOSTIC-BROADCAST.md +0 -394
  207. package/docs/prd-purple-lab-ide.md +0 -152
  208. package/docs/prd-purple-lab-platform-v2.md +0 -223
  209. package/docs/prd-purple-lab-platform.md +0 -319
  210. package/docs/retrospectives/v7.5.15-fleet-postmortem.md +0 -325
  211. package/docs/retrospectives/v7.5.15-honesty-audit.md +0 -136
  212. package/docs/retrospectives/v7.5.15-llm-failure-modes.md +0 -49
  213. package/docs/show-hn-post.md +0 -46
  214. package/docs/test-scenarios/enterprise-scenarios.md +0 -732
  215. package/docs/thick2thin.md +0 -173
@@ -0,0 +1,315 @@
1
+ # Market program slice cards (source: autonomi-dev/research/2026-10-08-market/MARKET.md)
2
+
3
+ Owner: Product Owner. Not committed to BOARD.md. Cards are at most 60 lines each. Shared Wall checks on every card: tsc clean (loki-ts), only the file set listed is touched, bash -n on touched shell, no emoji or dash characters, SKILL.md untouched, dist rebuilt when loki-ts/src changes (memory: ts edit needs dist rebuild), new test files registered in the runner and shard table (structural guards). Budgets: LOW 15 min, MEDIUM 30 min, HIGH 30 min build plus live pair review (D91-8). Every flag is default OFF unless the card says otherwise. Staffing order is the section order.
4
+
5
+ # STANDARDS
6
+
7
+ ## Program 1: MCP-2026-07-28 (write-first card)
8
+
9
+ Ground truth read from code (2026-10-08):
10
+ - Two separate MCP stacks. (a) Python `mcp/server.py` (FastMCP from the pip SDK via `mcp/_sdk_loader.py`; `mcp/lsp_proxy.py` is a second server on the same loader). The protocol version it advertises is whatever the SDK negotiates; installed SDK is mcp 1.27.0 whose `LATEST_PROTOCOL_VERSION` is 2025-11-25; `mcp/requirements.txt` and `requirements-test.txt` pin `mcp>=1.0.0,<2.0.0`. So Python does NOT advertise 2024-11-05; it is capped at 2025-11-25 by the SDK. (b) Hand-rolled JS `src/protocols/mcp-server.js:97` and `mcp-client.js:105`, hardcoded 2024-11-05.
11
+ - JS server defects beyond the version string: `initialize` ignores `params.protocolVersion`, returns the version inside `serverInfo` (spec puts `protocolVersion` at `result` top level), accepts only the legacy `initialized` method (spec name is `notifications/initialized`), and the client sends the same legacy name. These are fixed by MCP-A regardless of spec target.
12
+ - No code anywhere implements `server/discover`, `_meta.traceparent`, or the tasks extension (grep: 0 hits in mcp/ and src/).
13
+ - Existing tests to extend, not duplicate: `tests/protocols/mcp-server.test.js:191` (pins 2024-11-05), `tests/protocols/mcp-client.test.js`, `tests/test-mcp-server.sh`, `tests/test-mcp-http-auth.sh:115` (sends 2025-06-18), `tests/cli/test-mcp-launch.sh:278` (sends 2024-11-05), `tests/test-mcp-tool-surface-packaged.sh`.
14
+ - Uncertainty to resolve first (MCP-0): the market report says 2026-07-28 is stateless (no initialize), with `server/discover`, Multi Round-Trip Requests, Tasks as extension `io.modelcontextprotocol/tasks`, Roots/Sampling/Logging deprecated. The pip SDK 1.x has no such support (inferred; verify). Do not hand-roll the Python side if an SDK release exists.
15
+
16
+ ### MCP-0 Spec and SDK probe (LOW, 15 min)
17
+ - Goal: a checked-in, cited conformance table: which 2026-07-28 requirements apply to Loki (a stdio tool server and a client), and whether any published `mcp` pip release or `@modelcontextprotocol/sdk` npm release implements it.
18
+ - File set: docs/v11/MCP-2026-07-28.md (new). No code.
19
+ - Tests first: tests/test-mcp-spec-doc.sh asserts the doc names each of: server/discover, initialize removal, MRTR, tasks extension id, traceparent in _meta, deprecated Roots/Sampling/Logging/DCR, and has a "Python SDK latest version found" line with a PyPI version number and date.
20
+ - Wall: doc cites the spec changelog URL and fetch date; every claim marked verified or UNVERIFIED; no code changed.
21
+ - Commands: bash tests/test-mcp-spec-doc.sh; python3 -c "import importlib.metadata as m;print(m.version('mcp'))"; npm view @modelcontextprotocol/sdk version time.
22
+ - Flag: none. Tier LOW. Blocks MCP-C and MCP-D design, not MCP-A.
23
+
24
+ ### MCP-A JS server and client: version negotiation and legacy-compat fixes (MEDIUM, 30 min)
25
+ - Goal: JS server negotiates `protocolVersion` correctly across a supported list (2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25; add 2026-07-28 only after MCP-C), returns it at `result.protocolVersion`, accepts both `initialized` and `notifications/initialized`; client sends `notifications/initialized` and the highest version it supports, and adopts the server's reply.
26
+ - File set: src/protocols/mcp-server.js, src/protocols/mcp-client.js, tests/protocols/mcp-server.test.js, tests/protocols/mcp-client.test.js. Nothing else.
27
+ - Tests first (red before green): requested 2025-06-18 gets 2025-06-18 back; unknown future version gets the server's latest supported; result has top-level protocolVersion and serverInfo has none; `notifications/initialized` returns null; client handshake against the in-test server ends on the negotiated version; old test at line 191 rewritten, not deleted.
28
+ - Wall: zero new dependencies; a 2024-11-05 client still works (regression test); getCapabilities unchanged.
29
+ - Commands: node --test tests/protocols/mcp-server.test.js tests/protocols/mcp-client.test.js; bash tests/test-mcp-server.sh.
30
+ - Flag: none (bug fix; old clients stay supported). Tier MEDIUM.
31
+
32
+ ### MCP-B Python server: advertised-version regression guard and SDK bump path (LOW, 15 min)
33
+ - Goal: a test that handshakes `python -m mcp.server` over stdio and records the negotiated version, so an SDK bump that changes it is visible; raise the pin ceiling only to a release MCP-0 shows supports a newer spec, otherwise keep <2.0.0 and record why in the doc.
34
+ - File set: tests/test-mcp-protocol-version.sh (new), mcp/requirements.txt and requirements-test.txt (only if MCP-0 finds a supporting release).
35
+ - Tests first: handshake with 2025-11-25 returns 2025-11-25; handshake with 2024-11-05 returns 2024-11-05; both exit 0; reuse the handshake helper in tests/test-mcp-tool-surface-packaged.sh rather than writing a new one.
36
+ - Wall: tool surface guard (test-mcp-tool-surface-guard-rejects.sh) still green; runner and shard registration present.
37
+ - Commands: bash tests/test-mcp-protocol-version.sh; bash tests/test-mcp-tool-surface-packaged.sh.
38
+ - Flag: none. Tier LOW.
39
+
40
+ ### MCP-C 2026-07-28 stateless profile and server/discover (MEDIUM, 30 min; depends on MCP-0 and MCP-A)
41
+ - Goal: JS server answers `server/discover` (name, version, supported versions, capabilities) and serves tools/list and tools/call without a prior initialize when the request carries protocol version metadata per the spec; Python side gets the same only via the SDK (this slice documents the gate, adds no hand-rolled Python protocol).
42
+ - File set: src/protocols/mcp-server.js, tests/protocols/mcp-server.test.js, docs/v11/MCP-2026-07-28.md (conformance rows flip to done).
43
+ - Tests first: discover returns every supported version including 2026-07-28; stateless tools/list works with no prior initialize; legacy stateful flow still works; unknown method gives -32601.
44
+ - Wall: write/spawn tools stay behind the existing auth and read-only split (docs/v10/CP-ASK-PLAN.md); no session ids stored.
45
+ - Commands: node --test tests/protocols/mcp-server.test.js.
46
+ - Flag: LOKI_MCP_2026_07=1 enables advertising 2026-07-28; default off until MCP-0 conformance rows all pass.
47
+
48
+ ### MCP-D Tasks extension, traceparent propagation (HIGH, 30 min plus pair review; depends on MCP-C and OTEL-GENAI OTEL-1)
49
+ - Goal: expose `loki run` and `loki verify` as MCP Tasks under `io.modelcontextprotocol/tasks` (create, status poll, result, cancel), and read `_meta.traceparent` on incoming calls so the run's spans use it as parent. Verify exposure is HIGH (verifier path): the task wrapper may only call the existing `loki_v10_verify` / `loki_v10_run` (mcp/v10_tools.py) and may never change a verdict.
50
+ - File set: src/protocols/mcp-server.js, mcp/v10_tools.py (read-only adapter only), tests/protocols/mcp-tasks.test.js (new), tests/test-mcp-tasks-verify-readonly.sh (new).
51
+ - Tests first: task create returns a task id; poll sees working then completed; cancel stops the child by recorded PID only; a task result for verify is byte-identical to the direct tool result; traceparent in _meta becomes the parent of the first span (assert via OTEL-1 exporter fixture); verdict upgrade attempt is refused.
52
+ - Wall: auth token required for task creation over HTTP (test-mcp-http-auth.sh extended); no kill by name or pattern.
53
+ - Commands: node --test tests/protocols/mcp-tasks.test.js; bash tests/test-mcp-tasks-verify-readonly.sh; bash tests/test-mcp-http-auth.sh.
54
+ - Flag: LOKI_MCP_TASKS=1. Tier HIGH.
55
+
56
+ ## Program 2: OTEL-GENAI
57
+
58
+ Ground truth: `src/observability/{otel.js,spans.js,otel-bridge.js,index.js}` is a minimal OTLP/HTTP+JSON exporter, lazy and no-op unless LOKI_OTEL_ENDPOINT is set; the bridge (started by autonomy/run.sh:2860) tails the legacy event stream and emits `rarv.iteration` and `loki.session` spans. Engine10 writes `.loki/runs/<id>/events.jsonl` (loki-ts/src/engine10/events.ts, fold/tail) and has cost harvesting in engine10/cost.ts. Neither emits `gen_ai.*` (grep: 0). Reuse the bridge exporter; do not add an OTel SDK dependency.
59
+
60
+ ### OTEL-1 Engine10 events to gen_ai spans (MEDIUM, 30 min)
61
+ - Goal: for every engine10 run, the bridge emits `invoke_agent` (run), one child per stage, `execute_tool` per tool event when present, with `gen_ai.operation.name`, `gen_ai.agent.name=loki`, `gen_ai.provider.name`, `gen_ai.request.model`, `gen_ai.usage.input_tokens/output_tokens` from the cost events; semconv version pinned in one constant; trace id written to the receipt as `trace_id` only when tracing was on.
62
+ - File set: src/observability/genai-spans.js (new, pure mapper event to span), src/observability/otel-bridge.js (call mapper), tests/observability/genai-spans.test.js (new). Receipt field is OTEL-2.
63
+ - Tests first: fixture events.jsonl (with and without cost data) maps to the exact span tree and attribute names; unknown cost stays absent, never 0 (matches cost.ts UNKNOWN rule); semconv pin constant asserted; mapper pure, no network.
64
+ - Wall: zero overhead when LOKI_OTEL_ENDPOINT unset (existing no-op test stays green); no prompt or completion content in spans (opt-in content capture is out of scope).
65
+ - Commands: node --test tests/observability/genai-spans.test.js; bash tests/test-otel*.sh (existing).
66
+ - Flag: LOKI_OTEL_GENAI=1 (default off; spans only add when an endpoint is set). Tier MEDIUM.
67
+
68
+ ### OTEL-2 Trace id in the receipt and import fixture (HIGH, 30 min plus pair review)
69
+ - Goal: seal.ts records `trace_id` in the receipt body (inside the signed content) so a viewer can link receipt to trace; plus a documented collector config that imports unmodified into Grafana/Honeycomb/Datadog (docs only, no vendor test).
70
+ - File set: loki-ts/src/engine10/stages/seal.ts, loki-ts/src/engine10/events.ts (envelope field only), docs/AGENT-CHANGE-RECEIPT.md (Fields table), tests under loki-ts/test for seal receipt shape.
71
+ - Tests first: receipt without tracing is byte-identical to today (golden); with tracing, trace_id is present, 32 hex, covered by the existing signature check; tamper test flips trace_id and verify returns TAMPERED.
72
+ - Wall: Seal change, so HIGH; verdict logic untouched; schema id loki.v10.receipt/1 stays (additive optional field) unless reviewers require /2.
73
+ - Commands: cd loki-ts && bun test seal verify; bash tests/test-receipt*.sh.
74
+ - Flag: only populated when OTEL-1 flag is on. Tier HIGH.
75
+
76
+ ## Program 3: SARIF
77
+
78
+ Ground truth: SARIF exists only in Loki's own CI (.github/workflows/security-audit.yml CodeQL). Engine10 verify has no SAST step and no finding schema; `autonomy/lib/secret-scan.sh` is the only scanner in autonomy/lib. The issue-to-pr Action already splits read-only agent job from privileged steps (docs/AGENT-CHANGE-RECEIPT.md, Rule of Two); the SARIF upload needs `security-events: write`, so it MUST be a separate no-agent job.
79
+
80
+ ### SARIF-1 Findings to SARIF 2.1.0 converter (LOW, 15 min)
81
+ - Goal: pure function turning Loki findings (secret-scan hits, NOT PROVEN items as `note` level, wall/verify failures) into a valid SARIF 2.1.0 file with stable `partialFingerprints`.
82
+ - File set: loki-ts/src/features/sarif.ts (new), loki-ts/test/sarif.test.ts (new).
83
+ - Tests first: golden SARIF for 3 findings; schema-required fields present; NOT PROVEN maps to level note with ruleId loki/not-proven; fingerprint stable across line shifts; no secret value ever appears in the output (assert redaction using util/redact.ts).
84
+ - Wall: no network, no new dependency; secret text redacted.
85
+ - Commands: cd loki-ts && bun test sarif.test.ts && bunx tsc --noEmit.
86
+ - Flag: none (library). Tier LOW.
87
+
88
+ ### SARIF-2 `loki export --sarif` and receipt reference (MEDIUM, 30 min; after SARIF-1)
89
+ - Goal: `loki export --sarif [run-id]` writes `.loki/runs/<id>/findings.sarif`; also runs secret-scan on the run diff as the first finding source. No verdict change: findings are reported, not gating, in this slice.
90
+ - File set: loki-ts/src/commands/export_sarif.ts (new), registration in loki-ts/src/cli.ts and autonomy/loki dispatch, loki-ts/test/export_sarif.test.ts, completion.ts entry.
91
+ - Tests first: fixture run dir yields a file; unknown run exits 66 (match verify); help text lists flag; new-command cross-cutting registration checks (completion, help, docs) pass.
92
+ - Wall: structural guards for new command registration (memory: new-command cross-cutting).
93
+ - Commands: cd loki-ts && bun test export_sarif.test.ts; bash tests/test-completion*.sh.
94
+ - Flag: none (explicit command). Tier MEDIUM.
95
+
96
+ ### SARIF-3 Upload job in issue-to-pr Action (MEDIUM, 30 min; after SARIF-2)
97
+ - Goal: opt-in `sarif: true` input uploads findings.sarif via `github/codeql-action/upload-sarif` in a second job with no agent and `security-events: write`; the agent job keeps read-only permissions.
98
+ - File set: .github/actions/issue-to-pr/action.yml, docs/AGENT-CHANGE-RECEIPT.md (or docs/alternative-installations.md section), tests/test-action-sarif-split.sh (new, YAML assertion).
99
+ - Tests first: assert agent job permissions contain no security-events: write; upload step is in a job with no loki run step; action pins by version tag consistent with existing attest step.
100
+ - Wall: Rule of Two guard; secrets never in the upload job env.
101
+ - Commands: bash tests/test-action-sarif-split.sh; actionlint if installed.
102
+ - Flag: input sarif default false. Tier MEDIUM.
103
+
104
+ ## Program 4: SIGSTORE-RECEIPTS
105
+
106
+ Ground truth: Ed25519 receipt signing lives in loki-ts/src/util/receipt_signer.ts and engine10/stages/seal.ts, keys managed by engine10/keys_cmd.ts; `loki verify` is engine10/verify_cmd.ts (exit codes 0..4, 66); DSSE export exists (loki-ts/src/features/receipt_dsse.ts: in-toto Statement v1, custom predicate https://autonomi.dev/loki/receipt/v10, subject git commit and tree). GPG exists in autonomy/loki. Release images are cosign-keyless signed in release.yml. The issue-to-pr Action already has opt-in `attest: true` using actions/attest-build-provenance@v2 over receipt.json (docs/AGENT-CHANGE-RECEIPT.md "GitHub attestation"). SLSA: 0 hits. So the gap is narrower than the report says: not "no keyless", but (a) the attestation subject is receipt.json bytes, not the git commit, (b) no SLSA provenance predicate, (c) no cosign path.
107
+
108
+ ### SIGS-1 SLSA v1 provenance predicate mapping (HIGH, 30 min plus pair review)
109
+ - Goal: `loki verify --export-dsse --predicate slsa` emits an in-toto Statement v1 with predicateType https://slsa.dev/provenance/v1, subject = git commit (as today), buildDefinition (buildType URL under autonomi.dev, externalParameters = issue ref, internalParameters = provider, model, harness version) and runDetails (builder.id, metadata.invocationId = run id, byproducts = receipt sha256), with the full Loki receipt referenced, not duplicated. Default predicate stays unchanged.
110
+ - File set: loki-ts/src/features/receipt_slsa.ts (new), loki-ts/src/engine10/verify_cmd.ts (flag parsing only), loki-ts/test/receipt_slsa.test.ts, docs/AGENT-CHANGE-RECEIPT.md section.
111
+ - Tests first: golden statement; verifyEnvelope accepts it with the same Ed25519 key; verify of a slsa envelope returns the same verdict as the underlying receipt; refuses to export non-VERIFIED outcomes exactly like today; tamper of buildDefinition fails signature.
112
+ - Wall: Seal-adjacent, never changes the Seal or verdict; no new key type.
113
+ - Commands: cd loki-ts && bun test receipt_slsa receipt_dsse; tsc.
114
+ - Flag: --predicate slsa (explicit). Tier HIGH.
115
+
116
+ ### SIGS-2 Keyless Sigstore bundle for the DSSE envelope (HIGH, 30 min plus pair review; after SIGS-1)
117
+ - Goal: a CI-only helper that signs the DSSE statement with cosign keyless (`cosign attest-blob --predicate ... --type slsaprovenance1` or `gh attestation` with subject = commit digest) so `cosign verify-blob-attestation` and `gh attestation verify` pass without Loki installed. Local runs keep Ed25519; keyless is never attempted offline.
118
+ - File set: .github/actions/issue-to-pr/action.yml (extend existing attest job to attest the SLSA statement; keep it in the separate no-agent job), scripts/sigstore-attest.sh (new, thin), tests/test-sigstore-attest-dryrun.sh (new; stub cosign on PATH), docs/AGENT-CHANGE-RECEIPT.md.
119
+ - Tests first: dry-run with stub cosign records the exact argv (subject digest, predicate type, identity flags); script refuses when ACTIONS_ID_TOKEN_REQUEST_URL unset; agent job still lacks id-token: write (YAML assertion).
120
+ - Wall: Rule of Two; real Sigstore call only in a manual workflow_dispatch smoke documented, not in CI.
121
+ - Commands: bash tests/test-sigstore-attest-dryrun.sh; shellcheck scripts/sigstore-attest.sh.
122
+ - Flag: input attest-slsa default false. Tier HIGH.
123
+
124
+ ### SIGS-DOC in-toto agent-change predicate proposal (LOW, 15 min)
125
+ - Goal: docs-only draft following the in-toto attestation New Predicate Guidelines: name, type URI, fields (task source, base commit, head commit, agent identity, model ids, tools and MCP servers used, checks run, outcome, not-proven list), a worked example derived from a real receipt, Loki as reference implementation. Describe the proposal only; state it is a draft, not accepted.
126
+ - File set: docs/v11/INTOTO-AGENT-CHANGE-PREDICATE.md (new), test tests/test-predicate-doc.sh (asserts the example JSON parses and its field names match docs/AGENT-CHANGE-RECEIPT.md).
127
+ - Wall: no claim of standardization; no URL invented for an upstream PR.
128
+ - Commands: bash tests/test-predicate-doc.sh. Flag: none. Tier LOW.
129
+
130
+ ## Program 5: AI-ACT-MARKING (deadline before 2026-12-02)
131
+
132
+ Ground truth: seal.ts:138 already commits with trailer `Loki-Run: <runId>`; receipt carries provider and model (seal.ts:323). No AI-generated marker, no per-change BOM, no evidence-pack export (grep AI Act: 0). `.github/workflows/sbom.yml` produces a release CycloneDX SBOM only. Whether source code counts as "text" under Art 50 is unsettled (report). Language rule for all docs and CLI text in this program: describe what the feature writes; never state or imply compliance, legal sufficiency or certification.
133
+
134
+ ### MARK-1 Commit trailers and PR marker (HIGH, 30 min plus pair review)
135
+ - Goal: every Loki commit gets machine-readable trailers: `AI-Generated: true`, `AI-Provider: <p>`, `AI-Model: <m>`, `Loki-Receipt: <run-relative path or URL>` next to existing `Loki-Run`; PR body gets a single marker line and receipt link (pr_body.ts). The commit stage is in seal.ts, so HIGH.
136
+ - File set: loki-ts/src/engine10/stages/seal.ts (commit args only), loki-ts/src/engine10/pr_body.ts, loki-ts/test (seal commit trailer test, pr_body golden), docs/environment-variables.md.
137
+ - Tests first: `git interpret-trailers --parse` on the produced commit returns all four keys; commit body without the flag byte-identical to today; PR body stays within PR_BODY_LINE_BUDGET (60).
138
+ - Wall: receipt hash and verdict untouched; trailer values sanitized (no newlines); no co-author line (repo rule).
139
+ - Commands: cd loki-ts && bun test seal pr_body; tsc.
140
+ - Flag: LOKI_AI_MARKING=1 (default ON from the release before 2026-12-02 after a founder decision; ship OFF first). Tier HIGH.
141
+
142
+ ### MARK-2 Per-change AI-BOM (CycloneDX 1.7 ML-BOM block) (MEDIUM, 30 min)
143
+ - Goal: `.loki/runs/<id>/ai-bom.cdx.json` with the models (provider, id, version when known, UNKNOWN otherwise), tools, MCP servers (from loki-ts/src/providers/mcp_config.ts), harness version, plus the receipt sha256 as a property.
144
+ - File set: loki-ts/src/features/ai_bom.ts (new), loki-ts/test/ai_bom.test.ts. Writer hook is MARK-3.
145
+ - Tests first: golden for claude and codex fixture runs; unknown model version stays "unknown", never invented; validates required CycloneDX fields (bomFormat, specVersion, metadata, components).
146
+ - Wall: no network; pure over receipt plus config.
147
+ - Commands: cd loki-ts && bun test ai_bom; tsc. Flag: none (library). Tier MEDIUM.
148
+
149
+ ### MARK-3 `loki export --evidence-pack` (MEDIUM, 30 min; after MARK-1, MARK-2, SIGS-1 optional)
150
+ - Goal: one directory or tarball with receipt.json, DSSE envelope, AI-BOM, trailers log (`git log --format` of run commits), and a README that states what each file is and explicitly that it is evidence, not a compliance determination.
151
+ - File set: loki-ts/src/commands/export_evidence.ts (new), cli.ts and autonomy/loki dispatch registration, completion.ts, loki-ts/test/export_evidence.test.ts, docs/AGENT-CHANGE-RECEIPT.md.
152
+ - Tests first: fixture run produces the 5 files; a grep guard test fails if README or help text contains the words "compliant", "compliance achieved", "certified" (the guard asserts absence from generated text and docs for this feature); unknown run exits 66.
153
+ - Wall: new-command registration guards; no emoji or dashes.
154
+ - Commands: cd loki-ts && bun test export_evidence; bash tests/test-completion*.sh. Flag: explicit command. Tier MEDIUM.
155
+
156
+ # HUMAN-TIME and TRUST
157
+
158
+ ## Program 6: QUOTA-FORECAST
159
+
160
+ Ground truth (GOV-MEASURE exists, do not rebuild): `scripts/usage-governor.py` has `parse_usage_text` (parses `claude -p /usage --output-format json` into session_pct, week_pct, session_resets, week_resets, regexes at lines 396-397), `_run_usage_command` (bounded, process-group kill), `measured_usage` (15 min cache), `fit_tokens_per_percent`, and `--json` output. Caveats found in the code: (1) `last_wednesday_reset`/`next_wednesday_reset` hardcode the founder's weekly reset day, so they cannot be reused for a user; the user's reset must come from `session_resets`/`week_resets` text. (2) The reset fields are raw strings, not timestamps. (3) Only Claude has `/usage`; codex and others have no reading, so forecast must degrade to "unmeasured" (never a made-up number). Consumer today: `loki-ts/src/commands/queue.ts` `defaultGovernor` (shells out to the script, holds the queue on hold_above_70_session). Hard caps today: `--max-cost` (engine10/cli.ts:36, default $100 with API key, none on subscription) and the wall-clock cap (util/run_cap.ts). The F2 rough-prior cost estimate was merged (needs reading before PRED-1; locate with git log --grep F2-ROUGH-PRIOR). The user's own usage is read only on the user's machine via their own claude CLI; nothing is sent anywhere.
161
+
162
+ ### QF-1 Reset-time parser and window model (LOW, 15 min)
163
+ - Goal: pure function `parseResetText(s, now, tz)` returning an epoch for strings like the /usage output (formats to be captured from tests/fixtures of real `/usage` text already used by the governor tests), or null; plus a `UsageWindow` type {kind, used_pct, resets_at|null}.
164
+ - File set: loki-ts/src/util/usage_window.ts (new), loki-ts/test/usage_window.test.ts (new). Python script untouched.
165
+ - Tests first: every distinct reset string in the existing governor test fixtures (grep tests for "resets") parses to the right epoch across a DST boundary; unparseable returns null, never now+5h; no hardcoded weekday.
166
+ - Wall: no spawn, no network; reads no files.
167
+ - Commands: cd loki-ts && bun test usage_window; tsc. Flag: none (library). Tier LOW.
168
+
169
+ ### QF-2 Forecast before run and `issues run` (MEDIUM, 30 min; after QF-1)
170
+ - Goal: before `loki start` and `loki queue run` (the existing issue loop), print `forecast: ~X% of session window, ~Y% of week (basis: N past runs of this shape | rough prior | unmeasured)`. Reuse `defaultGovernor`'s script call, extended to return session_pct/week_pct/resets via `--json` (already in output). Basis uses engine10/cost.ts history when present, else the labelled rough prior, else prints "unmeasured" without a number.
171
+ - File set: loki-ts/src/engine10/forecast.ts (new), loki-ts/src/engine10/cli.ts (one call site), loki-ts/src/commands/queue.ts (one call site, reuse defaultGovernor), loki-ts/test/forecast.test.ts.
172
+ - Tests first: stub governor JSON gives the expected line; no reading gives "unmeasured" and no percent; forecast never written into the receipt as a measured value; output stays within narrow terminal width (util/term_width.ts).
173
+ - Wall: forecast is advisory, adds no new spawn beyond the existing cached read; runs must not slow by more than the cache hit path.
174
+ - Commands: cd loki-ts && bun test forecast queue; tsc. Flag: LOKI_FORECAST (default on, `=0` off) once QF-2 review passes. Tier MEDIUM.
175
+
176
+ ### QF-3 Hard cap default and pause-until-reset (HIGH, 30 min plus pair review; after QF-1, QF-2)
177
+ - Goal: a window cap on by default (default stop at 90% of the session window, configurable): when the reading shows the window exhausted or the forecast exceeds remaining, the run checkpoints (existing runner/checkpoint.ts) and the queue pauses, then auto-resumes at the parsed reset time; never enables or spills into paid overage; receipt records `stop_reason: quota_window`. Touches budget stop semantics and the receipt outcome set, so HIGH.
178
+ - File set: loki-ts/src/engine10/quota_cap.ts (new), loki-ts/src/commands/queue.ts (pause/resume loop, uses injected clock), loki-ts/src/engine10/supervisor.ts (cap hook only), loki-ts/test/quota_cap.test.ts, loki-ts/test/queue_resume.test.ts.
179
+ - Tests first (fake clock, stub governor): window exhausted pauses and does not start the next item; resume fires at resets_at plus jitter, not before; unmeasured window never silently disables the cap (it falls back to the wall-clock cap and says so); a paused queue survives process restart (state file); outcome is never mislabeled VERIFIED.
180
+ - Wall: sleep implemented as a timer in the one queue process (no stray background sleepers, record PID, stop only that PID); fail-safe default stays "stop", never "continue".
181
+ - Commands: cd loki-ts && bun test quota_cap queue_resume; bash tests/test-queue-consumer.sh; tsc.
182
+ - Flag: LOKI_QUOTA_CAP=1 initially, flipped default-on in a follow-up after one clean week (founder asked default on; the flip is a one-line change in the same slice if reviewers approve). Tier HIGH.
183
+
184
+ ## Program 7: VERIFY-PR
185
+
186
+ Ground truth: `loki verify` (engine10/verify_cmd.ts) verifies a receipt, not a PR; `.github/actions/receipt-check` posts a "Loki Receipt" check run from `check.sh`; the project model (loki-ts/src/project_model/{discover,package_suite,scope}.ts) discovers packages and per-package test suites; `util/safe_git.ts` is the hardened-git path (fsmonitor, hooks, ext:: off, tokens stripped); `util/redact.ts` exists. There is NO fail-to-pass concept in the engine (grep f2p: 0), no PR-checkout verify path, and no sandbox runner under loki-ts/src/runner other than what run.sh uses. The report's "F2P test" must be defined here: the checks derived from the linked issue (engine10/fetch_issue.ts, features/contract.ts) must FAIL on the PR base and PASS on the PR head. Untrusted code: Rule of Two means this job may combine at most two of {untrusted input, secrets/tokens, outbound write}. Design: the verify job gets untrusted input (the PR code) and NO token and NO network; a second job with no untrusted code (reads only the result artifact) holds `checks: write`, signs, and posts.
187
+
188
+ ### VPR-1 Sandbox spec and runner contract (HIGH, 30 min plus pair review)
189
+ - Goal: a runner script that executes derived checks against a PR checkout inside a container with: no network (`--network none` after deps are pre-installed from a lockfile-pinned cache or skipped with NOT PROVEN), read-only root, tmpfs workdir, non-root, CPU/mem/pids caps, wall timeout, env scrubbed with `tokenFreeEnv`, no mounted docker socket or HOME. Outputs only a JSON result file via a single mounted output dir.
190
+ - File set: scripts/verify-pr-sandbox.sh (new), docs/v11/VERIFY-PR-SANDBOX.md (threat model: malicious package.json scripts, git hooks, symlinks out of the repo, oversized output, fork bombs), tests/test-verify-pr-sandbox.sh (new, uses a hostile fixture repo).
191
+ - Tests first, hostile fixture: a test script that tries to curl, read $HOME, write outside the workdir, read GH_TOKEN, spawn 10k procs, and fill the disk; each attempt must fail or be capped and the result file must say so. If docker is absent the test SKIPs loudly with a positive control (memory: 0/N needs a positive control).
192
+ - Wall: never `git checkout` with repo hooks enabled (use safe_git); never kill by name or pattern; docker usage per memory (pool exhaustion looks like a product bug: detect and report as BLOCKED, not as a failing verdict).
193
+ - Commands: bash tests/test-verify-pr-sandbox.sh; shellcheck scripts/verify-pr-sandbox.sh. Flag: none (script, unused until VPR-2). Tier HIGH.
194
+
195
+ ### VPR-2 `loki verify-pr <url>` core (HIGH, 30 min plus pair review; after VPR-1)
196
+ - Goal: parse a PR URL or owner/repo#N; fetch metadata and linked issue via gh with a read-only token; fetch base and head with safe_git; derive the delivery contract from the linked issue (reuse features/contract.ts and pr_criteria.ts); run Project Model checks for the touched packages (project_model/scope.ts); run the F2P check as defined above through the VPR-1 sandbox; write `verify-pr-result.json` with a verdict from the existing outcome set (VERIFIED, NOT PROVEN with reasons) and exit codes aligned with `loki verify`. No linked issue means NOT PROVEN with reason, never VERIFIED. Verdict can only be VERIFIED if F2P went red-to-green AND package suites passed.
197
+ - File set: loki-ts/src/commands/verify_pr.ts (new), loki-ts/src/engine10/verify_pr_f2p.ts (new), registration in cli.ts, autonomy/loki dispatch, completion.ts, loki-ts/test/verify_pr.test.ts with a local bare-repo fixture (no network).
198
+ - Tests first: fixture PR whose fix is real gives VERIFIED; a PR that deletes the failing test gives NOT PROVEN (test removed); a PR where the check passes on base too gives NOT PROVEN (check does not discriminate); hostile PR script cannot reach network (uses VPR-1); missing linked issue; forged "tests pass" in PR body ignored.
199
+ - Wall: the verdict logic is a new Seal-class path, reviewers must run a mutation (flip the base/head order and see red); no model call in this slice, checks are the author's own.
200
+ - Commands: cd loki-ts && bun test verify_pr; tsc; bash tests/test-completion*.sh. Flag: LOKI_VERIFY_PR=1 until reviewed. Tier HIGH.
201
+
202
+ ### VPR-3 Signed receipt and check run job split (HIGH, 30 min plus pair review; after VPR-2)
203
+ - Goal: GitHub Action `.github/actions/verify-pr` with two jobs documented as a reusable workflow: job A (untrusted, `permissions: {}`, no secrets, runs VPR-2 and uploads the result artifact), job B (trusted, runs no PR code, `checks: write`, downloads only the JSON, validates it against a strict schema, signs with the receipt key from secrets or Sigstore keyless, and posts the check run by reusing `.github/actions/receipt-check/check.sh`). `pull_request_target` is forbidden in the examples.
204
+ - File set: .github/actions/verify-pr/action.yml (new), .github/workflows/verify-pr.example.yml (new), docs/v11/VERIFY-PR-SANDBOX.md (job split section), tests/test-verify-pr-action-split.sh (YAML assertions).
205
+ - Tests first: job A has no secrets/token and no write permission; job B never checks out PR code; no `pull_request_target`; the artifact schema rejects extra fields and over-size input; check summary is truncated and redacted.
206
+ - Wall: Rule of Two (never all three of untrusted code, token, write in one job).
207
+ - Commands: bash tests/test-verify-pr-action-split.sh. Flag: Action input only. Tier HIGH.
208
+
209
+ ## Program 8: FALSE-COMPLETION-RATE
210
+
211
+ Ground truth: `scripts/b9-scoreboard.sh` today has four arms (raw `claude -p`, router, no-router, no-advisor) and records `solve` (hidden tests) per run; the `--ab` flag and the raw/loki arms with cost, correctness, wall ratios live on branch slice-B9-RAW-ARM (tip 28d9ddf89, not on main as of this card; commits 1ae2fd914, c53882b40, 28d9ddf89). There is no raw codex arm and no "claimed done" capture anywhere. METRICS is docs/v10/METRICS.md. Do not start until slice-B9-RAW-ARM merges (check `git branch --contains 28d9ddf89`).
212
+
213
+ ### FCR-1 Claimed-done extraction (MEDIUM, 30 min; after B9-RAW-ARM merge)
214
+ - Goal: a function classifying each arm's final output as `claimed_done` (true/false/unclear) deterministically: raw arms by an explicit last-line contract appended to the prompt ("end with DONE or BLOCKED"), loki arm by its receipt outcome (VERIFIED counts as claimed done, NOT PROVEN does not).
215
+ - File set: scripts/b9-claim.py (new, stdlib), tests/test-b9-claim.sh, fixtures under tests/fixtures/b9-claim/.
216
+ - Tests first: fixtures for DONE, BLOCKED, missing marker (unclear, excluded and counted), a lying DONE with failing hidden tests; loki NOT PROVEN is not a claim.
217
+ - Wall: no model call to classify (a model judge would be a second unreliable measurer); script is pure.
218
+ - Commands: bash tests/test-b9-claim.sh. Flag: none. Tier MEDIUM.
219
+
220
+ ### FCR-2 Raw codex arm and public task set (MEDIUM, 30 min; after FCR-1)
221
+ - Goal: add `raw-codex` arm beside raw-claude; define the public task set as pinned repo+SHA+hidden test command rows in docs/v11/FCR-TASKS.tsv (at least 20, license-compatible, reproducible by anyone with the CLIs); `--dry-run` uses the existing stub CLIs.
222
+ - File set: scripts/b9-scoreboard.sh (arm only), docs/v11/FCR-TASKS.tsv, tests/test-b9-scoreboard.sh (extend).
223
+ - Tests first: dry-run produces one row per arm per task; codex arm preflight failure is BLOCKED not a fail (existing BLOCKED rule); a timed-out cell is recorded, not dropped (memory: bench timeout silent cell loss).
224
+ - Wall: a 0/N for an arm needs a positive control row; shellcheck; no billed run in CI.
225
+ - Commands: bash tests/test-b9-scoreboard.sh. Flag: --arms selector. Tier MEDIUM.
226
+
227
+ ### FCR-3 False-completion column and METRICS row (MEDIUM, 30 min; after FCR-2)
228
+ - Goal: `--fcr` prints, per arm, `claimed_done`, `actually_passes`, `false_completion_rate = claimed_done_and_failing / claimed_done` with n and a Wilson interval, appended as a labelled row in docs/v10/METRICS.md only from real (non-dry) runs.
229
+ - File set: scripts/b9-scoreboard.sh (reporting), docs/v10/METRICS.md (row format, no numbers invented), tests/test-b9-scoreboard.sh.
230
+ - Tests first: fixture TSV gives the exact rate and interval; n below 20 prints "insufficient n" instead of a rate; dry-run rows are tagged and refused by the METRICS writer.
231
+ - Wall: any published number cites the TSV, commands and run date (evidence rule); design floor check (memory) so small n never claims separation.
232
+ - Commands: bash tests/test-b9-scoreboard.sh. Flag: --fcr. Tier MEDIUM.
233
+
234
+ ## Program 9: UNDO
235
+
236
+ Ground truth: `loki rollback` (loki-ts/src/commands/rollback.ts) restores `.loki/` state checkpoints (runner/checkpoint.ts), NOT git commits; there is no `loki undo` (grep: none). The receipt has `base_sha`, `head_sha` (seal.ts:304-305); commits carry `Loki-Run: <id>` (seal.ts:138); engine10 `ctx.branch` is the branch; PR creation is in stages/pr.ts (`pr_url` in outputs). Git must go through util/safe_git.ts.
237
+
238
+ ### UNDO-1 Plan builder (read-only) (MEDIUM, 30 min)
239
+ - Goal: `loki undo <run-id> --plan` verifies the receipt first (reuse verify_cmd logic, refuses TAMPERED), then lists exactly the commits in base_sha..head_sha that carry that run's `Loki-Run` trailer, the branch, the PR url if any, and whether each commit is already on the default branch, pushed, or merged. Prints what undo would do. Changes nothing.
240
+ - File set: loki-ts/src/commands/undo.ts (new, plan only), cli.ts + autonomy/loki dispatch + completion.ts registration, loki-ts/test/undo_plan.test.ts (temp git repo fixture).
241
+ - Tests first: unmerged branch plan = delete branch; merged plan = revert commits; commit from another run in the range is excluded; tampered receipt refused; unknown run exits 66.
242
+ - Wall: zero writes in this slice (assert repo HEAD/refs unchanged); new-command registration guards.
243
+ - Commands: cd loki-ts && bun test undo_plan; tsc. Flag: none. Tier MEDIUM.
244
+
245
+ ### UNDO-2 Apply: revert or drop, with confirmation (HIGH, 30 min plus pair review; after UNDO-1)
246
+ - Goal: `loki undo <run-id>` executes the plan: local unmerged branch is deleted after confirmation; already-merged commits are reverted with `git revert --no-edit` on a new branch (never rewrite history, never force-push); closes the PR via gh only with `--close-pr`; a pre-undo ref is recorded so undo itself is undoable; `--yes` skips the prompt but never skips the receipt check. Reason HIGH: destructive and receipt-dependent.
247
+ - File set: loki-ts/src/commands/undo.ts, loki-ts/src/util/safe_git.ts (read only unless a revert wrapper is missing), loki-ts/test/undo_apply.test.ts.
248
+ - Tests first: revert leaves a clean tree and the revert restores base tree hash; branch with later foreign commits is refused with a message; dirty worktree refused; no force flags appear in any recorded git argv (assert on the injected runner); success and failure both write `.loki/undo/<run>.json`.
249
+ - Wall: never touches the user's current branch unless it is the run branch; no `reset --hard`; tokens only for the gh close step.
250
+ - Commands: cd loki-ts && bun test undo_plan undo_apply; tsc. Flag: LOKI_UNDO=1 until reviewed. Tier HIGH.
251
+
252
+ ## Program 10: MEMORY-CITES
253
+
254
+ Ground truth: T6 memory with proof v1 is `loki-ts/src/util/pr_lessons.ts` (store `.loki/memory/semantic/pr-lessons.json`; each lesson has source {pr, pr_url, comment_url, kind, author} and `uses` [{run_id, verdict, at}]) driven by `loki memory lessons` (commands/memory.ts). It already refuses non-merged PRs (pr_lessons.ts:84 `is not merged`). So "cites its receipt" is half built: `uses` carries run_id and verdict of runs that used a lesson, but a lesson does not cite the receipt (run) that justified creating it, and nothing learns from closed-unmerged PRs. 132-F3 in docs/v10/BACKLOG-D91.md ("lesson hit rate and demotion") touches the same file: sequence after it.
255
+
256
+ ### MC-1 Lesson cites the receipt of the PR's run (MEDIUM, 30 min; after 132-F3)
257
+ - Goal: when a lesson is learned from a PR whose branch/commits carry a `Loki-Run` trailer (or the PR body receipt link from MARK-1), store `justified_by: {run_id, receipt_sha256, verdict}`; lessons from non-Loki PRs have none and show "no receipt". `loki memory lessons` prints the citation.
258
+ - File set: loki-ts/src/util/pr_lessons.ts, loki-ts/src/commands/memory.ts, loki-ts/test/pr_lessons.test.ts (extend).
259
+ - Tests first: injected GhClient returns commits with trailer, so the lesson carries the cite; receipt hash comes from the local receipt file only if it exists and verifies, else `unverified`; file version bumps to 2 with a v1 reader test (old files still load).
260
+ - Wall: lesson text still verbatim; atomic write via util/atomic.ts; no change to prompt injection yet.
261
+ - Commands: cd loki-ts && bun test pr_lessons; tsc. Flag: none. Tier MEDIUM.
262
+
263
+ ### MC-2 Learn from closed-unmerged PRs (MEDIUM, 30 min; after MC-1)
264
+ - Goal: `loki memory lessons learn <pr>` accepts a PR closed without merge when it was a Loki PR (trailer present): records the review comments and the close event as lessons with `kind: "rejected"` and the PR's run id, so the planner prompt can show "a previous attempt on this repo was rejected for: ...". Non-Loki closed PRs and PRs with no human comments are skipped with a stated reason.
265
+ - File set: loki-ts/src/util/pr_lessons.ts (relax the merged guard behind a kind), loki-ts/src/commands/memory.ts, loki-ts/test/pr_lessons.test.ts.
266
+ - Tests first: closed-unmerged with comments yields rejected-kind lessons; merged PR path unchanged (regression); closed with zero comments yields none and says why; bot comments filtered the same way as today.
267
+ - Wall: lessons are data, never instructions: prompt injection use must keep the existing lesson quoting boundary (read how learnings are injected before changing; any prompt text goes in the cache-stable prefix per repo invariant).
268
+ - Commands: cd loki-ts && bun test pr_lessons. Flag: LOKI_LESSONS_REJECTED=1. Tier MEDIUM.
269
+
270
+ ## Program 11: CROSS-VENDOR-JUDGE
271
+
272
+ Ground truth: B4 is `loki-ts/src/engine10/stages/xreview.ts`: opt-in only, `reviewProvider()` returns the provider from LOKI_REVIEW_PROVIDER or loki.yaml `review:`, else null (off); `minVerdict` can only downgrade; providers limited to "codex" | "claude" (ReviewProvider type); `ctx.provider` is the builder. There is no auto-selection and no "different from builder" rule, and the review can be set equal to the builder today. Gemini is deprecated (do not add it).
273
+
274
+ ### XV-1 Default to a different vendor when one is installed (MEDIUM, 30 min)
275
+ - Goal: when no explicit `review:` is set, `reviewProvider` returns the other vendor than `ctx.provider` if its CLI is on PATH and authenticated (reuse the preflight check in engine10/preflight.ts), else null (unchanged, off). Explicit setting always wins, including explicit `off`. Receipt records `review.provider`, `review.vendor_differs: true|false`, and when no other vendor is configured a NOT PROVEN line "judge shares builder vendor or none configured".
276
+ - File set: loki-ts/src/engine10/stages/xreview.ts (selection function only), loki-ts/src/engine10/stages/seal.ts (receipt field and NOT PROVEN line only; this edit touches the Seal receipt body, so tier is HIGH, see below), loki-ts/test/xreview.test.ts.
277
+ - Tests first: builder claude + codex available gives codex; builder codex + claude available gives claude; only one vendor gives null plus the NOT PROVEN line; explicit review: claude with builder claude is honored and flagged vendor_differs false; the verdict can still only be downgraded (existing minVerdict test stays green).
278
+ - Wall: never upgrade a verdict; reviewer argv stays read-only (reviewArgv untouched); fail-safe default unchanged (judge unavailable means not_run, not pass).
279
+ - Commands: cd loki-ts && bun test xreview seal; tsc.
280
+ - Flag: LOKI_XVENDOR_DEFAULT=1 (default on after review; the existing opt-in behaviour is the OFF state). Tier HIGH (touches seal.ts receipt body).
281
+
282
+ # Index (id, tier, estimated minutes, flag)
283
+
284
+ | ID | Tier | Min | Flag | Depends on |
285
+ |---|---|---|---|---|
286
+ | MCP-0 | LOW | 15 | none | none |
287
+ | MCP-A | MEDIUM | 30 | none | none |
288
+ | MCP-B | LOW | 15 | none | MCP-0 optional |
289
+ | MCP-C | MEDIUM | 30 | LOKI_MCP_2026_07 | MCP-0, MCP-A |
290
+ | MCP-D | HIGH | 30+review | LOKI_MCP_TASKS | MCP-C, OTEL-1 |
291
+ | OTEL-1 | MEDIUM | 30 | LOKI_OTEL_GENAI | none |
292
+ | OTEL-2 | HIGH | 30+review | via OTEL-1 | OTEL-1 |
293
+ | SARIF-1 | LOW | 15 | none | none |
294
+ | SARIF-2 | MEDIUM | 30 | none | SARIF-1 |
295
+ | SARIF-3 | MEDIUM | 30 | action input | SARIF-2 |
296
+ | SIGS-1 | HIGH | 30+review | --predicate slsa | none |
297
+ | SIGS-2 | HIGH | 30+review | action input | SIGS-1 |
298
+ | SIGS-DOC | LOW | 15 | none | none |
299
+ | MARK-1 | HIGH | 30+review | LOKI_AI_MARKING | none |
300
+ | MARK-2 | MEDIUM | 30 | none | none |
301
+ | MARK-3 | MEDIUM | 30 | none | MARK-1, MARK-2 |
302
+ | QF-1 | LOW | 15 | none | none |
303
+ | QF-2 | MEDIUM | 30 | LOKI_FORECAST | QF-1 |
304
+ | QF-3 | HIGH | 30+review | LOKI_QUOTA_CAP | QF-2 |
305
+ | VPR-1 | HIGH | 30+review | none | none |
306
+ | VPR-2 | HIGH | 30+review | LOKI_VERIFY_PR | VPR-1 |
307
+ | VPR-3 | HIGH | 30+review | action input | VPR-2 |
308
+ | FCR-1 | MEDIUM | 30 | none | B9-RAW-ARM merged |
309
+ | FCR-2 | MEDIUM | 30 | --arms | FCR-1 |
310
+ | FCR-3 | MEDIUM | 30 | --fcr | FCR-2 |
311
+ | UNDO-1 | MEDIUM | 30 | none | none |
312
+ | UNDO-2 | HIGH | 30+review | LOKI_UNDO | UNDO-1 |
313
+ | MC-1 | MEDIUM | 30 | none | 132-F3 |
314
+ | MC-2 | MEDIUM | 30 | LOKI_LESSONS_REJECTED | MC-1 |
315
+ | XV-1 | HIGH | 30+review | LOKI_XVENDOR_DEFAULT | none |