loki-mode 11.17.41 → 11.17.42

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 (73) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/loki +1 -1
  4. package/autonomy/verify.sh +5 -0
  5. package/bin/loki +1 -1
  6. package/dashboard/__init__.py +1 -1
  7. package/docs/CLI-REFERENCE.md +1 -1
  8. package/docs/INSTALLATION.md +1 -1
  9. package/docs/v10/BOARD.md +2 -2
  10. package/docs/v10/FAILURE-CLASSES.md +42 -0
  11. package/docs/v10/PROGRESS.md +3 -0
  12. package/loki-ts/dist/loki.js +3 -3
  13. package/mcp/__init__.py +1 -1
  14. package/package.json +2 -2
  15. package/packages/control-plane/dist/server.js +2 -2
  16. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  17. package/web-app/dist/assets/{AdminPage-BSR_64u1.js → AdminPage-BPVS2lw_.js} +1 -1
  18. package/web-app/dist/assets/{Avatar-CnSNZSx6.js → Avatar-DeNmWN6j.js} +1 -1
  19. package/web-app/dist/assets/{Badge-C7p_bqIO.js → Badge-DHIpQiHX.js} +1 -1
  20. package/web-app/dist/assets/{Button-5CI0TYxR.js → Button-Codl3KHK.js} +1 -1
  21. package/web-app/dist/assets/{CockpitPage-CeiR5rfl.js → CockpitPage-7-0787T9.js} +1 -1
  22. package/web-app/dist/assets/{ComparePage-Cwh3wcqg.js → ComparePage-iH3EIb7E.js} +1 -1
  23. package/web-app/dist/assets/{ErrorBoundary-VZcsEDJl.js → ErrorBoundary-DSSzEuvn.js} +1 -1
  24. package/web-app/dist/assets/{EvidenceReceiptPanel-Cf5DXTqo.js → EvidenceReceiptPanel-DDkXp4dL.js} +1 -1
  25. package/web-app/dist/assets/{GitHubIssuesPanel-C8pxgZhD.js → GitHubIssuesPanel-C18iXGn9.js} +1 -1
  26. package/web-app/dist/assets/{GitHubPRsPanel-Dfrm9QTz.js → GitHubPRsPanel-CuoSxf1X.js} +1 -1
  27. package/web-app/dist/assets/{HomePage-Be-Hq5wb.js → HomePage-Cc-UkeTr.js} +2 -2
  28. package/web-app/dist/assets/{LoginPage-DijL2orB.js → LoginPage-Cz19E67v.js} +1 -1
  29. package/web-app/dist/assets/{MagicPage-x-KpX3Zk.js → MagicPage-B6zd2wsH.js} +1 -1
  30. package/web-app/dist/assets/{MetricsPage-uoMG8P0x.js → MetricsPage-B9INzw3f.js} +1 -1
  31. package/web-app/dist/assets/{NotFoundPage-DmW2a7pG.js → NotFoundPage-Do0a6qq9.js} +1 -1
  32. package/web-app/dist/assets/{ProjectPage-zpARxbll.js → ProjectPage-DX3o3FPS.js} +3 -3
  33. package/web-app/dist/assets/{ProjectsPage-5dTAn3K7.js → ProjectsPage-CBXj5ehW.js} +1 -1
  34. package/web-app/dist/assets/{SettingsPage-ptKy_Tbu.js → SettingsPage-dlB_5z5P.js} +1 -1
  35. package/web-app/dist/assets/{ShowcasePage-BkM5b-6b.js → ShowcasePage-B4AamDna.js} +1 -1
  36. package/web-app/dist/assets/{SystemSettingsPage-BbaZ8aqC.js → SystemSettingsPage-CRMvKGYU.js} +1 -1
  37. package/web-app/dist/assets/{TeamsPage-CBgDSDWj.js → TeamsPage-t9c4x788.js} +1 -1
  38. package/web-app/dist/assets/{TemplatesPage-IdBOifb1.js → TemplatesPage-DeGaZFTG.js} +1 -1
  39. package/web-app/dist/assets/{TerminalOutput-iLcaELwj.js → TerminalOutput-G31VzO9H.js} +1 -1
  40. package/web-app/dist/assets/{activity-Di09VZ-C.js → activity-CmEjbl9p.js} +1 -1
  41. package/web-app/dist/assets/{bell-CuHhohwY.js → bell-BrB1urp7.js} +1 -1
  42. package/web-app/dist/assets/{bot-pGvyFisf.js → bot-BMxqZc49.js} +1 -1
  43. package/web-app/dist/assets/{check-DYPycZns.js → check-DgIZol8f.js} +1 -1
  44. package/web-app/dist/assets/{chevron-left-lKRP1pKT.js → chevron-left-qMIE0cDr.js} +1 -1
  45. package/web-app/dist/assets/{circle-alert-D1rDQ9mD.js → circle-alert-CX8OMfQi.js} +1 -1
  46. package/web-app/dist/assets/{clock-BGhPbAAa.js → clock-BWn2Jze6.js} +1 -1
  47. package/web-app/dist/assets/{cloud-WsT8-0Fu.js → cloud-B-AKwdUd.js} +1 -1
  48. package/web-app/dist/assets/{code-xml-DtutBX9b.js → code-xml-D5g_nMzh.js} +1 -1
  49. package/web-app/dist/assets/{database-LiEeNmyC.js → database-FLci9a_L.js} +1 -1
  50. package/web-app/dist/assets/{dollar-sign-adGlfVLa.js → dollar-sign-oHFYulLR.js} +1 -1
  51. package/web-app/dist/assets/{file-code-corner-DY5GkQGM.js → file-code-corner-tOfIJYNi.js} +1 -1
  52. package/web-app/dist/assets/{file-plus-RLd_hPU8.js → file-plus-BdjSTmSi.js} +1 -1
  53. package/web-app/dist/assets/{globe-CQvcGE8E.js → globe-BhnmSAWt.js} +1 -1
  54. package/web-app/dist/assets/{hammer-BWOWu2Hf.js → hammer-CF-MPA1L.js} +1 -1
  55. package/web-app/dist/assets/{index-BBV2psih.js → index-6SmuA6vo.js} +3 -3
  56. package/web-app/dist/assets/{layers-C_cj_ShX.js → layers-7YlE4617.js} +1 -1
  57. package/web-app/dist/assets/{loader-circle-BpyfPEFt.js → loader-circle-BpZ0PaNs.js} +1 -1
  58. package/web-app/dist/assets/{lock-Bivqy2kG.js → lock--fYCznSR.js} +1 -1
  59. package/web-app/dist/assets/{package-DvDJIgWs.js → package-U_Arm0cd.js} +1 -1
  60. package/web-app/dist/assets/{plus-CVjTmPiU.js → plus-BZVrxRYG.js} +1 -1
  61. package/web-app/dist/assets/{refresh-cw-DPEeU-0s.js → refresh-cw-C5w6Ak_2.js} +1 -1
  62. package/web-app/dist/assets/{rotate-ccw-DZX_aED8.js → rotate-ccw-BoOWI6PB.js} +1 -1
  63. package/web-app/dist/assets/{scroll-text-BBMfK4J7.js → scroll-text-C0pBzd-k.js} +1 -1
  64. package/web-app/dist/assets/{server-Bq18pHWE.js → server-Cs9i_vco.js} +1 -1
  65. package/web-app/dist/assets/{shield-alert-Dc5xbnOx.js → shield-alert-3oKaRgIp.js} +1 -1
  66. package/web-app/dist/assets/{thumbs-up-4nFvjqQ-.js → thumbs-up-BOZEbhQH.js} +1 -1
  67. package/web-app/dist/assets/{trash-2-SjUKL3ek.js → trash-2-B8x1w7gc.js} +1 -1
  68. package/web-app/dist/assets/{trending-down-B7_1Kuct.js → trending-down-CSDM4aj2.js} +1 -1
  69. package/web-app/dist/assets/{trending-up-DgRWrCNb.js → trending-up-CKCveriW.js} +1 -1
  70. package/web-app/dist/assets/{upload-Cs07lSfb.js → upload-C3Vn2m4l.js} +1 -1
  71. package/web-app/dist/assets/{usePolling-BAUxt1Nu.js → usePolling-BQfKHNwN.js} +1 -1
  72. package/web-app/dist/assets/{user-DC2T8RYB.js → user-B6OJgsvN.js} +1 -1
  73. package/web-app/dist/index.html +1 -1
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: loki-mode
3
3
  description: An autonomous software factory that knows what it is supposed to deliver, and proves it did. Use when the user says Loki Mode or asks to build, fix or verify software autonomously.
4
4
  ---
5
5
 
6
- # Loki Mode v11.17.41
6
+ # Loki Mode v11.17.42
7
7
 
8
8
  **Current entry points (Loki 10 engine):** `loki "<task>"`, `loki owner/repo#N` and `loki quick "<task>"` run the Loki 10 engine and end with a signed receipt (`loki verify`). `loki backlog owner/repo --all` runs many issues in parallel. Guide: `docs/v10/GUIDE.md`. The skill instructions below, and `loki start`, describe the previous bash loop. PRD-file starts (`loki start ./prd.md`) and the opencode provider still run on it until FC38-SWEEP ports them; the legacy-engine command and the LOKI_ENGINE switch remain removed. Prefer `loki owner/repo#N` for issues.
9
9
 
@@ -483,4 +483,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
483
483
 
484
484
  ---
485
485
 
486
- **v11.17.41 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
486
+ **v11.17.42 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 11.17.41
1
+ 11.17.42
package/autonomy/loki CHANGED
@@ -19089,7 +19089,7 @@ cmd_verify() {
19089
19089
  local _pk_arg
19090
19090
  for _pk_arg in "$@"; do
19091
19091
  case "$_pk_arg" in
19092
- --pubkey|--pubkey=*) exec "$_LOKI_SCRIPT_DIR/../bin/loki" verify "$@" ;;
19092
+ --pubkey|--pubkey=*|--require-exogenous) exec "$_LOKI_SCRIPT_DIR/../bin/loki" verify "$@" ;;
19093
19093
  esac
19094
19094
  done
19095
19095
  # PATH slice: a workspace composite (composite.json, or --seal-composite RUN_DIR) is
@@ -2594,6 +2594,11 @@ OPTIONS:
2594
2594
  no signed issue time, or is more than 300s in the
2595
2595
  future. Exits 2 (UNCHECKED). Routed to the engine10
2596
2596
  verifier.
2597
+ --require-exogenous
2598
+ With a run receipt: exit 4 when a VERIFIED receipt has
2599
+ no agent-independent passing check or no recorded
2600
+ provenance (or set LOKI_VERIFY_REQUIRE_EXOGENOUS=1).
2601
+ Routed to the engine10 verifier.
2597
2602
  -h, --help Show this help.
2598
2603
 
2599
2604
  GATES (deterministic, reproducible by construction):
package/bin/loki CHANGED
@@ -556,7 +556,7 @@ case "v10" in
556
556
  status|verify|dashboard)
557
557
  if [ "$1" = "verify" ]; then
558
558
  for _pk in "$@"; do
559
- case "$_pk" in --pubkey|--pubkey=*) _e10=1; _e10_hard=1 ;; esac
559
+ case "$_pk" in --pubkey|--pubkey=*|--require-exogenous) _e10=1; _e10_hard=1 ;; esac
560
560
  done
561
561
  unset _pk
562
562
  fi
@@ -7,6 +7,6 @@ Modules:
7
7
  control: Session control helpers (status, atomic writes, origin check)
8
8
  """
9
9
 
10
- __version__ = "11.17.41"
10
+ __version__ = "11.17.42"
11
11
 
12
12
  __all__ = ["__version__"]
@@ -1,6 +1,6 @@
1
1
  # CLI reference
2
2
 
3
- Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.17.41. Do not edit by hand.
3
+ Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.17.42. Do not edit by hand.
4
4
  Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for the full inventory.
5
5
 
6
6
  | Command | Description |
@@ -2,7 +2,7 @@
2
2
 
3
3
  Loki Mode, by [Autonomi](https://www.autonomi.dev/), turns a spec or an issue into a verified pull request with a receipt you can check. This page covers installing it, a first run, and the options around it.
4
4
 
5
- **Version:** v11.17.41
5
+ **Version:** v11.17.42
6
6
 
7
7
  **Engine note:** `loki start` is the primary command. `loki start`, `loki "<task>"`, `loki owner/repo#N` and `loki quick` all run the Loki 10 engine, whatever the flag order or input form (PRD file, issue ref, task or one-word brief). The previous loop runs only on `--engine legacy`, `LOKI_ENGINE=legacy`, or for one call when a flag Loki 10 cannot honor is present. See the [user guide](v10/GUIDE.md) and the [5-minute quickstart](QUICKSTART.md).
8
8
 
package/docs/v10/BOARD.md CHANGED
@@ -1179,8 +1179,8 @@ Source: ~/git/autonomi-dev/research/2026-09-30-adoption/SWARM-PROMPT-ADOPTION.md
1179
1179
  | TEN-STABILITY-15 | fix: queue add on a corrupt queue file quarantines it and warns instead of silently overwriting every queued item | loki-ts/src/commands/queue.ts, loki-ts/tests/commands/queue.test.ts | MEDIUM | red: a truncated queue.json followed by queue add leaves a file holding only the new item; green: the bad file is renamed to queue.json.corrupt-<ts>, a warning is printed once, the new item is added to a fresh file; cd loki-ts && bunx tsc --noEmit && bun test tests/commands/queue.test.ts | released v11.17.41 | Gap: readQueue returns [] on any JSON error (queue.ts:79-86) and queueAdd then writeQueue overwrites (queue.ts:108-124). Same class as TEN-STABILITY-12 (outbox quarantine at util/outbox.ts:28-33); reuse that pattern and add the row to FAILURE-CLASSES.md. |
1180
1180
  | TEN-STABILITY-16 | enhancement: loki start sweeps stale temp files left by a killed atomic write (name.tmp.<deadpid>.<n>) older than 1 hour in the .loki state dirs | loki-ts/src/util/atomic.ts, loki-ts/tests/util/atomic.test.ts | MEDIUM | red: a leftover state.json.tmp.99999.1 with a dead pid stays forever; green: swept when pid is dead and mtime older than 1h, a live pid or fresh file is untouched, only exact tmp names matched; cd loki-ts && bunx tsc --noEmit && bun test tests/util | released (already shipped before the row: loki-ts/src/runner/state.ts:444 sweepOrphanTmpFiles) | Gap: grep -rnE '\.tmp\.' loki-ts/src shows temp names created at util/atomic.ts:89 and run_control.ts:13 with no sweeper anywhere. Never glob outside .loki; reuse processStartTime or kill -0 from util/run_pid.ts for the liveness test; wire from a util/ entry point, not engine10 core. |
1181
1181
  | TEN-STABILITY-17 | feature: loki doctor lists orphan runs (a run dir whose owner process died before run.completed) with the resume or undo command for each | loki-ts/src/commands/doctor.ts, loki-ts/tests/commands/doctor.test.ts | MEDIUM | red: doctor ignores a run dir with a dead pid and no run.completed event; green: a warn row names the run id and "loki resume" or "loki undo", live and completed runs produce no row; cd loki-ts && bunx tsc --noEmit && bun test tests/commands/doctor.test.ts | ready@2026-10-17T08:05Z | Gap: runOwnerAlive (util/run_pid.ts:59) is consumed only by util/run_outputs.ts:156; grep -n runOwnerAlive loki-ts/src/commands/doctor.ts returned 0 hits. Warn level only, never fails doctor. Serialize after TEN-DEPLOY-15 (same file). |
1182
- | TEN-STABILITY-18 | P0 fix-forward: nightly 39016259458 reds still red on main e32ee1b5d (pr_body_golden not-recorded producer util/check_result.ts; sizing wall brief 726 vs cap 616; router_optout_golden wall stage haiku for development; verify.test uv resolution CI-only via Bun.which PATH; test-sigpipe-guard 1737 vs ceiling 1728; help-changelog-drift loki verify --require-exogenous; test-ui-bare-loki exact-match on new control lines; test-local-ci-gitleaks scope) | the failing tests, loki-ts/src/util/check_result.ts, loki-ts/src/engine10/stages/wall.ts, loki-ts/src/engine10/stages/verify.ts, verify help and completions, scripts/local-ci.sh, docs/v10/FAILURE-CLASSES.md | MEDIUM | red: each named test fails on e32ee1b5d; green: cd loki-ts && bun test tests/engine10/pr_body_golden.test.ts tests/engine10/sizing.test.ts tests/engine10/router_optout_golden.test.ts tests/engine10/verify.test.ts tests/util; bash tests/test-sigpipe-guard.sh; bash tests/test-help-changelog-drift.sh; bash tests/test-ui-bare-loki.sh; bash tests/test-local-ci-gitleaks.sh | ready@2026-10-17T09:20Z | Diagnosis 2026-10-17 by nightly diag agent; one FAILURE-CLASSES row per class |
1183
- | TEN-STABILITY-19 | P0 fix-forward: moat P8.ablation-dead-code-not-sealed positive control headline VERIFIED WITH GAPS (expected VERIFIED) and first-run-gate --stub FAILED with dirty tracked tree M sum.js at intake.ts:61 | tests/moat/p8-*.sh or the ablation producer, scripts/first-run-gate.sh, loki-ts/src/engine10/stages/intake.ts only if the honest fix is there | HIGH | red: bash tests/moat/run.sh prints moat suite: FAIL (1 rule failure(s)); bash scripts/first-run-gate.sh --stub fails 7 assertions; green: both exit 0 | ready@2026-10-17T09:20Z | Diagnosis 2026-10-17; never weaken a moat assertion to pass |
1182
+ | TEN-STABILITY-18 | P0 fix-forward: nightly 39016259458 reds still red on main e32ee1b5d (pr_body_golden not-recorded producer util/check_result.ts; sizing wall brief 726 vs cap 616; router_optout_golden wall stage haiku for development; verify.test uv resolution CI-only via Bun.which PATH; test-sigpipe-guard 1737 vs ceiling 1728; help-changelog-drift loki verify --require-exogenous; test-ui-bare-loki exact-match on new control lines; test-local-ci-gitleaks scope) | the failing tests, loki-ts/src/util/check_result.ts, loki-ts/src/engine10/stages/wall.ts, loki-ts/src/engine10/stages/verify.ts, verify help and completions, scripts/local-ci.sh, docs/v10/FAILURE-CLASSES.md | MEDIUM | red: each named test fails on e32ee1b5d; green: cd loki-ts && bun test tests/engine10/pr_body_golden.test.ts tests/engine10/sizing.test.ts tests/engine10/router_optout_golden.test.ts tests/engine10/verify.test.ts tests/util; bash tests/test-sigpipe-guard.sh; bash tests/test-help-changelog-drift.sh; bash tests/test-ui-bare-loki.sh; bash tests/test-local-ci-gitleaks.sh | released v11.17.42 | Diagnosis 2026-10-17 by nightly diag agent; one FAILURE-CLASSES row per class |
1183
+ | TEN-STABILITY-19 | P0 fix-forward: moat P8.ablation-dead-code-not-sealed positive control headline VERIFIED WITH GAPS (expected VERIFIED) and first-run-gate --stub FAILED with dirty tracked tree M sum.js at intake.ts:61 | tests/moat/p8-*.sh or the ablation producer, scripts/first-run-gate.sh, loki-ts/src/engine10/stages/intake.ts only if the honest fix is there | HIGH | red: bash tests/moat/run.sh prints moat suite: FAIL (1 rule failure(s)); bash scripts/first-run-gate.sh --stub fails 7 assertions; green: both exit 0 | released v11.17.42 | Diagnosis 2026-10-17; never weaken a moat assertion to pass |
1184
1184
  | TEN-SECURITY-04 | fix: redactSecrets also strips GitLab (glpat-), npm (npm_), Hugging Face (hf_), Stripe (sk_live_, rk_live_) tokens and PEM private key blocks | loki-ts/src/util/redact.ts, loki-ts/tests/util/redact.test.ts | HIGH | red: each of the five token shapes and a -----BEGIN PRIVATE KEY----- block survive redactSecrets; green: all replaced with [REDACTED:...] markers, existing rules and ordering unchanged; cd loki-ts && bunx tsc --noEmit && bun test tests/util/redact.test.ts | released v11.17.40 | Gap: redact.ts RULES (lines 3-14) cover Anthropic, GitHub, Slack, AWS, JWT, Google, OpenAI, Bearer, URL userinfo; grep -rnE 'glpat or npm_ or hf_ or BEGIN [A-Z ]*PRIVATE or sk_live' loki-ts/src/util/redact.ts returned 0 hits (export_sarif.ts:18 and contrib/ai_bom.ts:83 know the shapes but are not the redactor). Specific rules before generic, keep ReDoS-safe quantifiers. |
1185
1185
  | TEN-SECURITY-05 | enhancement: redactSecrets strips secret query parameters (token, access_token, api_key, apikey, password, secret, sig) from URLs in logged and receipted output | loki-ts/src/util/redact.ts, loki-ts/tests/util/redact.test.ts | HIGH | red: https://h/x?access_token=abc123 survives; green: value replaced, parameter name and other params kept, non-secret params untouched; cd loki-ts && bunx tsc --noEmit && bun test tests/util/redact.test.ts | released v11.17.41 | Gap: TEN-SECURITY-02 covers URL userinfo and Authorization only (redact.ts:12-13); grep -nE 'access_token or api_key or \?' loki-ts/src/util/redact.ts returned 0 query-string rules. Serialize after TEN-SECURITY-04 (same two files). |
1186
1186
  | TEN-SECURITY-06 | feature: secure-scan rule 6 flags disabled TLS verification in committed code (verify=False, rejectUnauthorized: false, InsecureSkipVerify: true, NODE_TLS_REJECT_UNAUTHORIZED=0) | autonomy/lib/secure-scan.py, tests/test-secure-scan.sh | HIGH | red: a fixture with requests.get(url, verify=False) scans clean; green: finding rule tls-verify-disabled with file and line, test and fixture paths and comments excluded like rule 4; bash tests/test-secure-scan.sh | released v11.17.41 | Gap: secure-scan.py has rules 1-5 only (rule comments at lines 93, 105, 193, 238, 345); grep -nE 'verify=False or rejectUnauthorized or InsecureSkipVerify or NODE_TLS' autonomy/lib/secure-scan.py returned 0 hits. Bump RULES_VERSION (line 49). Serialize after TEN-GATES-20 and before TEN-SECURITY-07. |
@@ -1040,3 +1040,45 @@ L0 review rule (ENGINE-LAWS.md L0): a fix that adds an `if` or a regex about the
1040
1040
  - Siblings: util/outbox.ts runOnce (TEN-STABILITY-12, already quarantines); queue run reads the queue and returns "queue is empty" without writing, so it cannot overwrite; its end-of-run writeQueue only follows a successful read.
1041
1041
  - Mechanism: queueAdd calls quarantineCorruptQueue, which renames the bad file to issue-queue.json.corrupt-<ts> and warns once on stderr before the read.
1042
1042
  - Fixture: loki-ts/tests/commands/queue.test.ts "add on a corrupt queue file quarantines it".
1043
+
1044
+ ## FC-TEN-STABILITY-18a Test pins a literal that an intentional change moved, and the pin is not updated in the same slice (STALE-PIN-AFTER-INTENT)
1045
+ - User-visible vs raw: raw (test infrastructure). Nightly 39016259458 stayed red on main e32ee1b5d: pr_body_golden producer registry (util/check_result.ts moved the gate line there, TEN-STABILITY-13), sizing wall brief cap (710 measured vs 600; TEN-COST-14 output budget plus TEN-QUALITY-14 negative-case sentence), router_optout_golden (TEN-COST-11 haiku-first Wall), test-ui-bare-loki (TEN-UX-10 next-step lines), test-local-ci-gitleaks (TEN-SEC-GITLEAKS-01-F1 first-parent log-opts).
1046
+ - Law broken: a slice that changes an asserted surface owns the guards that assert it; green on the slice branch is not green on main when the change landed after the pin.
1047
+ - Siblings: the five pins above (all fixed). The sizing cap now records its measured number; the router golden pins LOKI_E10_WALL_FIRST=0 so it isolates router behavior (wall.test.ts owns haiku-first).
1048
+ - Mechanism: each guard names the owning change in a comment and asserts the intended new shape (first line plus next-step lines; the exact log-opts string), never a weaker match.
1049
+ - Fixture: tests/test-ui-bare-loki.sh "the URL is followed by the start and stop next-step lines"; tests/test-local-ci-gitleaks.sh exact log-opts grep and live invocation mirror.
1050
+
1051
+ ## FC-TEN-STABILITY-18b Bun.which reads the PATH captured at process start, so a test or caller that mutates process.env.PATH is ignored (BUN-WHICH-STALE-PATH)
1052
+ - User-visible vs raw: raw (CI only). verify.test.ts TEN-QUALITY-11 cases passed on a machine with uv installed and failed in CI without it: resolveTool asked Bun.which("uv") and never saw the fake uv prepended to process.env.PATH.
1053
+ - Law broken: tool resolution must use the same PATH the child process will receive.
1054
+ - Siblings: verify.ts resolveTool (fixed, both uv and fallback lookups); provider_failover.ts defaultInstalled, deep.ts:104 and modernize/lang/java.ts:159 call Bun.which without the live PATH when no path option is given (named, not changed: production PATH is fixed at start, no test mutates it).
1055
+ - Mechanism: resolveTool's onPath helper passes {PATH: process.env.PATH}.
1056
+ - Fixture: verify.test.ts TEN-QUALITY-11 cases, run with PATH=/usr/bin:/bin plus the bun directory (no uv): red before the fix (2 fail), green after.
1057
+
1058
+ ## FC-TEN-STABILITY-18c A verify flag exists in the engine10 verifier and completions but the dispatcher rejects it and help omits it (VERIFY-FLAG-NOT-ROUTED)
1059
+ - User-visible vs raw: user-visible. `loki verify --require-exogenous` (the CHANGELOG form) printed "[verify][error] unknown option" from the legacy verifier, and `loki verify --help` did not list the flag.
1060
+ - Law broken: a documented flag must reach the implementation that owns it, and its help must list it.
1061
+ - Siblings: --allow-unsigned and --export-dsse also lack a flag-first route in bin/loki (they work after a run id or receipt path); named, not changed here.
1062
+ - Mechanism: bin/loki and autonomy/loki cmd_verify route --require-exogenous to engine10 like --pubkey; autonomy/verify.sh help lists it.
1063
+ - Fixture: tests/test-help-changelog-drift.sh (flag in help); `bash bin/loki verify --require-exogenous` now reaches engine10 ("no runs found") instead of the unknown-option error.
1064
+
1065
+ ## FC-TEN-STABILITY-18d The legacy echo-into-grep-q ratchet is breached by new tests and the ceiling is the only guard (SIGPIPE-RATCHET-BREACH)
1066
+ - User-visible vs raw: raw (test infrastructure). tests/test-sigpipe-guard.sh counted 1737 legacy forms against a ceiling of 1728.
1067
+ - Law broken: the ceiling is lowered when a suite is converted, never raised (the guard's own header).
1068
+ - Siblings: 15 forms converted in test-next-resume-agree.sh (7), test-security-audit-config.sh (6) and test-doctor-ux.sh (2); the ceiling now equals the new count, 1722. Large holders remain (test-v10-pulse.sh 321, test-deploy-receipt-gate.sh 38).
1069
+ - Mechanism: grep -q PATTERN <<<"$var" here-string form.
1070
+ - Fixture: tests/test-sigpipe-guard.sh; SIGPIPE_GUARD_CEILING=1721 turns it red (count 1722 exceeds ceiling 1721).
1071
+
1072
+ ## FC-TEN-STABILITY-19a A headline policy change silently disarmed a moat positive control (MOAT-CONTROL-POLICY-DRIFT)
1073
+ - User-visible vs raw: raw (moat suite). `bash tests/moat/run.sh` printed "moat suite: FAIL (1 rule failure(s))": P8.ablation-dead-code-not-sealed got "positive control: load-bearing fixture headline=VERIFIED WITH GAPS, expected VERIFIED". The raw cause was TEN-GATES-10 (c6796b75b, D104): VERIFIED now needs one agent-independent fact beside the agent's suite, and the P8 fixture recorded only the suite (build marked not applicable), so every P8 fixture got an exogenous_evidence gap. The dead-code assertion "headline is not VERIFIED" then held for the wrong reason: removing the not_load_bearing rule from _compute_headline no longer turned it red.
1074
+ - Law broken: a negative assertion is evidence only while its positive control reaches the green state under the CURRENT headline rules; a headline rule change must re-green every moat control it touches.
1075
+ - Siblings: tests/test-proof-ablation-headline.sh (passes; it pins facts.ablation, not the headline); tests/test_proof_generator.py (updated by TEN-GATES-10 itself); P1-P7 and P9 were green on the same run, so no other moat control reads a suite-only VERIFIED.
1076
+ - Mechanism: the P8 fixture records a real build fact (byte-compiling every source file, exit code recorded, no .pyc written) so the control meets D104; the moat rule and the generator are unchanged.
1077
+ - Fixture: tests/moat/p8-load-bearing-proof.sh. Red with the build exit code forced to 1 (control headline=NOT VERIFIED), and red with the generator's not_load_bearing check mutated ("headline is VERIFIED although the checks pass with the change no-oped"), which was undetectable before this fix.
1078
+
1079
+ ## FC-TEN-STABILITY-19b The first-run gate stub treated the login probe as a work session (STUB-AUTH-STATUS-SILENT recurrence)
1080
+ - User-visible vs raw: raw (release gate). `bash scripts/first-run-gate.sh --stub` failed 7 assertions, all from "Reason: dirty tracked tree: M sum.js" at intake.ts:61, plus a python FileNotFoundError traceback from the cost-non-null probe. The engine preflight (TEN-UX-01, 08a8ae052) runs `claude auth status` in the repo before Intake; the gate's heredoc stub short-circuited only --help/--version, so the probe applied the sum.js fix and Intake refused the dirty tree. The real CLI's auth status is read-only, so users never saw this.
1081
+ - Law broken: same as FC-TEN-STABILITY-09: a stub provider must honour every CLI call the engine makes before a session.
1082
+ - Siblings: FC-TEN-STABILITY-09 fixed the loki-ts/tests stubs but not scripts/first-run-gate.sh (fixed here). scripts/b9-scoreboard.sh already answers auth. tests/test-quick-config-safety.sh, test-quick-receipt-order.sh, test-quick-artifacts.sh, test-json-schemas.sh and test-usage-governor.sh all pass on this base (their stubs do not edit the tree on the probe).
1083
+ - Mechanism: the gate stub answers `auth status` with {"loggedIn": true}, no side effects; the cost-non-null probe reports an unreadable run record as a FAIL line instead of a traceback.
1084
+ - Fixture: loki-ts/tests/engine10/e2e.test.ts "every engine10 stub claude answers claude auth status as logged in" now also pins the first-run gate stub (red with the stub line removed); the gate itself returns to 7 failures with that line removed.
@@ -2503,3 +2503,6 @@ v11.17.21 published (Release success on 462fbc40a; npm latest 11.17.21, next 11.
2503
2503
 
2504
2504
  ## 2026-10-17T09:37Z (CoS) v11.17.41
2505
2505
  - v11.17.41: wave AJ, 9 of 9 slices approved and merged cleanly; tests/util plus budget and L0 guards 446 pass 0 fail, tsc clean outside control-plane. Follow-ups noted by reviewers: doctor JSON path still serial, help-changelog-drift red (TEN-STABILITY-18 owns it).
2506
+
2507
+ ## 2026-10-17T09:41Z (CoS) v11.17.42
2508
+ - v11.17.42: TEN-STABILITY-18 and TEN-STABILITY-19 merged; FAILURE-CLASSES append conflicts resolved as union. Results: tests/util plus pr_body_golden, sizing, router_optout_golden, verify, budget and l0 guards 538 pass 0 fail. sigpipe, ui-bare and local-ci-gitleaks rc 0; first-run-gate --stub 0 assertions failed. help-changelog-drift still red on new v11.17.40 flags (report --since, undo --list); TEN-STABILITY-20 dispatched.
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var rw0=Object.create;var{getPrototypeOf:tw0,defineProperty:OW,getOwnPropertyNames:vd,getOwnPropertyDescriptor:ew0}=Object,hd=Object.prototype.hasOwnProperty;function fd(Z){return this[Z]}var Z_0,$_0,J_0=(Z,$,J)=>{var X=Z!=null&&typeof Z==="object";if(X){var Y=$?Z_0??=new WeakMap:$_0??=new WeakMap,z=Y.get(Z);if(z)return z}J=Z!=null?rw0(tw0(Z)):{};let Q=$||!Z||!Z.__esModule?OW(J,"default",{value:Z,enumerable:!0}):J;for(let W of vd(Z))if(!hd.call(Q,W))OW(Q,W,{get:fd.bind(Z,W),enumerable:!0});if(X)Y.set(Z,Q);return Q},X_0=(Z)=>{var $=(yd??=new WeakMap).get(Z),J;if($)return $;if($=OW({},"__esModule",{value:!0}),Z&&typeof Z==="object"||typeof Z==="function"){for(var X of vd(Z))if(!hd.call($,X))OW($,X,{get:fd.bind(Z,X),enumerable:!(J=ew0(Z,X))||J.enumerable})}return yd.set(Z,$),$},yd,RB=(Z,$)=>()=>($||Z(($={exports:{}}).exports,$),$.exports);var Y_0=(Z)=>Z;function z_0(Z,$){this[Z]=Y_0.bind(null,$)}var O0=(Z,$)=>{for(var J in $)OW(Z,J,{get:$[J],enumerable:!0,configurable:!0,set:z_0.bind($,J)})};var S=(Z,$)=>()=>(Z&&($=Z(Z=0)),$);var m9=import.meta.require;var md={};O0(md,{lokiDir:()=>P0,homeLokiDir:()=>Z2,findRepoRootForVersion:()=>tT,REPO_ROOT:()=>j0});import{resolve as sZ,dirname as rT}from"path";import{fileURLToPath as Q_0}from"url";import{existsSync as EB}from"fs";import{homedir as W_0}from"os";function K_0(){let Z=gd;for(let $=0;$<6;$++){if(EB(sZ(Z,"VERSION"))&&EB(sZ(Z,"autonomy/run.sh")))return Z;let J=rT(Z);if(J===Z)break;Z=J}return sZ(gd,"..","..","..")}function tT(Z){let $=Z;for(let J=0;J<6;J++){if(EB(sZ($,"VERSION"))&&EB(sZ($,"autonomy/run.sh")))return $;let X=rT($);if(X===$)break;$=X}return sZ(Z,"..","..","..")}function P0(){return process.env.LOKI_DIR??sZ(process.cwd(),".loki")}function Z2(){return sZ(W_0(),".loki")}var gd,j0;var n0=S(()=>{gd=rT(Q_0(import.meta.url));j0=K_0()});import{readFileSync as V_0}from"fs";import{resolve as G_0,dirname as H_0}from"path";import{fileURLToPath as q_0}from"url";function Y6(){if(Z1!==null)return Z1;let Z="11.17.41";if(typeof Z==="string"&&Z.length>0)return Z1=Z,Z1;try{let $=H_0(q_0(import.meta.url)),J=tT($);Z1=V_0(G_0(J,"VERSION"),"utf-8").trim()}catch{Z1="unknown"}return Z1}var Z1=null;var rZ=S(()=>{n0()});import{mkdirSync as ud,readFileSync as ZP,realpathSync as U_0,statSync as B_0,writeFileSync as pd}from"fs";import{dirname as AW,join as eT,resolve as cd}from"path";function A_0(){return cd(Z2(),"cache","update-check.json")}function tZ(Z){let $=/^(\d+)\.(\d+)\.(\d+)$/.exec(Z.trim());if(!$)return null;return[Number($[1]),Number($[2]),Number($[3])]}function LW(Z,$){let J=tZ(Z),X=tZ($);if(!J||!X)return!1;let[Y,z,Q]=J,[W,K,V]=X;if(Y!==W)return Y>W;if(z!==K)return z>K;return Q>V}function dd(){if(process.env.LOKI_NO_UPDATE_CHECK==="1")return!0;if(process.env.CI)return!0;if(!process.stdout.isTTY)return!0;return!1}function L_0(Z){try{let $=ZP(Z,"utf-8"),J=JSON.parse($);if(typeof J.checkedAt==="number"&&typeof J.latest==="string"&&tZ(J.latest)!==null)return{checkedAt:J.checkedAt,latest:J.latest}}catch{}return null}function j_0(Z,$){try{ud(AW(Z),{recursive:!0}),pd(Z,JSON.stringify($),"utf-8")}catch{}}async function F_0(){try{let Z=await fetch(N_0,{signal:AbortSignal.timeout(O_0),headers:{accept:"application/json"}});if(!Z.ok)return null;let $=await Z.json();if(typeof $.version==="string"&&tZ($.version)!==null)return $.version}catch{}return null}async function C_0(Z=Date.now(),$=F_0,J=A_0()){let X=L_0(J);if(X&&Z-X.checkedAt<M_0)return X.latest;let Y=await $();if(Y===null)return null;return j_0(J,{checkedAt:Z,latest:Y}),Y}function I_0(Z,$=process.env){if(tZ(Z)===null)return null;let X=$.PATH;if(!X)return null;let Y=new Set;for(let z of X.split(":")){if(!z)continue;let Q=eT(z,"loki"),W;try{B_0(Q),W=U_0(Q)}catch{continue}if(Y.has(W))continue;Y.add(W);try{let K=eT(AW(AW(W)),"package.json"),V=JSON.parse(ZP(K,"utf8")).version;if(typeof V!=="string")continue;if(LW(V,Z))return{path:Q,version:V}}catch{continue}}return null}function T_0(){return cd(Z2(),"cache","last-seen-version.json")}function P_0(Z,$={}){try{if(dd())return!1;if(tZ(Z)===null)return!1;let J=$.seenFile??T_0(),X=null;try{let z=JSON.parse(ZP(J,"utf-8")).version;if(typeof z==="string"&&tZ(z)!==null)X=z}catch{}if(X!==null&&!LW(Z,X))return!1;try{ud(AW(J),{recursive:!0}),pd(J,JSON.stringify({version:Z}),"utf-8")}catch{return!1}if(X===null)return!1;return($.write??((z)=>process.stderr.write(z)))(`Loki Mode upgraded ${X} -> ${Z}. What is new: https://github.com/asklokesh/loki-mode/releases/tag/v${Z}
2
+ var rw0=Object.create;var{getPrototypeOf:tw0,defineProperty:OW,getOwnPropertyNames:vd,getOwnPropertyDescriptor:ew0}=Object,hd=Object.prototype.hasOwnProperty;function fd(Z){return this[Z]}var Z_0,$_0,J_0=(Z,$,J)=>{var X=Z!=null&&typeof Z==="object";if(X){var Y=$?Z_0??=new WeakMap:$_0??=new WeakMap,z=Y.get(Z);if(z)return z}J=Z!=null?rw0(tw0(Z)):{};let Q=$||!Z||!Z.__esModule?OW(J,"default",{value:Z,enumerable:!0}):J;for(let W of vd(Z))if(!hd.call(Q,W))OW(Q,W,{get:fd.bind(Z,W),enumerable:!0});if(X)Y.set(Z,Q);return Q},X_0=(Z)=>{var $=(yd??=new WeakMap).get(Z),J;if($)return $;if($=OW({},"__esModule",{value:!0}),Z&&typeof Z==="object"||typeof Z==="function"){for(var X of vd(Z))if(!hd.call($,X))OW($,X,{get:fd.bind(Z,X),enumerable:!(J=ew0(Z,X))||J.enumerable})}return yd.set(Z,$),$},yd,RB=(Z,$)=>()=>($||Z(($={exports:{}}).exports,$),$.exports);var Y_0=(Z)=>Z;function z_0(Z,$){this[Z]=Y_0.bind(null,$)}var O0=(Z,$)=>{for(var J in $)OW(Z,J,{get:$[J],enumerable:!0,configurable:!0,set:z_0.bind($,J)})};var S=(Z,$)=>()=>(Z&&($=Z(Z=0)),$);var m9=import.meta.require;var md={};O0(md,{lokiDir:()=>P0,homeLokiDir:()=>Z2,findRepoRootForVersion:()=>tT,REPO_ROOT:()=>j0});import{resolve as sZ,dirname as rT}from"path";import{fileURLToPath as Q_0}from"url";import{existsSync as EB}from"fs";import{homedir as W_0}from"os";function K_0(){let Z=gd;for(let $=0;$<6;$++){if(EB(sZ(Z,"VERSION"))&&EB(sZ(Z,"autonomy/run.sh")))return Z;let J=rT(Z);if(J===Z)break;Z=J}return sZ(gd,"..","..","..")}function tT(Z){let $=Z;for(let J=0;J<6;J++){if(EB(sZ($,"VERSION"))&&EB(sZ($,"autonomy/run.sh")))return $;let X=rT($);if(X===$)break;$=X}return sZ(Z,"..","..","..")}function P0(){return process.env.LOKI_DIR??sZ(process.cwd(),".loki")}function Z2(){return sZ(W_0(),".loki")}var gd,j0;var n0=S(()=>{gd=rT(Q_0(import.meta.url));j0=K_0()});import{readFileSync as V_0}from"fs";import{resolve as G_0,dirname as H_0}from"path";import{fileURLToPath as q_0}from"url";function Y6(){if(Z1!==null)return Z1;let Z="11.17.42";if(typeof Z==="string"&&Z.length>0)return Z1=Z,Z1;try{let $=H_0(q_0(import.meta.url)),J=tT($);Z1=V_0(G_0(J,"VERSION"),"utf-8").trim()}catch{Z1="unknown"}return Z1}var Z1=null;var rZ=S(()=>{n0()});import{mkdirSync as ud,readFileSync as ZP,realpathSync as U_0,statSync as B_0,writeFileSync as pd}from"fs";import{dirname as AW,join as eT,resolve as cd}from"path";function A_0(){return cd(Z2(),"cache","update-check.json")}function tZ(Z){let $=/^(\d+)\.(\d+)\.(\d+)$/.exec(Z.trim());if(!$)return null;return[Number($[1]),Number($[2]),Number($[3])]}function LW(Z,$){let J=tZ(Z),X=tZ($);if(!J||!X)return!1;let[Y,z,Q]=J,[W,K,V]=X;if(Y!==W)return Y>W;if(z!==K)return z>K;return Q>V}function dd(){if(process.env.LOKI_NO_UPDATE_CHECK==="1")return!0;if(process.env.CI)return!0;if(!process.stdout.isTTY)return!0;return!1}function L_0(Z){try{let $=ZP(Z,"utf-8"),J=JSON.parse($);if(typeof J.checkedAt==="number"&&typeof J.latest==="string"&&tZ(J.latest)!==null)return{checkedAt:J.checkedAt,latest:J.latest}}catch{}return null}function j_0(Z,$){try{ud(AW(Z),{recursive:!0}),pd(Z,JSON.stringify($),"utf-8")}catch{}}async function F_0(){try{let Z=await fetch(N_0,{signal:AbortSignal.timeout(O_0),headers:{accept:"application/json"}});if(!Z.ok)return null;let $=await Z.json();if(typeof $.version==="string"&&tZ($.version)!==null)return $.version}catch{}return null}async function C_0(Z=Date.now(),$=F_0,J=A_0()){let X=L_0(J);if(X&&Z-X.checkedAt<M_0)return X.latest;let Y=await $();if(Y===null)return null;return j_0(J,{checkedAt:Z,latest:Y}),Y}function I_0(Z,$=process.env){if(tZ(Z)===null)return null;let X=$.PATH;if(!X)return null;let Y=new Set;for(let z of X.split(":")){if(!z)continue;let Q=eT(z,"loki"),W;try{B_0(Q),W=U_0(Q)}catch{continue}if(Y.has(W))continue;Y.add(W);try{let K=eT(AW(AW(W)),"package.json"),V=JSON.parse(ZP(K,"utf8")).version;if(typeof V!=="string")continue;if(LW(V,Z))return{path:Q,version:V}}catch{continue}}return null}function T_0(){return cd(Z2(),"cache","last-seen-version.json")}function P_0(Z,$={}){try{if(dd())return!1;if(tZ(Z)===null)return!1;let J=$.seenFile??T_0(),X=null;try{let z=JSON.parse(ZP(J,"utf-8")).version;if(typeof z==="string"&&tZ(z)!==null)X=z}catch{}if(X!==null&&!LW(Z,X))return!1;try{ud(AW(J),{recursive:!0}),pd(J,JSON.stringify({version:Z}),"utf-8")}catch{return!1}if(X===null)return!1;return($.write??((z)=>process.stderr.write(z)))(`Loki Mode upgraded ${X} -> ${Z}. What is new: https://github.com/asklokesh/loki-mode/releases/tag/v${Z}
3
3
  `),!0}catch{return!1}}async function ld(Z,$={}){try{if(dd())return;if(tZ(Z)===null)return;let J=$.write??((z)=>process.stderr.write(z));P_0(Z,{write:J,...$.cacheFile?{seenFile:eT(AW($.cacheFile),"last-seen-version.json")}:{}});let X=I_0(Z,$.env??process.env);if(X!==null){J(`Loki Mode ${X.version} is installed but not the one running (you are running ${Z}).
4
4
  Another loki earlier on PATH is winning. Newer copy: ${X.path}
5
5
  Run \`which -a loki\` to see the order, then remove or re-point the earlier entry.
@@ -744,7 +744,7 @@ ${G.stderr}`,U=G.exitCode===0?void 0:await Dz({repoDir:Z.repoDir,baseSha:Z.baseS
744
744
  `).map((O)=>O.trim()).filter(Boolean),N=H.findings.filter((O)=>String(O.severity).toUpperCase()==="HIGH");if(G.exitCode===3)q.push("secret-scan.sh failed to load");if(!H.ok)q.push(H.error??"secure-scan failed");if(B.length>0)U.push(`secret match: ${B.join(", ")}`);if(N.length>0)U.push(`secure-scan: ${N.map((O)=>`${O.rule}: ${O.file}:${O.line}`).join(", ")}`);let M=U.length>0?"fail":q.length>0?"not_run":"pass";if(X.push({name:"security scan",cmd:"secret-scan.sh + secure-scan.py",result:M,duration_s:(Date.now()-V)/1000,...M==="pass"?{}:{reason:(M==="fail"?U:q).join("; ")}}),M==="not_run")Y.add(`not run: security scan (${q.join("; ")})`)}function Yc8(Z,$){return["comment",Z,$]}function zc8(Z,$,J){let X=[`## Loki deep verify: ${J}`,"","### Checks"];return X.push(...Z.length?Z.map((Y)=>`- ${Y.result}: ${Y.name}${Y.reason?` (${Y.reason})`:""}`):["- none"]),X.push("","### NOT PROVEN",...$.length?$.map((Y)=>`- ${Y}`):["- none"]),`${X.join(`
745
745
  `)}
746
746
  `}async function Qc8(Z,$,J,X,Y){let z=[],Q=Z.pinnedOrigin;if(!Q)return z.push("push refused: no pinned origin (Rule of Two)"),z;let W=$.pushScriptPath??QW0,K={...process.env,...$.pushExtraEnv,_LOKI_ORIGIN_PINNED:"1",_LOKI_PINNED_ORIGIN:Q},V=Z.outputs().pr?.pr_url,G=V?rp8.exec(V)?.[1]:void 0;if(G){ib(Z.runDir,{recursive:!0});let q=Z4(Z.runDir,"deep-comment.md");ob(q,zc8(J,X,Y),"utf8");let U=await y0(["bash",W,...Yc8(G,q)],{cwd:Z.repoDir,env:K,timeoutMs:30000});if(U.exitCode!==0)z.push(`deep comment not posted (engine10-push.sh exit ${U.exitCode})`)}else z.push("deep comment not posted (no PR number)");let H=(await G9(Z.repoDir,["rev-parse","HEAD"],{timeoutMs:1e4})).stdout.trim();if(tp8.test(H)){let q={cmd:"status",sha:H,state:Y,description:`Loki 10 deep verify: ${Y}`},U=await y0(["bash",W,...i2(q)],{cwd:Z.repoDir,env:K,timeoutMs:30000});if(U.exitCode!==0)z.push(`loki/deep-verify status not set (engine10-push.sh exit ${U.exitCode})`)}else z.push("loki/deep-verify status not set (HEAD sha not resolvable)");return z}async function VW0(Z,$,J={}){if($.aborted)return{status:"failed",data:{},reason:"aborted before deep verify started"};try{qj(J.env??process.env)}catch(N){return{status:"failed",data:{},reason:N.message}}let X;try{X=FZ(Z.repoDir,Z.baseSha)}catch(N){return{status:"failed",data:{},reason:`git diff against base failed: ${N.message}`}}let Y=[],z=new Set;await KW0(Z,$,J,Y,z),await Zc8(Z,J,Y,z),await $c8(Z,X,Z.baseSha,$,J,Y,z),await Xc8(Z,X,J,Y,z);let Q=Y.some((N)=>N.result==="fail")?"failure":"success",W=[...z],K=Z.outputs().seal,V={schema:"loki.v10.receipt-addendum/1",run_id:Z.runId,base_receipt_sha256:K?.receipt_sha256??null,checks:Y,not_proven:W,status_state:Q},G=L7(n5(V)),H=h4(`${Z.runId}-deep`,G),q={...V,addendum_sha256:G,verification:{jwt:H.jwt,kid:H.kid}};ib(Z.runDir,{recursive:!0}),ob(Z4(Z.runDir,"receipt-addendum-1.json"),JSON.stringify(q,null,2)+`
747
- `);let U=await Qc8(Z,J,Y,W,Q),B=[...W,...U];return Z.emit("deep.completed","deep",{checks:Y,status_state:Q,addendum_sha256:G}),{status:"completed",data:{checks:Y,addendum_sha256:G,status_state:Q,not_proven:B}}}var QW0,WW0,np8=400000,sp8=600,ZW0=300000,rp8,tp8,ep8,GW0,Wc8;var sb=S(()=>{Pb();dL();O9();uL();ab();f4();pG();eQ0();A6();KG();r9();$Z();x0();QW0=new URL("../../../../autonomy/lib/engine10-push.sh",import.meta.url).pathname,WW0=new URL("../../../../autonomy/lib/secret-scan.sh",import.meta.url).pathname,rp8=/\/pull\/(\d+)$/,tp8=/^[0-9a-f]{40}$/,ep8={pytest:{cmd:"python",args:["-m","pytest","-q"]},vitest:{cmd:"npx",args:["vitest","run"]},jest:{cmd:"npx",args:["jest"]},bun:{cmd:"bun",args:["test"]},node:{cmd:"node",args:["--test"]},npm:{cmd:"npm",args:["test","--silent"]},go:{cmd:"go",args:["test","-json","./..."]},cargo:{cmd:"cargo",args:["test"]}};GW0={name:"deep",...y9.deep,run:(Z,$)=>VW0(Z,$,{council:zW0(Z.sessions)})},Wc8=GW0});var LW0={};O0(LW0,{verifyStage:()=>AW0,testConfigChanged:()=>hL,testCheckName:()=>J$,stage:()=>Oc8,skipped:()=>qG,runnerCmd:()=>BW0,runLintChecks:()=>OW0,runCheck:()=>v4,ran:()=>HG,firstError:()=>MW0,commandFor:()=>TZ,changedFiles:()=>FZ});import{existsSync as iG,mkdtempSync as Kc8,realpathSync as HW0,rmSync as Vc8}from"fs";import{tmpdir as Gc8}from"os";import{dirname as Hc8,isAbsolute as qW0,join as PZ,relative as eb}from"path";function UW0(Z,$,J,X=J){let Y=(W)=>{try{let K=eb(HW0(Z),HW0(W));return K!==""&&!K.startsWith("..")&&!qW0(K)}catch{return!1}},z=process.env.VIRTUAL_ENV,Q=[PZ(Z,".venv","bin",$),PZ(Z,"venv","bin",$),...z&&Y(z)?[PZ(z,"bin",$)]:[]].find(iG);return Q?[Q,"project",[]]:iG(PZ(Z,"uv.lock"))&&Bun.which("uv")?["uv","project",["run","--",$]]:[Bun.which(J)?J:X,"system",[]]}function BW0(Z,$){switch(Z.runner){case"pytest":{let[J,X,Y]=UW0($,"python","python3","python");return[J,[...Y,"-m","pytest","-q",Z.path],X]}case"vitest":return["npx",["vitest","run",Z.path]];case"jest":return["npx",["jest",Z.path]];case"bun":return["bun",["test",Z.path]];case"node":return["node",["--test",`./${Z.path}`]];case"npm":return["npm",["test","--silent"]];case"go":return["go",["test","-json",`./${Hc8(Z.path)}`]];case"cargo":return["cargo",["test"]]}}function TZ(Z,$,J){let X=wx(J,$,Z.path),[Y,z,Q]=BW0(X?{runner:Z.runner,path:X.file}:Z,$);return{cwd:X?.cwd??$,cmd:Y,args:z,argv:[Y,...z],...Q?{interpreter:Q}:{},pkgRoot:X?.root??"."}}async function Uj(Z,$,J,X,Y){if(!Bun.which(Z,{PATH:Y.path??process.env.PATH??""}))return{ok:!1,missing:!0,cut:!1,out:""};let z=AbortSignal.timeout(Y.timeoutMs??Zy),Q=Bun.spawn([Z,...$],{cwd:J,stdin:Y.stdin!==void 0?Buffer.from(Y.stdin):"ignore",stdout:"pipe",stderr:"pipe",signal:AbortSignal.any([X,z]),env:Y.path?{...O6(),PATH:Y.path}:O6()}),W="",K=[Q.stdout,Q.stderr].map((q)=>q.getReader()),V=K.map(async(q)=>{let U=new TextDecoder;for(;;){let B=await q.read().catch(()=>({done:!0,value:void 0}));if(B.done)return;W=(W+U.decode(B.value,{stream:!0})).slice(-65536)}}),G=await Q.exited;await Promise.race([Promise.all(V),new Promise((q)=>setTimeout(q,300))]),K.forEach((q)=>q.cancel().catch(()=>{}));let H=z.aborted||X.aborted;return{ok:G===0&&!H,missing:!1,cut:H,out:H?"":i5(W)}}function MW0(Z){let $=(Y)=>{try{let z=JSON.parse(Y);return typeof z.Action==="string"?z.Action==="output"||z.Action==="build-output"?z.Output??"":"":Y}catch{return Y}},J=Z.slice(-65536).split(`
747
+ `);let U=await Qc8(Z,J,Y,W,Q),B=[...W,...U];return Z.emit("deep.completed","deep",{checks:Y,status_state:Q,addendum_sha256:G}),{status:"completed",data:{checks:Y,addendum_sha256:G,status_state:Q,not_proven:B}}}var QW0,WW0,np8=400000,sp8=600,ZW0=300000,rp8,tp8,ep8,GW0,Wc8;var sb=S(()=>{Pb();dL();O9();uL();ab();f4();pG();eQ0();A6();KG();r9();$Z();x0();QW0=new URL("../../../../autonomy/lib/engine10-push.sh",import.meta.url).pathname,WW0=new URL("../../../../autonomy/lib/secret-scan.sh",import.meta.url).pathname,rp8=/\/pull\/(\d+)$/,tp8=/^[0-9a-f]{40}$/,ep8={pytest:{cmd:"python",args:["-m","pytest","-q"]},vitest:{cmd:"npx",args:["vitest","run"]},jest:{cmd:"npx",args:["jest"]},bun:{cmd:"bun",args:["test"]},node:{cmd:"node",args:["--test"]},npm:{cmd:"npm",args:["test","--silent"]},go:{cmd:"go",args:["test","-json","./..."]},cargo:{cmd:"cargo",args:["test"]}};GW0={name:"deep",...y9.deep,run:(Z,$)=>VW0(Z,$,{council:zW0(Z.sessions)})},Wc8=GW0});var LW0={};O0(LW0,{verifyStage:()=>AW0,testConfigChanged:()=>hL,testCheckName:()=>J$,stage:()=>Oc8,skipped:()=>qG,runnerCmd:()=>BW0,runLintChecks:()=>OW0,runCheck:()=>v4,ran:()=>HG,firstError:()=>MW0,commandFor:()=>TZ,changedFiles:()=>FZ});import{existsSync as iG,mkdtempSync as Kc8,realpathSync as HW0,rmSync as Vc8}from"fs";import{tmpdir as Gc8}from"os";import{dirname as Hc8,isAbsolute as qW0,join as PZ,relative as eb}from"path";function UW0(Z,$,J,X=J){let Y=(K)=>{try{let V=eb(HW0(Z),HW0(K));return V!==""&&!V.startsWith("..")&&!qW0(V)}catch{return!1}},z=process.env.VIRTUAL_ENV,Q=(K)=>Bun.which(K,{PATH:process.env.PATH??""}),W=[PZ(Z,".venv","bin",$),PZ(Z,"venv","bin",$),...z&&Y(z)?[PZ(z,"bin",$)]:[]].find(iG);return W?[W,"project",[]]:iG(PZ(Z,"uv.lock"))&&Q("uv")?["uv","project",["run","--",$]]:[Q(J)?J:X,"system",[]]}function BW0(Z,$){switch(Z.runner){case"pytest":{let[J,X,Y]=UW0($,"python","python3","python");return[J,[...Y,"-m","pytest","-q",Z.path],X]}case"vitest":return["npx",["vitest","run",Z.path]];case"jest":return["npx",["jest",Z.path]];case"bun":return["bun",["test",Z.path]];case"node":return["node",["--test",`./${Z.path}`]];case"npm":return["npm",["test","--silent"]];case"go":return["go",["test","-json",`./${Hc8(Z.path)}`]];case"cargo":return["cargo",["test"]]}}function TZ(Z,$,J){let X=wx(J,$,Z.path),[Y,z,Q]=BW0(X?{runner:Z.runner,path:X.file}:Z,$);return{cwd:X?.cwd??$,cmd:Y,args:z,argv:[Y,...z],...Q?{interpreter:Q}:{},pkgRoot:X?.root??"."}}async function Uj(Z,$,J,X,Y){if(!Bun.which(Z,{PATH:Y.path??process.env.PATH??""}))return{ok:!1,missing:!0,cut:!1,out:""};let z=AbortSignal.timeout(Y.timeoutMs??Zy),Q=Bun.spawn([Z,...$],{cwd:J,stdin:Y.stdin!==void 0?Buffer.from(Y.stdin):"ignore",stdout:"pipe",stderr:"pipe",signal:AbortSignal.any([X,z]),env:Y.path?{...O6(),PATH:Y.path}:O6()}),W="",K=[Q.stdout,Q.stderr].map((q)=>q.getReader()),V=K.map(async(q)=>{let U=new TextDecoder;for(;;){let B=await q.read().catch(()=>({done:!0,value:void 0}));if(B.done)return;W=(W+U.decode(B.value,{stream:!0})).slice(-65536)}}),G=await Q.exited;await Promise.race([Promise.all(V),new Promise((q)=>setTimeout(q,300))]),K.forEach((q)=>q.cancel().catch(()=>{}));let H=z.aborted||X.aborted;return{ok:G===0&&!H,missing:!1,cut:H,out:H?"":i5(W)}}function MW0(Z){let $=(Y)=>{try{let z=JSON.parse(Y);return typeof z.Action==="string"?z.Action==="output"||z.Action==="build-output"?z.Output??"":"":Y}catch{return Y}},J=Z.slice(-65536).split(`
748
748
  `).map((Y)=>(Y.startsWith("{")?$(Y):Y).trim()).filter(Boolean);return(J.find((Y)=>/^(FAILED\s|\u25cf\s.*\u203a|not ok\s|_{3,}\s.+\s_{3,}$)/.test(Y))??J.find((Y)=>/^[\w./-]+\.go:\d+:\d+: \S/.test(Y))??J.find((Y)=>/fail|error/i.test(Y)&&!/^(=|\u2713|ok\b|PASS)/.test(Y))??"").replace(/\d{4}-\d\d-\d\dT[\d:.]+Z?/g,"").replace(/(^|\s)\/(?:[\w.@-]+\/)*[\w.@-]+/g,"$1<path>").replace(/:\d+(?::\d+)?/g,"").replace(/\[?\d+(?:\.\d+)?m?s\]?/g,"").replace(/\s+/g," ").slice(0,160)}async function v4(Z,$,J,X,Y,z,Q={}){let W=Date.now(),K=[J,...X].join(" "),V=Q.kind??"test",G=Q.cwd??Z.repoDir,H=async(O)=>{let L=zJ({kind:V,ok:O.ok,cut:O.cut,missing:O.missing,out:O.out,...Cz(J,X),path:/\.[cm]?[jt]s$/.test(X[X.length-1]??"")?X[X.length-1]:void 0}),j=V==="test"&&!O.ok&&!O.cut&&!O.missing?await Dz({repoDir:Z.repoDir,baseSha:Z.baseSha,out:O.out,cmd:J,args:X,signal:Y,cwd:G,protect:Q.protect,...Q.path?{env:{PATH:Q.path}}:{}}):void 0;if(j)L={result:"not_run",reason:j,owner:"harness"};if(!j&&V==="static"&&!O.ok&&!O.cut&&!O.missing&&Q.wall?.size&&Cz0(O.out,G,Z.repoDir,Q.wall))L={result:"not_run",reason:Fz0,owner:"harness"};let F=O.missing?`${J} not found on PATH`:O.cut?Y.aborted?"aborted":`timed out after ${(Q.timeoutMs??Zy)/1000}s`:L.reason;return{...L,...F?{reason:F}:{}}},q=await Uj(J,X,G,Y,Q),U=await H(q),B=U.result;if(U.result==="fail")q=await Uj(J,X,G,Y,Q),U=await H(q),B=U.result==="not_run"?"not_run":U.result==="pass"?"flaky":"fail";let N=U.reason,M={name:$,cmd:K,result:B,duration_s:(Date.now()-W)/1000,...B==="fail"?{first_error:MW0(q.out),ids:jZ(q.out)}:B==="pass"&&V==="test"?{n:U.n??0,sk:qG(q.out)}:{},...N?{reason:N}:{},...U.owner?{owner:"harness"}:{},...Q.interpreter?{interpreter:Q.interpreter}:{}};if(B==="fail"&&!Q.opaque&&!$$(M))NW0.set(M,tJ0(q.out,Z.repoDir));if(z.push(M),Q.opaque&&M.result!=="pass"&&M.reason)Ob(Z.runDir,{check:$,result:M.result,reason:M.reason});return Z.emit("test.result","verify",Q.opaque?{...tb(M)}:{...M}),M}async function Bc8(Z,$,J,X,Y,z,Q,W){let K={ids:[],names:[],weak:[],cnt:{}},V=J.flatMap((B)=>{let N=X.find((M)=>J$(M)===B.name);return N?[{c:B,t:N}]:[]}),G=V.filter(({t:B})=>!Y.includes(B.path)),H=V.filter(({c:B})=>Q.has(B.name)&&B.result==="pass");if(!(G.some(({c:B})=>B.result==="fail"&&B.ids?.length)||H.length)||W.aborted)return K;let q=Kc8(PZ(Gc8(),"e10-base-")),U=(B)=>{J0(Z.repoDir,B,{stdio:"ignore",repoDrivers:!0})};try{U(["-c","core.hooksPath=/dev/null","worktree","add","--detach",q,Z.baseSha]);let B=new Map;for(let{c:M,t:O}of new Set([...G,...H])){let L=TZ(O,q,$),j=await Uj(L.cmd,L.args,L.cwd,W,{}),F=!j.ok&&!j.cut?jZ(j.out):[];B.set(M,{red:F,n:HG(j.out)??pJ0(j.out),sk:qG(j.out)})}K.weak=H.filter(({c:M})=>(M.sk??0)>B.get(M).sk||(M.n??0)<B.get(M).n).map(({c:M})=>M.name);for(let{c:M}of H)K.cnt[M.name]={b:{run:B.get(M).n,skipped:B.get(M).sk},h:{run:M.n??0,skipped:M.sk??0}};if(J.some((M)=>z.has(M.name)&&M.result==="pass")||H.some(({c:M})=>!K.weak.includes(M.name)&&B.get(M).red.length>0&&(M.n??0)>=B.get(M).n)){for(let{c:M}of G)if(!Q.has(M.name)&&M.result==="fail"&&M.ids?.length&&M.ids.every((O)=>B.get(M).red.includes(O)))K.names.push(M.name),K.ids.push(...M.ids)}}catch{}finally{try{U(["worktree","remove","--force",q])}catch{}Vc8(q,{recursive:!0,force:!0});try{U(["worktree","prune"])}catch{}}return K}function Nc8(Z){return iG(PZ(Z,"scripts","select-tests.sh"))}async function OW0(Z,$,J,X,Y={}){let{api:z,...Q}=Y;Y=Q;let W=[],K=$.filter((G)=>G.endsWith(".py"));if(K.length){let[G,H,q]=UW0(Z.repoDir,"ruff","ruff"),U=await v4(Z,"lint:ruff",G,[...q,"check","--output-format=concise",...K],J,X,{...Y,interpreter:H,kind:"static"});if(await rb(Z,J,U,"ruff",G,[...q,"check"],Z.repoDir,K,Y))W.push(U.name)}let V=$.filter((G)=>G.endsWith(".sh"));if(V.length){await v4(Z,"lint:bash-n","bash",["-c",'for f in "$@"; do bash -n "$f" || exit 1; done',"_",...V],J,X,{...Y,kind:"static"});let G=await v4(Z,"lint:shellcheck","shellcheck",V,J,X,{...Y,kind:"static"});if(await rb(Z,J,G,"shellcheck","shellcheck",[],Z.repoDir,V,Y))W.push(G.name)}for(let G of W10(z,Z.repoDir,$.filter((H)=>/\.(ts|tsx|js|jsx)$/.test(H)))){let H=G.root==="."?"":`:${G.root}`,q=G.root==="."?Y:{...Y,cwd:G.cwd};if(iG(PZ(G.cwd,"tsconfig.json")))await v4(Z,`lint:tsc${H}`,"npx",["tsc","--noEmit","-p","."],J,X,{...q,kind:"static"});if(Mc8.some((U)=>iG(PZ(G.cwd,U)))){let U=await v4(Z,`lint:eslint${H}`,"npx",["eslint",...G.rel],J,X,{...q,kind:"static"});if(await rb(Z,J,U,"eslint","npx",["eslint"],G.cwd,G.rel,q))W.push(U.name)}}return W}var Zy=60000,NW0,$$=(Z)=>Mb(Z.name),tb=(Z)=>({name:"holdout",cmd:"holdout",result:Z.result,duration_s:Z.duration_s,...Z.n!==void 0?{n:Z.n}:{},...Z.sk!==void 0?{sk:Z.sk}:{},...Z.owner?{owner:Z.owner,reason:"holdout infrastructure failure"}:{}}),J$=(Z)=>`${Z.runner}:${Z.path}`,qc8=(Z)=>[...new Map(Z.map(($)=>[`${$.runner}:${$.path}`,$])).values()],Uc8,Mc8,rb=(Z,$,J,X,Y,z,Q,W,K)=>J.result!=="fail"||$.aborted?Promise.resolve(!1):RS(X,z,W,{run:async(V,G)=>{if($.aborted)return null;let H=await Uj(Y,V,Q,AbortSignal.any([$,AbortSignal.timeout(K.timeoutMs??Zy)]),{...K,...G!==void 0?{stdin:G}:{}});return H.missing||H.cut?null:H},base:(V)=>{try{return J0(Z.repoDir,["show",`${Z.baseSha}:${eb(Z.repoDir,PZ(Q,V))}`],{stdio:["ignore","pipe","ignore"]})}catch{return null}}}),AW0,Oc8;var pG=S(()=>{xx();fL();Fb();KG();Cb();uL();Y7();I2();A6();Iz0();kG();r9();C2();x0();o3();A6();A6();fL();NW0=new WeakMap,Uc8=/\.(?:[cm]?[jt]sx?|py|go)$/;Mc8=[".eslintrc",".eslintrc.json",".eslintrc.js",".eslintrc.cjs","eslint.config.js","eslint.config.mjs","eslint.config.cjs"];AW0={name:"verify",targetS:y9.verify.targetS,limitS:y9.verify.limitS,async run(Z,$){let J;try{J=FZ(Z.repoDir,Z.baseSha)}catch(f){return{status:"failed",data:{},reason:`git diff against base failed: ${f.message}`}}if(J.length===0){if(Z.outputs().implement?.exit==="already_done")return{status:"completed",data:{already_satisfied:!0,checks:[],flaky:[],failures_grouped:[],changed_files:[]}};return{status:"failed",data:{changed_files:[]},reason:"empty diff without an already_done marker"}}let X=(()=>{try{let f=nJ0(sJ0(Z.repoDir,Z.baseSha));return US(Z.repoDir,f),f}catch{return null}})(),Y=[],z=H5(Z.repoDir),Q=await Z.tests.detect(Z.repoDir),W=Z.tests.impacted(Q,J),K=Q.tests.filter((f)=>J.includes(f.path)),V=Z.outputs().wall??{},G=new Set((V.files??[]).map((f)=>qW0(f.path)?eb(Z.repoDir,f.path):f.path)),H=Q.tests.filter((f)=>G.has(f.path)),q=Z.outputs().intake,U=Z.tests.impacted(Q,Gz(q?.task??"",t7(q?.repomap_ref))),B=Nz0(qc8([...W,...K,...H,...U]),Z.outputs().verify?.checks),N=B10(Q);if(N.length)Z.emit("test.scoped_out","verify",{tests:N});for(let f of B){if($.aborted)break;let a=TZ(f,Z.repoDir,z);await v4(Z,J$(f),a.cmd,a.args,$,Y,{...a.interpreter?{interpreter:a.interpreter}:{},protect:[...H,...U].includes(f),...a.pkgRoot!=="."?{cwd:a.cwd}:{}})}let M=V.holdout_dir?Yz0(V.holdout_dir,Z.repoDir):null;try{for(let[f,a]of(M?.tests??[]).entries()){if($.aborted)break;let g=a,u=TZ(g,Z.repoDir,z);await v4(Z,`holdout:${f+1}`,u.cmd,u.args,$,Y,{...u.interpreter?{interpreter:u.interpreter}:{},protect:!0,opaque:!0,...u.pkgRoot!=="."?{cwd:u.cwd}:{}})}}finally{M?.cleanup()}if(M?.missing.length){for(let a of M.missing)Ob(Z.runDir,{check:"holdout:store",result:"not_run",reason:a});let f={name:"holdout:store",cmd:"holdout",result:"not_run",duration_s:0,reason:"holdout store unavailable",owner:"harness"};Y.push(f),Z.emit("test.result","verify",{...tb(f)})}let O=new Set([...[...H,...U].map(J$),...Y.filter($$).map((f)=>f.name)]),L=await Bc8(Z,z,Y,B,J,new Set(H.map(J$)),new Set(U.map(J$)),$),j=KL(Z.repoDir,Z.baseSha,Y.filter((f)=>f.result==="fail"&&!L.names.includes(f.name)).map((f)=>({name:f.name,ids:f.ids,eligible:!O.has(f.name)&&!J.includes(f.name.slice(f.name.indexOf(":")+1))})));if(j.introducedChecks=[...new Set(j.introducedChecks.map((f)=>Mb(f)?"holdout":f))],L.names.push(...j.preExistingChecks),L.ids.push(...j.preExistingIds),!$.aborted){let f=await OW0(Z,J,$,Y,{api:z,wall:G});if(L.names.push(...f),f.length)j.line=[j.line,`baseline: ${f.join(", ")} static diagnostics already on base (not blocking)`].filter(Boolean).join("; ");if(Nc8(Z.repoDir))await v4(Z,"select-tests","bash",["scripts/select-tests.sh","--files","-","--run"],$,Y,{kind:"static",stdin:J.join(`
749
749
  `)+`
750
750
  `})}let F=new Set;if(X&&X.tier!=="low"&&!$.aborted){let{runFullSuite:f}=await Promise.resolve().then(() => (sb(),nb)),a=[];await f(Z,$,{},a,F);for(let u of a){let o={name:u.name,cmd:u.cmd,result:u.result,duration_s:u.duration_s,...u.reason?{reason:u.reason}:{}};Y.push(o),Z.emit("test.result","verify",{...o})}let g=PS(Z.repoDir,Z.baseSha,a,Y.filter((u)=>u.result==="fail"&&!L.names.includes(u.name)).flatMap((u)=>u.ids??[]),J);if(L.names.push(...g.preExistingChecks),L.ids.push(...g.preExistingIds),j.introducedChecks.push(...g.introducedChecks),j.line=[j.line,g.line].filter(Boolean).join("; ")||null,a.some((u)=>u.result==="pass"||u.result==="fail"))X=iJ0(X,["full test command","full suite"]),US(Z.repoDir,X)}let I=hL(Z.repoDir,Z.baseSha,J),T=(f)=>Z.tests.impacted(Q,[f]).some((a)=>Y.some((g)=>g.name===J$(a)&&UG([g]))),C=J.filter((f)=>Uc8.test(f)&&!e7(f)&&!G.has(f)&&!I.includes(f)&&!T(f)),R=Y.filter((f)=>f.result==="flaky").map((f)=>$$(f)?"holdout":f.name),D=rJ0,P=Y.filter((f)=>f.result==="fail"&&!L.names.includes(f.name)&&!$$(f)).map((f)=>{let a=$$(f)?"":BS(NW0.get(f)??"",Math.max(0,D));return D-=Buffer.byteLength(a),{signature:f.first_error?`${f.name} ${f.first_error}`:f.name,count:1,sample:a?`${f.cmd}
@@ -3074,4 +3074,4 @@ Unknown commands exit 2 with a suggestion; run 'loki help' for the full list.
3074
3074
  `);{let{suggestCommand:X}=await Promise.resolve().then(() => (Ld(),Lw0)),Y=$===void 0?void 0:X($);if(Y)process.stderr.write(`Did you mean 'loki ${Y}'?
3075
3075
  `)}return process.stderr.write(cw0),2}}wM0();var dw0=()=>globalThis[Symbol.for("loki.ownsStopSignals")]===!0;process.on("SIGINT",()=>{if(!dw0())process.exit(130)});process.on("SIGTERM",()=>{if(!dw0())process.exit(143)});var jz9=await Lz9(Bun.argv.slice(2));process.exit(jz9);
3076
3076
 
3077
- //# debugId=C4FF5EE0C349F31E90360B71FB3A8067
3077
+ //# debugId=C6E93FA4D9E70465BE78DEF9592C0C66
package/mcp/__init__.py CHANGED
@@ -75,4 +75,4 @@ try:
75
75
  except ImportError:
76
76
  __all__ = ['mcp']
77
77
 
78
- __version__ = '11.17.41'
78
+ __version__ = '11.17.42'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "loki-mode",
3
3
  "mcpName": "io.github.asklokesh/loki-mode",
4
- "version": "11.17.41",
4
+ "version": "11.17.42",
5
5
  "description": "An autonomous software factory that knows what it is supposed to deliver, and proves it did.",
6
6
  "keywords": [
7
7
  "agent",
@@ -158,5 +158,5 @@
158
158
  "dependencies": {
159
159
  "@resvg/resvg-wasm": "^2.6.2"
160
160
  },
161
- "gitHead": "511115313f825b09e87a9e4b5ff198b703b8f9de"
161
+ "gitHead": "793125fc22f11b3de37a2a3f27719c1420505ed2"
162
162
  }
@@ -14009,9 +14009,9 @@ function resolveTool(repoDir, bin, fallback, lastResort = fallback) {
14009
14009
  return false;
14010
14010
  }
14011
14011
  };
14012
- const venvEnv = process.env["VIRTUAL_ENV"];
14012
+ const venvEnv = process.env["VIRTUAL_ENV"], onPath = (b) => Bun.which(b, { PATH: process.env["PATH"] ?? "" });
14013
14013
  const project = [join56(repoDir, ".venv", "bin", bin), join56(repoDir, "venv", "bin", bin), ...venvEnv && inRepo(venvEnv) ? [join56(venvEnv, "bin", bin)] : []].find(existsSync36);
14014
- return project ? [project, "project", []] : existsSync36(join56(repoDir, "uv.lock")) && Bun.which("uv") ? ["uv", "project", ["run", "--", bin]] : [Bun.which(fallback) ? fallback : lastResort, "system", []];
14014
+ return project ? [project, "project", []] : existsSync36(join56(repoDir, "uv.lock")) && onPath("uv") ? ["uv", "project", ["run", "--", bin]] : [onPath(fallback) ? fallback : lastResort, "system", []];
14015
14015
  }
14016
14016
  function runnerCmd(t, repoDir) {
14017
14017
  switch (t.runner) {
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "loki-mode",
4
4
  "displayName": "Loki Mode",
5
- "version": "11.17.41",
5
+ "version": "11.17.42",
6
6
  "description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 8 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
7
7
  "author": {
8
8
  "name": "Autonomi",
@@ -1,4 +1,4 @@
1
- import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-BBV2psih.js";import{B as C}from"./Button-5CI0TYxR.js";import{T as $e}from"./trending-up-DgRWrCNb.js";import{C as z}from"./clock-BGhPbAAa.js";import{A as Be,U as ue,M as De}from"./Avatar-CnSNZSx6.js";import{A as J}from"./activity-Di09VZ-C.js";import{R as pe}from"./refresh-cw-DPEeU-0s.js";import{G as ze}from"./globe-CQvcGE8E.js";import{C as Le}from"./chevron-left-lKRP1pKT.js";import{C as je}from"./check-DYPycZns.js";import{D as Y}from"./dollar-sign-adGlfVLa.js";import{U as Te}from"./user-DC2T8RYB.js";import{D as Me}from"./database-LiEeNmyC.js";import{L as Ue}from"./lock-Bivqy2kG.js";import{S as Re}from"./scroll-text-BBMfK4J7.js";import{S as Ie}from"./shield-alert-Dc5xbnOx.js";/**
1
+ import{c as L,r as x,j as e,w as re,Z as ne,m as le,h as ie,p as P,F as ye,U as I,X as ce,L as de,x as oe,M as Ae,T as Z,S as we,l as xe,k as me,y as Ce,E as Fe,a0 as Se,a as U,a2 as he}from"./index-6SmuA6vo.js";import{B as C}from"./Button-Codl3KHK.js";import{T as $e}from"./trending-up-CKCveriW.js";import{C as z}from"./clock-BWn2Jze6.js";import{A as Be,U as ue,M as De}from"./Avatar-DeNmWN6j.js";import{A as J}from"./activity-CmEjbl9p.js";import{R as pe}from"./refresh-cw-C5w6Ak_2.js";import{G as ze}from"./globe-BhnmSAWt.js";import{C as Le}from"./chevron-left-qMIE0cDr.js";import{C as je}from"./check-DgIZol8f.js";import{D as Y}from"./dollar-sign-oHFYulLR.js";import{U as Te}from"./user-B6OJgsvN.js";import{D as Me}from"./database-FLci9a_L.js";import{L as Ue}from"./lock--fYCznSR.js";import{S as Re}from"./scroll-text-C0pBzd-k.js";import{S as Ie}from"./shield-alert-3oKaRgIp.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as l,j as s}from"./index-BBV2psih.js";/**
1
+ import{c as l,j as s}from"./index-6SmuA6vo.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{j as e}from"./index-BBV2psih.js";import{C as r}from"./clock-BGhPbAAa.js";import{C as a}from"./circle-alert-D1rDQ9mD.js";import{C as l}from"./check-DYPycZns.js";const i={completed:"bg-[#1FC5A8]/10 text-[#1FC5A8]",running:"bg-[#553DE9]/10 text-[#553DE9]",failed:"bg-[#C45B5B]/10 text-[#C45B5B]",started:"bg-[#D4A03C]/10 text-[#D4A03C]",empty:"bg-[#F8F4F0] text-[#6B6960]",version:"bg-[#553DE9]/10 text-[#553DE9]"};function o({status:t}){switch(t){case"completed":return e.jsx(l,{size:12});case"running":return e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"animate-ping motion-reduce:animate-none absolute inline-flex h-full w-full rounded-full bg-current opacity-75"}),e.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-current"})]});case"failed":return e.jsx(a,{size:12});case"started":return e.jsx(r,{size:12});default:return null}}function f({status:t,children:n,className:s=""}){return e.jsxs("span",{className:["inline-flex items-center gap-1 rounded-btn px-2.5 py-0.5 text-xs font-semibold",i[t],s].filter(Boolean).join(" "),children:[e.jsx(o,{status:t}),n]})}export{f as B};
1
+ import{j as e}from"./index-6SmuA6vo.js";import{C as r}from"./clock-BWn2Jze6.js";import{C as a}from"./circle-alert-CX8OMfQi.js";import{C as l}from"./check-DgIZol8f.js";const i={completed:"bg-[#1FC5A8]/10 text-[#1FC5A8]",running:"bg-[#553DE9]/10 text-[#553DE9]",failed:"bg-[#C45B5B]/10 text-[#C45B5B]",started:"bg-[#D4A03C]/10 text-[#D4A03C]",empty:"bg-[#F8F4F0] text-[#6B6960]",version:"bg-[#553DE9]/10 text-[#553DE9]"};function o({status:t}){switch(t){case"completed":return e.jsx(l,{size:12});case"running":return e.jsxs("span",{className:"relative flex h-2 w-2",children:[e.jsx("span",{className:"animate-ping motion-reduce:animate-none absolute inline-flex h-full w-full rounded-full bg-current opacity-75"}),e.jsx("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-current"})]});case"failed":return e.jsx(a,{size:12});case"started":return e.jsx(r,{size:12});default:return null}}function f({status:t,children:n,className:s=""}){return e.jsxs("span",{className:["inline-flex items-center gap-1 rounded-btn px-2.5 py-0.5 text-xs font-semibold",i[t],s].filter(Boolean).join(" "),children:[e.jsx(o,{status:t}),n]})}export{f as B};
@@ -1 +1 @@
1
- import{r as p,j as t}from"./index-BBV2psih.js";const m={primary:"bg-[#553DE9] text-white hover:bg-[#4432c4] shadow-button rounded-btn",secondary:"border border-[#553DE9] text-[#553DE9] hover:bg-[#E8E4FD] bg-transparent rounded-btn",ghost:"text-[#36342E] hover:bg-[#F8F4F0] rounded-btn",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border border-[#C45B5B]/20 hover:bg-[#C45B5B]/20 rounded-btn"},b={sm:"px-3 py-1.5 text-xs",md:"px-4 py-2 text-sm",lg:"px-6 py-3 text-base"},u={sm:14,md:16,lg:18};function h({size:e}){return t.jsxs("svg",{className:"animate-spin",width:e,height:e,viewBox:"0 0 24 24",fill:"none",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]})}const B=p.forwardRef(({variant:e="primary",size:o="md",icon:n,iconRight:i,loading:r=!1,disabled:a,className:c="",children:l,...x},d)=>{const s=u[o];return t.jsxs("button",{ref:d,disabled:a||r,className:["inline-flex items-center justify-center gap-2 font-medium transition-colors",m[e],b[o],(a||r)&&"opacity-60 cursor-not-allowed",c].filter(Boolean).join(" "),...x,children:[r?t.jsx(h,{size:s}):n?t.jsx(n,{size:s}):null,l,i&&!r&&t.jsx(i,{size:s})]})});B.displayName="Button";export{B};
1
+ import{r as p,j as t}from"./index-6SmuA6vo.js";const m={primary:"bg-[#553DE9] text-white hover:bg-[#4432c4] shadow-button rounded-btn",secondary:"border border-[#553DE9] text-[#553DE9] hover:bg-[#E8E4FD] bg-transparent rounded-btn",ghost:"text-[#36342E] hover:bg-[#F8F4F0] rounded-btn",danger:"bg-[#C45B5B]/10 text-[#C45B5B] border border-[#C45B5B]/20 hover:bg-[#C45B5B]/20 rounded-btn"},b={sm:"px-3 py-1.5 text-xs",md:"px-4 py-2 text-sm",lg:"px-6 py-3 text-base"},u={sm:14,md:16,lg:18};function h({size:e}){return t.jsxs("svg",{className:"animate-spin",width:e,height:e,viewBox:"0 0 24 24",fill:"none",children:[t.jsx("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),t.jsx("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})]})}const B=p.forwardRef(({variant:e="primary",size:o="md",icon:n,iconRight:i,loading:r=!1,disabled:a,className:c="",children:l,...x},d)=>{const s=u[o];return t.jsxs("button",{ref:d,disabled:a||r,className:["inline-flex items-center justify-center gap-2 font-medium transition-colors",m[e],b[o],(a||r)&&"opacity-60 cursor-not-allowed",c].filter(Boolean).join(" "),...x,children:[r?t.jsx(h,{size:s}):n?t.jsx(n,{size:s}):null,l,i&&!r&&t.jsx(i,{size:s})]})});B.displayName="Button";export{B};
@@ -1,4 +1,4 @@
1
- import{c as $,r as l,j as e,G as we,Q as Se,F as Ce,h as Re,T as U,Z as Ee,a as S,V as Me,S as $e,Y as Te,X as Pe,P as ie,i as Ae,g as ze,C as Ie,l as Le,N as I,J as _e,K as De,O as Fe,u as Oe}from"./index-BBV2psih.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-VZcsEDJl.js";import{C as qe,F as Ge,M as Ue,H as Ke,a as We,G as Ve,T as Qe}from"./thumbs-up-4nFvjqQ-.js";import{C as oe}from"./check-DYPycZns.js";import{C as Ye}from"./clock-BGhPbAAa.js";import{D as Xe}from"./dollar-sign-adGlfVLa.js";import{U as Ze}from"./upload-Cs07lSfb.js";import{L as V}from"./loader-circle-BpyfPEFt.js";/**
1
+ import{c as $,r as l,j as e,G as we,Q as Se,F as Ce,h as Re,T as U,Z as Ee,a as S,V as Me,S as $e,Y as Te,X as Pe,P as ie,i as Ae,g as ze,C as Ie,l as Le,N as I,J as _e,K as De,O as Fe,u as Oe}from"./index-6SmuA6vo.js";import{P as K,S as He,E as Be}from"./ErrorBoundary-DSSzEuvn.js";import{C as qe,F as Ge,M as Ue,H as Ke,a as We,G as Ve,T as Qe}from"./thumbs-up-BOZEbhQH.js";import{C as oe}from"./check-DgIZol8f.js";import{C as Ye}from"./clock-BWn2Jze6.js";import{D as Xe}from"./dollar-sign-oHFYulLR.js";import{U as Ze}from"./upload-C3Vn2m4l.js";import{L as V}from"./loader-circle-BpZ0PaNs.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as o,j as e}from"./index-BBV2psih.js";function f({value:r,prefix:t="",suffix:s=""}){const[u,n]=o.useState(0),c=o.useRef(0);return o.useEffect(()=>{const a=c.current,h=r-a;if(h===0)return;const i=600,d=performance.now();function l(b){const v=b-d,m=Math.min(v/i,1),N=1-Math.pow(1-m,3),p=Math.round(a+h*N);n(p),c.current=p,m<1&&requestAnimationFrame(l)}requestAnimationFrame(l)},[r]),e.jsxs("span",{className:"tabular-nums",children:[t,u.toLocaleString(),s]})}function g(){const[r,t]=o.useState(5),[s,u]=o.useState(30),[n,c]=o.useState(75),a=.4,i=Math.round(r*s*a*4.33),d=Math.round(i*n);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 shadow-sm",children:[e.jsx("h3",{className:"text-lg font-bold text-[#36342E] mb-1",children:"ROI Calculator"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-6",children:"Estimate how much your team could save with autonomous development."}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Team size"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[r," developers"]})]}),e.jsx("input",{type:"range",min:1,max:50,value:r,onChange:l=>t(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"1"}),e.jsx("span",{children:"50"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Hours coding per week"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[s,"h"]})]}),e.jsx("input",{type:"range",min:5,max:60,value:s,onChange:l=>u(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"5h"}),e.jsx("span",{children:"60h"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Average hourly rate"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:["$",n,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:n,onChange:l=>c(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"$25"}),e.jsx("span",{children:"$250"})]})]})]}),e.jsxs("div",{className:"mt-6 pt-6 border-t border-[#ECEAE3]",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(f,{value:i,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(f,{value:d,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. cost saved / month"})]})]}),e.jsxs("div",{className:"mt-4 p-3 rounded-lg bg-[#553DE9]/5 border border-[#553DE9]/10",children:[e.jsxs("p",{className:"text-sm text-[#36342E] text-center",children:["If Loki Mode saved ",Math.round(a*100),"% of coding time, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[i.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",d.toLocaleString()]})," ","per month."]}),e.jsxs("p",{className:"mt-2 text-xs text-[#6B6960] text-center",children:["The ",Math.round(a*100),"% is an assumption, not a measurement. Model and API spend is not included."]})]})]})]})}const j=[{feature:"Claude (Opus/Sonnet/Haiku)",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!0},{feature:"GPT-4o / Codex",category:"AI Models",lokiMode:!0,boltNew:!0,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"8 automated quality gates",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Blind 3-reviewer code review",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Anti-sycophancy checks",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Automated test generation",category:"Quality",lokiMode:!0,boltNew:!1,replit:"Partial",lovable:!1},{feature:"Docker container generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"CI/CD pipeline generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"One-click cloud deploy",category:"Deployment",lokiMode:"Planned",boltNew:!0,replit:!0,lovable:!0},{feature:"Self-hosted (your keys)",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Free tier available",category:"Cost",lokiMode:"Source-available (BUSL-1.1)",boltNew:!0,replit:!0,lovable:!0},{feature:"No vendor lock-in",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"SSO / OIDC authentication",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"RBAC access control",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Audit logging",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Air-gapped deployment",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1}];function y(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function w(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#C45B5B]/40",children:e.jsx("path",{d:"M18 6L6 18M6 6l12 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({value:r}){return typeof r=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:r}):r?e.jsx(y,{}):e.jsx(w,{})}const k=[{title:"Full Autonomy",description:"Describe what you want. Loki Mode handles planning, coding, testing, and verification automatically.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#553DE9]",children:e.jsx("path",{d:"M13 2L3 14h9l-1 8 10-12h-9l1-8z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Production Quality",description:"8 quality gates, blind code review, and anti-sycophancy checks ensure code that actually works.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Your Infrastructure",description:"Self-hosted, source-available (BUSL-1.1), no data leaves your network. Use your own API keys across 5 providers.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#2F71E3]",children:[e.jsx("rect",{x:"2",y:"2",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("rect",{x:"2",y:"14",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("circle",{cx:"6",cy:"6",r:"1",fill:"currentColor"}),e.jsx("circle",{cx:"6",cy:"18",r:"1",fill:"currentColor"})]})},{title:"Built for Teams",description:"Enterprise auth, RBAC, audit logs, and parallel workflows for teams of any size.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#E93D82]",children:[e.jsx("path",{d:"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("circle",{cx:"9",cy:"7",r:"4",stroke:"currentColor",strokeWidth:"2"}),e.jsx("path",{d:"M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}];function C(){const r=[...new Set(j.map(t=>t.category))];return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Compare"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:"See how Loki Mode stacks up against other AI development platforms."})]}),e.jsx("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[#ECEAE3]",children:[e.jsx("th",{className:"text-left px-4 py-3 font-medium text-[#6B6960] w-[240px]",children:"Feature"}),e.jsx("th",{className:"text-center px-4 py-3 font-bold text-[#553DE9] bg-[#553DE9]/5 w-[130px]",children:"Loki Mode"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"bolt.new"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Replit"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Lovable"})]})}),e.jsx("tbody",{children:r.map(t=>e.jsxs(e.Fragment,{children:[e.jsx("tr",{className:"bg-[#FAF9F6]",children:e.jsx("td",{colSpan:5,className:"px-4 py-2 text-xs font-bold text-[#939084] uppercase tracking-wider",children:t})},`cat-${t}`),j.filter(s=>s.category===t).map(s=>e.jsxs("tr",{className:"border-b border-[#ECEAE3] last:border-b-0",children:[e.jsx("td",{className:"px-4 py-2.5 text-[#36342E]",children:s.feature}),e.jsx("td",{className:"px-4 py-2.5 text-center bg-[#553DE9]/5",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lokiMode})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.boltNew})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.replit})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lovable})})})]},s.feature))]}))})]})})}),e.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"Why developers choose Loki Mode"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:k.map(t=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow",children:[e.jsx("div",{className:"mb-3",children:t.icon}),e.jsx("h3",{className:"text-base font-bold text-[#36342E] mb-1",children:t.title}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:t.description})]},t.title))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(g,{})})]})})}export{C as default};
1
+ import{r as o,j as e}from"./index-6SmuA6vo.js";function f({value:r,prefix:t="",suffix:s=""}){const[u,n]=o.useState(0),c=o.useRef(0);return o.useEffect(()=>{const a=c.current,h=r-a;if(h===0)return;const i=600,d=performance.now();function l(b){const v=b-d,m=Math.min(v/i,1),N=1-Math.pow(1-m,3),p=Math.round(a+h*N);n(p),c.current=p,m<1&&requestAnimationFrame(l)}requestAnimationFrame(l)},[r]),e.jsxs("span",{className:"tabular-nums",children:[t,u.toLocaleString(),s]})}function g(){const[r,t]=o.useState(5),[s,u]=o.useState(30),[n,c]=o.useState(75),a=.4,i=Math.round(r*s*a*4.33),d=Math.round(i*n);return e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-6 shadow-sm",children:[e.jsx("h3",{className:"text-lg font-bold text-[#36342E] mb-1",children:"ROI Calculator"}),e.jsx("p",{className:"text-sm text-[#6B6960] mb-6",children:"Estimate how much your team could save with autonomous development."}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Team size"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[r," developers"]})]}),e.jsx("input",{type:"range",min:1,max:50,value:r,onChange:l=>t(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"1"}),e.jsx("span",{children:"50"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Hours coding per week"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:[s,"h"]})]}),e.jsx("input",{type:"range",min:5,max:60,value:s,onChange:l=>u(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"5h"}),e.jsx("span",{children:"60h"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center justify-between mb-2",children:[e.jsx("label",{className:"text-sm font-medium text-[#36342E]",children:"Average hourly rate"}),e.jsxs("span",{className:"text-sm font-semibold text-[#553DE9] tabular-nums",children:["$",n,"/hr"]})]}),e.jsx("input",{type:"range",min:25,max:250,step:5,value:n,onChange:l=>c(Number(l.target.value)),className:"w-full h-2 bg-[#ECEAE3] rounded-full appearance-none cursor-pointer accent-[#553DE9]"}),e.jsxs("div",{className:"flex justify-between text-xs text-[#939084] mt-1",children:[e.jsx("span",{children:"$25"}),e.jsx("span",{children:"$250"})]})]})]}),e.jsxs("div",{className:"mt-6 pt-6 border-t border-[#ECEAE3]",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#553DE9]",children:e.jsx(f,{value:i,suffix:"h"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. hours saved / month"})]}),e.jsxs("div",{children:[e.jsx("div",{className:"text-2xl font-bold text-[#1FC5A8]",children:e.jsx(f,{value:d,prefix:"$"})}),e.jsx("div",{className:"text-xs text-[#6B6960] mt-1",children:"Est. cost saved / month"})]})]}),e.jsxs("div",{className:"mt-4 p-3 rounded-lg bg-[#553DE9]/5 border border-[#553DE9]/10",children:[e.jsxs("p",{className:"text-sm text-[#36342E] text-center",children:["If Loki Mode saved ",Math.round(a*100),"% of coding time, your team could save"," ",e.jsxs("span",{className:"font-bold text-[#553DE9]",children:[i.toLocaleString()," hours"]})," ","and"," ",e.jsxs("span",{className:"font-bold text-[#1FC5A8]",children:["$",d.toLocaleString()]})," ","per month."]}),e.jsxs("p",{className:"mt-2 text-xs text-[#6B6960] text-center",children:["The ",Math.round(a*100),"% is an assumption, not a measurement. Model and API spend is not included."]})]})]})]})}const j=[{feature:"Claude (Opus/Sonnet/Haiku)",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!0},{feature:"GPT-4o / Codex",category:"AI Models",lokiMode:!0,boltNew:!0,replit:!0,lovable:!1},{feature:"5-provider auto-failover",category:"AI Models",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"8 automated quality gates",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Blind 3-reviewer code review",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Anti-sycophancy checks",category:"Quality",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Automated test generation",category:"Quality",lokiMode:!0,boltNew:!1,replit:"Partial",lovable:!1},{feature:"Docker container generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"CI/CD pipeline generation",category:"Deployment",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"One-click cloud deploy",category:"Deployment",lokiMode:"Planned",boltNew:!0,replit:!0,lovable:!0},{feature:"Self-hosted (your keys)",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"Free tier available",category:"Cost",lokiMode:"Source-available (BUSL-1.1)",boltNew:!0,replit:!0,lovable:!0},{feature:"No vendor lock-in",category:"Cost",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1},{feature:"SSO / OIDC authentication",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"RBAC access control",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Audit logging",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!0,lovable:!1},{feature:"Air-gapped deployment",category:"Enterprise",lokiMode:!0,boltNew:!1,replit:!1,lovable:!1}];function y(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M20 6L9 17l-5-5",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})})}function w(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",className:"text-[#C45B5B]/40",children:e.jsx("path",{d:"M18 6L6 18M6 6l12 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function x({value:r}){return typeof r=="string"?e.jsx("span",{className:"text-xs text-[#6B6960] font-medium",children:r}):r?e.jsx(y,{}):e.jsx(w,{})}const k=[{title:"Full Autonomy",description:"Describe what you want. Loki Mode handles planning, coding, testing, and verification automatically.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#553DE9]",children:e.jsx("path",{d:"M13 2L3 14h9l-1 8 10-12h-9l1-8z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Production Quality",description:"8 quality gates, blind code review, and anti-sycophancy checks ensure code that actually works.",icon:e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#1FC5A8]",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})},{title:"Your Infrastructure",description:"Self-hosted, source-available (BUSL-1.1), no data leaves your network. Use your own API keys across 5 providers.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#2F71E3]",children:[e.jsx("rect",{x:"2",y:"2",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("rect",{x:"2",y:"14",width:"20",height:"8",rx:"2",stroke:"currentColor",strokeWidth:"2"}),e.jsx("circle",{cx:"6",cy:"6",r:"1",fill:"currentColor"}),e.jsx("circle",{cx:"6",cy:"18",r:"1",fill:"currentColor"})]})},{title:"Built for Teams",description:"Enterprise auth, RBAC, audit logs, and parallel workflows for teams of any size.",icon:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",className:"text-[#E93D82]",children:[e.jsx("path",{d:"M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"}),e.jsx("circle",{cx:"9",cy:"7",r:"4",stroke:"currentColor",strokeWidth:"2"}),e.jsx("path",{d:"M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})]})}];function C(){const r=[...new Set(j.map(t=>t.category))];return e.jsx("div",{className:"min-h-screen bg-[#FAF9F6]",children:e.jsxs("div",{className:"max-w-6xl mx-auto px-6 py-8",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-2xl font-bold text-[#36342E]",children:"Compare"}),e.jsx("p",{className:"text-[#6B6960] mt-1",children:"See how Loki Mode stacks up against other AI development platforms."})]}),e.jsx("div",{className:"bg-white border border-[#ECEAE3] rounded-xl overflow-hidden shadow-sm",children:e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-[#ECEAE3]",children:[e.jsx("th",{className:"text-left px-4 py-3 font-medium text-[#6B6960] w-[240px]",children:"Feature"}),e.jsx("th",{className:"text-center px-4 py-3 font-bold text-[#553DE9] bg-[#553DE9]/5 w-[130px]",children:"Loki Mode"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"bolt.new"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Replit"}),e.jsx("th",{className:"text-center px-4 py-3 font-medium text-[#6B6960] w-[130px]",children:"Lovable"})]})}),e.jsx("tbody",{children:r.map(t=>e.jsxs(e.Fragment,{children:[e.jsx("tr",{className:"bg-[#FAF9F6]",children:e.jsx("td",{colSpan:5,className:"px-4 py-2 text-xs font-bold text-[#939084] uppercase tracking-wider",children:t})},`cat-${t}`),j.filter(s=>s.category===t).map(s=>e.jsxs("tr",{className:"border-b border-[#ECEAE3] last:border-b-0",children:[e.jsx("td",{className:"px-4 py-2.5 text-[#36342E]",children:s.feature}),e.jsx("td",{className:"px-4 py-2.5 text-center bg-[#553DE9]/5",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lokiMode})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.boltNew})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.replit})})}),e.jsx("td",{className:"px-4 py-2.5 text-center",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(x,{value:s.lovable})})})]},s.feature))]}))})]})})}),e.jsxs("div",{className:"mt-12",children:[e.jsx("h2",{className:"text-xl font-bold text-[#36342E] mb-6",children:"Why developers choose Loki Mode"}),e.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-5",children:k.map(t=>e.jsxs("div",{className:"bg-white border border-[#ECEAE3] rounded-xl p-5 shadow-sm hover:shadow-md transition-shadow",children:[e.jsx("div",{className:"mb-3",children:t.icon}),e.jsx("h3",{className:"text-base font-bold text-[#36342E] mb-1",children:t.title}),e.jsx("p",{className:"text-sm text-[#6B6960]",children:t.description})]},t.title))})]}),e.jsx("div",{className:"mt-12 max-w-xl mx-auto",children:e.jsx(g,{})})]})})}export{C as default};
@@ -1,4 +1,4 @@
1
- import{c as o,r as a,j as e,T as n,h as i,p as c}from"./index-BBV2psih.js";/**
1
+ import{c as o,r as a,j as e,T as n,h as i,p as c}from"./index-6SmuA6vo.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- import{r as l,a as x,j as e}from"./index-BBV2psih.js";const N={verified:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Verified",proven:"The server recomputed the integrity hash and it matches, and the gpg signature verified against its keyring.",notProven:"That the code is correct, or that the recorded diff still matches your repo. A receipt records which checks ran, not that the result is right."},unsigned:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Unsigned",proven:"The server recomputed the integrity hash and it matches these receipt bytes.",notProven:"Who produced it. An unsigned receipt is forgeable: whoever controls the builder can rewrite the facts and recompute the hash."},unchecked:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Not checked",proven:"The server recomputed the integrity hash and it matches.",notProven:"Provenance. A signature is present but was not evaluated here, which is not the same as a bad signature."},tampered:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Tampered",proven:"Nothing. The server recomputed the integrity hash and it does not match the contents.",notProven:"Anything at all. This receipt was edited after it was written. Do not trust this build."},failed:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Failed verification",proven:"Nothing. A verification check ran on the server and said no.",notProven:"Anything the receipt claims. Read the reason below."},not_verified:{badge:"border-muted/20 text-muted",dot:"bg-muted/40",label:"Not verified here",proven:"Nothing. No verification result was computed for this receipt here.",notProven:"Integrity or provenance. Run the command below to check it yourself."}};function w(t){const n=t==null?void 0:t.integrity_check,r=t==null?void 0:t.verification;return n?n.status==="tampered"?"tampered":n.status==="failed"?"failed":n.status!=="verified"?"not_verified":n.gpg_ok===!0?"verified":r!=null&&r.attestation||r!=null&&r.gpg_signature?"unchecked":"unsigned":"not_verified"}const v=[{key:"verified",label:"Verified",bar:"bg-success",text:"text-success"},{key:"with_gaps",label:"With gaps",bar:"bg-warning",text:"text-warning"},{key:"not_verified",label:"Not verified",bar:"bg-danger",text:"text-danger"},{key:"unknown",label:"Unknown",bar:"bg-muted/40",text:"text-muted"}];function y({summary:t}){const n=t.total_receipts;return n?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex h-1.5 rounded-full overflow-hidden bg-muted/10",children:v.map(({key:r,bar:s})=>{const i=t[r];return i?e.jsx("div",{className:s,style:{width:`${i/n*100}%`},title:`${i} ${r}`},r):null})}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs",children:v.map(({key:r,label:s,text:i})=>{const c=t[r];return c?e.jsxs("span",{className:i,children:[e.jsx("span",{className:"font-semibold",children:c})," ",s.toLowerCase()]},r):null})}),e.jsxs("p",{className:"text-muted text-xs",children:["Recorded verdicts across ",n," receipt",n===1?"":"s",", not re-verified here."]})]}):null}function u({label:t,value:n}){return e.jsxs("div",{className:"flex items-baseline gap-2 text-xs",children:[e.jsx("span",{className:"text-muted w-28 flex-shrink-0",children:t}),e.jsx("span",{className:"font-mono truncate",title:n,children:n})]})}function k({proof:t}){var m,p,g,f,b;const[n,r]=l.useState(!1),[s,i]=l.useState(null),[c,d]=l.useState(null);l.useEffect(()=>{if(!n||s||c)return;let o=!1;return x.getProof(t.run_id).then(h=>{o||i(h)}).catch(h=>{o||d((h==null?void 0:h.message)||"could not load this receipt")}),()=>{o=!0}},[n,t.run_id,s,c]);const a=N[w(s)],j=t.generated_at?new Date(t.generated_at).toLocaleString():"unknown";return e.jsxs("div",{className:`border rounded-card overflow-hidden ${s?a.badge:"border-muted/20"}`,children:[e.jsxs("button",{type:"button",className:"w-full flex items-center gap-3 px-3 py-2.5 text-left",onClick:()=>r(!n),"aria-expanded":n,children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s?a.dot:"bg-muted/40"}`}),e.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:t.headline?`Recorded: ${t.headline}`:t.run_id}),t.final_verdict&&e.jsxs("span",{className:"text-xs font-mono uppercase tracking-wider flex-shrink-0 text-muted",children:["council ",t.final_verdict]}),e.jsx("span",{className:"text-muted text-xs flex-shrink-0",children:n?"−":"+"})]}),n&&e.jsxs("div",{className:"px-3 pb-3 space-y-3 border-t border-current/10 pt-3",children:[c&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load this receipt: ",c]}),!c&&!s&&e.jsx("p",{className:"text-xs text-muted",children:"Loading receipt…"}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{label:"Run",value:s.run_id}),e.jsx(u,{label:"Generated",value:j}),e.jsx(u,{label:"Loki version",value:s.loki_version||"unknown"}),e.jsx(u,{label:"Cost",value:typeof((m=s.cost)==null?void 0:m.usd)=="number"?`${s.cost.cost_partial===!0?"at least ":""}$${s.cost.usd.toFixed(2)}`:"unknown"}),e.jsx(u,{label:"Files changed",value:typeof((p=s.files_changed)==null?void 0:p.count)=="number"?String(s.files_changed.count):"unknown"}),((g=s.verification)==null?void 0:g.hash)&&e.jsx(u,{label:"Recorded hash",value:s.verification.hash})]}),e.jsxs("div",{className:`rounded-card border px-3 py-2 ${a.badge}`,children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wider mb-1",children:a.label}),e.jsxs("p",{className:"text-xs mb-1",children:[e.jsx("span",{className:"font-semibold",children:"Proven: "}),a.proven]}),e.jsxs("p",{className:"text-xs opacity-80",children:[e.jsx("span",{className:"font-semibold",children:"Not proven: "}),a.notProven]}),(((f=s.integrity_check)==null?void 0:f.reasons)||[]).slice(0,2).map(o=>e.jsx("p",{className:"text-xs opacity-80 mt-1",children:o},o))]}),e.jsxs("p",{className:"text-xs text-muted",children:["Verify it yourself (also re-derives the diff against your repo):"," ",e.jsxs("code",{className:"font-mono",children:["loki proof verify ",s.run_id,(b=s.verification)!=null&&b.attestation?" --jwks <url|file>":""]})]}),t.pr_url&&e.jsx("a",{href:t.pr_url,target:"_blank",rel:"noreferrer noopener",className:"text-xs text-primary underline",children:"View the pull request"})]})]})]})}function P(){const[t,n]=l.useState(null),[r,s]=l.useState(null),[i,c]=l.useState(null);return l.useEffect(()=>{let d=!1;return x.listProofs().then(a=>{d||n(a.proofs||[])}).catch(a=>{d||c((a==null?void 0:a.message)||"could not load receipts")}),x.proofsSummary().then(a=>{d||s(a)}).catch(()=>{}),()=>{d=!0}},[]),e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"Evidence Receipts"}),e.jsx("p",{className:"text-muted text-xs mt-1",children:"What each build actually checked, recorded so you can verify it yourself."})]}),i&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load receipts: ",i]}),!i&&t===null&&e.jsx("p",{className:"text-xs text-muted",children:"Loading…"}),r&&e.jsx(y,{summary:r}),t!==null&&t.length===0&&e.jsxs("p",{className:"text-xs text-muted",children:["No receipts yet. One is written at the end of each run (set ",e.jsx("code",{className:"font-mono",children:"LOKI_PROOF=0"})," to opt out)."]}),e.jsx("div",{className:"space-y-2",children:t==null?void 0:t.map(d=>e.jsx(k,{proof:d},d.run_id))})]})}export{P as E};
1
+ import{r as l,a as x,j as e}from"./index-6SmuA6vo.js";const N={verified:{badge:"bg-success/10 text-success border-success/20",dot:"bg-success",label:"Verified",proven:"The server recomputed the integrity hash and it matches, and the gpg signature verified against its keyring.",notProven:"That the code is correct, or that the recorded diff still matches your repo. A receipt records which checks ran, not that the result is right."},unsigned:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Unsigned",proven:"The server recomputed the integrity hash and it matches these receipt bytes.",notProven:"Who produced it. An unsigned receipt is forgeable: whoever controls the builder can rewrite the facts and recompute the hash."},unchecked:{badge:"bg-warning/10 text-warning border-warning/20",dot:"bg-warning",label:"Not checked",proven:"The server recomputed the integrity hash and it matches.",notProven:"Provenance. A signature is present but was not evaluated here, which is not the same as a bad signature."},tampered:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Tampered",proven:"Nothing. The server recomputed the integrity hash and it does not match the contents.",notProven:"Anything at all. This receipt was edited after it was written. Do not trust this build."},failed:{badge:"bg-danger/10 text-danger border-danger/20",dot:"bg-danger",label:"Failed verification",proven:"Nothing. A verification check ran on the server and said no.",notProven:"Anything the receipt claims. Read the reason below."},not_verified:{badge:"border-muted/20 text-muted",dot:"bg-muted/40",label:"Not verified here",proven:"Nothing. No verification result was computed for this receipt here.",notProven:"Integrity or provenance. Run the command below to check it yourself."}};function w(t){const n=t==null?void 0:t.integrity_check,r=t==null?void 0:t.verification;return n?n.status==="tampered"?"tampered":n.status==="failed"?"failed":n.status!=="verified"?"not_verified":n.gpg_ok===!0?"verified":r!=null&&r.attestation||r!=null&&r.gpg_signature?"unchecked":"unsigned":"not_verified"}const v=[{key:"verified",label:"Verified",bar:"bg-success",text:"text-success"},{key:"with_gaps",label:"With gaps",bar:"bg-warning",text:"text-warning"},{key:"not_verified",label:"Not verified",bar:"bg-danger",text:"text-danger"},{key:"unknown",label:"Unknown",bar:"bg-muted/40",text:"text-muted"}];function y({summary:t}){const n=t.total_receipts;return n?e.jsxs("div",{className:"space-y-2",children:[e.jsx("div",{className:"flex h-1.5 rounded-full overflow-hidden bg-muted/10",children:v.map(({key:r,bar:s})=>{const i=t[r];return i?e.jsx("div",{className:s,style:{width:`${i/n*100}%`},title:`${i} ${r}`},r):null})}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-xs",children:v.map(({key:r,label:s,text:i})=>{const c=t[r];return c?e.jsxs("span",{className:i,children:[e.jsx("span",{className:"font-semibold",children:c})," ",s.toLowerCase()]},r):null})}),e.jsxs("p",{className:"text-muted text-xs",children:["Recorded verdicts across ",n," receipt",n===1?"":"s",", not re-verified here."]})]}):null}function u({label:t,value:n}){return e.jsxs("div",{className:"flex items-baseline gap-2 text-xs",children:[e.jsx("span",{className:"text-muted w-28 flex-shrink-0",children:t}),e.jsx("span",{className:"font-mono truncate",title:n,children:n})]})}function k({proof:t}){var m,p,g,f,b;const[n,r]=l.useState(!1),[s,i]=l.useState(null),[c,d]=l.useState(null);l.useEffect(()=>{if(!n||s||c)return;let o=!1;return x.getProof(t.run_id).then(h=>{o||i(h)}).catch(h=>{o||d((h==null?void 0:h.message)||"could not load this receipt")}),()=>{o=!0}},[n,t.run_id,s,c]);const a=N[w(s)],j=t.generated_at?new Date(t.generated_at).toLocaleString():"unknown";return e.jsxs("div",{className:`border rounded-card overflow-hidden ${s?a.badge:"border-muted/20"}`,children:[e.jsxs("button",{type:"button",className:"w-full flex items-center gap-3 px-3 py-2.5 text-left",onClick:()=>r(!n),"aria-expanded":n,children:[e.jsx("span",{className:`w-2 h-2 rounded-full flex-shrink-0 ${s?a.dot:"bg-muted/40"}`}),e.jsx("span",{className:"text-sm font-medium flex-1 truncate",children:t.headline?`Recorded: ${t.headline}`:t.run_id}),t.final_verdict&&e.jsxs("span",{className:"text-xs font-mono uppercase tracking-wider flex-shrink-0 text-muted",children:["council ",t.final_verdict]}),e.jsx("span",{className:"text-muted text-xs flex-shrink-0",children:n?"−":"+"})]}),n&&e.jsxs("div",{className:"px-3 pb-3 space-y-3 border-t border-current/10 pt-3",children:[c&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load this receipt: ",c]}),!c&&!s&&e.jsx("p",{className:"text-xs text-muted",children:"Loading receipt…"}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx(u,{label:"Run",value:s.run_id}),e.jsx(u,{label:"Generated",value:j}),e.jsx(u,{label:"Loki version",value:s.loki_version||"unknown"}),e.jsx(u,{label:"Cost",value:typeof((m=s.cost)==null?void 0:m.usd)=="number"?`${s.cost.cost_partial===!0?"at least ":""}$${s.cost.usd.toFixed(2)}`:"unknown"}),e.jsx(u,{label:"Files changed",value:typeof((p=s.files_changed)==null?void 0:p.count)=="number"?String(s.files_changed.count):"unknown"}),((g=s.verification)==null?void 0:g.hash)&&e.jsx(u,{label:"Recorded hash",value:s.verification.hash})]}),e.jsxs("div",{className:`rounded-card border px-3 py-2 ${a.badge}`,children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-wider mb-1",children:a.label}),e.jsxs("p",{className:"text-xs mb-1",children:[e.jsx("span",{className:"font-semibold",children:"Proven: "}),a.proven]}),e.jsxs("p",{className:"text-xs opacity-80",children:[e.jsx("span",{className:"font-semibold",children:"Not proven: "}),a.notProven]}),(((f=s.integrity_check)==null?void 0:f.reasons)||[]).slice(0,2).map(o=>e.jsx("p",{className:"text-xs opacity-80 mt-1",children:o},o))]}),e.jsxs("p",{className:"text-xs text-muted",children:["Verify it yourself (also re-derives the diff against your repo):"," ",e.jsxs("code",{className:"font-mono",children:["loki proof verify ",s.run_id,(b=s.verification)!=null&&b.attestation?" --jwks <url|file>":""]})]}),t.pr_url&&e.jsx("a",{href:t.pr_url,target:"_blank",rel:"noreferrer noopener",className:"text-xs text-primary underline",children:"View the pull request"})]})]})]})}function P(){const[t,n]=l.useState(null),[r,s]=l.useState(null),[i,c]=l.useState(null);return l.useEffect(()=>{let d=!1;return x.listProofs().then(a=>{d||n(a.proofs||[])}).catch(a=>{d||c((a==null?void 0:a.message)||"could not load receipts")}),x.proofsSummary().then(a=>{d||s(a)}).catch(()=>{}),()=>{d=!0}},[]),e.jsxs("section",{className:"space-y-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-semibold",children:"Evidence Receipts"}),e.jsx("p",{className:"text-muted text-xs mt-1",children:"What each build actually checked, recorded so you can verify it yourself."})]}),i&&e.jsxs("p",{className:"text-xs text-danger",children:["Could not load receipts: ",i]}),!i&&t===null&&e.jsx("p",{className:"text-xs text-muted",children:"Loading…"}),r&&e.jsx(y,{summary:r}),t!==null&&t.length===0&&e.jsxs("p",{className:"text-xs text-muted",children:["No receipts yet. One is written at the end of each run (set ",e.jsx("code",{className:"font-mono",children:"LOKI_PROOF=0"})," to opt out)."]}),e.jsx("div",{className:"space-y-2",children:t==null?void 0:t.map(d=>e.jsx(k,{proof:d},d.run_id))})]})}export{P as E};
@@ -1,4 +1,4 @@
1
- import{c as _,r as o,a as k,j as e,m as B,J as v,N as h,a5 as H,M as L,l as q}from"./index-BBV2psih.js";import{B as N}from"./Button-5CI0TYxR.js";import{C as y}from"./thumbs-up-4nFvjqQ-.js";import{R as S}from"./refresh-cw-DPEeU-0s.js";import{C as z}from"./circle-alert-D1rDQ9mD.js";import{U as D}from"./user-DC2T8RYB.js";import{L as G}from"./loader-circle-BpyfPEFt.js";import{R as T}from"./rotate-ccw-DZX_aED8.js";/**
1
+ import{c as _,r as o,a as k,j as e,m as B,J as v,N as h,a5 as H,M as L,l as q}from"./index-6SmuA6vo.js";import{B as N}from"./Button-Codl3KHK.js";import{C as y}from"./thumbs-up-BOZEbhQH.js";import{R as S}from"./refresh-cw-C5w6Ak_2.js";import{C as z}from"./circle-alert-CX8OMfQi.js";import{U as D}from"./user-B6OJgsvN.js";import{L as G}from"./loader-circle-BpZ0PaNs.js";import{R as T}from"./rotate-ccw-BoOWI6PB.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
1
- import{c as I,r as c,a as b,j as e,G as me,A as ue,S as Z,k as ee,m as pe,h as he,p as fe,X as te,M as be}from"./index-BBV2psih.js";import{B as y}from"./Button-5CI0TYxR.js";import{C as ge}from"./chevron-left-lKRP1pKT.js";import{G as P}from"./thumbs-up-4nFvjqQ-.js";import{R as $}from"./refresh-cw-DPEeU-0s.js";import{C as Ne}from"./circle-alert-D1rDQ9mD.js";import{L as Q,S as je}from"./ProjectPage-zpARxbll.js";import{S as se}from"./shield-alert-Dc5xbnOx.js";import{F as ye}from"./file-code-corner-DY5GkQGM.js";import{C as V}from"./clock-BGhPbAAa.js";import{C as re}from"./check-DYPycZns.js";import"./ErrorBoundary-VZcsEDJl.js";import"./TerminalOutput-iLcaELwj.js";import"./lock-Bivqy2kG.js";import"./package-DvDJIgWs.js";import"./file-plus-RLd_hPU8.js";import"./activity-Di09VZ-C.js";import"./scroll-text-BBMfK4J7.js";import"./bot-pGvyFisf.js";import"./loader-circle-BpyfPEFt.js";import"./hammer-BWOWu2Hf.js";import"./dollar-sign-adGlfVLa.js";import"./globe-CQvcGE8E.js";import"./trash-2-SjUKL3ek.js";import"./upload-Cs07lSfb.js";import"./plus-CVjTmPiU.js";import"./rotate-ccw-DZX_aED8.js";import"./code-xml-DtutBX9b.js";import"./trending-up-DgRWrCNb.js";import"./layers-C_cj_ShX.js";import"./trending-down-B7_1Kuct.js";import"./server-Bq18pHWE.js";/**
1
+ import{c as I,r as c,a as b,j as e,G as me,A as ue,S as Z,k as ee,m as pe,h as he,p as fe,X as te,M as be}from"./index-6SmuA6vo.js";import{B as y}from"./Button-Codl3KHK.js";import{C as ge}from"./chevron-left-qMIE0cDr.js";import{G as P}from"./thumbs-up-BOZEbhQH.js";import{R as $}from"./refresh-cw-C5w6Ak_2.js";import{C as Ne}from"./circle-alert-CX8OMfQi.js";import{L as Q,S as je}from"./ProjectPage-DX3o3FPS.js";import{S as se}from"./shield-alert-3oKaRgIp.js";import{F as ye}from"./file-code-corner-tOfIJYNi.js";import{C as V}from"./clock-BWn2Jze6.js";import{C as re}from"./check-DgIZol8f.js";import"./ErrorBoundary-DSSzEuvn.js";import"./TerminalOutput-G31VzO9H.js";import"./lock--fYCznSR.js";import"./package-U_Arm0cd.js";import"./file-plus-BdjSTmSi.js";import"./activity-CmEjbl9p.js";import"./scroll-text-C0pBzd-k.js";import"./bot-BMxqZc49.js";import"./loader-circle-BpZ0PaNs.js";import"./hammer-CF-MPA1L.js";import"./dollar-sign-oHFYulLR.js";import"./globe-BhnmSAWt.js";import"./trash-2-B8x1w7gc.js";import"./upload-C3Vn2m4l.js";import"./plus-BZVrxRYG.js";import"./rotate-ccw-BoOWI6PB.js";import"./code-xml-D5g_nMzh.js";import"./trending-up-CKCveriW.js";import"./layers-7YlE4617.js";import"./trending-down-CSDM4aj2.js";import"./server-Cs9i_vco.js";/**
2
2
  * @license lucide-react v0.577.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.