loki-mode 10.5.14 → 10.5.16

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 (70) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/lib/claude-flags.sh +15 -5
  4. package/autonomy/run.sh +33 -7
  5. package/dashboard/__init__.py +1 -1
  6. package/docs/INSTALLATION.md +1 -1
  7. package/docs/v10/BOARD.md +18 -13
  8. package/docs/v10/DECISIONS.md +8 -0
  9. package/docs/v10/PROGRESS.md +37 -0
  10. package/loki-ts/dist/loki.js +430 -430
  11. package/mcp/__init__.py +1 -1
  12. package/package.json +1 -1
  13. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  14. package/web-app/dist/assets/{AdminPage-CJo9x2Xg.js → AdminPage-B1zdOJaF.js} +1 -1
  15. package/web-app/dist/assets/{Avatar-DUoCsqCG.js → Avatar-DKjAJ_w7.js} +1 -1
  16. package/web-app/dist/assets/{Badge--P0LPdSw.js → Badge-DP-UrPLv.js} +1 -1
  17. package/web-app/dist/assets/{Button-BhukYi6h.js → Button-c8qBEA2K.js} +1 -1
  18. package/web-app/dist/assets/{CockpitPage-DwEqY6Lm.js → CockpitPage-CFljzGbi.js} +1 -1
  19. package/web-app/dist/assets/{ComparePage-BPe_2mZj.js → ComparePage-BNKqdNRu.js} +1 -1
  20. package/web-app/dist/assets/{ErrorBoundary-B50WH4aR.js → ErrorBoundary-DNkpXGt5.js} +1 -1
  21. package/web-app/dist/assets/{EvidenceReceiptPanel-DCpCP8dt.js → EvidenceReceiptPanel-CQd49V4Z.js} +1 -1
  22. package/web-app/dist/assets/{GitHubIssuesPanel-DSYI3pJ_.js → GitHubIssuesPanel-B9wji_yi.js} +1 -1
  23. package/web-app/dist/assets/{GitHubPRsPanel-6_2i_L2e.js → GitHubPRsPanel-BkfCV4ag.js} +1 -1
  24. package/web-app/dist/assets/{HomePage-DDLSp0M5.js → HomePage-BVV3Cowy.js} +2 -2
  25. package/web-app/dist/assets/{LoginPage-C7lr6Agg.js → LoginPage-CWiOenLJ.js} +1 -1
  26. package/web-app/dist/assets/{MagicPage-Cz-HNoRN.js → MagicPage-DckrjTVd.js} +1 -1
  27. package/web-app/dist/assets/{MetricsPage-B0_jI3YB.js → MetricsPage-DNBnH68C.js} +1 -1
  28. package/web-app/dist/assets/{NotFoundPage-Bu5rS7Bj.js → NotFoundPage-Ca8za8mL.js} +1 -1
  29. package/web-app/dist/assets/{ProjectPage-Di908QYE.js → ProjectPage-C92sm9xi.js} +3 -3
  30. package/web-app/dist/assets/{ProjectsPage-B4Ll6cvX.js → ProjectsPage-BxsCyJ95.js} +1 -1
  31. package/web-app/dist/assets/{SettingsPage-CNkij0qv.js → SettingsPage-BKg-6aHI.js} +1 -1
  32. package/web-app/dist/assets/{ShowcasePage-A9l4k0hu.js → ShowcasePage-Bw_fI5rG.js} +1 -1
  33. package/web-app/dist/assets/{SystemSettingsPage-m0ce18E-.js → SystemSettingsPage-Bc-2OWUp.js} +1 -1
  34. package/web-app/dist/assets/{TeamsPage-Bk_dSFVZ.js → TeamsPage-GsYRD1b9.js} +1 -1
  35. package/web-app/dist/assets/{TemplatesPage-ZR0ZHWVu.js → TemplatesPage-BN7ZlULA.js} +1 -1
  36. package/web-app/dist/assets/{TerminalOutput-CKEzz0P1.js → TerminalOutput-d7__ysTd.js} +1 -1
  37. package/web-app/dist/assets/{activity-IlGG_ZsM.js → activity-ycOMpCGz.js} +1 -1
  38. package/web-app/dist/assets/{bell-jLSBSC-K.js → bell-B93o4lsL.js} +1 -1
  39. package/web-app/dist/assets/{bot-BLL9GpDV.js → bot-CB0kmriG.js} +1 -1
  40. package/web-app/dist/assets/{check-BBtHVmzR.js → check-BAYNAOEO.js} +1 -1
  41. package/web-app/dist/assets/{chevron-left-XeXYVEhg.js → chevron-left-Bgu8UgyR.js} +1 -1
  42. package/web-app/dist/assets/{circle-alert-BRjh-HyY.js → circle-alert-n_FciWUP.js} +1 -1
  43. package/web-app/dist/assets/{clock-ejBi2Q3o.js → clock-CNceeS66.js} +1 -1
  44. package/web-app/dist/assets/{cloud-DywHfOmD.js → cloud-CJBEdb7m.js} +1 -1
  45. package/web-app/dist/assets/{code-xml-B6x31Vqz.js → code-xml-BHnKVqrH.js} +1 -1
  46. package/web-app/dist/assets/{database-WvDL64wH.js → database-DSVoL7Pl.js} +1 -1
  47. package/web-app/dist/assets/{dollar-sign-ByQ6zYfj.js → dollar-sign-48dvOe4H.js} +1 -1
  48. package/web-app/dist/assets/{file-code-corner-DlL834lY.js → file-code-corner-8yzS5DeZ.js} +1 -1
  49. package/web-app/dist/assets/{file-plus-B_Od9s5t.js → file-plus-BcuVrrey.js} +1 -1
  50. package/web-app/dist/assets/{globe-C5z2FDS3.js → globe-Bb-O58oN.js} +1 -1
  51. package/web-app/dist/assets/{hammer-DlsFYtnb.js → hammer-DeMMY6xW.js} +1 -1
  52. package/web-app/dist/assets/{index--r7MYJoc.js → index-9hue9wt2.js} +3 -3
  53. package/web-app/dist/assets/{layers-DvZddrTO.js → layers-DmCoMrQC.js} +1 -1
  54. package/web-app/dist/assets/{loader-circle-BnINAMhT.js → loader-circle-CJvjM7JW.js} +1 -1
  55. package/web-app/dist/assets/{lock-DB01xu9i.js → lock-Dpje5cWO.js} +1 -1
  56. package/web-app/dist/assets/{package-BfQvuNvc.js → package-mA_hCaf8.js} +1 -1
  57. package/web-app/dist/assets/{plus-DXuOzHg3.js → plus-Db0JnAoC.js} +1 -1
  58. package/web-app/dist/assets/{refresh-cw-C5HbASs-.js → refresh-cw-DbCL1y7h.js} +1 -1
  59. package/web-app/dist/assets/{rotate-ccw-CcPMU7ks.js → rotate-ccw-Bt6pp50d.js} +1 -1
  60. package/web-app/dist/assets/{scroll-text-BrgDBJW1.js → scroll-text-7j0hXxm7.js} +1 -1
  61. package/web-app/dist/assets/{server-IkvvVPw2.js → server-BMJYtpVZ.js} +1 -1
  62. package/web-app/dist/assets/{shield-alert-JLLLiL1y.js → shield-alert-Bu8Pbdy-.js} +1 -1
  63. package/web-app/dist/assets/{thumbs-up-B5U1gYgk.js → thumbs-up-8erzRJ8k.js} +1 -1
  64. package/web-app/dist/assets/{trash-2-CRkgxIjF.js → trash-2-DBC_D_Hv.js} +1 -1
  65. package/web-app/dist/assets/{trending-down-BqGdVKpe.js → trending-down-DMNq5hSm.js} +1 -1
  66. package/web-app/dist/assets/{trending-up-C0bkGp2g.js → trending-up-9b1IqBqR.js} +1 -1
  67. package/web-app/dist/assets/{upload-WYPmSJcy.js → upload-SoA0iiLG.js} +1 -1
  68. package/web-app/dist/assets/{usePolling-DMKrfblv.js → usePolling-DLP2FX9M.js} +1 -1
  69. package/web-app/dist/assets/{user-CeohKmrz.js → user-D7Pb9wW3.js} +1 -1
  70. 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 v10.5.14
6
+ # Loki Mode v10.5.16
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -470,4 +470,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
470
470
 
471
471
  ---
472
472
 
473
- **v10.5.14 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
473
+ **v10.5.16 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 10.5.14
1
+ 10.5.16
@@ -784,6 +784,16 @@ loki_caveman_suppress_env() {
784
784
  # files, lockfiles, or compiled Python cache entries from polluting the user's
785
785
  # feature branch and proof diff. caveman's installer is already auto-
786
786
  # non-interactive without a TTY, but we belt-and-suspenders it.
787
+ # Caveman bootstrap notices. In quiet `loki quick` (inner run, not verbose) they
788
+ # go to a run log next to quick-run.log, not the user's terminal; otherwise stderr.
789
+ _loki_caveman_say() {
790
+ if [ -n "${LOKI_QUICK_INNER:-}" ] && [ "${LOKI_VERBOSE:-0}" != "1" ] && [ -d "${LOKI_QUICK_DIR:-}" ]; then
791
+ printf '%s\n' "$1" >>"$LOKI_QUICK_DIR/quick-run.notices.log" 2>/dev/null || true
792
+ else
793
+ printf '%s\n' "$1" >&2
794
+ fi
795
+ }
796
+
787
797
  loki_caveman_bootstrap() {
788
798
  [ "${LOKI_CAVEMAN:-1}" = "0" ] && return 1
789
799
  [ "${LOKI_CAVEMAN_AUTO_BOOTSTRAP:-1}" = "0" ] && return 1
@@ -801,11 +811,11 @@ loki_caveman_bootstrap() {
801
811
  _loki_caveman_installed && return 0 || return 1
802
812
  fi
803
813
  if ! command -v node >/dev/null 2>&1 || ! command -v npx >/dev/null 2>&1; then
804
- printf '%s\n' "[caveman] node>=18 + npx required to bootstrap; skipping (run proceeds uncompressed). Install Node or set LOKI_CAVEMAN=0 to silence." >&2
814
+ _loki_caveman_say "[caveman] node>=18 + npx required to bootstrap; skipping (run proceeds uncompressed). Install Node or set LOKI_CAVEMAN=0 to silence."
805
815
  mkdir -p "$marker_dir" 2>/dev/null && : > "$marker" 2>/dev/null || true
806
816
  return 1
807
817
  fi
808
- printf '%s\n' "[caveman] bootstrapping output-token compressor v${ver} (one-time, pinned). NOTE: caveman installs GLOBALLY (a Claude Code SessionStart hook in ~/.claude affecting every Claude Code session). Loki applies it only to free-form generation, NEVER to trust-gate subcalls. Opt out: LOKI_CAVEMAN=0." >&2
818
+ _loki_caveman_say "[caveman] bootstrapping output-token compressor v${ver} (one-time, pinned). NOTE: caveman installs GLOBALLY (a Claude Code SessionStart hook in ~/.claude affecting every Claude Code session). Loki applies it only to free-form generation, NEVER to trust-gate subcalls. Opt out: LOKI_CAVEMAN=0."
809
819
  # Pin via the git tag (v-prefixed) on the npx ref AND CAVEMAN_REF so the
810
820
  # downloaded hooks match the pinned release. Default install (no --all) wires
811
821
  # the Claude Code hook for the detected `claude` CLI. A timeout backstops a
@@ -816,7 +826,7 @@ loki_caveman_bootstrap() {
816
826
  fi
817
827
  local bootstrap_tmp=""
818
828
  bootstrap_tmp="$(mktemp -d "${TMPDIR:-/tmp}/loki-caveman-bootstrap.XXXXXX")" || {
819
- printf '%s\n' "[caveman] could not allocate an isolated bootstrap directory; run proceeds uncompressed." >&2
829
+ _loki_caveman_say "[caveman] could not allocate an isolated bootstrap directory; run proceeds uncompressed."
820
830
  mkdir -p "$marker_dir" 2>/dev/null && : > "$marker" 2>/dev/null || true
821
831
  return 1
822
832
  }
@@ -829,11 +839,11 @@ loki_caveman_bootstrap() {
829
839
  if [ "$bootstrap_rc" -eq 0 ]; then
830
840
  mkdir -p "$marker_dir" 2>/dev/null && : > "$marker" 2>/dev/null || true
831
841
  if _loki_caveman_installed; then
832
- printf '%s\n' "[caveman] installed v${ver}." >&2
842
+ _loki_caveman_say "[caveman] installed v${ver}."
833
843
  return 0
834
844
  fi
835
845
  fi
836
- printf '%s\n' "[caveman] bootstrap unavailable (upstream unreachable, timed out, or install failed); run proceeds uncompressed." >&2
846
+ _loki_caveman_say "[caveman] bootstrap unavailable (upstream unreachable, timed out, or install failed); run proceeds uncompressed."
837
847
  mkdir -p "$marker_dir" 2>/dev/null && : > "$marker" 2>/dev/null || true
838
848
  return 1
839
849
  }
package/autonomy/run.sh CHANGED
@@ -245,7 +245,18 @@ if [ -z "${LOKI_QUICK_INNER:-}" ] && [ "${LOKI_VERBOSE:-0}" != "1" ] && [ "${BAS
245
245
  case "${1:-}" in */quick-prd-*.md | quick-prd-*.md)
246
246
  _qd="$(cd "$(dirname "$1")" && pwd -P)"; rm -f "$_qd/quick-receipt.txt"
247
247
  # Async with default INT/QUIT (a bare `&` child ignores them), signals forwarded.
248
- ( trap - INT QUIT; LOKI_QUICK_DIR="$_qd" LOKI_QUICK_OUTER_PID=$$ LOKI_QUICK_INNER=1 exec "$BASH" "$0" "$@" >"$_qd/quick-run.log" ) &
248
+ # A Node/Bun parent starts us with SIGPIPE ignored, and bash cannot reset a
249
+ # signal ignored on entry; every `echo big | head -1` then prints "echo: write
250
+ # error: Broken pipe" onto the user's terminal. Re-exec the inner run through
251
+ # python3 with SIGPIPE back at default (SIG_DFL survives exec).
252
+ _qexec=("$BASH" "$0" "$@")
253
+ # Env differences under python (not bash): LC_CTYPE may be set when the locale is
254
+ # C, macOS adds __CF_USER_TEXT_ENCODING, and SIGXFSZ stays ignored.
255
+ # The import probe guards a python3 that exists but is broken (CLT stub, pyenv shim).
256
+ if command -v python3 >/dev/null 2>&1 && python3 -c 'import os,signal' >/dev/null 2>&1; then
257
+ _qexec=(python3 -c 'import os,signal,sys;signal.signal(signal.SIGPIPE,signal.SIG_DFL);os.execv(sys.argv[1],sys.argv[1:])' "${_qexec[@]}")
258
+ fi
259
+ ( trap - INT QUIT; LOKI_QUICK_DIR="$_qd" LOKI_QUICK_OUTER_PID=$$ LOKI_QUICK_INNER=1 exec "${_qexec[@]}" >"$_qd/quick-run.log" ) &
249
260
  _qpid=$!
250
261
  trap 'kill -INT "$_qpid" 2>/dev/null' INT
251
262
  trap 'kill -TERM "$_qpid" 2>/dev/null' TERM HUP
@@ -7429,7 +7440,22 @@ init_loki_dir() {
7429
7440
  fi
7430
7441
  fi
7431
7442
 
7432
- mkdir -p .loki/{state,queue,messages,logs,config,prompts,artifacts,scripts}
7443
+ # crash.sh's disclosure sentinel can have left a regular FILE at .loki/config
7444
+ # (LOKI_DIR is the project .loki); mkdir -p of the config DIRECTORY then fails
7445
+ # with "File exists". Fold the file into the directory (back-compat sentinel only),
7446
+ # but ONLY when it holds nothing except that sentinel, and NEVER for ~/.loki (a run
7447
+ # started from $HOME): there config is the user's real settings FILE (telemetry opt-out).
7448
+ if [ -f .loki/config ] && [ ! -L .loki/config ] \
7449
+ && [ "$(cd .loki 2>/dev/null && pwd -P)" != "$(cd "${HOME:-/nonexistent}/.loki" 2>/dev/null && pwd -P)" ] \
7450
+ && [ -z "$(grep -v -e '^DISCLOSURE_SHOWN=true$' -e '^[[:space:]]*$' .loki/config 2>/dev/null)" ]; then
7451
+ mv .loki/config .loki/config.disclosure.tmp 2>/dev/null \
7452
+ && mkdir -p .loki/config 2>/dev/null \
7453
+ && mv .loki/config.disclosure.tmp .loki/config/disclosure 2>/dev/null
7454
+ fi
7455
+ # Retry once: a concurrent creator of the same dir can make the first mkdir -p
7456
+ # fail with "File exists" (seen on CI, leaked to the quiet quick terminal).
7457
+ mkdir -p .loki/{state,queue,messages,logs,config,prompts,artifacts,scripts} 2>/dev/null \
7458
+ || mkdir -p .loki/{state,queue,messages,logs,config,prompts,artifacts,scripts}
7433
7459
  mkdir -p .loki/queue
7434
7460
  mkdir -p .loki/state/checkpoints
7435
7461
  mkdir -p .loki/artifacts/{releases,reports,backups}
@@ -7757,11 +7783,11 @@ write_dashboard_state() {
7757
7783
  local tasks_failed=0
7758
7784
 
7759
7785
  if [ -f ".loki/state/orchestrator.json" ]; then
7760
- current_phase=$(python3 -c "import json; print(json.load(open('.loki/state/orchestrator.json')).get('currentPhase', 'BOOTSTRAP'))" 2>/dev/null || echo "BOOTSTRAP")
7761
- version=$(python3 -c "import json; print(json.load(open('.loki/state/orchestrator.json')).get('version', 'unknown'))" 2>/dev/null || echo "unknown")
7762
- started_at=$(python3 -c "import json; print(json.load(open('.loki/state/orchestrator.json')).get('startedAt', ''))" 2>/dev/null || echo "")
7763
- tasks_completed=$(python3 -c "import json; print(json.load(open('.loki/state/orchestrator.json')).get('metrics', {}).get('tasksCompleted', 0))" 2>/dev/null || echo "0")
7764
- tasks_failed=$(python3 -c "import json; print(json.load(open('.loki/state/orchestrator.json')).get('metrics', {}).get('tasksFailed', 0))" 2>/dev/null || echo "0")
7786
+ _dv=$(python3 -c "import json; print(json.load(open('.loki/state/orchestrator.json')).get('currentPhase', 'BOOTSTRAP'))" 2>/dev/null) && current_phase="$_dv"
7787
+ _dv=$(python3 -c "import json; print(json.load(open('.loki/state/orchestrator.json')).get('version', 'unknown'))" 2>/dev/null) && version="$_dv"
7788
+ _dv=$(python3 -c "import json; print(json.load(open('.loki/state/orchestrator.json')).get('startedAt', ''))" 2>/dev/null) && started_at="$_dv"
7789
+ _dv=$(python3 -c "import json; print(json.load(open('.loki/state/orchestrator.json')).get('metrics', {}).get('tasksCompleted', 0))" 2>/dev/null) && tasks_completed="$_dv"
7790
+ _dv=$(python3 -c "import json; print(json.load(open('.loki/state/orchestrator.json')).get('metrics', {}).get('tasksFailed', 0))" 2>/dev/null) && tasks_failed="$_dv"
7765
7791
  fi
7766
7792
 
7767
7793
  # Emit phase change event if phase has changed (checked in background monitor loop)
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "10.5.14"
10
+ __version__ = "10.5.16"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -2,7 +2,7 @@
2
2
 
3
3
  The flagship product of [Autonomi](https://www.autonomi.dev/). Loki Mode is a spec-driven autonomous builder with a built-in trust layer that takes any spec to a deployed product and verifies completion with evidence (quality gates plus a completion council), not just a "done" claim. Complete installation instructions for all platforms and use cases.
4
4
 
5
- **Version:** v10.5.14
5
+ **Version:** v10.5.16
6
6
 
7
7
  ---
8
8
 
package/docs/v10/BOARD.md CHANGED
@@ -621,26 +621,31 @@ Source: ~/git/autonomi-dev/research/2026-09-30-adoption/SWARM-PROMPT-ADOPTION.md
621
621
  | A-103c | A-103 opus note: apply the missing-module not_run rule only when node's failing-tests block shows a file-level `test failed`, so a child node process crashing on a missing package (inherited stdio) cannot discard a real TypeError red; add the child-crash fixture | loki-ts/src/engine10/stages/wall.ts, loki-ts/tests/engine10/wall_runner.test.ts | HIGH | child-crash fixture red | released@2026-10-01T00:52Z | after A-103 Released in v10.5.13 (merge 774885e3 is an ancestor of v10.5.13). |
622
622
  | A-103d | A-103c opus note: nested Jest globals on node 20/22 TAP (`t.test("inner", () => expect(...))`) classify red (a false FAILED that keeps a bad Wall test) because nested yaml is indented 6 spaces and `^ {2}name:` misses it; node 26 gives not_run. Match `^ +name:` and `^ +stack:` at any indent. Pre-existing since 0cc1dea4 | loki-ts/src/engine10/stages/wall.ts, wall_runner.test.ts | HIGH | nested Jest-globals fixture not_run on node 20/22/26 | released@2026-10-01T00:52Z | CI runs node 22 Released in v10.5.13 (merge 634124cb is an ancestor of v10.5.13). |
623
623
  | A-111b | A-111 opus note: discount a zero-test trailer only when the test name equals the path under test, so one real passing test named like a bare filename (`a.test.js`) is not not_run | loki-ts/src/engine10/stages/verify.ts, its test | MEDIUM | bare-filename-named test passes | merged@2026-09-30T22:37Z | after A-113 (verify.ts) |
624
- | E-154 | Incident 17:14Z: tests wrote real signing keys to the founder's `~/.loki/keys` once signing became default (A-121, A-122 builders). Central guard: tests/run-all-tests.sh, the bun test preload and conftest set LOKI_RECEIPT_SIGNING_KEY_FILE/HOME to a run-owned path, plus a check that fails when a test run creates `~/.loki/keys` | tests/run-all-tests.sh, loki-ts bunfig preload, tests/conftest.py, new guard test | MEDIUM | guard test red when a test writes the real key dir | merged@2026-09-30T22:27Z | after A-121, A-122 |
624
+ | E-154 | Incident 17:14Z: tests wrote real signing keys to the founder's `~/.loki/keys` once signing became default (A-121, A-122 builders). Central guard: tests/run-all-tests.sh, the bun test preload and conftest set LOKI_RECEIPT_SIGNING_KEY_FILE/HOME to a run-owned path, plus a check that fails when a test run creates `~/.loki/keys` | tests/run-all-tests.sh, loki-ts bunfig preload, tests/conftest.py, new guard test | MEDIUM | guard test red when a test writes the real key dir | released@2026-10-01T01:19Z | after A-121, A-122 Released in v10.5.14 (merge 0d8a5dce is an ancestor of v10.5.14). |
625
625
  | E-155 | Incident 21:58Z: a shell test run from the MAIN checkout (633 diff-selected tests, xargs -P 4, 17:58:16 local) switched HEAD to the stale branch loki/session-1789047299-95963; main ref intact, restored by `git checkout main` 33s later. Candidates running that second: test-metrics-command, test-metrics-json-unmeasured, test-migration-post-edit-revert, test-mirofish-integration, test-magic-injection. A stray root bun.lock also appeared at 17:54. Guard: tests/run-all-tests.sh records `git symbolic-ref HEAD` + status before and fails loudly when any test changes the parent checkout branch; bisect the culprit with that guard | tests/run-all-tests.sh, culprit test | MEDIUM | guard test red when a test runs git checkout in the parent repo | merged@2026-09-30T22:27Z | process fix already applied: shell batches run only in a disposable worktree |
626
- | E-154c | CORRECTED PREMISE (builder, 59c1cb54): CI shards set LOKI_TEST_SHARD, not LOKI_TEST_LIST (a list-only mode that runs nothing), so sharded CI DOES run the guards; the train/14 failure was the guard test inheriting LOKI_TEST_SHARD. Slice adds shard-mode guard checks only. Original claim: the E-154/E-155 guards (run-owned signing key default, real ~/.loki/keys snapshot, parent HEAD check) are skipped whenever LOKI_TEST_LIST is set, and CI shards set it, so sharded CI runs carry NO guard: a test writing the real key dir or switching the parent branch would pass on CI. Make the guards active in shard mode too (the LOKI_TEST_LIST skip was presumably for selective local runs) and keep the guard test hermetic | tests/run-all-tests.sh, tests/test-e154-e155-guards.sh | MEDIUM | guard checks run and pass under LOKI_TEST_LIST | merged@2026-10-01T00:47Z | found while fixing train/14 shard 6 |
627
- | E-156 | Incident 22:00Z: pre-push gitleaks (generic-api-key) blocked train/11 on the key FILE NAME string `.loki/keys/receipt-ed25519.pem` (seal.ts:68, seal.test.ts:174, dist/loki.js:1244); no key material. Fixed by exact .gitleaksignore fingerprints, but any future commit that rewrites the minified dist line re-triggers and can block a release push. Durable fix needs a CTO call: a narrow `.gitleaks.toml` allowlist (regexTarget=secret, `^receipt-ed25519\.pem$`, extend defaults) pushed with LOKI_ALLOW_GITLEAKS_CONFIG_CHANGE=1 plus a test that a real key in the same position is still caught | .gitleaks.toml, tests/test-pre-push-gitleaks.sh | HIGH | real-key fixture still flagged; filename allowed | merged@2026-10-01T00:30Z | CTO approval (security scan config) |
628
- | E-157 | D46: Security Audit verdict reuse. (a) security-audit.yml also runs on push to train/** so every train tip gets the full --all gitleaks scan before main is fast-forwarded; (b) required-ci reuses the parent Security Audit verdict for an eligible VERSION-only bump under the existing eligibility rule (diff is VERSION plus generated version stamps only, parent run success at that exact SHA). Moat test: a non-VERSION-only bump still re-runs Security Audit. Supersedes FOUNDER-QUEUE 14 | .github/workflows/security-audit.yml, release.yml (required-ci), tests | HIGH | non-VERSION-only bump re-runs the scan | ready@2026-10-01T00:30Z | after slice-D46-ci |
629
- | A-113 | Stop reasons: STALLED and the fatal classifier (item 5) | see plan A-113 | HIGH | first-run-gate assertion per plan card | merged@2026-09-30T21:37Z | Wave per plan section 5; one writer per file. |
626
+ | E-154c | CORRECTED PREMISE (builder, 59c1cb54): CI shards set LOKI_TEST_SHARD, not LOKI_TEST_LIST (a list-only mode that runs nothing), so sharded CI DOES run the guards; the train/14 failure was the guard test inheriting LOKI_TEST_SHARD. Slice adds shard-mode guard checks only. Original claim: the E-154/E-155 guards (run-owned signing key default, real ~/.loki/keys snapshot, parent HEAD check) are skipped whenever LOKI_TEST_LIST is set, and CI shards set it, so sharded CI runs carry NO guard: a test writing the real key dir or switching the parent branch would pass on CI. Make the guards active in shard mode too (the LOKI_TEST_LIST skip was presumably for selective local runs) and keep the guard test hermetic | tests/run-all-tests.sh, tests/test-e154-e155-guards.sh | MEDIUM | guard checks run and pass under LOKI_TEST_LIST | released@2026-10-01T01:19Z | found while fixing train/14 shard 6 Released in v10.5.14 (merge 0d8a5dce is an ancestor of v10.5.14). |
627
+ | E-156 | Incident 22:00Z: pre-push gitleaks (generic-api-key) blocked train/11 on the key FILE NAME string `.loki/keys/receipt-ed25519.pem` (seal.ts:68, seal.test.ts:174, dist/loki.js:1244); no key material. Fixed by exact .gitleaksignore fingerprints, but any future commit that rewrites the minified dist line re-triggers and can block a release push. Durable fix needs a CTO call: a narrow `.gitleaks.toml` allowlist (regexTarget=secret, `^receipt-ed25519\.pem$`, extend defaults) pushed with LOKI_ALLOW_GITLEAKS_CONFIG_CHANGE=1 plus a test that a real key in the same position is still caught | .gitleaks.toml, tests/test-pre-push-gitleaks.sh | HIGH | real-key fixture still flagged; filename allowed | released@2026-10-01T01:19Z | CTO approval (security scan config) Released in v10.5.14 (merge 314b89fe is an ancestor of v10.5.14). |
628
+ | E-157 | D46: Security Audit verdict reuse. (a) security-audit.yml also runs on push to train/** so every train tip gets the full --all gitleaks scan before main is fast-forwarded; (b) required-ci reuses the parent Security Audit verdict for an eligible VERSION-only bump under the existing eligibility rule (diff is VERSION plus generated version stamps only, parent run success at that exact SHA). Moat test: a non-VERSION-only bump still re-runs Security Audit. Supersedes FOUNDER-QUEUE 14 | .github/workflows/security-audit.yml, release.yml (required-ci), tests | HIGH | non-VERSION-only bump re-runs the scan | merged@2026-10-01T01:45Z | after slice-D46-ci; r3 opus APPROVE 57b511d2 |
629
+ | E-159 | Pre-existing secret-scan gaps found by the E-157 r2 opus reviewer: (a) an evil merge, a merge commit whose OWN content adds a secret (merge -s ours --no-commit, token in the merge commit), is invisible to both the PARENT..SHA range scan and the --all scan (only `gitleaks dir` found it); (b) pinned gitleaks 8.30.0 exits 0 when its internal git log fails (invalid range), a latent fail-open. Fix: --diff-merges=first-parent (or -m) in --log-opts for both modes or a working-tree scan at the release SHA; guard `git rev-list RANGE` success or treat `[git] fatal` as failure | scripts/security-audit-gitleaks.sh, workflows, tests | HIGH | evil-merge and bad-range fixtures fail the scan | building@2026-10-01T01:45Z | CI-health engineer after E-157 r3; r1 opus REJECT 5f33451d: stdin merge scan false-positives on real history (v10.5.13..14 rc 1), Wall checks skip in CI |
630
+ | P0-t15 | train/15 and train/17 red: quiet `loki quick` default output 16 lines (stderr noise: mkdir .loki/config File exists, 2 caveman bootstrap lines, echo broken pipe). Fix: caveman notices to the quiet run log, fold a sentinel-only .loki/config into the config dir (never ~/.loki), SIGPIPE reset via python3 re-exec guarded by an import probe | autonomy/run.sh, autonomy/loki, tests/test-quick-config-safety.sh | MEDIUM | default output at most 15 lines; ~/.loki/config untouched from $HOME; broken python3 still runs | merged@2026-10-01T01:34Z | r1 REJECT (config clobber, python3 guard); r2 54da8960 APPROVE (config-safety 5/0, receipt-order 14/0 at 12 lines, crash-cli 57/0) |
631
+ | A-113 | Stop reasons: STALLED and the fatal classifier (item 5) | see plan A-113 | HIGH | first-run-gate assertion per plan card | released@2026-10-01T01:19Z | Wave per plan section 5; one writer per file. Released in v10.5.14 (merge 0377398d is an ancestor of v10.5.14). |
630
632
  | A-114 | FALSE VERIFIED ON MAIN (found by the A-112 opus reviewer, repro m6 on 4ad430ad): bugrepo plus an unrelated red test; the agent changes only other.js; verify selects only node:other.test.js (testmap from the diff), so the task's own target test sums.test.js is never run and the run seals VERIFIED rc=0 while it is red. Fix: the relevant tests of the task-named files (hasRelevantTests / impacted(likely), the lean-path Wall stand-in) are ALWAYS selected by verify, whatever the diff touches | loki-ts/src/engine10/stages/verify.ts or testmap selection, tests | HIGH | m6 fixture seals FAILED | merged@2026-09-30T22:37Z | coordinate with A-112 (verify.ts, same target notion); P0 moat |
631
633
  | A-115 | TIER 0 (steer 22:50Z). FALSE VERIFIED ON MAIN (A-112 opus reviewer, c10 on 275b4fc0): a conftest.py that skips the target test (and the unrelated red one) seals VERIFIED rc=0, "2 passed, 2 skipped", nothing disclosed. Seal accuracy: a relevant check with more skipped tests than base, or a diff touching conftest.py / pytest.ini / pyproject [tool.pytest] / jest or node test config, must not count as a pass or as progress; list it in NOT PROVEN | loki-ts/src/engine10/stages/verify.ts, failures.ts, tests | HIGH | c10 and e9 fixtures seal FAILED or NOT VERIFIED | released@2026-10-01T00:52Z | core at the 5000 cap: needs an offset (A-150) Released in v10.5.13 (merge bdb332e3 is an ancestor of v10.5.13). |
632
- | A-115b | A-115 opus notes: (1) an honest fix that also appends a new test to a relevant test file, in a repo with an unrelated red test, ends STALLED/FAILED instead of PARTIAL: the edited file is excluded from progress so the unrelated red is never subtracted; allow progress when the file's pre-existing target ids went red to green; (2) the node base-count fallback sums every `pass N`/`fail N` line, so a base test printing them inflates the count (safe-direction false PARTIAL); take the last pass and last fail lines | loki-ts/src/engine10/stages/verify.ts, verify_weak.test.ts | HIGH | both fixtures | ready@2026-09-30T23:42Z | |
633
- | A-117 | FALSE VERIFIED IN `loki verify` (A-130 r2 opus reviewer): on a run whose events.jsonl was tampered (append, edit, truncate, delete), the run now ends FAILED (A-130) but the receipt on disk still says VERIFIED with no tamper mark, because the worker sealed it before the supervisor detected the tamper; `loki verify` prints verdict: VERIFIED rc=0. Fix: record the tamper on the receipt via the registered receipt.addendum event (hash-chained) or have verify check the event log hash; verify must say TAMPERED and exit non-zero | loki-ts/src/engine10/verify_cmd.ts, supervisor.ts or seal.ts, tests | HIGH | tampered-log fixture: loki verify TAMPERED rc!=0 | ready@2026-09-30T23:23Z | after A-130 (supervisor.ts) |
634
- | A-118 | Exit-honest policy gap on the DEFAULT path (A-115 r2 finding): legacy `loki quick` prints `Evidence Receipt: NOT VERIFIED` yet exits rc 0 on a run whose target test was skipped; G1 exit-honest counts a skipped test as green, so it does not catch this. CTO call: should legacy quick exit non-zero on NOT VERIFIED when a relevant test was skipped/weakened, and should G1 count skipped as not-green? | autonomy/run.sh (quick exit path), scripts/first-run-gate.sh G1 | HIGH | skipped-target legacy run exits non-zero; G1 treats skipped as not green | ready@2026-09-30T23:33Z | CTO decision first; blocks promote of `latest` together with A-115 |
634
+ | A-115b | A-115 opus notes: (1) an honest fix that also appends a new test to a relevant test file, in a repo with an unrelated red test, ends STALLED/FAILED instead of PARTIAL: the edited file is excluded from progress so the unrelated red is never subtracted; allow progress when the file's pre-existing target ids went red to green; (2) the node base-count fallback sums every `pass N`/`fail N` line, so a base test printing them inflates the count (safe-direction false PARTIAL); take the last pass and last fail lines | loki-ts/src/engine10/stages/verify.ts, verify_weak.test.ts | HIGH | both fixtures | merged@2026-10-01T01:02Z | |
635
+ | A-119 | P0 FALSE VERIFIED ON MAIN (A-115b opus reviewer, reproduced on bba2e5ec): rename the target test file and weaken its expectation (sum.test.js => sum.spec.test.js with 6 changed to 5), add a comment to sum.js: rc=0 Outcome VERIFIED, receipt shows node:sum.spec.test.js pass, sum.js still buggy. verify only sees relevant test files that still exist on head; seal writes `weakened test: sum.test.js` (seal.ts:205) but that line never downgrades the verdict. Fix: seal's `weakened test:` downgrades to PARTIAL like verify's not_proven | loki-ts/src/engine10/stages/seal.ts, tests | HIGH | rename-and-weaken fixture: not VERIFIED, rc!=0 | merged@2026-10-01T01:17Z | Tier 0 |
636
+ | A-119b | A-119 opus review (REJECT on pre-existing holes, A-119 landed as a strict improvement): weakening still ends VERIFIED via (1) a helper file a base test imports (eq=()=>{}), (2) snapshot or fixture edits (__snapshots__/*.snap, tests/fixtures/*.json), (3) tests isTestFile (testmap.ts:51) does not recognise: __tests__/*.js, mocha test/*.js, cargo tests/*.rs, including rename to .bak. Also: verdictOf returns ALREADY_SATISFIED before the weakened downgrade when implement says already_done; package.json jest testPathIgnorePatterns and vite.config.ts test.exclude skip config detection. Fix: widen the seal.ts weakTests predicate to any changed/deleted base path under test/, tests/, __tests__/, __snapshots__/, fixtures dirs plus non-test files a base test imports; check weakened before the already_done early return; add vite.config and in-block jest keys to CFG detection | loki-ts/src/engine10/stages/seal.ts, verify.ts (CFG only), tests | HIGH | each repro gives not-VERIFIED; source-only fix and new test stay VERIFIED | review@2026-10-01T01:39Z | |
637
+ | A-117 | FALSE VERIFIED IN `loki verify` (A-130 r2 opus reviewer): on a run whose events.jsonl was tampered (append, edit, truncate, delete), the run now ends FAILED (A-130) but the receipt on disk still says VERIFIED with no tamper mark, because the worker sealed it before the supervisor detected the tamper; `loki verify` prints verdict: VERIFIED rc=0. Fix: record the tamper on the receipt via the registered receipt.addendum event (hash-chained) or have verify check the event log hash; verify must say TAMPERED and exit non-zero | loki-ts/src/engine10/verify_cmd.ts, supervisor.ts or seal.ts, tests | HIGH | tampered-log fixture: loki verify TAMPERED rc!=0 | building@2026-10-01T01:48Z | after A-130 (supervisor.ts); r2: opus REJECT, tail truncation erases post-seal tamper, fix = signed final log line |
638
+ | A-118 | Exit-honest policy gap on the DEFAULT path (A-115 r2 finding): legacy `loki quick` prints `Evidence Receipt: NOT VERIFIED` yet exits rc 0 on a run whose target test was skipped; G1 exit-honest counts a skipped test as green, so it does not catch this. CTO call: should legacy quick exit non-zero on NOT VERIFIED when a relevant test was skipped/weakened, and should G1 count skipped as not-green? | autonomy/run.sh (quick exit path), scripts/first-run-gate.sh G1 | HIGH | skipped-target legacy run exits non-zero; G1 treats skipped as not green | review@2026-10-01T01:45Z | D47 decided: rc 3 on tests_integrity failed (skip added, runner config changed, test file deleted/renamed); assertion edits disclosed rc 0; G1 green needs pass 2 fail 0, 9b asserts rc 3. Files: proof-generator.py, run.sh after generate_proof_of_run, first-run-gate.sh, docs/exit-codes.md. Blocks promote of `latest`; built df404970, opus review |
635
639
  | A-112b | A-112 readability debt: subtractBase in verify.ts was folded to reach 4999 of 5000 core lines (9 lines over 200 chars, longest 347; un/progress/base-run loop each on one line). Unfold when A-150 frees budget; no behaviour change | loki-ts/src/engine10/stages/verify.ts | MEDIUM | budget test plus verify_prered unchanged | ready@2026-09-30T22:37Z | after A-150 |
636
- | A-113b | A-110 opus notes on A-113: (1) under the CLI invoker (LOKI_E10_INVOKER=cli) the provider child stderr never reaches the fatal classifier (the *-impl.stderr.log is empty), so a credit/auth failure printed on plain stderr gives stop:null and burns the fix rounds; (2) machine.ts re-records the previous signature when a verify crashes, so a crashed verify counts toward a stall. Fix both in session.ts/machine.ts, with end-to-end tests through the real worker | loki-ts/src/engine10/session.ts, machine.ts, tests | HIGH | CLI stderr credit line stops fatal; crashed verify does not count as a stall repeat | merged@2026-10-01T00:30Z | keep the A-110 escalated emit; the A-110 reviewer plugin probe is a good e2e template |
640
+ | A-113b | A-110 opus notes on A-113: (1) under the CLI invoker (LOKI_E10_INVOKER=cli) the provider child stderr never reaches the fatal classifier (the *-impl.stderr.log is empty), so a credit/auth failure printed on plain stderr gives stop:null and burns the fix rounds; (2) machine.ts re-records the previous signature when a verify crashes, so a crashed verify counts toward a stall. Fix both in session.ts/machine.ts, with end-to-end tests through the real worker | loki-ts/src/engine10/session.ts, machine.ts, tests | HIGH | CLI stderr credit line stops fatal; crashed verify does not count as a stall repeat | released@2026-10-01T01:19Z | keep the A-110 escalated emit; the A-110 reviewer plugin probe is a good e2e template Released in v10.5.14 (merge 0377398d is an ancestor of v10.5.14). |
637
641
  | A-121 | v10 signs and verifies natively (item 3) | see plan A-121 | HIGH | first-run-gate assertion per plan card | released@2026-10-01T00:52Z | Wave per plan section 5; one writer per file. Released in v10.5.13 (merge 08b31271 is an ancestor of v10.5.13). |
638
642
  | A-122 | Delete the GPG signing layer (item 3, deletion) | see plan A-122 | HIGH | first-run-gate assertion per plan card | released@2026-10-01T00:52Z | Wave per plan section 5; one writer per file. Released in v10.5.13 (merge cb738c36 is an ancestor of v10.5.13). |
639
- | A-121b | A-121 opus note: a receipt downgrade exits 0. Anyone can edit the body, recompute receipt_sha256 and null the jwt to get UNSIGNED rc 0 on `loki verify`, and the legacy deploy gate refuses UNSIGNED but the v10 verify does not. Decide the signed-by-default policy: once a local key exists, UNSIGNED on a receipt from this machine exits non-zero (or the receipt records its kid outside the hashed body) | loki-ts/src/engine10/verify_cmd.ts, stages/seal.ts, tests | HIGH | downgrade fixture exits non-zero | ready@2026-09-30T21:37Z | CTO call on policy first |
643
+ | A-121b | A-121 opus note: a receipt downgrade exits 0. Anyone can edit the body, recompute receipt_sha256 and null the jwt to get UNSIGNED rc 0 on `loki verify`, and the legacy deploy gate refuses UNSIGNED but the v10 verify does not. Decide the signed-by-default policy: once a local key exists, UNSIGNED on a receipt from this machine exits non-zero (or the receipt records its kid outside the hashed body) | loki-ts/src/engine10/verify_cmd.ts, stages/seal.ts, tests | HIGH | downgrade fixture exits non-zero | building@2026-10-01T01:17Z | D47 decided: UNSIGNED exits 3 on both engines (verify_cmd.ts EXIT_BY_VERDICT, autonomy/verify.sh _verify_receipt_digest), --allow-unsigned / LOKI_VERIFY_ALLOW_UNSIGNED=1 accepts with explicit line; update tests/test-engine10-live-pr.sh 115-122; verify never creates a key |
640
644
  | A-110 | One named outcome, fixed exit ladder, --json (items 1 and 5) | see plan A-110 | HIGH | first-run-gate assertion per plan card | released@2026-10-01T00:52Z | Wave per plan section 5; one writer per file. Released in v10.5.13 (merge 47ac1ccc is an ancestor of v10.5.13). |
641
645
  | A-112 | Baseline subtract: judge only the delta (item 5) | see plan A-112 | HIGH | first-run-gate assertion per plan card | released@2026-10-01T00:52Z | Wave per plan section 5; one writer per file. Released in v10.5.13 (merge 69f1a910 is an ancestor of v10.5.13). |
642
646
  | A-123 | Doctor: only the selected provider blocks, one Ready line (item 3) | see plan A-123 | MEDIUM | first-run-gate assertion per plan card | released@2026-10-01T00:52Z | Wave per plan section 5; one writer per file. Released in v10.5.13 (merge 275b4fc0 is an ancestor of v10.5.13). |
643
647
  | A-134 | Legacy: receipt after the final commit, chatter behind --verbose (item 2) | see plan A-134 | MEDIUM | first-run-gate assertion per plan card | released@2026-10-01T00:52Z | Wave per plan section 5; one writer per file. Released in v10.5.13 (merge 7d3edf96 is an ancestor of v10.5.13). |
644
- | A-134b | A-134 opus notes: (1) standalone autonomy/verify.sh prints no attestation line (only `loki verify` has _deploy_receipt_verdict); print `attestation: UNCHECKED (run via loki verify)` instead of silence; (2) the quiet failure tail grep `[Ff]ailed` matched the RALPH system-prompt line and printed ~1.5k chars; anchor to `^\[(ERROR|WARN)\]` or cap line length; (3) the quiet inner run starts as a background job so its stdin is /dev/null even from a TTY: pause-mode keypress resume changes for quiet runs; (4) `loki quick --verbose` is also the A-122 cmd_quick flag, done | autonomy/verify.sh, autonomy/run.sh | MEDIUM | each note has a test | ready@2026-09-30T22:28Z | |
645
- | A-130 | v10 quiet by default (item 2) | see plan A-130 | MEDIUM | first-run-gate assertion per plan card | merged@2026-10-01T00:30Z | Wave per plan section 5; one writer per file. |
646
- | A-130b | A-130 Reason line prints first_error from a failing check verbatim (capped at 200 chars, control chars stripped) but unredacted: a `ghp_` token in a test failure line reaches the terminal. No TS redactor is reachable from engine10 core (only autonomy/lib/proof_redact.py). Port the token patterns to a small TS helper outside core or redact first_error where it is captured in verify | loki-ts/src (util), verify.ts or output.ts, tests | MEDIUM | ghp_/sk- token in first_error prints redacted | ready@2026-10-01T00:05Z | |
648
+ | A-134b | A-134 opus notes: (1) standalone autonomy/verify.sh prints no attestation line (only `loki verify` has _deploy_receipt_verdict); print `attestation: UNCHECKED (run via loki verify)` instead of silence; (2) the quiet failure tail grep `[Ff]ailed` matched the RALPH system-prompt line and printed ~1.5k chars; anchor to `^\[(ERROR|WARN)\]` or cap line length; (3) the quiet inner run starts as a background job so its stdin is /dev/null even from a TTY: pause-mode keypress resume changes for quiet runs; (4) `loki quick --verbose` is also the A-122 cmd_quick flag, done | autonomy/verify.sh, autonomy/run.sh | MEDIUM | each note has a test | review@2026-10-01T01:46Z | |
649
+ | A-134c | A-134b r1 review finding: provider call sites in autonomy/run.sh (mainline claude -p at about 25455/25460, provider_invoke_argv about 1050/1053) do not redirect stdin, so under LOKI_VERBOSE=1 (and any non-quiet path) a parent stdin pipe that never closes blocks `claude -p` reading stdin (pre-existing). Fix: `< /dev/null` at provider invocations that pass the prompt as an argument | autonomy/run.sh (provider call sites only), providers/*.sh, tests | MEDIUM | never-closing stdin pipe: verbose `loki quick` completes under timeout 60 | ready@2026-10-01T01:37Z | |
650
+ | A-130 | v10 quiet by default (item 2) | see plan A-130 | MEDIUM | first-run-gate assertion per plan card | released@2026-10-01T01:19Z | Wave per plan section 5; one writer per file. Released in v10.5.14 (merge a518bfea is an ancestor of v10.5.14). |
651
+ | A-130b | A-130 Reason line prints first_error from a failing check verbatim (capped at 200 chars, control chars stripped) but unredacted: a `ghp_` token in a test failure line reaches the terminal. No TS redactor is reachable from engine10 core (only autonomy/lib/proof_redact.py). Port the token patterns to a small TS helper outside core or redact first_error where it is captured in verify | loki-ts/src (util), verify.ts or output.ts, tests | MEDIUM | ghp_/sk- token in first_error prints redacted | merged@2026-10-01T01:45Z | ; sonnet APPROVE be50510f (redaction before cap, parity with proof_redact.py) |
@@ -375,3 +375,11 @@ Loki's definition: "autonomous software factory that runs with the knowledge of
375
375
  6. A v10-pulse RELEASE_SLO alarm fires below 3 `next` releases in the trailing 60 minutes; on it, the Chief of Staff ships the newest green train or the last green tree first, then fixes the cause.
376
376
  7. Slices stay small enough to build and pass in under 30 minutes; bigger work is split.
377
377
  - NOT applied without direct founder approval: moving the release-blocking full-history gitleaks scan (`--all`) out of the Release path (item 4 of the relay). It weakens a security gate on a relayed instruction; queued as FOUNDER-QUEUE row 14.
378
+
379
+ ## D47 (CTO, 2026-10-01): honest exits on the default path, and UNSIGNED is never a pass
380
+ 1. Legacy `loki quick` exits 3 when the diff weakens tests: a skip marker added, test runner config changed, or an existing test file deleted or renamed. Edited assertion lines are disclosed in the receipt and keep rc 0. A NOT VERIFIED headline from unproven gates alone keeps rc 0.
381
+ 2. The signal is a proof fact (tests_integrity in degraded[]), never the headline. It only raises an inner rc of 0, in quiet and verbose modes alike. first-run-gate G1 counts green only as pass 2 and fail 0, so a skip is not green.
382
+ 3. `loki verify` exits 3 on UNSIGNED on both engines, on any machine, with or without a local key, because a stripped receipt must never rank above UNCHECKED (rc 2).
383
+ 4. Recording the kid outside the hash and markers inside the body were rejected: verification is already unhashed and a forger can rewrite any body field.
384
+ 5. `--allow-unsigned` or LOKI_VERIFY_ALLOW_UNSIGNED=1 accepts UNSIGNED with an explicit line. It never changes TAMPERED or UNCHECKED, and verify never creates a key.
385
+ 6. Both slices (A-118, A-121b) are HIGH tier with red-first fixtures (skip, config, rename, downgrade, fresh HOME). They land before `latest` is promoted, together with A-115.
@@ -1627,3 +1627,40 @@ The swarm is stopped: .loki/V10-STOP exists, the loop has no wake-ups, and the c
1627
1627
  - Moat bugs found and fixed today (all false-VERIFIED class): A-112/A-114 (pre-red subtract, avoided target), A-115 (skip, xfail, pytest.exit, deleted target), A-130 (tampered event log sealed VERIFIED exit 0 on main). Open: A-117 (loki verify still VERIFIED on a tampered event log), A-118 (legacy quick exits 0 on NOT VERIFIED skipped target; CTO call). `latest` stays unpromoted until A-117/A-118 and a real-provider gate pass.
1628
1628
  - Merged on local main for train/15: A-130. In review: A-113b r3 (provider stderr in memory), E-156 (key file name constant: removes the gitleaks trigger at the source).
1629
1629
  - loki-seal: merged, ships with 10.5.13. Head-to-head: not run.
1630
+
1631
+ ## 2026-10-01T00:55Z first-run gate on the PUBLISHED next build (10.5.13)
1632
+ - 10.5.13 published to npm `next`: `npm view loki-mode@10.5.13 version gitHead` = 10.5.13 / 08f46297 (watcher 00:52:36Z); dist-tags next=10.5.13, latest=10.5.10 (unchanged); release body 25 lines. Registry lag about 8 minutes (no hold).
1633
+ - `bash scripts/first-run-gate.sh --stub --installed loki-mode@10.5.13` (npm-installed package, throwaway HOME, stub provider), GATE: 0 assertion(s) failed, wall 26s:
1634
+ - PASS exit-honest (rc=0, green=1); PASS tests-green (node --test 2/0, npm test rc=0); PASS no-stray-files (only sum.js); PASS digest-matches; PASS verify-ok (rc=0); PASS receipt-signed; PASS output-lines (15 of 15); PASS wall-time (26s).
1635
+ - G8: PASS skip-not-verified (v10: skipped target rc=1, Outcome FAILED); PASS skip-not-verified-legacy (legacy headline NOT VERIFIED; rc=0, not asserted: that is A-118).
1636
+ - REAL-provider mode: NOT RUN. The swarm has no provider credential in its environment and does not read stored secrets; FOUNDER-QUEUE row 15 has the exact command. Cost/wall vs raw `claude -p`: pending that run.
1637
+ - `latest` NOT promoted: needs the real-provider pass plus A-117 (loki verify on a tampered log, building) and A-118 (legacy quick exits 0 on NOT VERIFIED, CTO call).
1638
+ - Trains: train/16 (bba2e5ec) in Tier B. 1 `next` release in the trailing hour vs the D46 target of 3-6.
1639
+
1640
+ ## 2026-10-01T01:14Z train/17 red (D46 tally: cut 1, red 1, dropped 0)
1641
+ - train/17 935b2766 Tests run 36799190925: shard 4 only, 49/50 passed. The one failure is tests/test-quick-receipt-order.sh "default output is 16 lines (max 15)". The 16 lines are stderr noise (mkdir .loki/config exists, 2 caveman bootstrap lines, echo broken pipe), the same main-resident failure as train/15. A-115b is not implicated, so nothing is dropped. Fix forward is slice-P0-t15, in rework (2 reviewer blockers). train/18 = train/17 + P0-t15 once approved. Bun Parity and Coverage: success.
1642
+ - v10.5.14 (2f4462b7) Release run still in progress at 01:10Z; next=10.5.13, latest=10.5.10 (npm view dist-tags).
1643
+ - Staffed 01:12Z: A-119 opus review, A-130b and A-134b builders, CTO call on A-118/A-121b.
1644
+
1645
+ ## 2026-10-01T01:20Z v10.5.14 published
1646
+ - Release run success; `npm view loki-mode@10.5.14 version gitHead` = 10.5.14 / 2f4462b7; dist-tags next=10.5.14, latest=10.5.10 (unchanged); release body 17 lines.
1647
+ - D46 tally this hour: next releases 1 (10.5.14) vs target 3-6; trains cut 1 (train/17), red 1, dropped 0. Shortfall cause: the main-resident quiet-output flake (P0-t15 in rework).
1648
+ - OPUS_SHARE 33.7% vs 30%: no new opus seats until it drops; the open opus work is the A-117 r2 builder (resumed) only.
1649
+
1650
+ ## 2026-10-01T01:32Z train/18 cut
1651
+ - train/18 = 37267ebd (local main d5d679a4: A-119 merge c41a2b83 + docs, plus dist rebuild), pushed by SHA 01:34Z (`git ls-remote origin refs/heads/train/18` = 37267ebd). Tier B watcher armed.
1652
+ - P0-t15 round 2 at 54da8960 in sonnet re-review; train/19 = train/18 + P0-t15 when approved.
1653
+ - In review: A-130b (be50510f), A-134b (3bbec935). Building: A-117 r2, A-118, A-121b, A-119b (7edf4ae0 awaiting one clean full run).
1654
+ - Seats capped by worktrees 15/15 and load about 15-25; no new seats this tick.
1655
+
1656
+ ## 2026-10-01T01:41Z train/18 green, v10.5.15 cut, train/20 cut
1657
+ - train/18 37267ebd: Tests, Bun Parity, Coverage (baseline) all success (watcher b3l054ag3, 01:38:25Z). origin/main fast-forwarded 2f4462b7..37267ebd.
1658
+ - v10.5.15 release commit a7945d67 (parent 37267ebd == origin/main; `release.sh --check-clean` rc=0), pushed by SHA. Contents: A-119, A-115b. Watcher armed for Release run, npm version/gitHead, next == 10.5.15, latest unchanged (10.5.10).
1659
+ - train/19 89bf645b (P0-t15) is superseded for main because it lacks the release commit; train/20 c57eb914 = train/19 + main (release merge c908a37f), pushed 01:43Z, Tier B watcher armed.
1660
+ - D46 tally: trains cut 3 this hour (18, 19, 20), red 0 of the finished ones.
1661
+
1662
+ ## 2026-10-01T01:51Z trains 19/20 red on one lint line; train/21 carries the fix
1663
+ - train/19 89bf645b and train/20 c57eb914: Tests failed only in "ShellCheck Linting" (SC2088, a quoted "~/.loki/config" in tests/test-quick-config-safety.sh line 71, from P0-t15). The quiet-output 16-line failure did not recur (failparse on job 110179389806 lists only ShellCheck). Fixed forward on main 1be4bbe9 (run-shellcheck.sh rc=0); train/21 2ebfa3a1 = train/20 + fix + E-157, in Tier B.
1664
+ - v10.5.15 a7945d67: Release run queued at 01:48Z.
1665
+ - Reviews: E-157 r3 APPROVE (merged), A-130b APPROVE (merged), E-159 REJECT (rework), A-117 r2 REJECT (back-compat for old receipts; key-env tests), A-118/A-119b/A-134b r2 in review.
1666
+ - D46 tally this hour: next releases 1 confirmed (10.5.14) + 1 pending (10.5.15); trains cut 18/19/20/21, red 19 and 20 (one lint line), dropped 0. OPUS_SHARE 36% (HIGH reviews only); load about 25 of 28, no new seats.