loki-mode 11.12.1 → 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 (114) hide show
  1. package/README.md +2 -2
  2. package/SKILL.md +3 -3
  3. package/VERSION +1 -1
  4. package/autonomy/grill.sh +3 -1
  5. package/autonomy/hooks/validate-bash.sh +51 -13
  6. package/autonomy/lib/backlog.py +18 -3
  7. package/autonomy/lib/chat.sh +117 -7
  8. package/autonomy/lib/claude-flags.sh +20 -0
  9. package/autonomy/lib/claude_permissions.py +40 -0
  10. package/autonomy/lib/done-recognition.sh +8 -4
  11. package/autonomy/lib/engine10-push.sh +56 -7
  12. package/autonomy/lib/prd-enrich.sh +4 -2
  13. package/autonomy/lib/proof-generator.py +21 -0
  14. package/autonomy/lib/proof-verify.py +109 -1
  15. package/autonomy/lib/trust_trajectory.py +139 -0
  16. package/autonomy/lib/voter-agents.sh +3 -1
  17. package/autonomy/lib/workspace.py +2 -3
  18. package/autonomy/loki +427 -74
  19. package/autonomy/quickstart.sh +21 -2
  20. package/autonomy/run.sh +55 -21
  21. package/autonomy/trigger-server.py +461 -32
  22. package/bin/loki +4 -1
  23. package/completions/_loki +1 -1
  24. package/completions/loki.bash +10 -2
  25. package/dashboard/__init__.py +1 -1
  26. package/dashboard/api_start.py +2 -2
  27. package/dashboard/build_supervisor.py +2 -0
  28. package/docs/CLI-REFERENCE.md +6 -4
  29. package/docs/DEPLOYMENT.md +12 -5
  30. package/docs/EVALUATING.md +13 -0
  31. package/docs/INSTALLATION.md +2 -2
  32. package/docs/SIGNED-RECEIPTS.md +7 -0
  33. package/docs/WORKSPACES.md +2 -2
  34. package/docs/cost-controls.md +26 -0
  35. package/docs/merge-queue.md +19 -0
  36. package/docs/sentry-intake.md +4 -0
  37. package/docs/slack.md +2 -1
  38. package/docs/trackers.md +12 -1
  39. package/docs/v10/BOARD.md +148 -123
  40. package/docs/v10/CLI-MODERN.md +5 -5
  41. package/docs/v10/DECISIONS.md +2 -0
  42. package/docs/v10/ENGINE.md +2 -0
  43. package/docs/v10/FAILURE-CLASSES.md +18 -0
  44. package/docs/v10/MODERNIZE.md +32 -1
  45. package/docs/v10/PROGRESS.md +7 -0
  46. package/loki-ts/data/finding-schema.json +2 -1
  47. package/loki-ts/dist/loki.js +1222 -1128
  48. package/magic/core/debate.py +27 -1
  49. package/mcp/__init__.py +1 -1
  50. package/package.json +2 -2
  51. package/packages/control-plane/dist/server.js +5895 -5292
  52. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  53. package/providers/claude.sh +6 -3
  54. package/providers/model_catalog.json +6 -0
  55. package/schemas/loki-yaml.schema.json +5 -0
  56. package/src/policies/claude_permissions.js +114 -0
  57. package/web-app/dist/assets/{AdminPage-DuT74pf5.js → AdminPage-OVzN6eLm.js} +1 -1
  58. package/web-app/dist/assets/{Avatar-BtgidR5a.js → Avatar-hCCrxrCZ.js} +1 -1
  59. package/web-app/dist/assets/{Badge-D2nt8G_I.js → Badge-CDcpkhbJ.js} +1 -1
  60. package/web-app/dist/assets/{Button-BKl2jOyb.js → Button-8mwWlhEu.js} +1 -1
  61. package/web-app/dist/assets/{CockpitPage-DaWr0EUX.js → CockpitPage-D8cf3u22.js} +1 -1
  62. package/web-app/dist/assets/{ComparePage-aIiNhxLr.js → ComparePage-CIgkbDRY.js} +1 -1
  63. package/web-app/dist/assets/{ErrorBoundary-C1Q7rV23.js → ErrorBoundary-99kJH9g2.js} +1 -1
  64. package/web-app/dist/assets/{EvidenceReceiptPanel-C-C0-tOx.js → EvidenceReceiptPanel-C9fj32eS.js} +1 -1
  65. package/web-app/dist/assets/{GitHubIssuesPanel-l3IaXDag.js → GitHubIssuesPanel-De43YQ_C.js} +1 -1
  66. package/web-app/dist/assets/{GitHubPRsPanel-DweLBgr5.js → GitHubPRsPanel-7g7ZTnkx.js} +1 -1
  67. package/web-app/dist/assets/{HomePage-B_KK7AvY.js → HomePage-CcNA24ny.js} +2 -2
  68. package/web-app/dist/assets/{LoginPage-CKS-KLdH.js → LoginPage-BYjlb-IK.js} +1 -1
  69. package/web-app/dist/assets/{MagicPage-Cl6CEp8J.js → MagicPage-C0Dwt9Na.js} +1 -1
  70. package/web-app/dist/assets/{MetricsPage-n9CPUaX0.js → MetricsPage-jDGmdcgg.js} +1 -1
  71. package/web-app/dist/assets/{NotFoundPage-D85eWn70.js → NotFoundPage-C_ZO8tLE.js} +1 -1
  72. package/web-app/dist/assets/{ProjectPage-CDN7LpSo.js → ProjectPage-B5wnurfQ.js} +3 -3
  73. package/web-app/dist/assets/{ProjectsPage-D4SDmU4-.js → ProjectsPage--EyKt5-D.js} +1 -1
  74. package/web-app/dist/assets/{SettingsPage-Dby6GnKm.js → SettingsPage-cB0lnfti.js} +1 -1
  75. package/web-app/dist/assets/{ShowcasePage-CgHxeqoU.js → ShowcasePage-Dl16FDkK.js} +1 -1
  76. package/web-app/dist/assets/{SystemSettingsPage-BaewGHlc.js → SystemSettingsPage-BmAXd4V2.js} +1 -1
  77. package/web-app/dist/assets/{TeamsPage-905MJyke.js → TeamsPage-BFkWVOZe.js} +1 -1
  78. package/web-app/dist/assets/{TemplatesPage-DMrUHcvF.js → TemplatesPage-Bf2kmEUM.js} +1 -1
  79. package/web-app/dist/assets/{TerminalOutput-BsbEbBYX.js → TerminalOutput-BItv9Wa6.js} +1 -1
  80. package/web-app/dist/assets/{activity-BuaXhBsC.js → activity-Df2Awg6I.js} +1 -1
  81. package/web-app/dist/assets/{bell-BfEQ71OG.js → bell-D-1ztTsJ.js} +1 -1
  82. package/web-app/dist/assets/{bot-DOGeYewg.js → bot-A4qgZsKi.js} +1 -1
  83. package/web-app/dist/assets/{check-zbjPpb3E.js → check-BPfFpF0c.js} +1 -1
  84. package/web-app/dist/assets/{chevron-left-DWTOgfFt.js → chevron-left-CfSJvmDi.js} +1 -1
  85. package/web-app/dist/assets/{circle-alert-BEPKfRzR.js → circle-alert-wx2d1dzb.js} +1 -1
  86. package/web-app/dist/assets/{clock-C_fX3OHo.js → clock-pQMai6l-.js} +1 -1
  87. package/web-app/dist/assets/{cloud-DUXHygXQ.js → cloud-DWL470r6.js} +1 -1
  88. package/web-app/dist/assets/{code-xml-BEVl_9Hw.js → code-xml-BaEQpQLZ.js} +1 -1
  89. package/web-app/dist/assets/{database-_a22uh7l.js → database-h-N7WkQN.js} +1 -1
  90. package/web-app/dist/assets/{dollar-sign-l2en7xfg.js → dollar-sign-B5oYiD27.js} +1 -1
  91. package/web-app/dist/assets/{file-code-corner-DItKl6H4.js → file-code-corner-fbTtTy0o.js} +1 -1
  92. package/web-app/dist/assets/{file-plus-BSk7qFMA.js → file-plus-PaF6HMo8.js} +1 -1
  93. package/web-app/dist/assets/{globe-2TveFE5l.js → globe-Ct-GlWID.js} +1 -1
  94. package/web-app/dist/assets/{hammer-BU6OJlQj.js → hammer-C1oZFX51.js} +1 -1
  95. package/web-app/dist/assets/{index-DGnZXUYk.js → index-C2egrRhz.js} +3 -3
  96. package/web-app/dist/assets/{layers-DKw7MNuq.js → layers-Dt5ZK4v2.js} +1 -1
  97. package/web-app/dist/assets/{loader-circle-CoYfykzD.js → loader-circle-DrpMziic.js} +1 -1
  98. package/web-app/dist/assets/{lock-D9JzrXDL.js → lock-DOez8MmK.js} +1 -1
  99. package/web-app/dist/assets/{package-BZtqTIqH.js → package-ClGIkerr.js} +1 -1
  100. package/web-app/dist/assets/{plus-BGJfo8bV.js → plus-C004i9ua.js} +1 -1
  101. package/web-app/dist/assets/{refresh-cw-F6lowBgR.js → refresh-cw-Ddfk-7Sy.js} +1 -1
  102. package/web-app/dist/assets/{rotate-ccw-DHOK8dM4.js → rotate-ccw-Bu1KgDjS.js} +1 -1
  103. package/web-app/dist/assets/{scroll-text-CKcROoMV.js → scroll-text-3q1lW5pm.js} +1 -1
  104. package/web-app/dist/assets/{server-DbG8MDv6.js → server-pd6x4HW1.js} +1 -1
  105. package/web-app/dist/assets/{shield-alert-RNKNXdJT.js → shield-alert-B9jGJepT.js} +1 -1
  106. package/web-app/dist/assets/{thumbs-up-Yxp-UBxS.js → thumbs-up-Cdcc9nQf.js} +1 -1
  107. package/web-app/dist/assets/{trash-2-DY-eba1n.js → trash-2-foSojXHK.js} +1 -1
  108. package/web-app/dist/assets/{trending-down-CARiDB3t.js → trending-down-CTTiqlJ1.js} +1 -1
  109. package/web-app/dist/assets/{trending-up-brQqWbA3.js → trending-up-B_MgmRAx.js} +1 -1
  110. package/web-app/dist/assets/{upload-D6wRjKhz.js → upload-g6BfALzG.js} +1 -1
  111. package/web-app/dist/assets/{usePolling-BMrqNbAI.js → usePolling-DrHwvzuh.js} +1 -1
  112. package/web-app/dist/assets/{user-CK5-EXIj.js → user-COp75m7l.js} +1 -1
  113. package/web-app/dist/index.html +1 -1
  114. package/autonomy/lib/doctor-fix.py +0 -279
@@ -6,12 +6,12 @@ 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
- - Registry paths (commands and nested subcommands): 193
14
+ - Registry paths (commands and nested subcommands): 194
15
15
 
16
16
  ## Commands
17
17
 
@@ -139,11 +139,11 @@ Classes: KEEP-MODERN (v10-native or engine-neutral), UPDATE (live but needs mode
139
139
  | trigger | autonomy/loki | DROP-LEGACY | Legacy engine |
140
140
  | failover | autonomy/loki | DROP-LEGACY | Legacy engine |
141
141
  | reset | autonomy/loki | DROP-LEGACY | Legacy engine |
142
- | merge | autonomy/loki | DROP-LEGACY | Legacy parallel mode |
142
+ | merge | autonomy/loki | DROP-LEGACY | Bash PR merge gate |
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' |
@@ -265,6 +265,7 @@ One entry per decision: context, choice, why, how to reverse. Newest last.
265
265
  - modernize/ gets its own cap of 4,000 lines in the same test: 25 planned modules (MODERNIZE.md section 13) at about 150 lines each plus 15% slack. M-24's view moves to mod/dashboard.ts. M-14 stays under 20 lines in wall.ts and calls into mod/oracle/.
266
266
  - Core never imports modernize/ (the cli.ts TABLE string is exempt), so the split cannot hide core code.
267
267
  - Hitting either cap means re-slice or delete, never raise. Ruled by the CTO (opus) on the Chief of Staff's request; implemented by E-76.
268
+ - 2026-10-15 (M-22/M-23 integration): loki-ts/src/util/ may host engine10 entry points and modernize helpers that would push modernize/ past its cap (util/modernize_unit.ts for remote unit jobs, util/python.ts for pytest running and parsing); they import engine10, engine10 core never imports them.
268
269
 
269
270
  ## D34. 2026-09-28: large tier is real upstream PRs, one size gate, legacy moves to M-27
270
271
 
@@ -582,6 +583,7 @@ The $20.00 default per-run cap stays. It is a hard stop on priced sessions only;
582
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.
583
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.
584
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.
585
587
 
586
588
  ## D78
587
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,6 +248,8 @@ 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), `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
+
251
253
  ## 6. Process topology and Rule of Two
252
254
 
253
255
  The process that reads untrusted issue text into an LLM context never holds a push token. The PR step runs as a separate process.
@@ -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).
@@ -381,7 +381,7 @@ The report never states more than the equivalence data proves. It is sealed and
381
381
  | M-20 | Wave verify: full build, integration and original suite | mod/wave.ts, T/wave.test.ts | MEDIUM | Wb T/wave.test.ts | M-17, M-19 |
382
382
  | M-21 | Wave ship: one PR per wave with unit receipts, draft unless all proven | mod/ship.ts, T/ship.test.ts | HIGH | Wb T/ship.test.ts | M-20 |
383
383
  | M-22 | Unit-level resume after coordinator crash | mod/resume.ts, T/resume.test.ts | MEDIUM | Wb T/resume.test.ts | M-17, E-39 |
384
- | M-23 | Remote units via POST /jobs kind unit, Helm worker.engine v10, local re-verify | autonomy/trigger-server.py (unit job kind only), deploy/helm/autonomi/templates/job-worker.yaml, deploy/helm/autonomi/values.yaml, mod/remote.ts, T/remote.test.ts, tests/test-trigger-server-unit-jobs.py | HIGH | python3 tests/test-trigger-server-unit-jobs.py && Wb T/remote.test.ts | M-17 |
384
+ | M-23 | Remote units via POST /jobs kind unit, Helm worker.engine v10, local re-verify | autonomy/trigger-server.py (unit job kind only), deploy/helm/autonomi/templates/job-worker.yaml, deploy/helm/autonomi/values.yaml, loki-ts/src/util/modernize_unit.ts, T/remote.test.ts, tests/test-trigger-server-unit-jobs.py | HIGH | python3 tests/test-trigger-server-unit-jobs.py && Wb T/remote.test.ts | M-17 |
385
385
  | M-24 | Dashboard /modernize view | loki-ts/src/engine10/dashboard/modernize.ts, loki-ts/src/engine10/dashboard/server.ts (one route), T/dashboard.test.ts | LOW | Wb T/dashboard.test.ts | M-01 |
386
386
  | M-25 | Final report and verdict (COMPLETE only if all proven), sealed | mod/report.ts, T/report.test.ts | HIGH | Wb T/report.test.ts | M-13, M-21 |
387
387
  | M-26 | End-to-end: py2 fixture repo modernized with stub provider | T/e2e.test.ts, T/fixtures/e2e_py2/ | MEDIUM | Wb T/e2e.test.ts | M-08, M-22, M-25 |
@@ -398,3 +398,34 @@ The report never states more than the equivalence data proves. It is sealed and
398
398
  - Red: the test file is missing or asserts the absent behavior.
399
399
  - Green: every assertion named in the goal holds.
400
400
  - Each HIGH slice needs a unanimous opus review (D12).
401
+
402
+ ## 14. Fan-out alignment: G-04 cloud dispatch and the M-23 unit job (G-05)
403
+
404
+ Both fan-outs hand one independent piece of work to a remote worker and accept the result only after the coordinator checks it. They share one shape so a single dispatcher can drive either.
405
+
406
+ **M-23 unit job schema** (POST /jobs, same bearer token as every job kind; the schema is closed and any other field is rejected with 400):
407
+
408
+ | Field | Bound | Required |
409
+ |---|---|---|
410
+ | `kind` | the literal `unit` | yes |
411
+ | `repo` | `owner/name`, at most 140 chars, no leading dash, no `.` or `..` segment | yes |
412
+ | `ref` | git ref, at most 200 chars, no `..`, no leading dash | yes |
413
+ | `unit` | unit id, `[A-Za-z0-9][A-Za-z0-9_.-]{0,127}`, never contains `~` | yes |
414
+ | `mid` | `mod-<utc>-<6 hex>` | no |
415
+ | `target` | `python3` or `java21` | no |
416
+
417
+ The worker runs `loki modernize unit --repo <repo> --ref <ref> --unit <unit>` (plus `--mid` and `--target` when given). It fetches repo@ref into a run-owned temp directory with the safe_git helpers, runs the unit there through the same unit runner as a local run, and removes the directory afterwards. A checkout failure, a runner failure or any verdict other than PROVEN exits nonzero with the reason on stderr; exit 2 means bad arguments or runners that are not wired yet.
418
+
419
+ **G-04 dispatch fields mapped onto it** (scripts/cloud-dispatch.sh, docs/v10/SWARM.md "Cloud dispatch"):
420
+
421
+ | G-04 field | M-23 field | Rule |
422
+ |---|---|---|
423
+ | slice id (`SLICE-ID`) | `unit` | Same unit-id charset; the id is the unit of fan-out and of overlap checks. |
424
+ | branch `cloud/<slice-id>` | `ref` | The worker works on this ref (G-04 also returns it); the coordinator never merges a ref it did not name. |
425
+ | repository of the checkout | `repo` | Always `owner/name`; no URL, no userinfo. |
426
+ | file set (overlap check) | the unit's own files | Resolved coordinator-side from plan.json before dispatch; never sent in the job. Overlap with in-flight work refuses the dispatch in both. |
427
+ | tier and governor max | scheduler `--workers` | Concurrency is the governor cap, not a job field. |
428
+ | cloud session id (BOARD note) | server job `id` | Recorded by the coordinator against the unit (events.jsonl for M-23, the BOARD row for G-04). |
429
+ | PR and check conclusion | local re-verify | The PR check result and the remote "passed" are claims. The coordinator re-verifies locally (equivalence check for a unit, required checks for a slice) and merges only if both agree. |
430
+
431
+ Shared rules: credentials are never in the payload (the token is an Authorization header for POST /jobs, and the cloud session uses its own login); an unobserved or unknown remote outcome is not a pass; a remote pass with a failing local re-verify never merges; dispatch refuses rather than guesses when the schema, the overlap check or the cap cannot be evaluated.
@@ -2383,3 +2383,10 @@ The swarm is stopped: .loki/V10-STOP exists, the loop has no wake-ups, and the c
2383
2383
  - 2026-10-15T23:56Z Dispatched 7 ready rows (FC-09r, CPE24-P2a, CPE24-P4a, CP-NITS1, FC-01b, FC-19b, CP-START); every one was already on main (fix commits are ancestors of HEAD, reviewers reran tests and mutations on main). BOARD rows were stale at ready; set to released. New FC-09s sibling row from the FC-09r review. M-17 r2 Opus HIGH APPROVED at d0437a578.
2384
2384
  - 2026-10-16T00:00Z Merged M-17 (4d2e9f5f1, Opus HIGH approved r2) and FC-09s (8bfddbe4d, Opus HIGH approved). Fixed the engine10 L7 guard hit (M-15 unit.ts comment said 'not recorded') and a scheduler test type error against the M-15 conformance type (tests field). Both fold into v11.12.0.
2385
2385
  - 2026-10-16T00:30Z v11.12.0 CI red on Linux (never published): full_env_spawn_guard, spawn_env_guard and model_output_regex_guard flagged the M-15/M-17 modernize unit.ts spawns, and the sitecustomize conformance test named a readdir-order-dependent file. Fixed with tokenFreeEnv on both spawns, sorted drift iteration, and a reasoned allowlist entry; shipping as v11.12.1. FC-09t r3 (064cb191b) held out of main on branch fc09t-wip after a second Opus BLOCK (# inside """ strings, \u escapes in quoted keys); r4 rework running. Factory-parity workflow wy3yizr98 building 40 FV slices plus COST-1/4/5 in 12 lanes; COST-2/3/6 parked (Engine Law L1, moat, paid eval).
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
+ - 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
+ - 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
  }