loki-mode 11.15.0 → 11.17.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 (98) hide show
  1. package/SKILL.md +3 -3
  2. package/VERSION +1 -1
  3. package/autonomy/grill.sh +3 -1
  4. package/autonomy/hooks/validate-bash.sh +51 -13
  5. package/autonomy/lib/chat.sh +111 -7
  6. package/autonomy/lib/claude-flags.sh +20 -0
  7. package/autonomy/lib/claude_permissions.py +40 -0
  8. package/autonomy/lib/done-recognition.sh +8 -4
  9. package/autonomy/lib/engine10-push.sh +30 -5
  10. package/autonomy/lib/prd-enrich.sh +4 -2
  11. package/autonomy/lib/proof-generator.py +5 -0
  12. package/autonomy/lib/proof-verify.py +109 -1
  13. package/autonomy/lib/trust_trajectory.py +13 -4
  14. package/autonomy/lib/voter-agents.sh +3 -1
  15. package/autonomy/loki +175 -26
  16. package/autonomy/quickstart.sh +21 -2
  17. package/autonomy/run.sh +16 -6
  18. package/autonomy/trigger-server.py +11 -5
  19. package/completions/loki.bash +2 -2
  20. package/dashboard/__init__.py +1 -1
  21. package/dashboard/api_start.py +2 -2
  22. package/dashboard/build_supervisor.py +2 -0
  23. package/docs/CLI-REFERENCE.md +2 -1
  24. package/docs/EVALUATING.md +1 -1
  25. package/docs/INSTALLATION.md +1 -1
  26. package/docs/v10/BOARD.md +25 -0
  27. package/docs/v10/CLI-MODERN.md +3 -3
  28. package/docs/v10/DECISIONS.md +1 -0
  29. package/docs/v10/ENGINE.md +1 -1
  30. package/docs/v10/FAILURE-CLASSES.md +18 -0
  31. package/docs/v10/PROGRESS.md +4 -0
  32. package/loki-ts/data/finding-schema.json +2 -1
  33. package/loki-ts/dist/loki.js +1135 -1114
  34. package/magic/core/debate.py +27 -1
  35. package/mcp/__init__.py +1 -1
  36. package/package.json +2 -2
  37. package/packages/control-plane/dist/server.js +3761 -3454
  38. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  39. package/providers/claude.sh +6 -3
  40. package/providers/model_catalog.json +6 -0
  41. package/src/policies/claude_permissions.js +114 -0
  42. package/web-app/dist/assets/{AdminPage-bZlvH4TL.js → AdminPage-OVzN6eLm.js} +1 -1
  43. package/web-app/dist/assets/{Avatar-BZrBstQe.js → Avatar-hCCrxrCZ.js} +1 -1
  44. package/web-app/dist/assets/{Badge-Q8l8r4Vq.js → Badge-CDcpkhbJ.js} +1 -1
  45. package/web-app/dist/assets/{Button-B8Bt0A3S.js → Button-8mwWlhEu.js} +1 -1
  46. package/web-app/dist/assets/{CockpitPage-CIYExrXa.js → CockpitPage-D8cf3u22.js} +1 -1
  47. package/web-app/dist/assets/{ComparePage-CBOmHdam.js → ComparePage-CIgkbDRY.js} +1 -1
  48. package/web-app/dist/assets/{ErrorBoundary-BKwDPSnK.js → ErrorBoundary-99kJH9g2.js} +1 -1
  49. package/web-app/dist/assets/{EvidenceReceiptPanel-KqzjphWl.js → EvidenceReceiptPanel-C9fj32eS.js} +1 -1
  50. package/web-app/dist/assets/{GitHubIssuesPanel-lF3GkHRv.js → GitHubIssuesPanel-De43YQ_C.js} +1 -1
  51. package/web-app/dist/assets/{GitHubPRsPanel-BCzipPWD.js → GitHubPRsPanel-7g7ZTnkx.js} +1 -1
  52. package/web-app/dist/assets/{HomePage-CIdnkzaN.js → HomePage-CcNA24ny.js} +2 -2
  53. package/web-app/dist/assets/{LoginPage-D-178nTT.js → LoginPage-BYjlb-IK.js} +1 -1
  54. package/web-app/dist/assets/{MagicPage-BmHuzMT8.js → MagicPage-C0Dwt9Na.js} +1 -1
  55. package/web-app/dist/assets/{MetricsPage-CPCiyDFn.js → MetricsPage-jDGmdcgg.js} +1 -1
  56. package/web-app/dist/assets/{NotFoundPage-B2T6n1gx.js → NotFoundPage-C_ZO8tLE.js} +1 -1
  57. package/web-app/dist/assets/{ProjectPage-DQmpFhb0.js → ProjectPage-B5wnurfQ.js} +3 -3
  58. package/web-app/dist/assets/{ProjectsPage-BmugzFEd.js → ProjectsPage--EyKt5-D.js} +1 -1
  59. package/web-app/dist/assets/{SettingsPage-ZB-RrmgM.js → SettingsPage-cB0lnfti.js} +1 -1
  60. package/web-app/dist/assets/{ShowcasePage-BAhwHt4_.js → ShowcasePage-Dl16FDkK.js} +1 -1
  61. package/web-app/dist/assets/{SystemSettingsPage-Bt7sf2Vu.js → SystemSettingsPage-BmAXd4V2.js} +1 -1
  62. package/web-app/dist/assets/{TeamsPage-B-v5j_8q.js → TeamsPage-BFkWVOZe.js} +1 -1
  63. package/web-app/dist/assets/{TemplatesPage-bdqUL-LG.js → TemplatesPage-Bf2kmEUM.js} +1 -1
  64. package/web-app/dist/assets/{TerminalOutput-CRHEXBwS.js → TerminalOutput-BItv9Wa6.js} +1 -1
  65. package/web-app/dist/assets/{activity-C-ROkmXt.js → activity-Df2Awg6I.js} +1 -1
  66. package/web-app/dist/assets/{bell-DbiCBxQA.js → bell-D-1ztTsJ.js} +1 -1
  67. package/web-app/dist/assets/{bot-DsIgE_qr.js → bot-A4qgZsKi.js} +1 -1
  68. package/web-app/dist/assets/{check-CkAdmHWP.js → check-BPfFpF0c.js} +1 -1
  69. package/web-app/dist/assets/{chevron-left-CYTLivAo.js → chevron-left-CfSJvmDi.js} +1 -1
  70. package/web-app/dist/assets/{circle-alert-BVIcAsFJ.js → circle-alert-wx2d1dzb.js} +1 -1
  71. package/web-app/dist/assets/{clock-Dg3Rq0go.js → clock-pQMai6l-.js} +1 -1
  72. package/web-app/dist/assets/{cloud-CenrqHFl.js → cloud-DWL470r6.js} +1 -1
  73. package/web-app/dist/assets/{code-xml-C2mvfoug.js → code-xml-BaEQpQLZ.js} +1 -1
  74. package/web-app/dist/assets/{database-BKa0_eCb.js → database-h-N7WkQN.js} +1 -1
  75. package/web-app/dist/assets/{dollar-sign-DfelUK1S.js → dollar-sign-B5oYiD27.js} +1 -1
  76. package/web-app/dist/assets/{file-code-corner-CZKWoHVg.js → file-code-corner-fbTtTy0o.js} +1 -1
  77. package/web-app/dist/assets/{file-plus-CZ-m1zMX.js → file-plus-PaF6HMo8.js} +1 -1
  78. package/web-app/dist/assets/{globe-S0kv_GwC.js → globe-Ct-GlWID.js} +1 -1
  79. package/web-app/dist/assets/{hammer-BW1MDdu1.js → hammer-C1oZFX51.js} +1 -1
  80. package/web-app/dist/assets/{index-ACEYsTc2.js → index-C2egrRhz.js} +3 -3
  81. package/web-app/dist/assets/{layers-BrXHYZ-L.js → layers-Dt5ZK4v2.js} +1 -1
  82. package/web-app/dist/assets/{loader-circle-DOdhKFx0.js → loader-circle-DrpMziic.js} +1 -1
  83. package/web-app/dist/assets/{lock-BcFTyg8J.js → lock-DOez8MmK.js} +1 -1
  84. package/web-app/dist/assets/{package-D34cMVQG.js → package-ClGIkerr.js} +1 -1
  85. package/web-app/dist/assets/{plus-CEaMeBxL.js → plus-C004i9ua.js} +1 -1
  86. package/web-app/dist/assets/{refresh-cw-D2Rzxr5U.js → refresh-cw-Ddfk-7Sy.js} +1 -1
  87. package/web-app/dist/assets/{rotate-ccw-C_-EjRLh.js → rotate-ccw-Bu1KgDjS.js} +1 -1
  88. package/web-app/dist/assets/{scroll-text-BSSCMI_c.js → scroll-text-3q1lW5pm.js} +1 -1
  89. package/web-app/dist/assets/{server-BKvLonWt.js → server-pd6x4HW1.js} +1 -1
  90. package/web-app/dist/assets/{shield-alert-DbbQbPdW.js → shield-alert-B9jGJepT.js} +1 -1
  91. package/web-app/dist/assets/{thumbs-up-NoBD1fUR.js → thumbs-up-Cdcc9nQf.js} +1 -1
  92. package/web-app/dist/assets/{trash-2-BXz8rAyd.js → trash-2-foSojXHK.js} +1 -1
  93. package/web-app/dist/assets/{trending-down-D8u535Re.js → trending-down-CTTiqlJ1.js} +1 -1
  94. package/web-app/dist/assets/{trending-up-q8k3kgiy.js → trending-up-B_MgmRAx.js} +1 -1
  95. package/web-app/dist/assets/{upload-Cp7_zeBI.js → upload-g6BfALzG.js} +1 -1
  96. package/web-app/dist/assets/{usePolling-CTHVdcuX.js → usePolling-DrHwvzuh.js} +1 -1
  97. package/web-app/dist/assets/{user-DF7bfSf_.js → user-COp75m7l.js} +1 -1
  98. package/web-app/dist/index.html +1 -1
@@ -97,6 +97,8 @@ _PROVIDER_AUTH_COMMANDS = {
97
97
  "cline": ("cline", "auth", "status"),
98
98
  }
99
99
  _PROVIDER_READINESS_COMMANDS = {
100
+ # P12-26b scoped out: fixed sandboxed printf probe that must run Bash; a restrictive
101
+ # policy would report a false provider-auth failure. Listed in the guard test.
100
102
  "claude": (
101
103
  "claude",
102
104
  "--dangerously-skip-permissions",
@@ -1,6 +1,6 @@
1
1
  # CLI reference
2
2
 
3
- Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.15.0. Do not edit by hand.
3
+ Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.17.1. Do not edit by hand.
4
4
  Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for the full inventory.
5
5
 
6
6
  | Command | Description |
@@ -159,3 +159,4 @@ Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for th
159
159
  | `loki metrics` | Metrics |
160
160
  | `loki sentrux` | Architecture sensor |
161
161
  | `loki magic` | Magic modules |
162
+ | `loki steer` | Nudge a running build |
@@ -225,7 +225,7 @@ One set of definitions for the effort and honesty numbers, used by the bench rep
225
225
  - Term misleading completion: Loki or the agent claimed done and was wrong. Bench name `false_completion` = (reported success and not accepted) / reported success. `loki trust` name `false_verified` = VERIFIED claims later FAILED / VERIFIED claims. Same idea, same denominator (claims of success). Null when nothing claimed success.
226
226
  - Term cost per accepted: total spend across ALL attempts, failures included, divided by accepted. Null when nothing was accepted, and null when any run's cost is unmeasured (a partial sum is not a total; the bench also reports a lower bound). Never zero for an unknown.
227
227
  - Interventions by type: counts of blocking pauses that waited on a person, split into `steer`, `input`, `authorization` and `repair` (a fixed enum, no free text). Written to `.loki/state/interventions.json` at the pause site; shown in `loki trust`, HANDOFF.md and the proof as `interventions_detail`. Absent means not recorded, not zero.
228
- - Waited versus active minutes: only `waited_s` is measured, the wall-clock seconds a run sat blocked on a person. It is an upper bound on human attention. Active minutes (time a person actually spent working) are NOT measured and are never reported. `loki trust` labels the figure "waited, upper bound".
228
+ - Waited versus active minutes: `waited_s` is the wall-clock seconds a run sat blocked on a person, an upper bound on human attention. `active_s` (in `interventions.json` and `interventions_detail`) is the measured time a person actually worked on steer, input, authorization and repair events, recorded only when both timestamps were measured. `loki trust` shows "Active minutes per accepted" only when every run measured it, otherwise "n/a (not measured)"; an unmeasured value is never reported as 0. Status: the runner does not yet write `active_s` (nothing calls `recordActiveSeconds`), so `loki trust` shows n/a until the writer slice lands. Only non-negative integers are accepted; a float or negative value is dropped as unmeasured.
229
229
  - Retries: iterations to completion, taken from the proof `iterations.count` (`loki trust` iterations axis). A retry is not an intervention.
230
230
 
231
231
  ---
@@ -2,7 +2,7 @@
2
2
 
3
3
  Loki Mode, by [Autonomi](https://www.autonomi.dev/), turns a spec or an issue into a verified pull request with a receipt you can check. This page covers installing it, a first run, and the options around it.
4
4
 
5
- **Version:** v11.15.0
5
+ **Version:** v11.17.1
6
6
 
7
7
  **Engine note:** `loki start` is the primary command. `loki start`, `loki "<task>"`, `loki owner/repo#N` and `loki quick` all run the Loki 10 engine, whatever the flag order or input form (PRD file, issue ref, task or one-word brief). The previous loop runs only on `--engine legacy`, `LOKI_ENGINE=legacy`, or for one call when a flag Loki 10 cannot honor is present. See the [user guide](v10/GUIDE.md) and the [5-minute quickstart](QUICKSTART.md).
8
8
 
package/docs/v10/BOARD.md CHANGED
@@ -44,6 +44,31 @@ merge (all touch trust-core or security-relevant surfaces), oldest first.
44
44
  |---|---|---|---|---|---|---|
45
45
  | PF-1 | pkill-scoping fix | main @ 9cd51d1a | autonomy/run.sh (kill_provider_child), tests/test-kill-provider-child-scoping.sh, docs/v10/DECISIONS.md (D15) | HIGH | released@2026-09-27T01:33Z | Founder-reported: every loki-mode session ending via signal (supervisor signal, double Ctrl+C, Ctrl+C in perpetual mode) ran an unscoped `pkill -f` matching ANY process on the machine by command-line substring, terminating unrelated Claude Code sessions. Fixed to scope by process group. Shipped as v9.54.1, ahead of the swarm queue. |
46
46
  | PF-2 | P7 scanner gap fix | main @ fa5de15f | tests/moat/p7-no-fabricated-data.sh | HIGH | released@2026-09-27T15:00Z | Round 5, unanimous 4/4 APPROVE under a corrected scoping rule (only a regression/false-positive/weakening introduced by the diff blocks; a pre-existing gap the diff doesn't worsen is a new slice, not a veto). Rebased onto current main, merged fa5de15f, pushed. 10 candidate follow-up slices recorded below (B-1..B-8 plus 2 more from the review). Shipped in v9.56.0 (merged before the 14:16:24Z release push of b651b98d; on npm 15:00:06Z). |
47
+ | P12-17 | Slack thread steer | main @ 2d333d158 | loki-ts/src/contrib/slack_inbound.ts + test | MEDIUM | released@2026-10-16T17:19Z | reviewed and merged; v11.16.0 was never published, shipped in v11.17.0 |
48
+ | P12-12 | stall watchdog | main @ 4c0ee6dbf | engine10 session, runner watchdog + tests | MEDIUM | released@2026-10-16T17:19Z | reviewed and merged; v11.16.0 was never published, shipped in v11.17.0 |
49
+ | P12-16 | chat commands | main @ 6d6f69f73 | autonomy/lib/chat.sh, tests/test-doctor-ux.sh | MEDIUM | released@2026-10-16T17:19Z | reviewed and merged; v11.16.0 was never published, shipped in v11.17.0 |
50
+ | P12-24 | doctor min claude version | main @ e6754c961 | doctor, compat manifest | LOW | released@2026-10-16T17:19Z | reviewed and merged; v11.16.0 was never published, shipped in v11.17.0 |
51
+ | P12-21 | per-stage cost | main @ 44c0810f2 | cost breakdown | MEDIUM | released@2026-10-16T17:19Z | reviewed and merged; v11.16.0 was never published, shipped in v11.17.0 |
52
+ | P12-31 | active human minutes | main @ 9e2604b95 | trust, proof | MEDIUM | released@2026-10-16T17:19Z | reviewed and merged; v11.16.0 was never published, shipped in v11.17.0 |
53
+ | P12-25 | provider isolation matrix | main @ 8c256963b | tests/providers, guard revert | MEDIUM | released@2026-10-16T17:19Z | reviewed and merged; v11.16.0 was never published, shipped in v11.17.0 |
54
+ | P12-03 | merge pinned to proven head | main @ b3ff4bb1d | merge, proofs | HIGH | released@2026-10-16T17:19Z | reviewed and merged; v11.16.0 was never published, shipped in v11.17.0 |
55
+ | P12-06 | council file:line anchors | main @ 40ee4c1a9 | council | MEDIUM | released@2026-10-16T17:19Z | reviewed and merged; v11.16.0 was never published, shipped in v11.17.0 |
56
+ | P12-04 | respond refuses moved head | main @ 6da9172e6 | verify-pr respond | HIGH | released@2026-10-16T17:19Z | reviewed and merged; v11.16.0 was never published, shipped in v11.17.0 |
57
+ | P12-07 | per-stage resume (07b-07g) | main @ f5c54cbb7 | engine10 resume, autonomy/loki start | HIGH | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
58
+ | P12-01 | Seal drift and receipt tamper checks (01b, 01c) | main @ f5c54cbb7 | loki verify, proofs | HIGH | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
59
+ | P12-26 | compiled Claude permission policy (26b, 26c) | main @ f5c54cbb7 | src/policies, launch sites | HIGH | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
60
+ | P12-09 | quota wait-then-rerun (09b) | main @ f5c54cbb7 | runner retry_class | MEDIUM | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
61
+ | P12-08 | work-item ids and lifecycle states (08b, 08c) | main @ f5c54cbb7 | engine10 state, loki status | MEDIUM | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
62
+ | P12-02 | post-Wall steer blocks Seal (02b, 02c) | main @ f5c54cbb7 | steer, seal | HIGH | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
63
+ | P12-03b | dirty-tree proof fails closed (03c, 03d) | main @ f5c54cbb7 | proofs | HIGH | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
64
+ | P12-05 | Wall holdout, off by default | main @ f5c54cbb7 | engine10 wall | HIGH | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
65
+ | P12-16b | chat /run reports only a live run | main @ f5c54cbb7 | autonomy/lib/chat.sh | MEDIUM | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
66
+ | P12-17b | Slack echo redaction | main @ f5c54cbb7 | contrib/slack | MEDIUM | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
67
+ | P12-23 | start flag parsing (23b) | main @ f5c54cbb7 | autonomy/loki | LOW | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
68
+ | P12-29 | configured Claude Code eval arm | main @ f5c54cbb7 | eval/loki10 | MEDIUM | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
69
+ | P12-30 | eval task families with hidden tests | main @ f5c54cbb7 | eval/loki10 | MEDIUM | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
70
+ | P12-40 | uncited-claim guard (40b) | main @ f5c54cbb7 | structural checks | LOW | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
71
+ | P12-CAP | engine10 core line cap | main @ f5c54cbb7 | tests | LOW | released@2026-10-16T17:19Z | v11.17.0, reviewed and merged |
47
72
 
48
73
  ## Fixed on main already (not slices; recorded for PO context)
49
74
 
@@ -6,9 +6,9 @@ Classes: KEEP-MODERN (v10-native or engine-neutral), UPDATE (live but needs mode
6
6
 
7
7
  ## Counts
8
8
 
9
- - KEEP-MODERN: 70
9
+ - KEEP-MODERN: 71
10
10
  - UPDATE: 22
11
- - DROP-LEGACY: 32
11
+ - DROP-LEGACY: 31
12
12
  - DELETE: 14
13
13
  - Total rows: 138
14
14
  - Registry paths (commands and nested subcommands): 194
@@ -143,7 +143,7 @@ Classes: KEEP-MODERN (v10-native or engine-neutral), UPDATE (live but needs mode
143
143
  | heal | autonomy/loki | DROP-LEGACY | Legacy engine |
144
144
  | migrate | autonomy/loki | DROP-LEGACY | Superseded by modernize |
145
145
  | dogfood | autonomy/loki | DROP-LEGACY | Legacy engine |
146
- | steer | autonomy/loki | DROP-LEGACY | Needs legacy prompt injection |
146
+ | steer | autonomy/loki | KEEP-MODERN | Session control |
147
147
  | outcomes | autonomy/loki | DROP-LEGACY | Legacy outcome store |
148
148
  | worktree | autonomy/loki | DROP-LEGACY | Legacy parallel mode |
149
149
  | wt | autonomy/loki | DELETE | Alias of worktree; shown only under 'loki help aliases' |
@@ -583,6 +583,7 @@ The $20.00 default per-run cap stays. It is a hard stop on priced sessions only;
583
583
  6. Cap: 90s small, 180s normal, LOKI_E10_WALL_LIMIT_S may override up to 300s, fixed before the session. A Wall timeout stays not_run, never red or already_satisfied, and Seal discloses it.
584
584
  7. Ships behind LOKI_E10_WALL_MANIFEST with a lift row (augmentiq#52 plus 2 brownfield tasks, manifest off versus on). Lower lift drops the change. Slices W1-S1..W1-S4 on BOARD; S1 to S3 touch the engine10 core and wait for core budget room.
585
585
 
586
+ 8. P12-05 holdout, behind LOKI_WALL_HOLDOUT_RATIO (default 0 = off, opt-in; founder decision C-C4 pending on the default ratio and block versus warn): a deterministic subset (sha256 of run id and test id, max(1, round(ratio*N)), none under 3 Wall tests) is kept outside the repo and runDir, copied in only by verify as blocking holdout:N checks, and its private store is removed when the run ends. Preconditions before C-C4 may enable it by default: (a) pin the holdout hashes outside the store (run memory or the sealed event) and check them at verify, because the manifest is self-attesting today; (b) drop targetDir from the manifest; (c) scrub first_error for holdout checks before it reaches the fix stage; (d) close the rmSync/mkdirSync symlink race on the shared OS tmp dir; (e) define resume, since the run-end cleanup deletes the store.
586
587
 
587
588
  ## D78
588
589
  2026-10-03T10:39Z, CoS (D69). GitHub push protection rejected train/94 because commit 04f62ff4e (SEC-SCAN-1) carried planted fake AWS key literals in tests/test-secret-scan.sh. Nothing in the range was on origin, so the 124 unpushed main commits were rewritten locally (filter-branch index-filter on that one file): each literal is split with an adjacent empty single-quoted string, so bash builds the same value and the scanner test still blocks it (6/0). The tree diff from the old head was that file only. This was not a force-push, and no protection bypass was requested. Commit SHAs cited on BOARD and PROGRESS for 10:25Z and earlier today, after a185ce16, are pre-rewrite and resolve only through the reflog. Rule: a test fixture never holds a scanner-matching secret literal, split it at write time.
@@ -248,7 +248,7 @@ Required keys: `type`, `stage` (null for run-level events), `ts` (ISO UTC, ms),
248
248
 
249
249
  Unknown is never 0. A missing cost is `usd: null`, and every reader renders null as "not measured".
250
250
 
251
- **Work-item state (one vocabulary).** `workItemState(events, nowMs?)` in `util/run_outputs.ts` (beside `phaseOf`) folds the log into one name per run, used by `loki status --json` (`state`), `phaseOf` (resume) and chat (which shells to status): `received` (run.started only), `prepared` (intake done), `planned` (plan done or wall seen), `executing` (implement running), `validating` (implement done, or verify/fix/commit/seal/pr/deep seen), `ready_to_ship` (receipt.sealed). Terminal states come only from run.completed: `completed`, `waiting_for_input` (verdict SPEC_CONFLICT), `budget_stopped` (cap.hit with verdict PARTIAL or FAILED), `failed`, `cancelled`. `stalled` needs the clock argument and 30 minutes without events on an unfinished run.
251
+ **Work-item state (one vocabulary).** `workItemState(events, nowMs?)` in `util/run_outputs.ts` (beside `phaseOf`) folds the log into one name per run, used by `loki status --json` (`state`), `phaseOf` (resume) and chat (which shells to status): `received` (run.started only), `prepared` (intake done), `planned` (plan done or wall seen), `executing` (implement running), `validating` (implement done, or verify/fix/commit/seal/pr/deep seen), `ready_to_ship` (receipt.sealed), `delivering` (pr.opened, written by the supervisor, run not yet complete), `observing` (delivering plus deep.started, the supervisor's detached post-PR deep verify is running). Terminal states come only from run.completed: `completed`, `waiting_for_input` (verdict SPEC_CONFLICT), `budget_stopped` (cap.hit with verdict PARTIAL or FAILED), `failed`, `cancelled`. `stalled` needs the clock argument and 30 minutes without events on an unfinished run.
252
252
 
253
253
  ## 6. Process topology and Rule of Two
254
254
 
@@ -795,3 +795,21 @@ L0 review rule (ENGINE-LAWS.md L0): a fix that adds an `if` or a regex about the
795
795
  - Mechanism: scripts/v10-worktree-reap.sh removes (non-force, by exact path) clean worktrees merged into origin/main or idle past 6h by HEAD reflog mtime and not on an active BOARD row; idle dirty ones are salvaged to wt-save/<name> first (node_modules and .rv deleted, loki-ts/dist discarded); detached unmerged HEADs get a wt-save ref; locked and fresh ones are kept. It runs after each main sync in train-cycle.sh and from .githooks/post-merge. scripts/v10-worktree-add.sh enforces the 40G floor (LOKI_WORKTREE_DISK_FLOOR_GB), reaping first. Pulse emits WORKTREE_SPRAWL above 20.
796
796
  - Fixture: tests/test-worktree-reap.sh (merged, idle, detached, dirty-idle, .rv, dist-only, dirty-fresh, locked, fresh, BOARD-held, floor refusal, pulse 20 vs 21).
797
797
  - Known limits: a locked worktree whose owning agent is dead is kept (the reaper cannot tell dead from alive, so it never touches a locked one); and slice worktrees created by the agent harness bypass the disk floor unless the dispatcher creates them through scripts/v10-worktree-add.sh.
798
+
799
+ ## FC-100 The merge gate accepted a proof not bound to the PR head (MERGE-HEAD-PIN)
800
+ - User saw: a PR could merge on a VERIFIED verdict that was earned by a different commit than the one merged (last-proof-id pointed at whatever ran last, and gh pr merge named no expected head).
801
+ - Law: a verdict binds to the exact bytes it judged; the merge must prove the head it lands equals the head that was proven.
802
+ - Cause (measured): _merge_pr_gated read .loki/state/last-proof-id.txt without comparing facts.git.head_sha to the PR headRefOid, and called gh pr merge without --match-head-commit; a scan that stopped at the first matching proof let an older VERIFIED override a newer NOT_PROVEN.
803
+ - Siblings swept: verify-pr respond headRefOid compare (P12-04, loki-ts); the queue path shares _merge_pr_gated and is pinned too.
804
+ - Mechanism: the gate reads headRefOid, requires every clean (non-dirty) proof for that head to agree on VERIFIED, refuses with gate: head when none exists or the head is unreadable or moved, and merges with --match-head-commit.
805
+ - Fixture: tests/test-loki-merge-queue.sh (pin flag, stale proof, proof resolved by head, older VERIFIED vs newer NOT_PROVEN, dirty proof, unreadable head, head moved).
806
+ - Known limits: a proof without facts.git.head_sha never matches (fails closed); dirty is ignoring .loki/ only.
807
+
808
+ ## FC-101 A receipt field the writer always emits was treated as optional, so deleting it passed as UNSIGNED (RECEIPT-FIELD-OPTIONAL)
809
+ - User saw: a hand-edited receipt with events_sha256, time or time.stages removed (or set to null or a string) verified as UNSIGNED, and --allow-unsigned accepted it.
810
+ - Law: a verifier may treat a field as optional only if some writer omits it; absence of an always-written field is evidence of editing, never a pass.
811
+ - Cause (measured): checkEventLog returned null when events_sha256 was not a string, and the P12-01b stages check accepted any non-object time; seal.ts has written both fields since ad80fd4e6.
812
+ - Siblings swept: the group receipt (seal_group.ts), Python proof receipts and control-plane fixtures never carry these fields and are not gated; signed receipts already cover both fields through receipt_sha256 and the attestation. The control-plane verify fixture (packages/control-plane/test/server/verify.test.ts signed()) and the undo_plan, undo_apply and workspace e2e receipt/1 fixtures are gated and now carry seal-shaped fields (empty-log hash with zero stages).
813
+ - Mechanism: verify_cmd.ts checkEventLog, for schema loki.v10.receipt/1 only, returns TAMPERED naming the missing field (events_sha256 not 64-char lowercase hex, time absent or null, time.stages not a plain object) and ends "Re-run the task to produce a fresh receipt."
814
+ - Fixture: loki-ts/tests/engine10/verify_cmd.test.ts P12-01c (field missing, malformed hash, time removed with stages at top level, time null, stages string, stages array, honest zero-stage receipt stays UNSIGNED); hand-built receipt/1 fixtures in seal_group, log_seal and visual_evidence tests now carry both fields.
815
+ - Known limits: a receipt with a schema variant or no schema field falls to the ungated path and reads UNSIGNED (its receipt_sha256 still must match, and signed ones are covered by the attestation).
@@ -2386,3 +2386,7 @@ The swarm is stopped: .loki/V10-STOP exists, the loop has no wake-ups, and the c
2386
2386
  - 2026-10-16T01:20Z v11.13.0: fast-forwarded main to fv-train 79a127fa9 (12 factory-parity lanes, FC-09t r5, M-20 wave verify; Opus integration review APPROVED, engine10 2291/0, tsc 0). 43 BOARD rows released; FV-gh-steer-4 and FV-pr-loop-4 back to ready. M-22 approved, M-23 in Opus round 2; both merge next.
2387
2387
  - 2026-10-16T02:04Z v11.14.0: v11.13.0 never published (credentialed_push_guard red: verify-pr respond pushed with its own token). Fixed by routing respond through engine10-push.sh push-pr with origin read once before the fixer runs (Opus HIGH approved r3 after two BLOCKs). Merged M-21 wave ship, M-22 unit resume, M-23 remote units and G-05, FV-pr-loop-4 and FV-gh-steer-4, fv-train follow-ups; engine10 core trimmed to 4946 lines. Guards 158/0, engine10+util 2523 pass (31 route-matrix fails are local TMPDIR-only, green in CI).
2388
2388
  - 2026-10-16T02:40Z v11.15.0: v11.14.0 never published (CI red: route matrix packages link, merge-queue gh PATH and stat order, FC-89 marker); all four fixed. Shipped M-25 sealed final report (row 379 released), resume adopts only landed merges (mutation-checked 18/1 red, 19/0 green), modernize coordinator wiring (Opus round 2 approve; real runs still exit 2 naming four missing pieces), modernize trim 4107 to 3792. Gates: shell 14/14 rc 0, bun guard set 640/1 then L0 allowlist entry dropped (3/0), tsc 0.
2389
+ - 2026-10-16T15:20Z v11.16.0: merged P12-17 Slack steer (2d333d158), P12-12 stall watchdog (4c0ee6dbf), P12-16 chat commands (6d6f69f73) on top of P12-14/04/N3-N4/15/20/24/06/03/31/21/25; budget.test 33/0, tsc 0 errors (outside control-plane). P12-26, P12-07, P12-29, P12-30 sent back on BLOCK; P12-01 in Opus re-review.
2390
+ - 2026-10-16T17:19Z v11.17.0: cut at f5c54cbb7 after Tests run 38936426289 passed. Ships everything written under v11.16.0 (never published: four CI guard reds, all fixed) plus engine-plan slices P12-07 resume, P12-01 Seal drift and tamper, P12-26 compiled permission policy, P12-09 quota rerun, P12-08 lifecycle, P12-02 post-Wall steer, P12-03b dirty-tree proofs, P12-05 holdout (off), P12-16b, P12-17b, P12-23, P12-29, P12-30, P12-40, P12-CAP. Queued after release: P12-07h, P12-09c, P12-12/25, P12-30b, P12-16c (all approved); P12-26d in HIGH re-review; P12-01d building.
2391
+ - 2026-10-16T17:52Z v11.17.0 never published (help-drift guard red); fixed f0aae2698. Tests on 4ade347be then red on model_output_regex_guard (session.ts baseline 6 vs 4 after P12-12d); fixed f80f2a3f7, Tests pending. v11.17.1 cuts on green. Approved and queued for v11.17.2: P12-07i, 07j, 30c, 30e, 02c+02d, 26e, 12e. In review: P12-02e, 16f, 26f (HIGH). Building: P12-30d, 07k, 01e.
2392
+ - 2026-10-16T18:06Z v11.17.1: cut at f80f2a3f7 after Tests run 38942790682 passed. First publish of the v11.16.0 and v11.17.0 content plus P12-01d, 07h, 09c, 12/25, 12c/12d, 26d, 16c-16e, 30b and the help/guard fixes. Queued for v11.17.2: 07j, 07m (2a6a4b196), 30d (with 30e), 02f or 02g (HIGH review), 26e or 26f (HIGH review), 12e, 16f, M-MOD, 07k, 01e. Building: 07n heartbeat.
@@ -63,7 +63,8 @@
63
63
  "description": {
64
64
  "type": "string",
65
65
  "minLength": 1,
66
- "maxLength": 2000
66
+ "maxLength": 2000,
67
+ "description": "What is wrong. CRITICAL and HIGH issues should cite path:line (e.g. src/a.ts:42); uncited ones are downgraded to MEDIUM."
67
68
  }
68
69
  }
69
70
  }