loki-mode 11.77.0 → 11.79.0

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 (86) hide show
  1. package/SKILL.md +3 -3
  2. package/VERSION +1 -1
  3. package/autonomy/lib/cockpit-render.sh +1 -1
  4. package/autonomy/lib/proof-generator.py +48 -0
  5. package/autonomy/lib/proof-pr.sh +13 -0
  6. package/autonomy/lib/telemetry-schema.json +4 -0
  7. package/autonomy/loki +280 -13
  8. package/autonomy/run.sh +126 -8
  9. package/autonomy/telemetry.sh +13 -0
  10. package/autonomy/verify.sh +2 -2
  11. package/bin/loki +17 -12
  12. package/completions/_loki +24 -0
  13. package/completions/loki.bash +22 -1
  14. package/dashboard/__init__.py +1 -1
  15. package/docs/{v10/CLI-MODERN.md → CLI-INVENTORY.md} +9 -8
  16. package/docs/CLI-REFERENCE.md +3 -2
  17. package/docs/INSTALLATION.md +1 -1
  18. package/docs/PRIVACY.md +1 -0
  19. package/docs/dev/architecture-reference.md +3 -2
  20. package/docs/dev/project-structure.md +2 -1
  21. package/loki-ts/data/child-env.json +1 -0
  22. package/loki-ts/dist/loki.js +1657 -1645
  23. package/loki-ts/package.json +2 -2
  24. package/mcp/__init__.py +1 -1
  25. package/mcp/requirements.txt +1 -1
  26. package/package.json +3 -3
  27. package/packages/control-plane/dist/server.js +19608 -19067
  28. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  29. package/skills/quality-gates.md +6 -0
  30. package/web-app/dist/assets/{AdminPage-DrlEpTKN.js → AdminPage-Bph4VGNm.js} +1 -1
  31. package/web-app/dist/assets/{Avatar-CJ9juG_K.js → Avatar-Btrppoor.js} +1 -1
  32. package/web-app/dist/assets/{Badge-DcttGvjK.js → Badge-fJFe3CEH.js} +1 -1
  33. package/web-app/dist/assets/{Button-b5O9YocE.js → Button-B_cYY4Me.js} +1 -1
  34. package/web-app/dist/assets/{CockpitPage-Bx6KwmVB.js → CockpitPage-26oBcuYy.js} +1 -1
  35. package/web-app/dist/assets/{ComparePage-BaevXGrD.js → ComparePage-CSuQZUm2.js} +1 -1
  36. package/web-app/dist/assets/{ErrorBoundary-2sZmLblz.js → ErrorBoundary-Cf7DQMz0.js} +1 -1
  37. package/web-app/dist/assets/{EvidenceReceiptPanel-C2XY1fMD.js → EvidenceReceiptPanel-BMZszYBV.js} +1 -1
  38. package/web-app/dist/assets/{GitHubIssuesPanel-DwHuq31X.js → GitHubIssuesPanel-Bt5dkJwW.js} +1 -1
  39. package/web-app/dist/assets/{GitHubPRsPanel-BQMn-YnD.js → GitHubPRsPanel-CL4NbWJ3.js} +1 -1
  40. package/web-app/dist/assets/{HomePage-Dpo55VLr.js → HomePage-Bqugxf45.js} +2 -2
  41. package/web-app/dist/assets/{LoginPage-Dfnw1PTO.js → LoginPage-ENM9QyG8.js} +1 -1
  42. package/web-app/dist/assets/{MagicPage-DoR3K8ef.js → MagicPage-D-7g-mew.js} +1 -1
  43. package/web-app/dist/assets/{MetricsPage-Brf8VAOe.js → MetricsPage-CelqK13G.js} +1 -1
  44. package/web-app/dist/assets/{NotFoundPage-CepMv0TW.js → NotFoundPage-EQ3Aq4Xg.js} +1 -1
  45. package/web-app/dist/assets/{ProjectPage-DKGi8lof.js → ProjectPage-D3Jls_Oh.js} +3 -3
  46. package/web-app/dist/assets/{ProjectsPage-BxPCmo7e.js → ProjectsPage-CgGRkJ3X.js} +1 -1
  47. package/web-app/dist/assets/{SettingsPage-CriniWvU.js → SettingsPage-B79K8xg2.js} +1 -1
  48. package/web-app/dist/assets/{ShowcasePage-B2PV4GFW.js → ShowcasePage-DxSsaGGx.js} +1 -1
  49. package/web-app/dist/assets/{SystemSettingsPage-CQUapqwh.js → SystemSettingsPage-CYNKB-5I.js} +1 -1
  50. package/web-app/dist/assets/{TeamsPage-BkLyYavH.js → TeamsPage-Bit01iEC.js} +1 -1
  51. package/web-app/dist/assets/{TemplatesPage-CeU_rnJk.js → TemplatesPage-DQ3fPi7x.js} +1 -1
  52. package/web-app/dist/assets/{TerminalOutput-oLOjcbqL.js → TerminalOutput-By137hB-.js} +1 -1
  53. package/web-app/dist/assets/{activity-DEHJPfgq.js → activity-rbRWrIjS.js} +1 -1
  54. package/web-app/dist/assets/{bell-BmXaknK2.js → bell-DIiSalJU.js} +1 -1
  55. package/web-app/dist/assets/{bot-B-JWrH_p.js → bot-BQyrbJaf.js} +1 -1
  56. package/web-app/dist/assets/{check-BaspF93s.js → check-BJ_PqlU2.js} +1 -1
  57. package/web-app/dist/assets/{chevron-left-M6VCet0K.js → chevron-left-_QsMbFBT.js} +1 -1
  58. package/web-app/dist/assets/{circle-alert-DVLpodrK.js → circle-alert-DEovFrER.js} +1 -1
  59. package/web-app/dist/assets/{clock-BRy8KpHK.js → clock-Dmrl0gvN.js} +1 -1
  60. package/web-app/dist/assets/{cloud-jTlY1qAB.js → cloud-Bs2a7FCR.js} +1 -1
  61. package/web-app/dist/assets/{code-xml-73Xelkkd.js → code-xml-D2WdclgQ.js} +1 -1
  62. package/web-app/dist/assets/{database-DpMqKrsA.js → database-kbYbPMS5.js} +1 -1
  63. package/web-app/dist/assets/{dollar-sign-Bcw89Epb.js → dollar-sign-BoOAvw6B.js} +1 -1
  64. package/web-app/dist/assets/{file-code-corner-5Drrk2XB.js → file-code-corner-ew5NSFtR.js} +1 -1
  65. package/web-app/dist/assets/{file-plus-D1PmiWXN.js → file-plus-CNV2nXNx.js} +1 -1
  66. package/web-app/dist/assets/{globe-Dq8rgYwT.js → globe-CZo7LjYX.js} +1 -1
  67. package/web-app/dist/assets/{hammer-Duyrm7AU.js → hammer-BedES-IA.js} +1 -1
  68. package/web-app/dist/assets/{index-Dg4Wvsep.js → index-C_uRanCX.js} +3 -3
  69. package/web-app/dist/assets/{layers-zbNbb_Hz.js → layers-B-OfB6O0.js} +1 -1
  70. package/web-app/dist/assets/{loader-circle-vOKp3Yno.js → loader-circle-C8hx3EE8.js} +1 -1
  71. package/web-app/dist/assets/{lock-AsdJPlwj.js → lock-Cyi_Tc3f.js} +1 -1
  72. package/web-app/dist/assets/{package-Dt8-zN2y.js → package-Cfps-Gdr.js} +1 -1
  73. package/web-app/dist/assets/{plus-md8Hlau_.js → plus-CjSNRaN2.js} +1 -1
  74. package/web-app/dist/assets/{refresh-cw-BSTU8fSw.js → refresh-cw-pEhkaiQh.js} +1 -1
  75. package/web-app/dist/assets/{rotate-ccw-D5Wn5NCl.js → rotate-ccw-twl6HuT5.js} +1 -1
  76. package/web-app/dist/assets/{scroll-text-ChmR_jcw.js → scroll-text-B9XWtVcd.js} +1 -1
  77. package/web-app/dist/assets/{server-NY1F729P.js → server-DeBbwC8T.js} +1 -1
  78. package/web-app/dist/assets/{shield-alert-yhSn1RwF.js → shield-alert-BGQQ_YfF.js} +1 -1
  79. package/web-app/dist/assets/{thumbs-up-GEJKgG1X.js → thumbs-up-Dy9nEa04.js} +1 -1
  80. package/web-app/dist/assets/{trash-2-elTR7osS.js → trash-2-DIftKB8Y.js} +1 -1
  81. package/web-app/dist/assets/{trending-down-ptCvIKeg.js → trending-down-Cjh8EsVU.js} +1 -1
  82. package/web-app/dist/assets/{trending-up-DbdbNpEl.js → trending-up-xWyMrayW.js} +1 -1
  83. package/web-app/dist/assets/{upload-D61Rwawf.js → upload-Bh3moncl.js} +1 -1
  84. package/web-app/dist/assets/{usePolling-DNF7DO1q.js → usePolling-C2sF90ff.js} +1 -1
  85. package/web-app/dist/assets/{user-BEYk6Un_.js → user-CtBrnwfC.js} +1 -1
  86. package/web-app/dist/index.html +1 -1
package/autonomy/run.sh CHANGED
@@ -6386,7 +6386,7 @@ ${_del_receipt}"
6386
6386
  # legacy parallel workflow remains byte-for-byte on its old path.
6387
6387
  _loki_exec_manifest() {
6388
6388
  [ "${LOKI_EXEC_MANIFEST:-0}" = "1" ] || return 0
6389
- bun "${SCRIPT_DIR}/../loki-ts/dist/loki.js" internal exec-manifest "$@"
6389
+ bun --no-env-file --config=/dev/null "${SCRIPT_DIR}/../loki-ts/dist/loki.js" internal exec-manifest "$@"
6390
6390
  }
6391
6391
 
6392
6392
  init_exec_manifest() {
@@ -15759,6 +15759,29 @@ enforce_mock_integrity() {
15759
15759
  return 0
15760
15760
  }
15761
15761
 
15762
+ # Skill-declared checks gate. Delegates to `loki internal skill-checks` (the Bun
15763
+ # runSkillChecks implementation) so both routes run the same commands with the
15764
+ # same hardened env. Sets _LOKI_SKILL_CHECKS_STATUS to pass|fail|not_run.
15765
+ # Fail closed: a missing launcher, missing bun, or an absent subcommand (rc 2,
15766
+ # e.g. a stale build) is recorded not_run, never pass; any other non-zero rc
15767
+ # (a failed check, or the runner erroring) is a fail.
15768
+ enforce_skill_checks() {
15769
+ local _sk_loki="${PROJECT_DIR}/bin/loki" _sk_out _sk_rc=0
15770
+ _LOKI_SKILL_CHECKS_STATUS="not_run"
15771
+ _LOKI_SKILL_CHECKS_REASON="launcher_absent"
15772
+ _LOKI_SKILL_CHECKS_DETAIL=""
15773
+ if [ ! -x "$_sk_loki" ] || ! command -v bun >/dev/null 2>&1; then
15774
+ return 0
15775
+ fi
15776
+ _sk_out="$(cd "${TARGET_DIR:-.}" 2>/dev/null && "$_sk_loki" internal skill-checks 2>&1)" || _sk_rc=$?
15777
+ _LOKI_SKILL_CHECKS_DETAIL="$(printf '%s' "$_sk_out" | tail -n 3 | tr '\n' ' ' | cut -c1-500)"
15778
+ case "$_sk_rc" in
15779
+ 0) _LOKI_SKILL_CHECKS_STATUS="pass"; _LOKI_SKILL_CHECKS_REASON="measured"; return 0 ;;
15780
+ 2) _LOKI_SKILL_CHECKS_REASON="subcommand_absent"; return 0 ;;
15781
+ *) _LOKI_SKILL_CHECKS_STATUS="fail"; _LOKI_SKILL_CHECKS_REASON="check_failed_or_runner_error"; return 1 ;;
15782
+ esac
15783
+ }
15784
+
15762
15785
  enforce_lsp_diagnostics() {
15763
15786
  local lsp_file="${TARGET_DIR:-.}/.loki/quality/lsp-diagnostics.json"
15764
15787
  local verdict="absent"
@@ -16977,6 +17000,32 @@ _severity_is_blocking() {
16977
17000
  grep -qiE '(\[(critical|high)\])|(\*\*[[:space:]]*(critical|high)[[:space:]]*\*\*)|(severity:?[[:space:]]*(critical|high))|(^[[:space:]]*[-*][[:space:]]+(critical|high)([[:space:]:.,*]|$))' "$file"
16978
17001
  }
16979
17002
 
17003
+ # Advisory reviewers run and record findings but carry no veto. Default on;
17004
+ # LOKI_REVIEW_ADVISORY=0 restores blocking. Parity-locked with
17005
+ # ADVISORY_REVIEWERS / isAdvisoryReviewer() in loki-ts/src/runner/quality_gates.ts.
17006
+ _is_advisory_reviewer() {
17007
+ [ "${LOKI_REVIEW_ADVISORY:-1}" != "0" ] || return 1
17008
+ case "$1" in
17009
+ architecture-strategist|maintainer-mergeability|test-coverage-auditor) return 0 ;;
17010
+ *) return 1 ;;
17011
+ esac
17012
+ }
17013
+
17014
+ # Count Critical and High findings in a reviewer file, same 4 severity forms as
17015
+ # _severity_is_blocking. Echoes "<critical_count> <high_count>". Parity-locked
17016
+ # with countBlockingSeverityFindings() in loki-ts/src/runner/quality_gates.ts.
17017
+ _count_blocking_severity_findings() {
17018
+ local file="$1"
17019
+ if [ ! -f "$file" ]; then
17020
+ echo "0 0"
17021
+ return 0
17022
+ fi
17023
+ local crit high
17024
+ crit=$(grep -icE '(\[critical\])|(\*\*[[:space:]]*critical[[:space:]]*\*\*)|(severity:?[[:space:]]*critical)|(^[[:space:]]*[-*][[:space:]]+critical([[:space:]:.,*]|$))' "$file")
17025
+ high=$(grep -icE '(\[high\])|(\*\*[[:space:]]*high[[:space:]]*\*\*)|(severity:?[[:space:]]*high)|(^[[:space:]]*[-*][[:space:]]+high([[:space:]:.,*]|$))' "$file")
17026
+ echo "${crit:-0} ${high:-0}"
17027
+ }
17028
+
16980
17029
  # 7.114.0 (rank 9): count non-blocking (Medium/Low) findings in a reviewer file.
16981
17030
  # Feeds the weighted mergeability quality score. Mirrors the severity-token
16982
17031
  # tolerance of _severity_is_blocking (bracketed, bold, 'Severity:', or bullet).
@@ -17961,7 +18010,10 @@ reviewers = mandatory + [
17961
18010
  # TRIMMING ORDER IS A SAFETY PROPERTY. Mandatory reviewers
17962
18011
  # (requirements-verifier, architecture-strategist, maintainer-mergeability) are
17963
18012
  # NEVER dropped: each carries a mandate no keyword-selected specialist has, and
17964
- # shrinking a council must never be able to manufacture an approval. Only the
18013
+ # shrinking a council must never be able to manufacture an approval. They are
18014
+ # mandatory to run, not to block: architecture-strategist, maintainer-mergeability
18015
+ # and test-coverage-auditor are advisory (findings recorded, no veto) unless
18016
+ # LOKI_REVIEW_ADVISORY=0. Only the
17965
18017
  # appended tail (installed agents, then keyword specialists beyond the floor) is
17966
18018
  # trimmed, and the cap can never cut below the mandatory set.
17967
18019
  #
@@ -18837,6 +18889,10 @@ REVIEW_WAVE_TIMING
18837
18889
  # reviewers to compute the weighted mergeability quality score below.
18838
18890
  local nonblocking_medium=0
18839
18891
  local nonblocking_low=0
18892
+ # Advisory reviewers: Critical/High counts recorded with no veto.
18893
+ local advisory_critical=0
18894
+ local advisory_high=0
18895
+ local reviewer_rows=""
18840
18896
 
18841
18897
  for i in $(seq 0 $((reviewer_count - 1))); do
18842
18898
  local reviewer_name
@@ -18892,9 +18948,24 @@ REVIEW_WAVE_TIMING
18892
18948
  # contradictory PASS token. Structured output already normalizes this in
18893
18949
  # cr-rematerialize.py; keep the text fallback equally fail-closed.
18894
18950
  local _reviewer_has_blocking=false
18951
+ local _reviewer_advisory=false _sev_counts _sev_crit _sev_high
18952
+ if _is_advisory_reviewer "$reviewer_name"; then
18953
+ _reviewer_advisory=true
18954
+ fi
18955
+ _sev_counts=$(_count_blocking_severity_findings "$review_output")
18956
+ _sev_crit=${_sev_counts%% *}
18957
+ _sev_high=${_sev_counts##* }
18958
+ if [ "$_reviewer_advisory" = "true" ]; then
18959
+ advisory_critical=$((advisory_critical + _sev_crit))
18960
+ advisory_high=$((advisory_high + _sev_high))
18961
+ fi
18895
18962
  if _severity_is_blocking "$review_output"; then
18896
- _reviewer_has_blocking=true
18897
- has_blocking=true
18963
+ if [ "$_reviewer_advisory" = "true" ]; then
18964
+ log_warn "ADVISORY: $reviewer_name recorded critical=$_sev_crit high=$_sev_high (no veto; LOKI_REVIEW_ADVISORY=0 restores blocking)"
18965
+ else
18966
+ _reviewer_has_blocking=true
18967
+ has_blocking=true
18968
+ fi
18898
18969
  if [ "$verdict" = "PASS" ]; then
18899
18970
  log_error "BLOCKING: $reviewer_name returned PASS with Critical/High findings; normalizing verdict to FAIL"
18900
18971
  verdict="FAIL"
@@ -18915,6 +18986,8 @@ REVIEW_WAVE_TIMING
18915
18986
  log_error "BLOCKING: structured requirements contract did not pass"
18916
18987
  elif [ "$_reviewer_has_blocking" = "true" ]; then
18917
18988
  log_error "BLOCKING: $reviewer_name found Critical/High severity issues"
18989
+ elif [ "$_reviewer_advisory" = "true" ]; then
18990
+ log_warn "FAIL: advisory reviewer $reviewer_name (non-blocking)"
18918
18991
  else
18919
18992
  log_warn "FAIL: $reviewer_name found Medium/Low issues (non-blocking)"
18920
18993
  fi
@@ -18923,6 +18996,8 @@ REVIEW_WAVE_TIMING
18923
18996
  log_info "PASS: $reviewer_name"
18924
18997
  fi
18925
18998
  verdicts_summary="${verdicts_summary}${reviewer_name}:${verdict:-UNKNOWN} "
18999
+ reviewer_rows="${reviewer_rows}${reviewer_name}|${verdict}|${_reviewer_advisory}|${_sev_crit}|${_sev_high}
19000
+ "
18926
19001
  done
18927
19002
 
18928
19003
  # Finding #596 FIX A2 + WAVE8 FIX run.sh-F3: a review is INCONCLUSIVE (=>
@@ -18983,6 +19058,9 @@ REVIEW_WAVE_TIMING
18983
19058
  export LOKI_REVIEW_AGG_QSCORE="$quality_score"
18984
19059
  export LOKI_REVIEW_AGG_QMED="$nonblocking_medium"
18985
19060
  export LOKI_REVIEW_AGG_QLOW="$nonblocking_low"
19061
+ export LOKI_REVIEW_AGG_ADV_CRIT="$advisory_critical"
19062
+ export LOKI_REVIEW_AGG_ADV_HIGH="$advisory_high"
19063
+ export LOKI_REVIEW_AGG_ROWS="$reviewer_rows"
18986
19064
  python3 -E - << 'AGG_SCRIPT'
18987
19065
  import sys; sys.path[:] = [p for p in sys.path if p not in ("", ".")]
18988
19066
  import json, os
@@ -18999,7 +19077,15 @@ result = {
18999
19077
  # else 100 - 5*medium - 2*low, floored at 0). Reported metric, not a hard gate.
19000
19078
  "quality_score": int(os.environ["LOKI_REVIEW_AGG_QSCORE"]),
19001
19079
  "nonblocking_medium": int(os.environ["LOKI_REVIEW_AGG_QMED"]),
19002
- "nonblocking_low": int(os.environ["LOKI_REVIEW_AGG_QLOW"])
19080
+ "nonblocking_low": int(os.environ["LOKI_REVIEW_AGG_QLOW"]),
19081
+ # Advisory reviewers run and record findings without a veto; never silent.
19082
+ "advisory_critical": int(os.environ["LOKI_REVIEW_AGG_ADV_CRIT"]),
19083
+ "advisory_high": int(os.environ["LOKI_REVIEW_AGG_ADV_HIGH"]),
19084
+ "reviewers": [
19085
+ {"name": f[0], "verdict": f[1], "advisory": f[2] == "true",
19086
+ "critical": int(f[3]), "high": int(f[4])}
19087
+ for f in (ln.split("|") for ln in os.environ["LOKI_REVIEW_AGG_ROWS"].splitlines() if ln.strip())
19088
+ ]
19003
19089
  }
19004
19090
  with open(os.environ["LOKI_REVIEW_AGG_FILE"], "w") as f:
19005
19091
  json.dump(result, f, indent=2)
@@ -19008,6 +19094,7 @@ AGG_SCRIPT
19008
19094
  unset LOKI_REVIEW_AGG_PASS LOKI_REVIEW_AGG_FAIL LOKI_REVIEW_AGG_BLOCKING LOKI_REVIEW_AGG_VERDICTS
19009
19095
  unset LOKI_REVIEW_AGG_REAL LOKI_REVIEW_AGG_INCONCLUSIVE
19010
19096
  unset LOKI_REVIEW_AGG_QSCORE LOKI_REVIEW_AGG_QMED LOKI_REVIEW_AGG_QLOW
19097
+ unset LOKI_REVIEW_AGG_ADV_CRIT LOKI_REVIEW_AGG_ADV_HIGH LOKI_REVIEW_AGG_ROWS
19011
19098
 
19012
19099
  emit_event_json "code_review_council_complete" \
19013
19100
  "review_id=$review_id" \
@@ -19236,6 +19323,9 @@ DA_AGG_PATCH
19236
19323
  fi
19237
19324
 
19238
19325
  log_info "Code review passed ($pass_count/$reviewer_count PASS, $fail_count FAIL - no blocking issues)"
19326
+ if [ "$((advisory_critical + advisory_high))" -gt 0 ]; then
19327
+ log_warn "Advisory findings (no veto): critical=$advisory_critical high=$advisory_high; see $review_dir/$review_id/aggregate.json"
19328
+ fi
19239
19329
  return 0
19240
19330
  }
19241
19331
 
@@ -27067,9 +27157,36 @@ EOF
27067
27157
  gate_failures="${gate_failures}production_build,"
27068
27158
  log_warn "Production build gate FAILED ($build_count consecutive)"
27069
27159
  fi
27160
+ # Skill-declared checks gate (bash-route parity with the Bun
27161
+ # skill_checks gate). Blocking, fail closed. Toggle
27162
+ # LOKI_GATE_SKILL_CHECKS (default on), same predicate as the Bun
27163
+ # route flag() in quality_gates.ts: unset/empty = on, else only
27164
+ # "true" or "1" keeps the gate on. Runs through the Bun
27165
+ # implementation, so the commands executed and their env match.
27166
+ if [ -z "${LOKI_GATE_SKILL_CHECKS:-}" ] || [ "${LOKI_GATE_SKILL_CHECKS}" = "true" ] || [ "${LOKI_GATE_SKILL_CHECKS}" = "1" ]; then
27167
+ log_info "Quality gate: skill-declared checks..."
27168
+ local _stg_t0=$(date +%s 2>/dev/null); local _stg_ok=pass
27169
+ enforce_skill_checks || true
27170
+ _stg_ok="${_LOKI_SKILL_CHECKS_STATUS:-not_run}"
27171
+ case "$_stg_ok" in
27172
+ pass) clear_gate_failure "skill_checks" ;;
27173
+ fail)
27174
+ local sk_count
27175
+ sk_count=$(track_gate_failure "skill_checks")
27176
+ gate_failures="${gate_failures}skill_checks,"
27177
+ log_warn "Skill checks gate FAILED ($sk_count consecutive) - ${_LOKI_SKILL_CHECKS_DETAIL:-}"
27178
+ ;;
27179
+ *) log_info "Skill checks: gate did not run (${_LOKI_SKILL_CHECKS_REASON:-unknown})" ;;
27180
+ esac
27181
+ emit_stage_complete "skill_checks" "$_stg_ok" "$_stg_t0"
27182
+ fi
27070
27183
  # Secure-by-default scan (v7.87.0). Advisory by default (never
27071
27184
  # blocks); records .loki/quality/security-findings.json each
27072
27185
  # iteration. Blocks only on un-waived HIGH when LOKI_SECURE_GATE=block.
27186
+ # LOKI_GATE_SECURITY_SCAN toggle (default on), same predicate as the
27187
+ # Bun route flag() in quality_gates.ts: unset/empty = on, else only
27188
+ # "true" or "1" keeps the gate on.
27189
+ if [ -z "${LOKI_GATE_SECURITY_SCAN:-}" ] || [ "${LOKI_GATE_SECURITY_SCAN}" = "true" ] || [ "${LOKI_GATE_SECURITY_SCAN}" = "1" ]; then
27073
27190
  log_info "Quality gate: security scan (advisory)..."
27074
27191
  local _stg_t0=$(date +%s 2>/dev/null); local _stg_ok=pass
27075
27192
  if run_secure_scan; then
@@ -27082,6 +27199,7 @@ EOF
27082
27199
  log_warn "Security gate BLOCKED ($sec_count consecutive) - un-waived HIGH findings (LOKI_SECURE_GATE=block)"
27083
27200
  fi
27084
27201
  emit_stage_complete "security_scan" "$_stg_ok" "$_stg_t0"
27202
+ fi
27085
27203
  # BUG-ST-002: Check pause signal between quality gates
27086
27204
  if [ -f "${TARGET_DIR:-.}/.loki/PAUSE" ] || [ -f "${TARGET_DIR:-.}/.loki/STOP" ]; then
27087
27205
  log_warn "Pause/stop signal detected between quality gates - deferring remaining gates"
@@ -27403,7 +27521,7 @@ EOF
27403
27521
  local _phase1_overrode=false
27404
27522
  if [ "${LOKI_OVERRIDE_COUNCIL:-1}" != "0" ] && command -v bun >/dev/null 2>&1; then
27405
27523
  local _override_out
27406
- _override_out=$(bun "${SCRIPT_DIR}/../loki-ts/dist/loki.js" internal phase1-hooks override "$ITERATION_COUNT" 2>/dev/null || true)
27524
+ _override_out=$(bun --no-env-file --config=/dev/null "${SCRIPT_DIR}/../loki-ts/dist/loki.js" internal phase1-hooks override "$ITERATION_COUNT" 2>/dev/null || true)
27407
27525
  case "$_override_out" in
27408
27526
  *"override: LIFTED"*)
27409
27527
  log_info "Phase 1 override council lifted code_review BLOCK"
@@ -27435,7 +27553,7 @@ EOF
27435
27553
  # v7.5.3 Phase 1 hook: structured handoff doc before
27436
27554
  # bare PAUSE. Embedded; opt out LOKI_HANDOFF_MD=0.
27437
27555
  if [ "${LOKI_HANDOFF_MD:-1}" != "0" ] && command -v bun >/dev/null 2>&1; then
27438
- bun "${SCRIPT_DIR}/../loki-ts/dist/loki.js" internal phase1-hooks handoff code_review "$cr_count" "$ITERATION_COUNT" 2>/dev/null || true
27556
+ bun --no-env-file --config=/dev/null "${SCRIPT_DIR}/../loki-ts/dist/loki.js" internal phase1-hooks handoff code_review "$cr_count" "$ITERATION_COUNT" 2>/dev/null || true
27439
27557
  fi
27440
27558
  touch "${TARGET_DIR:-.}/.loki/PAUSE"
27441
27559
  gate_failures="${gate_failures}code_review_PAUSED,"
@@ -27456,7 +27574,7 @@ EOF
27456
27574
  # Best-effort; never fails the main loop.
27457
27575
  if [ "${LOKI_INJECT_FINDINGS:-1}" != "0" ]; then
27458
27576
  if command -v bun >/dev/null 2>&1; then
27459
- bun "${SCRIPT_DIR}/../loki-ts/dist/loki.js" internal phase1-hooks reflect "$ITERATION_COUNT" 2>/dev/null || true
27577
+ bun --no-env-file --config=/dev/null "${SCRIPT_DIR}/../loki-ts/dist/loki.js" internal phase1-hooks reflect "$ITERATION_COUNT" 2>/dev/null || true
27460
27578
  else
27461
27579
  # DEGRADED, and said so. Findings injection is what
27462
27580
  # tells the next iteration WHAT to fix; without it the
@@ -408,6 +408,19 @@ loki_emit_build_verified() {
408
408
  return 0
409
409
  }
410
410
 
411
+ # loki_emit_seal_hook_decision <allow|block> <reason>: one event per loki-seal
412
+ # Stop hook decision (the Claude Code wedge). Enum args only: any decision or
413
+ # reason outside the fixed lists sends nothing, and the schema re-filters. Never
414
+ # a path, file name, test name or error text. Same strict analytics gate as
415
+ # build_verified, so every existing opt-out wins.
416
+ loki_emit_seal_hook_decision() {
417
+ _loki_analytics_enabled || return 0
418
+ case "${1:-}" in allow|block) ;; *) return 0 ;; esac
419
+ case "${2:-}" in none|tests_failed|tests_weakened|no_tests|contract_unverified|released|error) ;; *) return 0 ;; esac
420
+ loki_telemetry "seal_hook_decision" "decision=$1" "reason=$2"
421
+ return 0
422
+ }
423
+
411
424
  # loki_emit_build_verified_enum <headline> <route>: build_verified for the
412
425
  # default engine10 route, which has no proof.json reader. Enum args only:
413
426
  # anything but headline=VERIFIED and route=engine10 sends nothing. Same strict
@@ -2972,9 +2972,9 @@ verify_hosted_enrich() {
2972
2972
  [ -z "$engine_base" ] && engine_base="$base_ref"
2973
2973
  local engine_out engine_rc
2974
2974
  if [ -n "$engine_base" ]; then
2975
- engine_out="$(bun "$bundle" --dir . --base "$engine_base" 2>/dev/null)"; engine_rc=$?
2975
+ engine_out="$(bun --no-env-file --config=/dev/null "$bundle" --dir . --base "$engine_base" 2>/dev/null)"; engine_rc=$?
2976
2976
  else
2977
- engine_out="$(bun "$bundle" --dir . 2>/dev/null)"; engine_rc=$?
2977
+ engine_out="$(bun --no-env-file --config=/dev/null "$bundle" --dir . 2>/dev/null)"; engine_rc=$?
2978
2978
  fi
2979
2979
  if [ "$engine_rc" -ne 0 ] || [ -z "$engine_out" ]; then
2980
2980
  _verify_log "hosted: embedded engine unusable (rc=$engine_rc); keeping deterministic verdict (fail-open)"
package/bin/loki CHANGED
@@ -103,6 +103,11 @@ fi
103
103
  # v7.4.2 fix (BUG-1): BUN_FROM_SOURCE=1 used to hard-fail on npm/Docker/brew
104
104
  # installs because src/ is excluded by .npmignore. Now we warn once and fall
105
105
  # back to dist if src/cli.ts is missing.
106
+ # Bun auto-loads bunfig.toml (preload scripts) and .env from its cwd, and the cwd is the
107
+ # user's repo, which may be hostile. Every Bun entry below passes these flags: no .env, and
108
+ # an empty config (/dev/null) instead of the repo's bunfig.toml. The cwd itself is unchanged,
109
+ # so commands still operate on the user's repo.
110
+ _LOKI_BUN_SAFE=(--no-env-file --config=/dev/null)
106
111
  if [ -n "${LOKI_TS_ENTRY:-}" ]; then
107
112
  # v7.5.1 fix B18: validate that the explicit override actually exists.
108
113
  # Pre-v7.5.1 a typo (LOKI_TS_ENTRY=/nonexistent) produced a raw Bun
@@ -166,7 +171,7 @@ if [ -t 1 ] && [ -z "${CI:-}" ] && [ "${LOKI_NO_COMPLETIONS:-}" != "1" ] \
166
171
  && [ "${1:-}" != "completion" ] && [ "${1:-}" != "__complete" ] \
167
172
  && [ "$(cat "${HOME}/.loki/completions-version" 2>/dev/null)" != "$(cat "$REPO_ROOT/VERSION" 2>/dev/null)" ] \
168
173
  && command -v bun >/dev/null 2>&1; then
169
- bun "$BUN_CLI" completion --auto </dev/null || true
174
+ bun "${_LOKI_BUN_SAFE[@]}" "$BUN_CLI" completion --auto </dev/null || true
170
175
  fi
171
176
 
172
177
  # v7.88.1 covert-path fix (council cF_r2 + cG_r2 sentinel edge): under on-by-default
@@ -494,7 +499,7 @@ if [ "${1:-}" = "modernize" ]; then
494
499
  if [ "$_loki_mod_a" = "--to" ] || [ "${2:-}" = "unit" ]; then
495
500
  _lb=$(_loki_bun)
496
501
  [ -n "$_lb" ] || { echo "Error: loki modernize needs bun." >&2; exit 1; }
497
- exec "$_lb" "$BUN_CLI" engine10 "$@"
502
+ exec "$_lb" "${_LOKI_BUN_SAFE[@]}" "$BUN_CLI" engine10 "$@"
498
503
  fi
499
504
  done
500
505
  unset _loki_mod_a
@@ -586,7 +591,7 @@ if [ "${1:-}" = "start" ]; then
586
591
  _lb=$(_loki_bun)
587
592
  [ -n "$_lb" ] || { echo "loki: --attempts $_loki_att_n needs bun (install from https://bun.sh); refusing to run a single attempt silently." >&2; exit 1; }
588
593
  _loki_attempts_refuse "${@:2}"
589
- exec "$_lb" "$BUN_CLI" "$@"
594
+ exec "$_lb" "${_LOKI_BUN_SAFE[@]}" "$BUN_CLI" "$@"
590
595
  ;;
591
596
  *) echo "loki: --attempts must be an integer from 1 to 5, got '$_loki_att_n'." >&2; exit 2 ;;
592
597
  esac
@@ -602,7 +607,7 @@ if [ "${1:-}" = "start" ]; then
602
607
  --spec|--spec=*|--spec-first)
603
608
  _lb=$(_loki_bun)
604
609
  [ -n "$_lb" ] || { echo "loki: --spec needs bun (install from https://bun.sh)." >&2; exit 1; }
605
- exec "$_lb" "$BUN_CLI" "$@"
610
+ exec "$_lb" "${_LOKI_BUN_SAFE[@]}" "$BUN_CLI" "$@"
606
611
  ;;
607
612
  esac
608
613
  done
@@ -617,7 +622,7 @@ if [ "${1:-}" = "start" ]; then
617
622
  for _loki_da in "${@:2}"; do [ "$_loki_da" = "--dry-run" ] && _loki_dry=1; done
618
623
  if [ "$_loki_dry" = "1" ] && ! _loki_start_needs_bash "${@:2}"; then
619
624
  _loki_dry_bun="$(_loki_bun)"
620
- [ -n "$_loki_dry_bun" ] && exec "$_loki_dry_bun" "$BUN_CLI" "$@"
625
+ [ -n "$_loki_dry_bun" ] && exec "$_loki_dry_bun" "${_LOKI_BUN_SAFE[@]}" "$BUN_CLI" "$@"
621
626
  fi
622
627
  unset _loki_dry _loki_da _loki_dry_bun
623
628
  fi
@@ -772,7 +777,7 @@ case "v10" in
772
777
  unset _e10_v
773
778
  ;;
774
779
  esac
775
- exec "$_lb" "$BUN_CLI" engine10 "${_e10_args[@]}"
780
+ exec "$_lb" "${_LOKI_BUN_SAFE[@]}" "$BUN_CLI" engine10 "${_e10_args[@]}"
776
781
  fi
777
782
  unset _e10 _e10_args _e10_hard
778
783
  ;;
@@ -814,13 +819,13 @@ fi
814
819
  # legacy route honored, or a provider engine10 cannot invoke, is refused loudly instead.
815
820
  if [ "${1:-}" = "start" ] && [ "$_LOKI_START_ATTEMPTS" = "1" ]; then
816
821
  _loki_attempts_refuse "${@:2}"
817
- exec bun "$BUN_CLI" "$@"
822
+ exec bun "${_LOKI_BUN_SAFE[@]}" "$BUN_CLI" "$@"
818
823
  fi
819
824
  if [ "${1:-}" = "start" ] && { [ "${LOKI_SDK_LOOP:-}" = "1" ] || [ "${LOKI_SDK_LOOP:-}" = "true" ]; }; then
820
825
  if _loki_start_needs_bash "${@:2}"; then
821
826
  exec "$BASH_CLI" "$@"
822
827
  fi
823
- exec bun "$BUN_CLI" "$@"
828
+ exec bun "${_LOKI_BUN_SAFE[@]}" "$BUN_CLI" "$@"
824
829
  fi
825
830
 
826
831
  # CLI consolidation (Phase A): `trust detail` is the grouped form of the
@@ -862,9 +867,9 @@ if [ "${1:-}" = "doctor" ]; then
862
867
  fi
863
868
  _doctor_t=$(command -v timeout || command -v gtimeout || true)
864
869
  if [ -n "$_doctor_t" ]; then
865
- "$_doctor_t" -k 1 5 "$_doctor_bun" "$BUN_CLI" version >/dev/null 2>&1 || exec "$BASH_CLI" "$@"
870
+ "$_doctor_t" -k 1 5 "$_doctor_bun" "${_LOKI_BUN_SAFE[@]}" "$BUN_CLI" version >/dev/null 2>&1 || exec "$BASH_CLI" "$@"
866
871
  else
867
- "$_doctor_bun" "$BUN_CLI" version >/dev/null 2>&1 || exec "$BASH_CLI" "$@"
872
+ "$_doctor_bun" "${_LOKI_BUN_SAFE[@]}" "$BUN_CLI" version >/dev/null 2>&1 || exec "$BASH_CLI" "$@"
868
873
  fi
869
874
  fi
870
875
 
@@ -910,7 +915,7 @@ if [ "${1:-}" = "report" ]; then
910
915
  ( SCRIPT_DIR="$REPO_ROOT/autonomy"; source "$SCRIPT_DIR/telemetry.sh" 2>/dev/null && loki_telemetry "cli_command" "command=$(_loki_known_command "${1:-}")" 2>/dev/null ) >/dev/null 2>&1 </dev/null &
911
916
  disown 2>/dev/null || true
912
917
  fi
913
- exec bun "$BUN_CLI" "$@"
918
+ exec bun "${_LOKI_BUN_SAFE[@]}" "$BUN_CLI" "$@"
914
919
  fi
915
920
  fi
916
921
 
@@ -952,7 +957,7 @@ case "${1:-}" in
952
957
  ( SCRIPT_DIR="$REPO_ROOT/autonomy"; source "$SCRIPT_DIR/telemetry.sh" 2>/dev/null && loki_telemetry "cli_command" "command=$(_loki_known_command "${1:-}")" 2>/dev/null ) >/dev/null 2>&1 </dev/null &
953
958
  disown 2>/dev/null || true
954
959
  fi
955
- exec bun "$BUN_CLI" "$@"
960
+ exec bun "${_LOKI_BUN_SAFE[@]}" "$BUN_CLI" "$@"
956
961
  ;;
957
962
  *)
958
963
  exec "$BASH_CLI" "$@"
package/completions/_loki CHANGED
@@ -43,6 +43,12 @@ function _loki {
43
43
  '--provider[Provider]:provider:(claude opencode codex cline aider)' \
44
44
  '--max-cost[Hard per-run cap in USD]:usd:'
45
45
  ;;
46
+ try)
47
+ _arguments \
48
+ '--dry-run[Clone, print the task and estimate, no model call]' \
49
+ '--provider[Provider]:provider:(claude opencode codex cline aider)' \
50
+ '--max-cost[Hard per-run cap in USD]:usd:'
51
+ ;;
46
52
  control)
47
53
  _arguments \
48
54
  '--port[Port for the control plane server]:port:' \
@@ -74,6 +80,23 @@ function _loki {
74
80
  agent)
75
81
  _loki_agent
76
82
  ;;
83
+ cost)
84
+ _arguments \
85
+ '--json[Output machine-readable JSON]' \
86
+ '--last[Show only the last N runs]:count:' \
87
+ '--month[Only runs generated in that month]:month (YYYY-MM):' \
88
+ '--csv[One CSV row per run]' \
89
+ '--detail[Per-iteration cache and trend breakdown]' \
90
+ '--help[Show help]'
91
+ ;;
92
+ next)
93
+ _arguments \
94
+ '--yes[Skip the confirmation prompt]' \
95
+ '--dry-run[Show what would run without running it]' \
96
+ '--suggest[With no active run, propose up to 3 small tasks]' \
97
+ '--json[Output machine-readable JSON]' \
98
+ '--help[Show help]'
99
+ ;;
77
100
  estimate)
78
101
  _arguments \
79
102
  '--json[Output machine-readable JSON]' \
@@ -267,6 +290,7 @@ function _loki_commands {
267
290
  'demo:Interactive 60-second demo'
268
291
  'tour:Offline sample receipt replay (no key, no spend)'
269
292
  'wow:Tiny real task in a temp repo, or the offline sample'
293
+ 'try:Try Loki on a public repo in a temp clone, keep only the receipt'
270
294
  'factory:loki start with the autonomy policy printed'
271
295
  'welcome:Friendly first-run opener (what Loki is, next steps)'
272
296
  'init:Interactive PRD builder'
@@ -5,7 +5,7 @@ _loki_completion() {
5
5
  _init_completion || return
6
6
 
7
7
  # Main subcommands (must match autonomy/loki main case statement)
8
- local main_commands="start backlog quick monitor demo tour wow factory welcome init stop pause resume cancel steer status next ship dashboard web serve api sandbox notify import github issue intent config provider reset memory compound checkpoint council dogfood projects enterprise secrets cockpit secure own handoff doctor watchdog audit metrics syslog onboard share proof receipt outcomes explain plan report cost estimate kpis stats test ci watch telemetry agent context ctx code run export review optimize heal modernize migrate cluster worktree wt trigger failover remote deploy docker mcp magic assets analyze compliance crash control workspace open otel preview quickstart rc rollback merge self-update sentrux setup-skill spec state template trust trust-metrics ultracode update verify voice why wiki bench cleanup logs grill docs cp version completions help keys answer queue issues undo runs acp verify-pr chat route edit setup models agents diff backup restore"
8
+ local main_commands="start backlog quick monitor demo tour wow try factory welcome init stop pause resume cancel steer status next ship dashboard web serve api sandbox notify import github issue intent config provider reset memory compound checkpoint council dogfood projects enterprise secrets cockpit secure own handoff doctor watchdog audit metrics syslog onboard share proof receipt outcomes explain plan report cost estimate kpis stats test ci watch telemetry agent context ctx code run export review optimize heal modernize migrate cluster worktree wt trigger failover remote deploy docker mcp magic assets analyze compliance crash control workspace open otel preview quickstart rc rollback merge self-update sentrux setup-skill spec state template trust trust-metrics ultracode update verify voice why wiki bench cleanup logs grill docs cp version completions help keys answer queue issues undo runs acp verify-pr chat route edit setup models agents diff backup restore"
9
9
 
10
10
  # 1. If we are on the first argument (subcommand)
11
11
  if [[ $cword -eq 1 ]]; then
@@ -125,6 +125,20 @@ _loki_completion() {
125
125
  COMPREPLY=( $(compgen -W "${syslog_cmds}" -- "$cur") )
126
126
  ;;
127
127
 
128
+ cost)
129
+ if [[ "$cur" == -* ]]; then
130
+ COMPREPLY=( $(compgen -W "--json --last --month --csv --detail --help" -- "$cur") )
131
+ return 0
132
+ fi
133
+ ;;
134
+
135
+ next)
136
+ if [[ "$cur" == -* ]]; then
137
+ COMPREPLY=( $(compgen -W "--yes --dry-run --suggest --json --help" -- "$cur") )
138
+ return 0
139
+ fi
140
+ ;;
141
+
128
142
  estimate)
129
143
  if [[ "$cur" == -* ]]; then
130
144
  COMPREPLY=( $(compgen -W "--json --model --provider --help" -- "$cur") )
@@ -254,6 +268,13 @@ _loki_completion() {
254
268
  fi
255
269
  ;;
256
270
 
271
+ try)
272
+ if [[ "$cur" == -* ]]; then
273
+ COMPREPLY=( $(compgen -W "--dry-run --provider --max-cost --help" -- "$cur") )
274
+ return 0
275
+ fi
276
+ ;;
277
+
257
278
  quickstart)
258
279
  if [[ "$cur" == -* ]]; then
259
280
  COMPREPLY=( $(compgen -W "--dry-run --explain-match --from-preview --verify-preview --json --list-templates --template --yes --help" -- "$cur") )
@@ -7,6 +7,6 @@ Modules:
7
7
  control: Session control helpers (status, atomic writes, origin check)
8
8
  """
9
9
 
10
- __version__ = "11.77.0"
10
+ __version__ = "11.79.0"
11
11
 
12
12
  __all__ = ["__version__"]
@@ -6,12 +6,12 @@ Classes: KEEP-MODERN (v10-native or engine-neutral), UPDATE (live but needs mode
6
6
 
7
7
  ## Counts
8
8
 
9
- - KEEP-MODERN: 77
9
+ - KEEP-MODERN: 78
10
10
  - UPDATE: 22
11
11
  - DROP-LEGACY: 31
12
12
  - DELETE: 14
13
- - Total rows: 144
14
- - Registry paths (commands and nested subcommands): 212
13
+ - Total rows: 145
14
+ - Registry paths (commands and nested subcommands): 215
15
15
 
16
16
  ## Commands
17
17
 
@@ -85,6 +85,7 @@ Classes: KEEP-MODERN (v10-native or engine-neutral), UPDATE (live but needs mode
85
85
  | notify | autonomy/loki | KEEP-MODERN | Engine-neutral |
86
86
  | tour | autonomy/loki | KEEP-MODERN | Onboarding |
87
87
  | wow | autonomy/loki | KEEP-MODERN | Onboarding: loki tour --live |
88
+ | try | autonomy/loki | KEEP-MODERN | Onboarding: never touches your checkout |
88
89
  | factory | autonomy/loki | KEEP-MODERN | propose, execute, operate unchanged |
89
90
  | welcome | autonomy/loki | KEEP-MODERN | Onboarding |
90
91
  | onboard | autonomy/loki | UPDATE | Overlaps wiki |
@@ -169,19 +170,19 @@ Classes: KEEP-MODERN (v10-native or engine-neutral), UPDATE (live but needs mode
169
170
  - compliance: 1
170
171
  - config: 4
171
172
  - context: 5
172
- - cost: 6
173
+ - cost: 7
173
174
  - deploy: 1
174
175
  - docs: 4
175
176
  - enterprise: 2
176
177
  - explain: 5
177
- - export: 6
178
- - github: 6
178
+ - export: 7
179
+ - github: 7
179
180
  - import: 1
180
181
  - init: 21
181
182
  - issue: 2
182
183
  - magic: 12
183
184
  - memory: 7
184
- - metrics: 6
185
+ - metrics: 7
185
186
  - modernize: 3
186
187
  - next: 1
187
188
  - notify: 6
@@ -198,7 +199,7 @@ Classes: KEEP-MODERN (v10-native or engine-neutral), UPDATE (live but needs mode
198
199
  - secrets: 3
199
200
  - secure: 3
200
201
  - setup-skill: 1
201
- - share: 6
202
+ - share: 7
202
203
  - ship: 1
203
204
  - syslog: 3
204
205
  - telemetry: 1
@@ -1,7 +1,7 @@
1
1
  # CLI reference
2
2
 
3
- Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.77.0. Do not edit by hand.
4
- Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for the full inventory.
3
+ Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.79.0. Do not edit by hand.
4
+ Hidden and legacy-only commands are omitted; see `docs/CLI-INVENTORY.md` for the full inventory.
5
5
 
6
6
  | Command | Description |
7
7
  | --- | --- |
@@ -147,6 +147,7 @@ Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for th
147
147
  | `loki notify desktop` | Send a desktop notification (macOS or Linux notify-send) |
148
148
  | `loki tour` | See a sample result |
149
149
  | `loki wow` | Tiny real task, or the offline sample |
150
+ | `loki try` | Try Loki on a public repo in a temp clone, keep only the receipt |
150
151
  | `loki factory` | loki start with the autonomy policy printed |
151
152
  | `loki welcome` | First-run opener |
152
153
  | `loki onboard` | Onboard to a codebase |
@@ -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.77.0
5
+ **Version:** v11.79.0
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/PRIVACY.md CHANGED
@@ -101,6 +101,7 @@ paths, keys, or repo names -- only anonymous diagnostics.
101
101
  | `dashboard_start` | the dashboard starts | none |
102
102
  | `first_start_attempted` | first `loki start`, strict opt-in (section 4) | `entry` (a known loki subcommand, else `other`) |
103
103
  | `first_run_blocked` | first run stopped, strict opt-in (section 5) | `blocker` (fixed enum, section 5) |
104
+ | `seal_hook_decision` | the loki-seal Stop hook decides, strict opt-in (section 4) | `decision` (allow, block), `reason` (none, tests_failed, tests_weakened, no_tests, contract_unverified, released, error) |
104
105
  | `build_verified` | a build finishes, strict opt-in (section 4) | see section 4 |
105
106
 
106
107
  The `install` event of older versions is now `installed`. The npm postinstall
@@ -82,7 +82,7 @@ time-to-first-preview write-once (bash route only).
82
82
 
83
83
  ## Anthropic SDK upgrade capability matrix (RQ-104, 2026-10-23)
84
84
 
85
- Pins (exact, all sites): `@anthropic-ai/sdk` 0.124.0 -> 1.2.0 (loki-ts/package.json, loki-ts/bun.lock, docker/Dockerfile peer pin); `@anthropic-ai/claude-agent-sdk` 0.3.293 -> 0.3.309 (loki-ts/package.json, package.json, package-lock.json, bun.lock, docker/Dockerfile). `tests/test-sdk-version-sync.sh` asserts both. Sources: sdk CHANGELOG 0.125.0..1.2.0, agent-sdk CHANGELOG 0.3.294..0.3.309.
85
+ Pins (exact, all sites): `@anthropic-ai/sdk` 0.124.0 -> 1.3.0 (loki-ts/package.json, loki-ts/bun.lock, docker/Dockerfile peer pin); `@anthropic-ai/claude-agent-sdk` 0.3.293 -> 0.3.312 (loki-ts/package.json, package.json, package-lock.json, bun.lock, docker/Dockerfile). `tests/test-sdk-version-sync.sh` asserts both. Sources: sdk CHANGELOG 0.125.0..1.3.0, agent-sdk CHANGELOG 0.3.294..0.3.312.
86
86
 
87
87
  | Change | Status |
88
88
  |---|---|
@@ -117,6 +117,7 @@ Default-on in the Bun runner (see `CHANGELOG.md` v7.x entries; documented in `sk
117
117
  - `LOKI_AUTO_LEARNINGS` -- auto-write structured learnings per code_review cycle. Optional `LOKI_AUTO_LEARNINGS_EPISODE=1` also writes the learning into the episode store.
118
118
  **Bun route only.** This var has ZERO occurrences in `autonomy/run.sh` and `autonomy/loki` (measured; controls: `LOKI_HANDOFF_MD` returns 2, `LOKI_INJECT_FINDINGS` returns 3), so "set to `1` to force-enable on the bash route" does not apply to this knob -- there is nothing on bash to enable. The bash route DOES have a learnings store (`init_learnings_db`, `run.sh`); what is Bun-only is the automatic per-code_review-cycle write.
119
119
  - `LOKI_HANDOFF_MD` -- write a structured handoff doc before iteration close.
120
+ - `LOKI_REVIEW_ADVISORY` -- default on (`0` restores blocking). architecture-strategist, maintainer-mergeability and test-coverage-auditor are mandatory to run, not to block: they still run and their findings are recorded (`advisory: true` per reviewer plus `advisory_critical` / `advisory_high` in the review `aggregate.json`, one display-only row in the Evidence Receipt), but they carry no veto. `has_blocking` ignores them; security-sentinel and the other reviewers still block. maintainer-mergeability and test-coverage-auditor are routed to haiku at every tier. Bun: `ADVISORY_REVIEWERS` in `loki-ts/src/runner/quality_gates.ts`; bash: `_is_advisory_reviewer` in `autonomy/run.sh` (parity-locked in `tests/test-mergeability-review.sh`).
120
121
 
121
122
  These knobs together implement the RARV-C (closure) loop: findings -> override council -> learnings -> handoff. Reference: `skills/quality-gates.md`, `CHANGELOG.md` entries from v7.x for default-on flip and override-council semantics.
122
123
 
@@ -142,7 +143,7 @@ extract_learnings_from_session (autonomy/run.sh) mirrors learnings and decisions
142
143
 
143
144
  - Wall publish (FC-VERIFIED-PR-WITHOUT-ITS-TEST): on a VERIFIED seal only, `publishWall` (`util/check_result.ts`, called from `stages/seal.ts`) makes ONE child commit (trailer `Loki-Wall-Publish: <runId>`) of the SEALED Wall bytes (`runDir/wall`, hash-checked against `wall.files[].sha256`) that verify ran and passed (`publishableWall`). Before writing, the realpath of each Wall file's parent directory must be inside the repo, and an existing file or symlink is removed first. The child commit runs with hooks and signing OFF (the default `git()` call, no `userHooks`), so a pre-commit hook cannot add files or rewrite the Wall bytes. Afterwards the commit must touch exactly the published paths and each committed blob must equal the blob hash of the sealed bytes (computed in process, never read from the worktree); on any mismatch the child is rolled back (`update-ref` HEAD to the product head plus `read-tree`), nothing is published and a NOT PROVEN note is added. The receipt binds the PRODUCT head (head_sha, tree, diff_sha256 are computed before the child commit). A re-seal binds `HEAD^` only when HEAD's message has the exact trailer line for this run, HEAD touches only paths of this run's `wall.files`, and every blob sha256 matches (`wallChild`); a forged trailer is not enough. `util/seal_drift.ts` accepts a moved HEAD after head_sha as benign only when every commit after it is such a Wall publish commit (linear, trailer line for the receipt's run_id, only `wall.files` paths, blob sha256 equal to the sealed one); any commit after head_sha that carries this run's trailer but fails that check is head drift (UNCHECKED). Later commits without the trailer stay under the TEN-GATES-16 sealed-path overlap rule. The PR body gains an "Acceptance tests" section. Commit stage and `backstopCommit` still drop Wall files. `LOKI_COMMIT_WALL=0` restores the old behavior (nothing published).
144
145
 
145
- ### Python anthropic SDK (RQ-105: pinned `anthropic==2.2.0`)
146
+ ### Python anthropic SDK (RQ-105: pinned `anthropic==2.3.0`)
146
147
 
147
148
  `mcp/requirements.txt` pins the Python SDK exactly (was `>=0.40,<1.0.0`; the resolver landed on 0.125.0). Requires Python >=3.10 (Ubuntu 24.04 image ships 3.12). The SDK runs on `httpx2`; no repo code passes `httpx` objects to it. v2.0.0 changes (API version 2026-10-21): `temperature`/`top_p`/`top_k` removed from Messages (no call site uses them), Admin API field renames (unused). Python-side call sites: `memory/managed_memory/client.py` (the only importer) and `providers/managed.py` (lazy import, `tests/managed/test_registry_lazy.py` contract unchanged).
148
149
 
@@ -61,7 +61,8 @@ events/ # Unified Event Bus (v5.17.0)
61
61
  emit.sh # Bash helper for emitting events
62
62
  docs/ # Architecture documentation
63
63
  SYNERGY-ROADMAP.md # 5-pillar tool integration architecture
64
- v10/ # User guides: GUIDE.md, GUIDE-MODERNIZE.md, CLI-MODERN.md, DEPS.md
64
+ CLI-INVENTORY.md # Generated command inventory (from loki-ts/src/cli/registry.ts)
65
+ v10/ # User guides: GUIDE.md, GUIDE-MODERNIZE.md, DEPS.md
65
66
  dev/ # Developer reference docs (this file and its siblings)
66
67
  autonomy/ # Runtime and autonomous execution
67
68
  context-tracker.py # Context window usage tracking
@@ -256,6 +256,7 @@
256
256
  "LOKI_RESUME_SESSION",
257
257
  "LOKI_REVIEWER_BRIEF",
258
258
  "LOKI_REVIEWER_TIER_ROUTING",
259
+ "LOKI_REVIEW_ADVISORY",
259
260
  "LOKI_REVIEW_ALLOWLIST",
260
261
  "LOKI_REVIEW_INCONCLUSIVE_BLOCK",
261
262
  "LOKI_REVIEW_JSON_SCHEMA",