loki-mode 10.7.1 → 10.9.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 (185) hide show
  1. package/README.md +2 -2
  2. package/SKILL.md +2 -2
  3. package/VERSION +1 -1
  4. package/autonomy/loki +20 -32
  5. package/autonomy/run.sh +9 -5
  6. package/autonomy/tui.sh +5 -1
  7. package/dashboard/__init__.py +1 -1
  8. package/dashboard/api_phases.py +1 -1
  9. package/dashboard/api_start.py +0 -1
  10. package/dashboard/server.py +28 -146
  11. package/docs/COCKPIT-SPEC.md +3 -1
  12. package/docs/DASHBOARD-9.12-EVIDENCE.md +1 -1
  13. package/docs/DASHBOARD-ARCHITECTURE.md +13 -11
  14. package/docs/DASHBOARD_V2_CHECKLIST.md +2 -0
  15. package/docs/INSTALLATION.md +12 -11
  16. package/docs/MERGE-DEDUP-MAP.md +1 -1
  17. package/docs/MERGE-ROUTE-MAP.md +1 -1
  18. package/docs/MERGE3-PLAN.md +2 -2
  19. package/docs/R3-COST-OBSERVABILITY-DESIGN.md +2 -2
  20. package/docs/R4-TRUST-TRAJECTORY-DESIGN.md +1 -1
  21. package/docs/R5-AUTO-WIKI-DESIGN.md +1 -1
  22. package/docs/R6-ROLLBACK-CHECKPOINT-PLAN.md +1 -1
  23. package/docs/RARV-C-100X-PLAN.md +3 -3
  24. package/docs/SONNET5-DEFAULT-PLAN.md +2 -2
  25. package/docs/SYNERGY-TASKS.md +1 -1
  26. package/docs/TOOL-INTEGRATION.md +1 -1
  27. package/docs/TOP-100-BACKLOG.md +1 -1
  28. package/docs/alternative-installations.md +1 -1
  29. package/docs/architecture/ADR-001-runtime-migration.md +1 -1
  30. package/docs/architecture/DASHBOARD_V2_ARCHITECTURE.md +2 -0
  31. package/docs/audit-logging.md +2 -0
  32. package/docs/authentication.md +2 -0
  33. package/docs/authorization.md +2 -0
  34. package/docs/certification/02-enterprise-features/lab.md +2 -0
  35. package/docs/certification/02-enterprise-features/lesson.md +2 -0
  36. package/docs/certification/04-production-deployment/lab.md +2 -0
  37. package/docs/certification/04-production-deployment/lesson.md +2 -0
  38. package/docs/control-plane-migration.md +97 -0
  39. package/docs/dashboard-guide.md +6 -7
  40. package/docs/dev/release-checklist.md +9 -11
  41. package/docs/enterprise/integration-cookbook.md +2 -0
  42. package/docs/enterprise/migration.md +1 -1
  43. package/docs/enterprise/performance.md +3 -1
  44. package/docs/enterprise/sdk-guide.md +2 -0
  45. package/docs/enterprise/security.md +2 -0
  46. package/docs/plans/FORGE-AUTONOMOUS-QUEUE.md +2 -2
  47. package/docs/research-2026-07/OBSERVABILITY-TOOL-SPEC.md +1 -1
  48. package/docs/retrospectives/v7.5.15-honesty-audit.md +2 -2
  49. package/docs/test-scenarios/enterprise-scenarios.md +2 -2
  50. package/docs/v10/ARCHITECT-CUTS.md +9 -9
  51. package/docs/v10/BACKLOG.md +7 -7
  52. package/docs/v10/BOARD.md +25 -25
  53. package/docs/v10/CONTROL-PLANE.md +4 -4
  54. package/docs/v10/CP-ENTERPRISE-UI.md +270 -9
  55. package/docs/v10/D51-PHASE-B.md +1 -1
  56. package/docs/v10/DECISIONS.md +3 -3
  57. package/docs/v10/DEPS.md +10 -10
  58. package/docs/v10/FAILURE-CLASSES.md +66 -1
  59. package/docs/v10/LEGACY-REMOVAL.md +2 -2
  60. package/docs/v10/METRICS.md +6 -0
  61. package/docs/v10/SWARM.md +2 -2
  62. package/loki-ts/data/model-pricing.json +6 -6
  63. package/loki-ts/dist/cockpit.js +11 -11
  64. package/loki-ts/dist/loki.js +819 -809
  65. package/loki-ts/package.json +1 -1
  66. package/magic/core/design_tokens.py +1 -2
  67. package/magic/core/generator.py +2 -2
  68. package/magic/tokens/README.md +1 -3
  69. package/mcp/__init__.py +1 -1
  70. package/package.json +3 -8
  71. package/packages/control-plane/dist/server.js +17954 -5696
  72. package/packages/control-plane/drizzle/0004_cpe03_local_repos_actions.sql +17 -0
  73. package/packages/control-plane/drizzle/meta/0004_snapshot.json +542 -0
  74. package/packages/control-plane/drizzle/meta/_journal.json +9 -2
  75. package/packages/control-plane/package.json +4 -1
  76. package/packages/control-plane/src/db/schema.ts +19 -0
  77. package/packages/control-plane/src/server/app.ts +11 -22
  78. package/packages/control-plane/src/server/audit.ts +15 -0
  79. package/packages/control-plane/src/server/auth.ts +7 -1
  80. package/packages/control-plane/src/server/legacy/routes-audit.ts +50 -0
  81. package/packages/control-plane/src/server/legacy/routes-control.ts +26 -0
  82. package/packages/control-plane/src/server/legacy/routes-memory.ts +30 -0
  83. package/packages/control-plane/src/server/legacy/routes-metrics.ts +18 -0
  84. package/packages/control-plane/src/server/legacy/routes.ts +237 -0
  85. package/packages/control-plane/src/server/legacy/shim.ts +201 -0
  86. package/packages/control-plane/src/server/repos.ts +27 -0
  87. package/packages/control-plane/src/server/routes/artifacts.ts +104 -0
  88. package/packages/control-plane/src/server/routes/audit.ts +17 -0
  89. package/packages/control-plane/src/server/routes/checkpoints.ts +171 -0
  90. package/packages/control-plane/src/server/routes/config.ts +319 -0
  91. package/packages/control-plane/src/server/routes/control.ts +75 -0
  92. package/packages/control-plane/src/server/routes/cost.ts +70 -0
  93. package/packages/control-plane/src/server/routes/cost_ledger.ts +210 -0
  94. package/packages/control-plane/src/server/routes/fleet.ts +101 -0
  95. package/packages/control-plane/src/server/routes/index.ts +71 -0
  96. package/packages/control-plane/src/server/routes/integrations.ts +123 -0
  97. package/packages/control-plane/src/server/routes/memory.ts +219 -0
  98. package/packages/control-plane/src/server/routes/merge_risk.ts +209 -0
  99. package/packages/control-plane/src/server/routes/metrics.ts +93 -0
  100. package/packages/control-plane/src/server/routes/notify.ts +48 -0
  101. package/packages/control-plane/src/server/routes/providers.ts +111 -0
  102. package/packages/control-plane/src/server/routes/session_control.ts +155 -0
  103. package/packages/control-plane/src/server/routes/start.ts +39 -0
  104. package/packages/control-plane/src/server/routes/stats.ts +76 -0
  105. package/packages/control-plane/src/server/routes/stream.ts +85 -0
  106. package/packages/control-plane/src/server/routes/verify.ts +66 -0
  107. package/packages/control-plane/src/server/spawn.ts +79 -0
  108. package/packages/control-plane/src/shipper/discover.ts +19 -1
  109. package/packages/control-plane/ui/dist/assets/index-BQbFv65M.css +1 -0
  110. package/packages/control-plane/ui/dist/assets/index-Dbhu244h.js +155 -0
  111. package/packages/control-plane/ui/dist/index.html +2 -2
  112. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  113. package/references/magic-modules-patterns.md +2 -2
  114. package/skills/factory-operations.md +3 -3
  115. package/skills/magic-modules.md +1 -1
  116. package/skills/release-cadence.md +1 -1
  117. package/tools/audit-docs.py +1 -1
  118. package/tools/index-codebase.py +1 -1
  119. package/web-app/dist/assets/{AdminPage-BJSU5hY1.js → AdminPage-DqMnfZrH.js} +1 -1
  120. package/web-app/dist/assets/{Avatar-CSOSpw9c.js → Avatar-BEof29du.js} +1 -1
  121. package/web-app/dist/assets/{Badge-COr7vj0D.js → Badge-WD53OL5m.js} +1 -1
  122. package/web-app/dist/assets/{Button-DGoWFERp.js → Button-Rzk5flhU.js} +1 -1
  123. package/web-app/dist/assets/{CockpitPage-CBpWkNXY.js → CockpitPage-Bqz3PCMh.js} +1 -1
  124. package/web-app/dist/assets/{ComparePage-BwT8vqrL.js → ComparePage-Byo2NzAZ.js} +1 -1
  125. package/web-app/dist/assets/{ErrorBoundary-D7SicDDA.js → ErrorBoundary-BuE0kH3W.js} +1 -1
  126. package/web-app/dist/assets/{EvidenceReceiptPanel-bx-5liG2.js → EvidenceReceiptPanel-CKFHOPBx.js} +1 -1
  127. package/web-app/dist/assets/{GitHubIssuesPanel-BAeeWLqY.js → GitHubIssuesPanel-Df_kTMqI.js} +1 -1
  128. package/web-app/dist/assets/{GitHubPRsPanel-CssD8lGI.js → GitHubPRsPanel-CouvcKrZ.js} +1 -1
  129. package/web-app/dist/assets/{HomePage-SL5PT3m5.js → HomePage-dEpLzj0x.js} +2 -2
  130. package/web-app/dist/assets/{LoginPage-C8hFOZOM.js → LoginPage-6DVjUND5.js} +1 -1
  131. package/web-app/dist/assets/{MagicPage-xHbHkrPf.js → MagicPage-BDQ9MOfY.js} +1 -1
  132. package/web-app/dist/assets/{MetricsPage-B_2CKFcC.js → MetricsPage-CXiJ04G_.js} +1 -1
  133. package/web-app/dist/assets/{NotFoundPage-CXwXMq35.js → NotFoundPage-BaXhZvyj.js} +1 -1
  134. package/web-app/dist/assets/{ProjectPage-AaisMQI-.js → ProjectPage-BzE4V7Ti.js} +3 -3
  135. package/web-app/dist/assets/{ProjectsPage-Cej5ResX.js → ProjectsPage-ipf6TLMX.js} +1 -1
  136. package/web-app/dist/assets/{SettingsPage-DKv4mn9H.js → SettingsPage-BDxkUKN6.js} +1 -1
  137. package/web-app/dist/assets/{ShowcasePage-Dkiyzne4.js → ShowcasePage-YQXD72SM.js} +1 -1
  138. package/web-app/dist/assets/{SystemSettingsPage-DaBLQ5dU.js → SystemSettingsPage-Dou7zHS0.js} +1 -1
  139. package/web-app/dist/assets/{TeamsPage-B2yUr31k.js → TeamsPage-CQarfcYr.js} +1 -1
  140. package/web-app/dist/assets/{TemplatesPage-CfYiANhU.js → TemplatesPage-CPi1R8Xj.js} +1 -1
  141. package/web-app/dist/assets/{TerminalOutput-CMXoexLM.js → TerminalOutput-WiGhWdYD.js} +1 -1
  142. package/web-app/dist/assets/{activity-B0dzoZtY.js → activity-DOa7ejQA.js} +1 -1
  143. package/web-app/dist/assets/{bell-DFOTaSoo.js → bell-CX-VAlYN.js} +1 -1
  144. package/web-app/dist/assets/{bot-Dz-WSQyP.js → bot-EDXaZmHc.js} +1 -1
  145. package/web-app/dist/assets/{check-L1QIRueJ.js → check-CnBdKk3L.js} +1 -1
  146. package/web-app/dist/assets/{chevron-left-1TrnIEZS.js → chevron-left-BJ_ydRQW.js} +1 -1
  147. package/web-app/dist/assets/{circle-alert-8Bf6xEDx.js → circle-alert-tz8ufhc_.js} +1 -1
  148. package/web-app/dist/assets/{clock-DB8NE6P5.js → clock-DFBZPSsH.js} +1 -1
  149. package/web-app/dist/assets/{cloud-DUSL3wZS.js → cloud-uy3p_5Q7.js} +1 -1
  150. package/web-app/dist/assets/{code-xml-DbjryWNl.js → code-xml-3CbYD9YL.js} +1 -1
  151. package/web-app/dist/assets/{database-DrezrMSs.js → database-YiNBXc9c.js} +1 -1
  152. package/web-app/dist/assets/{dollar-sign-CGbaLMzR.js → dollar-sign-D0wBa4Cv.js} +1 -1
  153. package/web-app/dist/assets/{file-code-corner-Dfypa-r4.js → file-code-corner-DDdZVZ5v.js} +1 -1
  154. package/web-app/dist/assets/{file-plus-CzV5L2Gd.js → file-plus-D09LTBqt.js} +1 -1
  155. package/web-app/dist/assets/{globe-BoYjTwPQ.js → globe-BirTPwff.js} +1 -1
  156. package/web-app/dist/assets/{hammer-WO-HuiyJ.js → hammer-DaE5qgnd.js} +1 -1
  157. package/web-app/dist/assets/{index-CjIOUjnd.js → index-D8t7KnQf.js} +3 -3
  158. package/web-app/dist/assets/{layers-Bn6jtKNk.js → layers-DVVrckRY.js} +1 -1
  159. package/web-app/dist/assets/{loader-circle-gERWRnmW.js → loader-circle-2-nMGmcb.js} +1 -1
  160. package/web-app/dist/assets/{lock-BIiMLJq8.js → lock-D0Xj43pC.js} +1 -1
  161. package/web-app/dist/assets/{package-dLvDSVys.js → package-BB7S3egm.js} +1 -1
  162. package/web-app/dist/assets/{plus-BHM3ZLhZ.js → plus-BLhoMrn3.js} +1 -1
  163. package/web-app/dist/assets/{refresh-cw-BAp_alv6.js → refresh-cw-DMc2uPLw.js} +1 -1
  164. package/web-app/dist/assets/{rotate-ccw-CBhwq_MG.js → rotate-ccw-DM3IP9x7.js} +1 -1
  165. package/web-app/dist/assets/{scroll-text-DoS-6dfU.js → scroll-text-lH2uW7rB.js} +1 -1
  166. package/web-app/dist/assets/{server-5JgdDWQO.js → server-BkerZcdR.js} +1 -1
  167. package/web-app/dist/assets/{shield-alert-DjmlLT34.js → shield-alert-B8ohcUfu.js} +1 -1
  168. package/web-app/dist/assets/{thumbs-up-BtiEXl3p.js → thumbs-up-CTIxLzPD.js} +1 -1
  169. package/web-app/dist/assets/{trash-2-ClsWU_Vg.js → trash-2-C3zIpsH5.js} +1 -1
  170. package/web-app/dist/assets/{trending-down-DPS4M7_X.js → trending-down-BTT7wV4Y.js} +1 -1
  171. package/web-app/dist/assets/{trending-up-D6OJ38-V.js → trending-up-BzHdCDvF.js} +1 -1
  172. package/web-app/dist/assets/{upload-DOCzLUpF.js → upload-HxR34-A8.js} +1 -1
  173. package/web-app/dist/assets/{usePolling-CljQTWj_.js → usePolling-DDj6Fupy.js} +1 -1
  174. package/web-app/dist/assets/{user-C0G82Weu.js → user-qH5y9yNy.js} +1 -1
  175. package/web-app/dist/index.html +1 -1
  176. package/dashboard/static/assets/mermaid.min.js +0 -2030
  177. package/dashboard/static/cost.html +0 -344
  178. package/dashboard/static/favicon.svg +0 -5
  179. package/dashboard/static/index.html +0 -15577
  180. package/dashboard/static/proofs.html +0 -194
  181. package/dashboard/static/start.html +0 -131
  182. package/dashboard/static/trust.html +0 -325
  183. package/packages/control-plane/src/server/actions.ts +0 -60
  184. package/packages/control-plane/ui/dist/assets/index-DHDI_dHM.css +0 -1
  185. package/packages/control-plane/ui/dist/assets/index-DaQr0MPS.js +0 -129
@@ -62,7 +62,8 @@ L0 review rule (ENGINE-LAWS.md L0): a fix that adds an `if` or a regex about the
62
62
  - fix.ts:63 escalation gate;
63
63
  - implement.ts:56 limit;
64
64
  - the plan stage on the "fast" tier;
65
- - no effort field in SessionRunOptions.
65
+ - no effort field in SessionRunOptions;
66
+ - `loki start prd.md` still goes to the legacy run.sh route, whose default is sonnet (providers/claude.sh CLAUDE_DEFAULT_DEVELOPMENT).
66
67
  - Mechanism: a catalog best_default plus a top tier for each provider (EL-W0-06, EL-W0-07), and a size gate on the artifact (EL-W0-05).
67
68
  - Fixture: a unit test that the default run.started.model equals the catalog best_default, plus a parity replay row.
68
69
 
@@ -125,6 +126,18 @@ L0 review rule (ENGINE-LAWS.md L0): a fix that adds an `if` or a regex about the
125
126
  - Mechanism: one runner-config registry for each runner. Any added or changed file that it names (configs, preloads, setup files, conftest) caps the verdict below VERIFIED, with NOT PROVEN naming the file.
126
127
  - Fixture: a stub-provider repro for each runner (bun preload, vitest setupFiles, jest moduleNameMapper, pytest conftest).
127
128
 
129
+ ## FC-10 Live line truncated to ~20 columns on a pty with no size
130
+ - User saw: on a pty with no column size (script -q, CI, tmux before a resize, IDE terminals) the quiet-mode live status line was cut to about 20 characters, for example "[implement] implemen". Raw: the stage events were complete; only the rendering was wrong.
131
+ - Law: L7 (outputs are contracts).
132
+ - Siblings (every terminal width read, with its old fallback):
133
+ - loki-ts/src/engine10/supervisor.ts:334 passed process.stdout.columns straight to LiveLine (undefined or 0);
134
+ - loki-ts/src/e10ext/liveline.ts:35 used Math.max(20, (columns ?? 80) - 1), so 0 became 20 (the bug);
135
+ - loki-ts/src/cockpit/cli.ts:73 used columns || $COLUMNS || 0 with no 80 default and accepted widths of 5 or more;
136
+ - autonomy/tui.sh:27 used `tput cols || echo 80`, which accepts tput printing 0 or nothing;
137
+ - packages/*/src: no terminal width reads.
138
+ - Mechanism: one shared terminalWidth() helper (loki-ts/src/util/term_width.ts): a finite columns >= 40, else a valid $COLUMNS >= 40, else 80. Every TS read goes through it and the bash read applies the same rule.
139
+ - Fixture: loki-ts/tests/engine10/term_width.test.ts (columns undefined, 0 and 20 give >= 80; the live line shows the full "[implement] implementing" text; a guard fails on any raw .columns read in src outside the helper).
140
+
128
141
  ## FC-11 Repo-wide structural guards went red after slices passed narrowed reviews
129
142
  - User saw: nothing yet; the 10.7.1 train was blocked on main 51e02b229 (2 failures in the full loki-ts bun test).
130
143
  - Law: L7 (the release is a contract), and the D44 gate.
@@ -143,3 +156,55 @@ L0 review rule (ENGINE-LAWS.md L0): a fix that adds an `if` or a regex about the
143
156
  - the shipper imports in e10ext/ship_hook.ts and commands/control.ts, which have no external deps today but share the same path.
144
157
  - Mechanism: one `postinstall` in loki-ts/package.json installs packages/control-plane from its frozen lockfile, so every loki-ts install (CI, Docker, local) gets the sibling's deps. No per-workflow steps.
145
158
  - Fixture: a clean `git worktree add` at HEAD, then `bun install --frozen-lockfile && bun run build` in loki-ts, and again with `--production`. Both exit 0 and the dist is byte-identical to the committed one; without the postinstall the build exits 1 with the error above.
159
+
160
+ ## FC-13 Tests pin a data value that a correct change is allowed to move
161
+ - User saw: nothing; the full loki-ts bun test on merged main ca9b85b7f had 5 red in "budget: cache token pricing" after MW-1 correctly moved sonnet from 3/15/0.3/3.75 to 2/10/0.2/2.5. The expected totals (0.6617, 3.0) and tiers were literals, so the price change read as a cost bug. The MW-1 review was approved on the slice's own suites, without the full bun test (an FC-11 sibling).
162
+ - Law: L7 (the release is a contract); a guard must fail on wrong behavior, not on a legitimate data change.
163
+ - Siblings:
164
+ - tests/dashboard/test_api_cost_cache.py stubs its own table, so it stays consistent, but its docstring says the other routes return 0.6617, which is stale (cosmetic);
165
+ - tests/test-pricing-parity.sh (MW-1) compares routes against model-pricing.json, the correct shape;
166
+ - the codex and gpt rows drift between run.sh and budget.ts (rv-mw1 follow-up), which is the same file-is-the-source rule.
167
+ - Mechanism: arithmetic tests derive expectations from the single pricing source (loki-ts/data/model-pricing.json) and assert the loaded table equals the file; only the fixture token counts are literal. Pricing-table changes run the full bun test in main before the train (FC-11 mechanism).
168
+ - Fixture: loki-ts/test/budget_cache_pricing.test.ts at 0de0838e1, 8 pass 0 fail; "cache tiers survive loading" compares the loaded PRICING with the file (loader mutation not yet run; follow-up).
169
+
170
+ ## FC-14 A nested sandbox trusts an inherited pointer to the real environment
171
+ - User saw: running the test runner truncated the founder real ~/.loki/keys/receipt-ed25519.pem. A fixture wrote through an inherited LOKI_REAL_HOME that still named the real home while HOME was a stand-in.
172
+ - Law: L2 (trust fails closed).
173
+ - Siblings:
174
+ - loki_hermetic_home_enter (tests/lib/hermetic-home.sh) took LOKI_REAL_HOME from the environment;
175
+ - loki-ts/tests/preload.ts used LOKI_REAL_HOME ?? HOME;
176
+ - run_runner in tests/test-e154-e155-guards.sh kept the exported LOKI_REAL_HOME;
177
+ - the outer E-154 key check compared names only, so truncating an existing key was invisible.
178
+ - Mechanism: derive the real path from the current HOME, never from an inherited variable (enter unsets LOKI_REAL_HOME, preload reads HOME); the key check fingerprints name, size and mtime.
179
+ - Fixture: tests/test-e154-e155-guards.sh (run_runner strips the pointers; t-keys writes only the runner-derived stand-in). A decoy-pointer probe and a bun HOME probe are owed after Oct 7 (B3, phase D vacuity).
180
+
181
+ ## FC-15 A run judges "already done" against Loki's own unmerged work
182
+ - User saw: FireLater#17 rerun on 10.7.1 (e10-20261003T185853Z-2d44) reported ALREADY_SATISFIED in 2m07s for $0.52. That was false. The run branched from the checked-out loki/e10-20261003T150744Z-59b1 (eda184e). That branch was the earlier FAILED run's unmerged draft PR #25, which also lacks the route edits the old scope control reverted.
183
+ - Law: L4 (the base is a contract), L2 (trust fails closed).
184
+ - Founder rule (2026-10-03):
185
+ - Base precedence: an explicit CLI flag (add `--base` if none exists), then the loki.yaml base_branch setting (a branch name, `current` or `default`), then the user's checked-out branch.
186
+ - The repo default branch is used only when it is configured as `default`. Never hardcode "main" (L0).
187
+ - The start line prints `base: <branch> (<flag, config or checkout>)`.
188
+ - The PR target is the configured target, else the repo default branch, and the PR body names it.
189
+ - Siblings: every outcome that compares against the base (ALREADY_SATISFIED, the Wall base run, the scope diff, the receipt delta).
190
+ - Mechanism:
191
+ - Detect Loki's own unmerged work on the base from its run records (the loki/e10-* branch plus the run receipt), not from a branch-name regex.
192
+ - Report "this branch already has run <id>'s unmerged work (PR #N, <state>); resume or review it", never ALREADY_SATISFIED.
193
+ - A dirty or foreign checkout is noted in the output.
194
+ - Fixture: owed. A repo whose checkout is a prior run's branch with a receipt must yield the unmerged-work outcome.
195
+
196
+ ## FC-16 ALREADY_SATISFIED with zero Loki-executed checks
197
+ - User saw: the same run had verify "checks": [] and changed_files []. The verdict rested only on the implement agent's self-report ("10/10 named impacted tests pass ... via npx vitest run").
198
+ - Law: L0 and L3 (the model never grades its own work), L5; Seal accuracy.
199
+ - Siblings: every outcome that is reachable with an empty checks list.
200
+ - Mechanism:
201
+ - A success-class outcome requires harness-executed evidence against the target base: the impacted tests run through the Project Model commands, plus each acceptance point of the issue checked.
202
+ - With zero executed checks the outcome is NOT VERIFIED.
203
+ - Fixture: owed. A verify with checks [] and a self-reported pass must yield NOT VERIFIED.
204
+
205
+ ## FC-17 The Wall spends time and money and writes nothing
206
+ - User saw: the same run's Wall produced "files": [] in 1m42s, with base_run 0/0/0. This is the D82-WALL0 class again.
207
+ - Law: L5 (no work without evidence), cost.
208
+ - Siblings: D82-WALL0 and any stage that can finish with zero artifacts and still bill.
209
+ - Mechanism: if the Wall cannot write a check, it skips in under 10s with a NOT PROVEN note and never runs a model session to an empty result.
210
+ - Fixture: owed. A repo with no runnable test command yields a Wall skip under 10s with NOT PROVEN.
@@ -66,7 +66,7 @@ Evidence: `grep -rn autonomy/|providers/` over loki-ts/src/engine10, packages/co
66
66
  | loki-ts/src/runner, commands, providers (v8 loop) | PORT subset | engine10 imports runner/github_token, types, retry_class, providers, budget; providers/claude_flags, mcp_config; delete the rest |
67
67
  | council/, quality gates scripts, swarm/, agents/ | DELETE (6e) | no engine10 refs |
68
68
  | dashboard/ (Python) | KEEP until D56 flip, then DELETE | D57 item 3 |
69
- | dashboard-ui/ | KEEP until D56 flip, then DELETE | same |
69
+ | legacy-ui/ | KEEP until D56 flip, then DELETE | same |
70
70
  | engine10/dashboard | KEEP until D56 flip | engine10/cli.ts TABLE |
71
71
  | web-app/ (Purple Lab) | DELETE | no engine10 or CP ref; 55k lines |
72
72
  | mcp/ | DELETE (6d) | mcp/server.py has 0 engine10 calls; loki-ts refs are v8 runner only |
@@ -94,7 +94,7 @@ Wall check for every slice: v10 suite, Bun Parity (redefined in W2-01), first-ru
94
94
  10. W2-10 providers/*.sh (~3k).
95
95
  11. W2-11 autonomy/run.sh, autonomy/loki, autonomy/lib except KEEP rows (~125k). Last code slice; depends on 01, 02, 08, 09.
96
96
  12. W2-12 legacy docs/ plans and wiki pages (~1000 mentions).
97
- 13. W2-13 dashboard/ + dashboard-ui/ (~113k), only after D56 default flip.
97
+ 13. W2-13 dashboard/ + legacy-ui/ (~113k), only after D56 default flip.
98
98
 
99
99
  ## 5. Guard spec (D57 item 4)
100
100
 
@@ -579,3 +579,9 @@ Raw rows: ~/loki-ci-logs/d50-{raw-haiku,raw-sonnet,v10-haiku,v10-sonnet}/results
579
579
  | pub-humanize-174 | 0/3 | 2/3 |
580
580
  | aiq-52-searchbar (no_change_needed) | 0/3 | 2/3 |
581
581
  Two of the four baseline losses were noise; two are real. Internal measurement, not for publication until the fixes are re-measured.
582
+
583
+ ## Cost rate re-baseline (MW-1)
584
+ | Date | Model | Input $/MTok | Output $/MTok | Cache read | Cache write 5m | Context | Source |
585
+ | --- | --- | --- | --- | --- | --- | --- | --- |
586
+ | 2026-10-03 | claude-sonnet-5-5 (and claude-sonnet-5, now the standard price) | 2 (was 3 in loki-ts/data/model-pricing.json) | 10 (was 15) | 0.20 | 2.50 | 1M, standard pricing | platform.claude.com/docs/en/about-claude/pricing, read 2026-10-03 |
587
+ Cost per completed task for sonnet arms measured before this date used the old 3/15 table; they overstate by 1.5x and are not comparable without rescaling.
package/docs/v10/SWARM.md CHANGED
@@ -159,8 +159,8 @@ shrink for pending), `CHANGELOG.md`, `docs/v10/BACKLOG.md`,
159
159
 
160
160
  **Generated bundles** (never edited by hand by a builder; the Captain
161
161
  rebuilds all three after every merge that could touch their sources):
162
- `loki-ts/dist/loki.js` (from `loki-ts/src`), `dashboard/static/index.html`
163
- and `dashboard-ui/dist` (from `dashboard-ui/scripts/build-standalone.js` and
162
+ `loki-ts/dist/loki.js` (from `loki-ts/src`), `legacy-ui-static/index.html`
163
+ and `legacy-ui/dist` (from `legacy-ui/scripts/build-standalone.js` and
164
164
  components), `web-app/dist` (from `web-app/src`).
165
165
 
166
166
  **Cross-wave exclusion:** a promise chain only serializes within one
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema_version": 1,
3
3
  "_comment": "Rolling pricing table consumed by loki-ts/src/runner/budget.ts. Update this file when Anthropic / OpenAI / others publish new prices; no code change required. Pricing is USD per 1 million tokens. Aliases (opus/sonnet/haiku) point to the latest model of that family per providers/model_catalog.json.",
4
- "_updated": "2026-06-30",
5
- "_source": "https://www.anthropic.com/pricing + provider docs. sonnet=claude-sonnet-5 (list $3/$15; intro $2/$10 through 2026-08-31). opus=claude-opus-5. codex=gpt-5.3-codex standard tier. Cache tiers: read 0.1x input, write 1.25x input (Anthropic + OpenAI published multipliers).",
4
+ "_updated": "2026-10-03",
5
+ "_source": "https://www.anthropic.com/pricing + provider docs. sonnet=claude-sonnet-5 and claude-sonnet-5-5, both $2/$10 per MTok (the Sonnet 5 intro price became the standard price; the 2026-09-01 increase to $3/$15 will not occur), cache write 5m $2.50, cache read $0.20, 1M context at standard pricing (platform.claude.com/docs/en/about-claude/pricing, read 2026-10-03). opus=claude-opus-5. codex=gpt-5.3-codex standard tier. Cache tiers: read 0.1x input, write 1.25x input (Anthropic + OpenAI published multipliers).",
6
6
  "pricing": {
7
7
  "fable": {
8
8
  "input": 10.0,
@@ -17,10 +17,10 @@
17
17
  "cache_write": 6.25
18
18
  },
19
19
  "sonnet": {
20
- "input": 3.0,
21
- "output": 15.0,
22
- "cache_read": 0.3,
23
- "cache_write": 3.75
20
+ "input": 2.0,
21
+ "output": 10.0,
22
+ "cache_read": 0.2,
23
+ "cache_write": 2.5
24
24
  },
25
25
  "haiku": {
26
26
  "input": 1.0,
@@ -1,19 +1,19 @@
1
1
  // @bun
2
- var EJ=Object.defineProperty;var TJ=(J)=>J;function WJ(J,Q){this[J]=TJ.bind(null,Q)}var FJ=(J,Q)=>{for(var X in Q)EJ(J,X,{get:Q[X],enumerable:!0,configurable:!0,set:WJ.bind(Q,X)})};var BJ=(J,Q)=>()=>(J&&(Q=J(J=0)),Q);var F=import.meta.require;var qJ={};FJ(qJ,{initWasm:()=>mJ,Resvg:()=>dJ});function Y(J){if(_===T.length)T.push(T.length+1);let Q=_;return _=T[Q],T[Q]=J,Q}function A(J){return T[J]}function OJ(J){if(J<132)return;T[J]=_,_=J}function W(J){let Q=A(J);return OJ(J),Q}function b(){if(j===null||j.byteLength===0)j=new Uint8Array(D.memory.buffer);return j}function g(J,Q,X){if(X===void 0){let K=y.encode(J),P=Q(K.length,1)>>>0;return b().subarray(P,P+K.length).set(K),h=K.length,P}let Z=J.length,$=Q(Z,1)>>>0,G=b(),q=0;for(;q<Z;q++){let K=J.charCodeAt(q);if(K>127)break;G[$+q]=K}if(q!==Z){if(q!==0)J=J.slice(q);$=X($,Z,Z=q+J.length*3,1)>>>0;let K=b().subarray($+q,$+Z),P=jJ(J,K);q+=P.written,$=X($,Z,q,1)>>>0}return h=q,$}function i(J){return J===void 0||J===null}function N(){if(x===null||x.byteLength===0)x=new Int32Array(D.memory.buffer);return x}function w(J,Q){return J=J>>>0,DJ.decode(b().subarray(J,J+Q))}function xJ(J,Q){if(!(J instanceof Q))throw Error(`expected instance of ${Q.name}`);return J.ptr}function _J(J,Q){try{return J.apply(this,Q)}catch(X){D.__wbindgen_exn_store(Y(X))}}async function vJ(J,Q){if(typeof Response==="function"&&J instanceof Response){if(typeof WebAssembly.instantiateStreaming==="function")try{return await WebAssembly.instantiateStreaming(J,Q)}catch(Z){if(J.headers.get("Content-Type")!="application/wasm")console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",Z);else throw Z}let X=await J.arrayBuffer();return await WebAssembly.instantiate(X,Q)}else{let X=await WebAssembly.instantiate(J,Q);if(X instanceof WebAssembly.Instance)return{instance:X,module:J};else return X}}function bJ(){let J={};return J.wbg={},J.wbg.__wbg_new_28c511d9baebfa89=function(Q,X){let Z=Error(w(Q,X));return Y(Z)},J.wbg.__wbindgen_memory=function(){let Q=D.memory;return Y(Q)},J.wbg.__wbg_buffer_12d079cc21e14bdb=function(Q){let X=A(Q).buffer;return Y(X)},J.wbg.__wbg_newwithbyteoffsetandlength_aa4a17c33a06e5cb=function(Q,X,Z){let $=new Uint8Array(A(Q),X>>>0,Z>>>0);return Y($)},J.wbg.__wbindgen_object_drop_ref=function(Q){W(Q)},J.wbg.__wbg_new_63b92bc8671ed464=function(Q){let X=new Uint8Array(A(Q));return Y(X)},J.wbg.__wbg_values_839f3396d5aac002=function(Q){let X=A(Q).values();return Y(X)},J.wbg.__wbg_next_196c84450b364254=function(){return _J(function(Q){let X=A(Q).next();return Y(X)},arguments)},J.wbg.__wbg_done_298b57d23c0fc80c=function(Q){return A(Q).done},J.wbg.__wbg_value_d93c65011f51a456=function(Q){let X=A(Q).value;return Y(X)},J.wbg.__wbg_instanceof_Uint8Array_2b3bbecd033d19f6=function(Q){let X;try{X=A(Q)instanceof Uint8Array}catch($){X=!1}return X},J.wbg.__wbindgen_string_get=function(Q,X){let Z=A(X),$=typeof Z==="string"?Z:void 0;var G=i($)?0:g($,D.__wbindgen_malloc,D.__wbindgen_realloc),q=h;N()[Q/4+1]=q,N()[Q/4+0]=G},J.wbg.__wbg_new_16b304a2cfa7ff4a=function(){return Y([])},J.wbg.__wbindgen_string_new=function(Q,X){let Z=w(Q,X);return Y(Z)},J.wbg.__wbg_push_a5b05aedc7234f9f=function(Q,X){return A(Q).push(A(X))},J.wbg.__wbg_length_c20a40f15020d68a=function(Q){return A(Q).length},J.wbg.__wbg_set_a47bac70306a19a7=function(Q,X,Z){A(Q).set(A(X),Z>>>0)},J.wbg.__wbindgen_throw=function(Q,X){throw Error(w(Q,X))},J}function yJ(J,Q){}function wJ(J,Q){return D=J.exports,KJ.__wbindgen_wasm_module=Q,x=null,j=null,D}async function KJ(J){if(D!==void 0)return D;if(typeof J>"u")J=new URL("index_bg.wasm",void 0);let Q=bJ();if(typeof J==="string"||typeof Request==="function"&&J instanceof Request||typeof URL==="function"&&J instanceof URL)J=fetch(J);yJ(Q);let{instance:X,module:Z}=await vJ(await J,Q);return wJ(X,Z)}function pJ(J){return Object.prototype.hasOwnProperty.call(J,"fontBuffers")}var D,T,_,h=0,j=null,y,jJ,x=null,DJ,$J,p=class J{static __wrap(Q){Q=Q>>>0;let X=Object.create(J.prototype);return X.__wbg_ptr=Q,$J.register(X,X.__wbg_ptr,X),X}__destroy_into_raw(){let Q=this.__wbg_ptr;return this.__wbg_ptr=0,$J.unregister(this),Q}free(){let Q=this.__destroy_into_raw();D.__wbg_bbox_free(Q)}get x(){return D.__wbg_get_bbox_x(this.__wbg_ptr)}set x(Q){D.__wbg_set_bbox_x(this.__wbg_ptr,Q)}get y(){return D.__wbg_get_bbox_y(this.__wbg_ptr)}set y(Q){D.__wbg_set_bbox_y(this.__wbg_ptr,Q)}get width(){return D.__wbg_get_bbox_width(this.__wbg_ptr)}set width(Q){D.__wbg_set_bbox_width(this.__wbg_ptr,Q)}get height(){return D.__wbg_get_bbox_height(this.__wbg_ptr)}set height(Q){D.__wbg_set_bbox_height(this.__wbg_ptr,Q)}},GJ,hJ=class J{static __wrap(Q){Q=Q>>>0;let X=Object.create(J.prototype);return X.__wbg_ptr=Q,GJ.register(X,X.__wbg_ptr,X),X}__destroy_into_raw(){let Q=this.__wbg_ptr;return this.__wbg_ptr=0,GJ.unregister(this),Q}free(){let Q=this.__destroy_into_raw();D.__wbg_renderedimage_free(Q)}get width(){return D.renderedimage_width(this.__wbg_ptr)>>>0}get height(){return D.renderedimage_height(this.__wbg_ptr)>>>0}asPng(){try{let $=D.__wbindgen_add_to_stack_pointer(-16);D.renderedimage_asPng($,this.__wbg_ptr);var Q=N()[$/4+0],X=N()[$/4+1],Z=N()[$/4+2];if(Z)throw W(X);return W(Q)}finally{D.__wbindgen_add_to_stack_pointer(16)}}get pixels(){let Q=D.renderedimage_pixels(this.__wbg_ptr);return W(Q)}},fJ,uJ=class{__destroy_into_raw(){let J=this.__wbg_ptr;return this.__wbg_ptr=0,fJ.unregister(this),J}free(){let J=this.__destroy_into_raw();D.__wbg_resvg_free(J)}constructor(J,Q,X){try{let P=D.__wbindgen_add_to_stack_pointer(-16);var Z=i(Q)?0:g(Q,D.__wbindgen_malloc,D.__wbindgen_realloc),$=h;D.resvg_new(P,Y(J),Z,$,i(X)?0:Y(X));var G=N()[P/4+0],q=N()[P/4+1],K=N()[P/4+2];if(K)throw W(q);return this.__wbg_ptr=G>>>0,this}finally{D.__wbindgen_add_to_stack_pointer(16)}}get width(){return D.resvg_width(this.__wbg_ptr)}get height(){return D.resvg_height(this.__wbg_ptr)}render(){try{let Z=D.__wbindgen_add_to_stack_pointer(-16);D.resvg_render(Z,this.__wbg_ptr);var J=N()[Z/4+0],Q=N()[Z/4+1],X=N()[Z/4+2];if(X)throw W(Q);return hJ.__wrap(J)}finally{D.__wbindgen_add_to_stack_pointer(16)}}toString(){let J,Q;try{let $=D.__wbindgen_add_to_stack_pointer(-16);D.resvg_toString($,this.__wbg_ptr);var X=N()[$/4+0],Z=N()[$/4+1];return J=X,Q=Z,w(X,Z)}finally{D.__wbindgen_add_to_stack_pointer(16),D.__wbindgen_free(J,Q,1)}}innerBBox(){let J=D.resvg_innerBBox(this.__wbg_ptr);return J===0?void 0:p.__wrap(J)}getBBox(){let J=D.resvg_getBBox(this.__wbg_ptr);return J===0?void 0:p.__wrap(J)}cropByBBox(J){xJ(J,p),D.resvg_cropByBBox(this.__wbg_ptr,J.__wbg_ptr)}imagesToResolve(){try{let Z=D.__wbindgen_add_to_stack_pointer(-16);D.resvg_imagesToResolve(Z,this.__wbg_ptr);var J=N()[Z/4+0],Q=N()[Z/4+1],X=N()[Z/4+2];if(X)throw W(Q);return W(J)}finally{D.__wbindgen_add_to_stack_pointer(16)}}resolveImage(J,Q){try{let $=D.__wbindgen_add_to_stack_pointer(-16),G=g(J,D.__wbindgen_malloc,D.__wbindgen_realloc),q=h;D.resvg_resolveImage($,this.__wbg_ptr,G,q,Y(Q));var X=N()[$/4+0],Z=N()[$/4+1];if(Z)throw W(X)}finally{D.__wbindgen_add_to_stack_pointer(16)}}},lJ,c=!1,mJ=async(J)=>{if(c)throw Error("Already initialized. The `initWasm()` function can be used only once.");await lJ(await J),c=!0},dJ;var VJ=BJ(()=>{T=Array(128).fill(void 0);T.push(void 0,null,!0,!1);_=T.length;y=typeof TextEncoder<"u"?new TextEncoder("utf-8"):{encode:()=>{throw Error("TextEncoder not available")}},jJ=typeof y.encodeInto==="function"?function(J,Q){return y.encodeInto(J,Q)}:function(J,Q){let X=y.encode(J);return Q.set(X),{read:J.length,written:X.length}};DJ=typeof TextDecoder<"u"?new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0}):{decode:()=>{throw Error("TextDecoder not available")}};if(typeof TextDecoder<"u")DJ.decode();$J=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((J)=>D.__wbg_bbox_free(J>>>0)),GJ=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((J)=>D.__wbg_renderedimage_free(J>>>0)),fJ=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((J)=>D.__wbg_resvg_free(J>>>0));lJ=KJ,dJ=class extends uJ{constructor(J,Q){if(!c)throw Error("Wasm has not been initialized. Call `initWasm()` function.");let X=Q?.font;if(!!X&&pJ(X)){let Z={...Q,font:{...X,fontBuffers:void 0}};super(J,JSON.stringify(Z),X.fontBuffers)}else super(J,JSON.stringify(Q))}}});function U(J){return String(J??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function HJ(J,Q,X){let Z=X/512;return`<g transform="translate(${J},${Q}) scale(${Z})">
2
+ var zD=Object.defineProperty;var FD=(D)=>D;function HD(D,J){this[D]=FD.bind(null,J)}var BD=(D,J)=>{for(var Q in J)zD(D,Q,{get:J[Q],enumerable:!0,configurable:!0,set:HD.bind(J,Q)})};var ID=(D,J)=>()=>(D&&(J=D(D=0)),J);var F=import.meta.require;var qD={};BD(qD,{initWasm:()=>pD,Resvg:()=>nD});function A(D){if(_===W.length)W.push(W.length+1);let J=_;return _=W[J],W[J]=D,J}function U(D){return W[D]}function xD(D){if(D<132)return;W[D]=_,_=D}function z(D){let J=U(D);return xD(D),J}function b(){if(j===null||j.byteLength===0)j=new Uint8Array(G.memory.buffer);return j}function n(D,J,Q){if(Q===void 0){let K=y.encode(D),N=J(K.length,1)>>>0;return b().subarray(N,N+K.length).set(K),h=K.length,N}let X=D.length,Z=J(X,1)>>>0,$=b(),q=0;for(;q<X;q++){let K=D.charCodeAt(q);if(K>127)break;$[Z+q]=K}if(q!==X){if(q!==0)D=D.slice(q);Z=Q(Z,X,X=q+D.length*3,1)>>>0;let K=b().subarray(Z+q,Z+X),N=_D(D,K);q+=N.written,Z=Q(Z,X,q,1)>>>0}return h=q,Z}function i(D){return D===void 0||D===null}function P(){if(x===null||x.byteLength===0)x=new Int32Array(G.memory.buffer);return x}function w(D,J){return D=D>>>0,GD.decode(b().subarray(D,D+J))}function hD(D,J){if(!(D instanceof J))throw Error(`expected instance of ${J.name}`);return D.ptr}function uD(D,J){try{return D.apply(this,J)}catch(Q){G.__wbindgen_exn_store(A(Q))}}async function yD(D,J){if(typeof Response==="function"&&D instanceof Response){if(typeof WebAssembly.instantiateStreaming==="function")try{return await WebAssembly.instantiateStreaming(D,J)}catch(X){if(D.headers.get("Content-Type")!="application/wasm")console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",X);else throw X}let Q=await D.arrayBuffer();return await WebAssembly.instantiate(Q,J)}else{let Q=await WebAssembly.instantiate(D,J);if(Q instanceof WebAssembly.Instance)return{instance:Q,module:D};else return Q}}function wD(){let D={};return D.wbg={},D.wbg.__wbg_new_28c511d9baebfa89=function(J,Q){let X=Error(w(J,Q));return A(X)},D.wbg.__wbindgen_memory=function(){let J=G.memory;return A(J)},D.wbg.__wbg_buffer_12d079cc21e14bdb=function(J){let Q=U(J).buffer;return A(Q)},D.wbg.__wbg_newwithbyteoffsetandlength_aa4a17c33a06e5cb=function(J,Q,X){let Z=new Uint8Array(U(J),Q>>>0,X>>>0);return A(Z)},D.wbg.__wbindgen_object_drop_ref=function(J){z(J)},D.wbg.__wbg_new_63b92bc8671ed464=function(J){let Q=new Uint8Array(U(J));return A(Q)},D.wbg.__wbg_values_839f3396d5aac002=function(J){let Q=U(J).values();return A(Q)},D.wbg.__wbg_next_196c84450b364254=function(){return uD(function(J){let Q=U(J).next();return A(Q)},arguments)},D.wbg.__wbg_done_298b57d23c0fc80c=function(J){return U(J).done},D.wbg.__wbg_value_d93c65011f51a456=function(J){let Q=U(J).value;return A(Q)},D.wbg.__wbg_instanceof_Uint8Array_2b3bbecd033d19f6=function(J){let Q;try{Q=U(J)instanceof Uint8Array}catch(Z){Q=!1}return Q},D.wbg.__wbindgen_string_get=function(J,Q){let X=U(Q),Z=typeof X==="string"?X:void 0;var $=i(Z)?0:n(Z,G.__wbindgen_malloc,G.__wbindgen_realloc),q=h;P()[J/4+1]=q,P()[J/4+0]=$},D.wbg.__wbg_new_16b304a2cfa7ff4a=function(){return A([])},D.wbg.__wbindgen_string_new=function(J,Q){let X=w(J,Q);return A(X)},D.wbg.__wbg_push_a5b05aedc7234f9f=function(J,Q){return U(J).push(U(Q))},D.wbg.__wbg_length_c20a40f15020d68a=function(J){return U(J).length},D.wbg.__wbg_set_a47bac70306a19a7=function(J,Q,X){U(J).set(U(Q),X>>>0)},D.wbg.__wbindgen_throw=function(J,Q){throw Error(w(J,Q))},D}function lD(D,J){}function mD(D,J){return G=D.exports,KD.__wbindgen_wasm_module=J,x=null,j=null,G}async function KD(D){if(G!==void 0)return G;if(typeof D>"u")D=new URL("index_bg.wasm",void 0);let J=wD();if(typeof D==="string"||typeof Request==="function"&&D instanceof Request||typeof URL==="function"&&D instanceof URL)D=fetch(D);lD(J);let{instance:Q,module:X}=await yD(await D,J);return mD(Q,X)}function iD(D){return Object.prototype.hasOwnProperty.call(D,"fontBuffers")}var G,W,_,h=0,j=null,y,_D,x=null,GD,ZD,p=class D{static __wrap(J){J=J>>>0;let Q=Object.create(D.prototype);return Q.__wbg_ptr=J,ZD.register(Q,Q.__wbg_ptr,Q),Q}__destroy_into_raw(){let J=this.__wbg_ptr;return this.__wbg_ptr=0,ZD.unregister(this),J}free(){let J=this.__destroy_into_raw();G.__wbg_bbox_free(J)}get x(){return G.__wbg_get_bbox_x(this.__wbg_ptr)}set x(J){G.__wbg_set_bbox_x(this.__wbg_ptr,J)}get y(){return G.__wbg_get_bbox_y(this.__wbg_ptr)}set y(J){G.__wbg_set_bbox_y(this.__wbg_ptr,J)}get width(){return G.__wbg_get_bbox_width(this.__wbg_ptr)}set width(J){G.__wbg_set_bbox_width(this.__wbg_ptr,J)}get height(){return G.__wbg_get_bbox_height(this.__wbg_ptr)}set height(J){G.__wbg_set_bbox_height(this.__wbg_ptr,J)}},$D,fD=class D{static __wrap(J){J=J>>>0;let Q=Object.create(D.prototype);return Q.__wbg_ptr=J,$D.register(Q,Q.__wbg_ptr,Q),Q}__destroy_into_raw(){let J=this.__wbg_ptr;return this.__wbg_ptr=0,$D.unregister(this),J}free(){let J=this.__destroy_into_raw();G.__wbg_renderedimage_free(J)}get width(){return G.renderedimage_width(this.__wbg_ptr)>>>0}get height(){return G.renderedimage_height(this.__wbg_ptr)>>>0}asPng(){try{let Z=G.__wbindgen_add_to_stack_pointer(-16);G.renderedimage_asPng(Z,this.__wbg_ptr);var J=P()[Z/4+0],Q=P()[Z/4+1],X=P()[Z/4+2];if(X)throw z(Q);return z(J)}finally{G.__wbindgen_add_to_stack_pointer(16)}}get pixels(){let J=G.renderedimage_pixels(this.__wbg_ptr);return z(J)}},vD,bD=class{__destroy_into_raw(){let D=this.__wbg_ptr;return this.__wbg_ptr=0,vD.unregister(this),D}free(){let D=this.__destroy_into_raw();G.__wbg_resvg_free(D)}constructor(D,J,Q){try{let N=G.__wbindgen_add_to_stack_pointer(-16);var X=i(J)?0:n(J,G.__wbindgen_malloc,G.__wbindgen_realloc),Z=h;G.resvg_new(N,A(D),X,Z,i(Q)?0:A(Q));var $=P()[N/4+0],q=P()[N/4+1],K=P()[N/4+2];if(K)throw z(q);return this.__wbg_ptr=$>>>0,this}finally{G.__wbindgen_add_to_stack_pointer(16)}}get width(){return G.resvg_width(this.__wbg_ptr)}get height(){return G.resvg_height(this.__wbg_ptr)}render(){try{let X=G.__wbindgen_add_to_stack_pointer(-16);G.resvg_render(X,this.__wbg_ptr);var D=P()[X/4+0],J=P()[X/4+1],Q=P()[X/4+2];if(Q)throw z(J);return fD.__wrap(D)}finally{G.__wbindgen_add_to_stack_pointer(16)}}toString(){let D,J;try{let Z=G.__wbindgen_add_to_stack_pointer(-16);G.resvg_toString(Z,this.__wbg_ptr);var Q=P()[Z/4+0],X=P()[Z/4+1];return D=Q,J=X,w(Q,X)}finally{G.__wbindgen_add_to_stack_pointer(16),G.__wbindgen_free(D,J,1)}}innerBBox(){let D=G.resvg_innerBBox(this.__wbg_ptr);return D===0?void 0:p.__wrap(D)}getBBox(){let D=G.resvg_getBBox(this.__wbg_ptr);return D===0?void 0:p.__wrap(D)}cropByBBox(D){hD(D,p),G.resvg_cropByBBox(this.__wbg_ptr,D.__wbg_ptr)}imagesToResolve(){try{let X=G.__wbindgen_add_to_stack_pointer(-16);G.resvg_imagesToResolve(X,this.__wbg_ptr);var D=P()[X/4+0],J=P()[X/4+1],Q=P()[X/4+2];if(Q)throw z(J);return z(D)}finally{G.__wbindgen_add_to_stack_pointer(16)}}resolveImage(D,J){try{let Z=G.__wbindgen_add_to_stack_pointer(-16),$=n(D,G.__wbindgen_malloc,G.__wbindgen_realloc),q=h;G.resvg_resolveImage(Z,this.__wbg_ptr,$,q,A(J));var Q=P()[Z/4+0],X=P()[Z/4+1];if(X)throw z(Q)}finally{G.__wbindgen_add_to_stack_pointer(16)}}},dD,g=!1,pD=async(D)=>{if(g)throw Error("Already initialized. The `initWasm()` function can be used only once.");await dD(await D),g=!0},nD;var LD=ID(()=>{W=Array(128).fill(void 0);W.push(void 0,null,!0,!1);_=W.length;y=typeof TextEncoder<"u"?new TextEncoder("utf-8"):{encode:()=>{throw Error("TextEncoder not available")}},_D=typeof y.encodeInto==="function"?function(D,J){return y.encodeInto(D,J)}:function(D,J){let Q=y.encode(D);return J.set(Q),{read:D.length,written:Q.length}};GD=typeof TextDecoder<"u"?new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0}):{decode:()=>{throw Error("TextDecoder not available")}};if(typeof TextDecoder<"u")GD.decode();ZD=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((D)=>G.__wbg_bbox_free(D>>>0)),$D=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((D)=>G.__wbg_renderedimage_free(D>>>0)),vD=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((D)=>G.__wbg_resvg_free(D>>>0));dD=KD,nD=class extends bD{constructor(D,J){if(!g)throw Error("Wasm has not been initialized. Call `initWasm()` function.");let Q=J?.font;if(!!Q&&iD(Q)){let X={...J,font:{...Q,fontBuffers:void 0}};super(D,JSON.stringify(X),Q.fontBuffers)}else super(D,JSON.stringify(J))}}});function T(D){return String(D??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function RD(D,J,Q){let X=Q/512;return`<g transform="translate(${D},${J}) scale(${X})">
3
3
  <rect x="0" y="0" width="512" height="512" rx="118" fill="#553de9"/>
4
4
  <path d="M152 405 L242 120" stroke="#FFFEFB" stroke-width="28" stroke-linecap="round" fill="none"/>
5
5
  <path d="M360 405 L270 120" stroke="#FFFEFB" stroke-width="28" stroke-linecap="round" fill="none"/>
6
6
  <path d="M242 120 Q256 86 270 120" stroke="#FFFEFB" stroke-width="28" stroke-linecap="round" fill="none"/>
7
7
  <circle cx="256" cy="295" r="20" fill="#1FC5A8"/>
8
- </g>`}function SJ(J){switch(J){case"verified":return"#1f8a52";case"failed":return"#b23a3a";case"working":case"pending":return"#9a6a12";default:return"#6b6675"}}function RJ(J){switch(J){case"pass":return"#1f8a52";case"fail":return"#b23a3a";case"pending":return"#9a6a12";default:return"#6b6675"}}function IJ(J){switch(J){case"approve":return"#1f8a52";case"reject":return"#b23a3a";case"concern":return"#9a6a12";default:return"#6b6675"}}function v(J,Q,X,Z,$="#201515"){return`<text x="${J}" y="${Q}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="12" fill="#6b6675" letter-spacing="0.5">${U(X.toUpperCase())}</text>
9
- <text x="${J}" y="${Q+24}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="20" font-weight="600" fill="${$}">${U(Z)}</text>`}var kJ=["Reason","Act","Reflect","Verify"];function MJ(J){let Q=(J||"").toLowerCase();if(/verif|complet|done|ship|deploy/.test(Q))return 3;if(/reflect|review|council|critique|assess/.test(Q))return 2;if(/reason|plan|design|architect|spec|analy/.test(Q))return 0;return 1}function ZJ(J){let Z={run:J?.run||"cockpit",iteration:typeof J?.iteration==="number"?J.iteration:0,phase:J?.phase||"idle",tier:J?.tier||"",provider:J?.provider||"",verdict:J?.verdict||"unknown",budgetUsd:typeof J?.budgetUsd==="number"?J.budgetUsd:0,budgetLimitUsd:J?.budgetLimitUsd,freshness:J?.freshness,gates:Array.isArray(J?.gates)?J.gates:[],council:Array.isArray(J?.council)?J.council:[],fleet:Array.isArray(J?.fleet)?J.fleet:[]},$=Z.budgetLimitUsd&&Z.budgetLimitUsd>0?`$${Z.budgetUsd.toFixed(2)} / $${Z.budgetLimitUsd.toFixed(2)}`:`$${Z.budgetUsd.toFixed(2)}`,G="";G+=HJ(32,32,44),G+=`<text x="92" y="54" font-family="'Fraunces','Georgia',serif" font-size="24" font-weight="600" fill="#201515">Autonomi</text>`,G+=`<text x="92" y="74" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" fill="#6b6675">Loki Cockpit</text>`;let q=Z.freshness?`updated ${Z.freshness}`:"live";G+=`<text x="868" y="54" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#6b6675">${U(q)}</text>`,G+=`<text x="868" y="74" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="13" fill="${SJ(Z.verdict)}" font-weight="600">${U(Z.verdict.toUpperCase())}</text>`;let K=96,P=168;G+=`<rect x="32" y="${K}" width="836" height="${P}" rx="16" fill="#ffffff" stroke="#e2e0e8"/>`,G+=`<text x="56" y="${K+34}" font-family="'Fraunces','Georgia',serif" font-size="20" font-weight="600" fill="#201515">${U(Z.run)}</text>`,G+=`<text x="56" y="${K+54}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" fill="#6b6675">phase ${U(Z.phase)}</text>`;let z=K+96,E=(V)=>56+V*168;G+=v(E(0),z,"iteration",String(Z.iteration)),G+=v(E(1),z,"tier",Z.tier),G+=v(E(2),z,"provider",Z.provider),G+=v(E(3),z,"budget",$);let n=K+P+40;G+=`<text x="32" y="${n}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">RARV LOOP</text>`;let s=MJ(Z.phase),R=n+14,o=200;kJ.forEach((V,C)=>{let L=32+C*(o+12),O=C<s,H=C===s;G+=`<rect x="${L}" y="${R}" width="${o}" height="40" rx="10" fill="${H?"#553de9":"#ffffff"}" fill-opacity="${H?"0.10":"1"}" stroke="${H?"#553de9":O?"#1f8a52":"#6b6675"}" stroke-width="${H?2:1}"/>`;let XJ=O?"check":H?"dot":"wait";if(XJ==="check")G+=`<path d="M${L+16} ${R+20} l6 6 l10 -12" stroke="#1f8a52" stroke-width="2.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>`;else if(XJ==="dot")G+=`<circle cx="${L+22}" cy="${R+20}" r="5" fill="#553de9"/>`;else G+=`<circle cx="${L+22}" cy="${R+20}" r="5" fill="none" stroke="#6b6675" stroke-width="1.5"/>`;G+=`<text x="${L+40}" y="${R+25}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="14" font-weight="${H?600:500}" fill="${H?"#553de9":O?"#201515":"#6b6675"}">${V}</text>`});let a=R+40+40;G+=`<text x="32" y="${a}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">QUALITY GATES</text>`;let r=Z.gates.length?Z.gates:[{name:"no gates yet",status:"pending"}],I=30,k=a+12;G+=`<rect x="32" y="${k}" width="836" height="${r.slice(0,8).length*I+8}" rx="12" fill="#ffffff" stroke="#e2e0e8"/>`,k+=8;for(let V of r.slice(0,8)){let C=RJ(V.status),L=k+I/2;if(G+=`<circle cx="50" cy="${L}" r="4" fill="${C}"/>`,G+=`<text x="66" y="${L+4}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#201515">${U(V.name)}</text>`,V.runner)G+=`<text x="242" y="${L+4}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="11" fill="#6b6675">${U(V.runner)}</text>`;if(V.evidence){let O=V.evidence.length>52?`${V.evidence.slice(0,49)}...`:V.evidence;G+=`<text x="332" y="${L+4}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="11" fill="#6b6675">${U(O)}</text>`}G+=`<text x="852" y="${L+4}" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="11" font-weight="700" fill="${C}">${U(V.status.toUpperCase())}</text>`,k+=I}let t=k+40;G+=`<text x="32" y="${t}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">COMPLETION COUNCIL</text>`;let e=Z.council.length?Z.council:[{reviewer:"pending",vote:"pending"}],M=t+12;G+=`<rect x="32" y="${M}" width="836" height="${e.slice(0,6).length*I+8}" rx="12" fill="#ffffff" stroke="#e2e0e8"/>`,M+=8;for(let V of e.slice(0,6)){let C=IJ(V.vote),L=M+I/2;if(G+=`<circle cx="50" cy="${L}" r="4" fill="${C}"/>`,G+=`<text x="66" y="${L+4}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="12.5" font-weight="500" fill="#201515">${U(V.reviewer)}</text>`,V.tier)G+=`<text x="292" y="${L+4}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="11" fill="#6b6675">${U(V.tier)}</text>`;G+=`<text x="852" y="${L+4}" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="11" font-weight="700" fill="${C}">${U(V.vote.toUpperCase())}</text>`,M+=I}let JJ=M+46,QJ=Z.fleet.filter((V)=>V.running).length,zJ=QJ>0?`FLEET (${QJ} active / ${Z.fleet.length})`:`FLEET (${Z.fleet.length}, none active)`;G+=`<text x="32" y="${JJ}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">${zJ}</text>`;let B=JJ+20,m=Z.fleet.slice(0,4);for(let V of m){let C=V.running?"#1f8a52":"#6b6675";G+=`<circle cx="38" cy="${B-4}" r="5" fill="${C}"/>`,G+=`<text x="52" y="${B}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="13" fill="#201515">${U(V.name)}</text>`;let L=`iter ${V.iteration??0} ${U(V.phase||V.status||"")}`;G+=`<text x="868" y="${B}" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#6b6675">${L}</text>`,B+=26}if(Z.fleet.length>m.length)G+=`<text x="52" y="${B}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="12" fill="#6b6675">+ ${Z.fleet.length-m.length} more</text>`,B+=26;let d=Math.round(B+32);return`<svg xmlns="http://www.w3.org/2000/svg" width="900" height="${d}" viewBox="0 0 900 ${d}">
8
+ </g>`}function SD(D){switch(D){case"verified":return"#1f8a52";case"failed":return"#b23a3a";case"working":case"pending":return"#9a6a12";default:return"#6b6675"}}function MD(D){switch(D){case"pass":return"#1f8a52";case"fail":return"#b23a3a";case"pending":return"#9a6a12";default:return"#6b6675"}}function kD(D){switch(D){case"approve":return"#1f8a52";case"reject":return"#b23a3a";case"concern":return"#9a6a12";default:return"#6b6675"}}function v(D,J,Q,X,Z="#201515"){return`<text x="${D}" y="${J}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="12" fill="#6b6675" letter-spacing="0.5">${T(Q.toUpperCase())}</text>
9
+ <text x="${D}" y="${J+24}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="20" font-weight="600" fill="${Z}">${T(X)}</text>`}var OD=["Reason","Act","Reflect","Verify"];function jD(D){let J=(D||"").toLowerCase();if(/verif|complet|done|ship|deploy/.test(J))return 3;if(/reflect|review|council|critique|assess/.test(J))return 2;if(/reason|plan|design|architect|spec|analy/.test(J))return 0;return 1}function XD(D){let X={run:D?.run||"cockpit",iteration:typeof D?.iteration==="number"?D.iteration:0,phase:D?.phase||"idle",tier:D?.tier||"",provider:D?.provider||"",verdict:D?.verdict||"unknown",budgetUsd:typeof D?.budgetUsd==="number"?D.budgetUsd:0,budgetLimitUsd:D?.budgetLimitUsd,freshness:D?.freshness,gates:Array.isArray(D?.gates)?D.gates:[],council:Array.isArray(D?.council)?D.council:[],fleet:Array.isArray(D?.fleet)?D.fleet:[]},Z=X.budgetLimitUsd&&X.budgetLimitUsd>0?`$${X.budgetUsd.toFixed(2)} / $${X.budgetLimitUsd.toFixed(2)}`:`$${X.budgetUsd.toFixed(2)}`,$="";$+=RD(32,32,44),$+=`<text x="92" y="54" font-family="'Fraunces','Georgia',serif" font-size="24" font-weight="600" fill="#201515">Autonomi</text>`,$+=`<text x="92" y="74" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" fill="#6b6675">Loki Cockpit</text>`;let q=X.freshness?`updated ${X.freshness}`:"live";$+=`<text x="868" y="54" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#6b6675">${T(q)}</text>`,$+=`<text x="868" y="74" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="13" fill="${SD(X.verdict)}" font-weight="600">${T(X.verdict.toUpperCase())}</text>`;let K=96,N=168;$+=`<rect x="32" y="${K}" width="836" height="${N}" rx="16" fill="#ffffff" stroke="#e2e0e8"/>`,$+=`<text x="56" y="${K+34}" font-family="'Fraunces','Georgia',serif" font-size="20" font-weight="600" fill="#201515">${T(X.run)}</text>`,$+=`<text x="56" y="${K+54}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" fill="#6b6675">phase ${T(X.phase)}</text>`;let E=K+96,Y=(L)=>56+L*168;$+=v(Y(0),E,"iteration",String(X.iteration)),$+=v(Y(1),E,"tier",X.tier),$+=v(Y(2),E,"provider",X.provider),$+=v(Y(3),E,"budget",Z);let c=K+N+40;$+=`<text x="32" y="${c}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">RARV LOOP</text>`;let s=jD(X.phase),R=c+14,o=200;OD.forEach((L,C)=>{let V=32+C*(o+12),O=C<s,B=C===s;$+=`<rect x="${V}" y="${R}" width="${o}" height="40" rx="10" fill="${B?"#553de9":"#ffffff"}" fill-opacity="${B?"0.10":"1"}" stroke="${B?"#553de9":O?"#1f8a52":"#6b6675"}" stroke-width="${B?2:1}"/>`;let QD=O?"check":B?"dot":"wait";if(QD==="check")$+=`<path d="M${V+16} ${R+20} l6 6 l10 -12" stroke="#1f8a52" stroke-width="2.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>`;else if(QD==="dot")$+=`<circle cx="${V+22}" cy="${R+20}" r="5" fill="#553de9"/>`;else $+=`<circle cx="${V+22}" cy="${R+20}" r="5" fill="none" stroke="#6b6675" stroke-width="1.5"/>`;$+=`<text x="${V+40}" y="${R+25}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="14" font-weight="${B?600:500}" fill="${B?"#553de9":O?"#201515":"#6b6675"}">${L}</text>`});let a=R+40+40;$+=`<text x="32" y="${a}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">QUALITY GATES</text>`;let r=X.gates.length?X.gates:[{name:"no gates yet",status:"pending"}],S=30,M=a+12;$+=`<rect x="32" y="${M}" width="836" height="${r.slice(0,8).length*S+8}" rx="12" fill="#ffffff" stroke="#e2e0e8"/>`,M+=8;for(let L of r.slice(0,8)){let C=MD(L.status),V=M+S/2;if($+=`<circle cx="50" cy="${V}" r="4" fill="${C}"/>`,$+=`<text x="66" y="${V+4}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#201515">${T(L.name)}</text>`,L.runner)$+=`<text x="242" y="${V+4}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="11" fill="#6b6675">${T(L.runner)}</text>`;if(L.evidence){let O=L.evidence.length>52?`${L.evidence.slice(0,49)}...`:L.evidence;$+=`<text x="332" y="${V+4}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="11" fill="#6b6675">${T(O)}</text>`}$+=`<text x="852" y="${V+4}" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="11" font-weight="700" fill="${C}">${T(L.status.toUpperCase())}</text>`,M+=S}let e=M+40;$+=`<text x="32" y="${e}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">COMPLETION COUNCIL</text>`;let t=X.council.length?X.council:[{reviewer:"pending",vote:"pending"}],k=e+12;$+=`<rect x="32" y="${k}" width="836" height="${t.slice(0,6).length*S+8}" rx="12" fill="#ffffff" stroke="#e2e0e8"/>`,k+=8;for(let L of t.slice(0,6)){let C=kD(L.vote),V=k+S/2;if($+=`<circle cx="50" cy="${V}" r="4" fill="${C}"/>`,$+=`<text x="66" y="${V+4}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="12.5" font-weight="500" fill="#201515">${T(L.reviewer)}</text>`,L.tier)$+=`<text x="292" y="${V+4}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="11" fill="#6b6675">${T(L.tier)}</text>`;$+=`<text x="852" y="${V+4}" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="11" font-weight="700" fill="${C}">${T(L.vote.toUpperCase())}</text>`,k+=S}let DD=k+46,JD=X.fleet.filter((L)=>L.running).length,WD=JD>0?`FLEET (${JD} active / ${X.fleet.length})`:`FLEET (${X.fleet.length}, none active)`;$+=`<text x="32" y="${DD}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="13" font-weight="600" fill="#6b6675" letter-spacing="0.5">${WD}</text>`;let H=DD+20,m=X.fleet.slice(0,4);for(let L of m){let C=L.running?"#1f8a52":"#6b6675";$+=`<circle cx="38" cy="${H-4}" r="5" fill="${C}"/>`,$+=`<text x="52" y="${H}" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="13" fill="#201515">${T(L.name)}</text>`;let V=`iter ${L.iteration??0} ${T(L.phase||L.status||"")}`;$+=`<text x="868" y="${H}" text-anchor="end" font-family="'JetBrains Mono','SF Mono',ui-monospace,monospace" font-size="12" fill="#6b6675">${V}</text>`,H+=26}if(X.fleet.length>m.length)$+=`<text x="52" y="${H}" font-family="'Inter','Helvetica Neue',Arial,sans-serif" font-size="12" fill="#6b6675">+ ${X.fleet.length-m.length} more</text>`,H+=26;let d=Math.round(H+32);return`<svg xmlns="http://www.w3.org/2000/svg" width="900" height="${d}" viewBox="0 0 900 ${d}">
10
10
  <rect x="0" y="0" width="900" height="${d}" fill="#f1f2f6"/>
11
- ${G}
12
- </svg>`}var f,u;function PJ(){if(f!==void 0)return f;try{let J=globalThis.require??F;J.resolve("@resvg/resvg-js"),f=J("@resvg/resvg-js")}catch{f=null}return f}async function LJ(){if(u!==void 0)return u;try{let J=await Promise.resolve().then(() => (VJ(),qJ)),Q=globalThis.require??F,{readFileSync:X,existsSync:Z}=await import("fs"),{resolve:$,dirname:G}=await import("path"),{fileURLToPath:q}=await import("url"),K=null;try{let P=G(q(import.meta.url));for(let z of["../data/resvg.wasm","../../data/resvg.wasm"]){let E=$(P,z);if(Z(E)){K=X(E);break}}}catch{}if(!K){let P=Q.resolve("@resvg/resvg-wasm/index_bg.wasm");K=X(P)}await J.initWasm(K),u={Resvg:J.Resvg}}catch{u=null}return u}async function NJ(){if(PJ()?.Resvg)return!0;return(await LJ())?.Resvg!=null}var S;async function gJ(){if(S!==void 0)return S;try{let{readFileSync:J,existsSync:Q}=await import("fs"),X=["/System/Library/Fonts/Supplemental/Arial.ttf","/System/Library/Fonts/Helvetica.ttc","/Library/Fonts/Arial.ttf","/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf","/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf","/usr/share/fonts/dejavu/DejaVuSans.ttf","/usr/share/fonts/TTF/DejaVuSans.ttf","C:\\Windows\\Fonts\\arial.ttf","C:\\Windows\\Fonts\\segoeui.ttf"];for(let Z of X)if(Q(Z))return S=new Uint8Array(J(Z)),S;S=null}catch{S=null}return S}async function UJ(J,Q=900){let X=PJ();if(X?.Resvg)try{let $=new X.Resvg(J,{fitTo:{mode:"width",value:Q}});return{png:Uint8Array.from($.render().asPng()),available:!0}}catch{}let Z=await LJ();if(Z?.Resvg)try{let $=await gJ(),G={fitTo:{mode:"width",value:Q}};if($)G.font={fontBuffers:[$],defaultFontFamily:"Arial",loadSystemFonts:!1};else G.font={loadSystemFonts:!0};let q=new Z.Resvg(J,G);return{png:Uint8Array.from(q.render().asPng()),available:!0}}catch($){return{png:null,available:!1,reason:`raster failed: ${$.message}`}}return{png:null,available:!1,reason:"rasterizer unavailable (no resvg native or wasm)"}}function AJ(J){return Buffer.from(J).toString("base64")}function iJ(J,Q){let X=AJ(J),Z=Q&&Q>0?`${Q}`:"auto";return`\x1B]1337;File=${`inline=1;size=${J.length};width=${Z};height=auto;preserveAspectRatio=1`}:${X}\x07`}function cJ(J,Q=4096,X){let Z=AJ(J);if(Z.length===0)return"\x1B_Ga=T,f=100,m=0;\x1B\\";let $=[];for(let K=0;K<Z.length;K+=Q)$.push(Z.slice(K,K+Q));let G=X&&X>0?`,c=${X}`:"",q="";for(let K=0;K<$.length;K++){let z=K===$.length-1?0:1,E=K===0?`a=T,f=100${G},m=${z}`:`m=${z}`;q+=`\x1B_G${E};${$[K]}\x1B\\`}return q}function YJ(J,Q,X){return J==="kitty"?cJ(Q,4096,X):iJ(Q,X)}var nJ=new Set(["iterm.app","wezterm","ghostty"]);function l(J=process.env){let Q=(J.LOKI_COCKPIT_PROTOCOL||"").trim().toLowerCase();if(Q==="iterm2"||Q==="kitty"||Q==="none")return Q;let X=(J.KITTY_WINDOW_ID||"").trim(),Z=(J.TERM||"").trim().toLowerCase();if(X.length>0||Z==="xterm-kitty")return"kitty";let $=(J.TERM_PROGRAM||"").trim().toLowerCase();if(nJ.has($))return"iterm2";return"none"}async function CJ(J,Q={}){let X=ZJ(J);if(Q.forceText)return{kind:"fallback",protocol:"none",reason:"--no-image (text/browser fallback)",svg:X};let Z;if(Q.protocol&&Q.protocol!=="auto")Z=Q.protocol;else Z=l(Q.env);if(Z==="none")return{kind:"fallback",protocol:Z,reason:"no inline-image terminal detected",svg:X};let $=await UJ(X);if(!$.available||!$.png)return{kind:"fallback",protocol:Z,reason:$.reason||"rasterization unavailable",svg:X};let G=YJ(Z,$.png,Q.cols);return{kind:"image",protocol:Z,data:G,svg:X}}async function sJ(){let J=[];for await(let Q of process.stdin)J.push(Q);return Buffer.concat(J).toString("utf-8")}function oJ(J){let Q="auto",X=!1,Z;for(let $=0;$<J.length;$++){let G=J[$];if(G==="--protocol"){let q=(J[++$]||"auto").toLowerCase();Q=q==="iterm2"||q==="kitty"||q==="none"?q:"auto"}else if(G==="--no-image")X=!0;else if(G==="--svg-out")Z=J[++$]}return{protocol:Q,noImage:X,svgOut:Z}}async function aJ(){let J=l(),Q=await NJ(),X=J!=="none"&&Q?"image":"text+dashboard";return process.stdout.write(`protocol=${J}
13
- `),process.stdout.write(`resvg=${Q?"yes":"no"}
14
- `),process.stdout.write(`path=${X}
15
- `),0}async function rJ(J=process.argv.slice(2)){if(J.includes("--probe"))return await aJ();let{protocol:Q,noImage:X,svgOut:Z}=oJ(J),$;try{let P=await sJ();$=JSON.parse(P)}catch(P){return process.stderr.write(`FALLBACK could not parse cockpit state: ${P.message}
16
- `),3}let G=process.stdout.columns||Number(process.env.COLUMNS)||0,q=G>4?G-2:void 0,K=await CJ($,{protocol:Q,forceText:X,cols:q});if(Z)try{let{writeFileSync:P}=await import("fs");P(Z,K.svg)}catch{}if(K.kind==="image"&&K.data)return process.stdout.write(K.data),0;return process.stderr.write(`FALLBACK ${K.reason||"image unavailable"}
17
- `),3}if(import.meta.main)rJ().then((J)=>process.exit(J));export{rJ as main};
11
+ ${$}
12
+ </svg>`}var u,f;function ND(){if(u!==void 0)return u;try{let D=globalThis.require??F;D.resolve("@resvg/resvg-js"),u=D("@resvg/resvg-js")}catch{u=null}return u}async function VD(){if(f!==void 0)return f;try{let D=await Promise.resolve().then(() => (LD(),qD)),J=globalThis.require??F,{readFileSync:Q,existsSync:X}=await import("fs"),{resolve:Z,dirname:$}=await import("path"),{fileURLToPath:q}=await import("url"),K=null;try{let N=$(q(import.meta.url));for(let E of["../data/resvg.wasm","../../data/resvg.wasm"]){let Y=Z(N,E);if(X(Y)){K=Q(Y);break}}}catch{}if(!K){let N=J.resolve("@resvg/resvg-wasm/index_bg.wasm");K=Q(N)}await D.initWasm(K),f={Resvg:D.Resvg}}catch{f=null}return f}async function PD(){if(ND()?.Resvg)return!0;return(await VD())?.Resvg!=null}var I;async function gD(){if(I!==void 0)return I;try{let{readFileSync:D,existsSync:J}=await import("fs"),Q=["/System/Library/Fonts/Supplemental/Arial.ttf","/System/Library/Fonts/Helvetica.ttc","/Library/Fonts/Arial.ttf","/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf","/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf","/usr/share/fonts/dejavu/DejaVuSans.ttf","/usr/share/fonts/TTF/DejaVuSans.ttf","C:\\Windows\\Fonts\\arial.ttf","C:\\Windows\\Fonts\\segoeui.ttf"];for(let X of Q)if(J(X))return I=new Uint8Array(D(X)),I;I=null}catch{I=null}return I}async function TD(D,J=900){let Q=ND();if(Q?.Resvg)try{let Z=new Q.Resvg(D,{fitTo:{mode:"width",value:J}});return{png:Uint8Array.from(Z.render().asPng()),available:!0}}catch{}let X=await VD();if(X?.Resvg)try{let Z=await gD(),$={fitTo:{mode:"width",value:J}};if(Z)$.font={fontBuffers:[Z],defaultFontFamily:"Arial",loadSystemFonts:!1};else $.font={loadSystemFonts:!0};let q=new X.Resvg(D,$);return{png:Uint8Array.from(q.render().asPng()),available:!0}}catch(Z){return{png:null,available:!1,reason:`raster failed: ${Z.message}`}}return{png:null,available:!1,reason:"rasterizer unavailable (no resvg native or wasm)"}}function UD(D){return Buffer.from(D).toString("base64")}function cD(D,J){let Q=UD(D),X=J&&J>0?`${J}`:"auto";return`\x1B]1337;File=${`inline=1;size=${D.length};width=${X};height=auto;preserveAspectRatio=1`}:${Q}\x07`}function sD(D,J=4096,Q){let X=UD(D);if(X.length===0)return"\x1B_Ga=T,f=100,m=0;\x1B\\";let Z=[];for(let K=0;K<X.length;K+=J)Z.push(X.slice(K,K+J));let $=Q&&Q>0?`,c=${Q}`:"",q="";for(let K=0;K<Z.length;K++){let E=K===Z.length-1?0:1,Y=K===0?`a=T,f=100${$},m=${E}`:`m=${E}`;q+=`\x1B_G${Y};${Z[K]}\x1B\\`}return q}function AD(D,J,Q){return D==="kitty"?sD(J,4096,Q):cD(J,Q)}var oD=new Set(["iterm.app","wezterm","ghostty"]);function l(D=process.env){let J=(D.LOKI_COCKPIT_PROTOCOL||"").trim().toLowerCase();if(J==="iterm2"||J==="kitty"||J==="none")return J;let Q=(D.KITTY_WINDOW_ID||"").trim(),X=(D.TERM||"").trim().toLowerCase();if(Q.length>0||X==="xterm-kitty")return"kitty";let Z=(D.TERM_PROGRAM||"").trim().toLowerCase();if(oD.has(Z))return"iterm2";return"none"}async function CD(D,J={}){let Q=XD(D);if(J.forceText)return{kind:"fallback",protocol:"none",reason:"--no-image (text/browser fallback)",svg:Q};let X;if(J.protocol&&J.protocol!=="auto")X=J.protocol;else X=l(J.env);if(X==="none")return{kind:"fallback",protocol:X,reason:"no inline-image terminal detected",svg:Q};let Z=await TD(Q);if(!Z.available||!Z.png)return{kind:"fallback",protocol:X,reason:Z.reason||"rasterization unavailable",svg:Q};let $=AD(X,Z.png,J.cols);return{kind:"image",protocol:X,data:$,svg:Q}}var ED=(D)=>typeof D==="number"&&Number.isFinite(D)&&D>=40;function YD(D=process.stdout,J=process.env){let Q=D?.columns;if(ED(Q))return Math.floor(Q);let X=Number(J.COLUMNS);if(ED(X))return Math.floor(X);return 80}async function aD(){let D=[];for await(let J of process.stdin)D.push(J);return Buffer.concat(D).toString("utf-8")}function rD(D){let J="auto",Q=!1,X;for(let Z=0;Z<D.length;Z++){let $=D[Z];if($==="--protocol"){let q=(D[++Z]||"auto").toLowerCase();J=q==="iterm2"||q==="kitty"||q==="none"?q:"auto"}else if($==="--no-image")Q=!0;else if($==="--svg-out")X=D[++Z]}return{protocol:J,noImage:Q,svgOut:X}}async function eD(){let D=l(),J=await PD(),Q=D!=="none"&&J?"image":"text+dashboard";return process.stdout.write(`protocol=${D}
13
+ `),process.stdout.write(`resvg=${J?"yes":"no"}
14
+ `),process.stdout.write(`path=${Q}
15
+ `),0}async function tD(D=process.argv.slice(2)){if(D.includes("--probe"))return await eD();let{protocol:J,noImage:Q,svgOut:X}=rD(D),Z;try{let K=await aD();Z=JSON.parse(K)}catch(K){return process.stderr.write(`FALLBACK could not parse cockpit state: ${K.message}
16
+ `),3}let $=YD()-2,q=await CD(Z,{protocol:J,forceText:Q,cols:$});if(X)try{let{writeFileSync:K}=await import("fs");K(X,q.svg)}catch{}if(q.kind==="image"&&q.data)return process.stdout.write(q.data),0;return process.stderr.write(`FALLBACK ${q.reason||"image unavailable"}
17
+ `),3}if(import.meta.main)tD().then((D)=>process.exit(D));export{tD as main};
18
18
 
19
- //# debugId=FA320A456FDE2DB7437C9AA473A12AC3
19
+ //# debugId=2F4CD3BF5DE92F4F02A2CF0BED7BBB85