loki-mode 9.8.0 → 9.12.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 (79) hide show
  1. package/README.md +19 -14
  2. package/SKILL.md +3 -2
  3. package/VERSION +1 -1
  4. package/autonomy/loki +122 -1
  5. package/autonomy/run.sh +49 -2
  6. package/dashboard/__init__.py +1 -1
  7. package/dashboard/api_evidence.py +411 -0
  8. package/dashboard/api_operator.py +283 -0
  9. package/dashboard/api_phases.py +262 -0
  10. package/dashboard/api_releases.py +242 -0
  11. package/dashboard/api_runs.py +477 -0
  12. package/dashboard/api_tests.py +444 -0
  13. package/dashboard/api_v2.py +47 -1
  14. package/dashboard/server.py +54 -0
  15. package/dashboard/static/index.html +246 -135
  16. package/docs/ARCHITECTURE-OVERVIEW.md +5 -3
  17. package/docs/CAPABILITY-BACKLOG.md +53 -0
  18. package/docs/COMPARISON.md +2 -2
  19. package/docs/COMPETITIVE-ANALYSIS.md +1 -1
  20. package/docs/COMPETITIVE-SCORECARD.md +422 -0
  21. package/docs/DASHBOARD-9.12-EVIDENCE.md +97 -0
  22. package/docs/DASHBOARD-ARCHITECTURE.md +423 -0
  23. package/docs/DEMOS.md +21 -23
  24. package/docs/HANDOFF-2026-08-03.md +439 -0
  25. package/docs/INSTALLATION.md +17 -10
  26. package/docs/OUTCOME-FRONTIER.md +536 -0
  27. package/docs/PROMPT-ABLATION-RESULT.md +97 -0
  28. package/docs/TOOLS.md +800 -0
  29. package/docs/alternative-installations.md +2 -3
  30. package/docs/audit-logging.md +44 -35
  31. package/docs/authentication.md +13 -2
  32. package/docs/authorization.md +87 -81
  33. package/docs/git-workflow.md +6 -3
  34. package/docs/metrics.md +15 -16
  35. package/docs/network-security.md +16 -13
  36. package/docs/openclaw-integration.md +36 -556
  37. package/docs/show-hn-post.md +2 -2
  38. package/docs/siem-integration.md +39 -36
  39. package/loki-ts/dist/loki.js +18 -18
  40. package/mcp/__init__.py +1 -1
  41. package/package.json +2 -2
  42. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  43. package/references/confidence-routing.md +18 -1
  44. package/references/invariant-checks.md +13 -8
  45. package/references/magic-rarv-integration.md +0 -1
  46. package/references/multi-provider.md +27 -5
  47. package/skills/healing.md +4 -2
  48. package/tools/audit-docs.py +488 -0
  49. package/tools/baseline-pin.py +19 -1
  50. package/tools/calibration-audit.py +523 -0
  51. package/tools/ci-gate.py +19 -1
  52. package/tools/cost-forecast.py +344 -0
  53. package/tools/cost-guard.py +19 -1
  54. package/tools/cost-history.py +19 -1
  55. package/tools/cost-per-outcome.py +394 -0
  56. package/tools/estimate-run.py +19 -1
  57. package/tools/evidence-freshness.py +307 -0
  58. package/tools/gate-init.py +19 -1
  59. package/tools/gate-report.py +19 -1
  60. package/tools/gate-simulate.py +570 -0
  61. package/tools/gate-trend.py +354 -0
  62. package/tools/model-advisor.py +52 -1
  63. package/tools/policy-load.py +19 -1
  64. package/tools/prompt-cost.py +363 -0
  65. package/tools/prompt-diff.py +448 -0
  66. package/tools/prompt-lint.py +448 -0
  67. package/tools/receipt-bundle.py +72 -2
  68. package/tools/receipt-diff.py +19 -1
  69. package/tools/receipt-find.py +19 -1
  70. package/tools/receipt-stats.py +380 -0
  71. package/tools/receipt-timeline.py +478 -0
  72. package/tools/receipt-verify-batch.py +291 -0
  73. package/tools/run-replay.py +19 -1
  74. package/tools/signing-status.py +19 -1
  75. package/tools/token-guard.py +19 -1
  76. package/tools/token-tax.py +375 -0
  77. package/tools/tool-index.py +19 -1
  78. package/tools/verification-tax.py +277 -0
  79. package/tools/verify-chain.py +361 -0
package/README.md CHANGED
@@ -15,7 +15,7 @@ _The free, source-available autonomous coding agent by [Autonomi](https://www.au
15
15
 
16
16
  [Website](https://www.autonomi.dev/) | [Documentation](wiki/Home.md) | [Installation](docs/INSTALLATION.md) | [Changelog](CHANGELOG.md) | [Purple Lab -- deprecated v7.44.0](#purple-lab)
17
17
 
18
- **Current release: v8.5.2**
18
+ **Current release: v9.8.1**
19
19
 
20
20
  </div>
21
21
 
@@ -194,7 +194,7 @@ public key can verify offline. See [docs/SIGNED-RECEIPTS.md](docs/SIGNED-RECEIPT
194
194
  - **Legacy system healing** -- `loki modernize heal` archaeology/stabilize/isolate/modernize/validate phases (v6.67.0, see `skills/healing.md`)
195
195
  - **MCP server** -- 34 tools (including ChromaDB code search) plus 3 resources and 2 prompts (`mcp/server.py`, with magic tools registered from `mcp/magic_tools.py` and the managed-memory tool from `mcp/managed_tools.py`). Of the 34, 33 are always available; `loki_memory_redact` is registered but only succeeds when `LOKI_MANAGED_AGENTS=true` and `LOKI_MANAGED_MEMORY=true`. Launch with `loki mcp` (bootstraps the Python MCP SDK on first run).
196
196
  - **Full-stack output** -- Source code, tests, Docker Compose stacks (multi-service with healthchecks), CI/CD pipelines, audit logs
197
- - **Provider-agnostic** -- runs on Claude, Codex, Cline, or Aider with automatic failover (`loki-ts/src/runner/providers.ts`); no vendor lock-in. Gemini CLI deprecated v7.5.18.
197
+ - **Provider-agnostic** -- runs on Claude, Cline, Codex, Aider, or opencode with automatic failover (`loki-ts/src/runner/providers.ts`); no vendor lock-in. When `LOKI_PROVIDER` is unset, Loki auto-detects in that order; an explicit choice always wins and is never silently substituted. Gemini was removed as a provider in v7.5.18.
198
198
  - **Source-available (BUSL-1.1)** -- Free for personal, internal, and academic use.
199
199
 
200
200
  ---
@@ -410,7 +410,7 @@ loki doctor # check your setup before the fir
410
410
 
411
411
  Required:
412
412
 
413
- - An agent provider CLI: [Claude Code](https://docs.claude.com/en/docs/claude-code) (`claude`, Tier 1, recommended and E2E-verified - the provider Loki Mode is built for). Codex, Cline, and Aider are supported as experimental providers (wiring in place; not yet E2E-verified by us). Loki cannot run a build without one of these installed and authenticated.
413
+ - An agent provider CLI: [Claude Code](https://docs.claude.com/en/docs/claude-code) (`claude`, Tier 1, recommended and E2E-verified - the provider Loki Mode is built for). Cline, Codex, Aider, and opencode are supported as experimental providers (wiring in place; not yet E2E-verified by us). Loki cannot run a build without one of these installed and authenticated.
414
414
  - Python 3.10+ (`python3`) for the dashboard, memory system, and orchestration helpers.
415
415
  - Git 2.x (`git`) for checkpoints and worktrees.
416
416
  - `curl` for installation and network calls.
@@ -656,7 +656,7 @@ The historical feature set (platform pages, Monaco IDE workspace, AI chat panel)
656
656
  | Feature | Loki Mode | bolt.new | Replit | Lovable |
657
657
  |---------|:---------:|:--------:|:------:|:-------:|
658
658
  | Self-hosted / your keys | Yes | No | No | No |
659
- | Multi-provider failover (4 providers) | Yes | No | No | No |
659
+ | Multi-provider failover (5 providers) | Yes | No | No | No |
660
660
  | 8 quality gates | Yes | No | No | No |
661
661
  | Blind code review | Yes | No | No | No |
662
662
  | Enterprise auth (OIDC token + scoped RBAC) | Yes | No | Yes | No |
@@ -665,22 +665,23 @@ The historical feature set (platform pages, Monaco IDE workspace, AI chat panel)
665
665
  | Source-available (BUSL-1.1) | Yes | No | No | No |
666
666
  | Free tier | Source-available | Yes | Yes | Yes |
667
667
 
668
- Loki Mode is the only platform that is fully self-hosted, source-available (BUSL-1.1), and includes automated quality verification. Your code, your keys, your infrastructure.
668
+ Among the four tools in this table, Loki Mode is the one that is fully self-hosted, source-available (BUSL-1.1), and includes automated quality verification. Your code, your keys, your infrastructure. We have not surveyed every tool on the market, so read this as a comparison against the named three, not a claim about the whole category.
669
669
 
670
670
  ---
671
671
 
672
672
  <details>
673
673
  <summary><strong>Provider matrix -- per-provider status, autonomous flags, parallelism, install (includes deprecated Gemini)</strong></summary>
674
674
 
675
- Loki's autonomy and quality loop are the product; the underlying coding CLI is swappable. Loki runs on any of the providers below so you are never locked to one vendor.
675
+ Loki's autonomy and quality loop are the product; the underlying coding CLI is swappable. Loki runs on any of the providers below so you are never locked to one vendor. With `LOKI_PROVIDER` unset, Loki auto-detects the first installed provider in the order the table lists (claude, cline, codex, aider, opencode); setting it explicitly always wins and is never silently substituted.
676
676
 
677
677
  | Provider | Status | Autonomous Flag | Parallel Agents | Install |
678
678
  |----------|--------|:-:|:-:|---------|
679
679
  | **Claude Code** | Active (Tier 1, E2E-verified) | `--dangerously-skip-permissions` | Yes (10+) | `npm i -g @anthropic-ai/claude-code` |
680
- | **Codex CLI** | Experimental (Tier 3) | `--sandbox workspace-write --skip-git-repo-check` | Sequential | `npm i -g @openai/codex` |
681
- | **Cline CLI** | Experimental (Tier 2) | `-y` | Sequential | `npm i -g @anthropic-ai/cline` |
680
+ | **Cline CLI** | Experimental (Tier 2) | `-y` | Sequential | `npm install -g cline` |
681
+ | **Codex CLI** | Experimental (Tier 3) | `exec --sandbox workspace-write --skip-git-repo-check` | Sequential | `npm i -g @openai/codex` |
682
682
  | **Aider** | Experimental (Tier 3) | `--yes-always` | Sequential | `pip install aider-chat` |
683
- | **Google Gemini CLI** | DEPRECATED v7.5.18 | -- | -- | Upstream deprecated; runtime removed. `LOKI_PROVIDER=gemini` exits with migration message. |
683
+ | **opencode** | Experimental | `--auto` | Sequential | `npm install -g opencode-ai` |
684
+ | **Google Gemini CLI** | REMOVED v7.5.18 | -- | -- | Upstream deprecated; runtime removed. `LOKI_PROVIDER=gemini` exits with a migration message. |
684
685
 
685
686
  Status legend: "E2E-verified" means we run real spec-to-code builds on it ourselves. Claude Code is the primary, fully supported provider and the one Loki Mode is built for; it gets full features (subagents, parallelization, MCP, Task tool). "Experimental" means the wiring is in place but we have not produced an end-to-end verified build ourselves; treat as community-tested. Experimental providers run sequentially. Auto-failover switches providers when rate-limited. See [Provider Guide](skills/providers.md).
686
687
 
@@ -753,6 +754,7 @@ Loki Mode's accuracy and autonomy behaviors are default-on. Each is an opt-out e
753
754
  | `LOKI_CONFIDENCE_SPIKE` | `1` (on) | Forces one EXTRA verification pass when the agent's self-reported confidence spikes, instead of trusting the claim. Strictly additive -- it can never skip a gate. Set `0` to opt out; tune with `LOKI_CONFIDENCE_SPIKE_DELTA` (default `40`) and `LOKI_CONFIDENCE_SPIKE_MIN` (default `90`). |
754
755
  | `LOKI_GOAL_SCORING` | `1` (on) | Flags a goal with no measurable success condition and asks for a threshold, metric, or concrete artifact. Advisory only -- never blocks a build or rewrites the goal. Set `0` to opt out. |
755
756
  | `LOKI_SMART_RETRY` | `1` (on) | Stops early on a positively-identified permanent failure (bad credentials, unknown model, exhausted quota) rather than burning retries. Unrecognized errors and rate limits still retry as before. Set `0` to retry every failure. |
757
+ | `LOKI_SIMPLE` | `0` (off) | EXPERIMENTAL. Strips the coaching half of the system prompt -- the RARV cycle, SDLC phases and memory habits that a frontier model already does natively. Per-iteration state (which gate failed, self-heal output, checklist status) is never touched, because that is information the model cannot derive. Measured at -78% prompt size, ~1562 tokens per iteration, on both the bash and Bun routes. INERT on degraded providers (Codex, Aider): those take an earlier return path whose prompt is already minimal by design, so the flag has nothing to strip there -- a measured zero, not an untested case. Whether it changes build speed or quality is NOT yet measured, so treat it as an experiment, not a tuning knob: run `benchmarks/run-prompt-ablation.sh` on your own workload before adopting it. |
756
758
 
757
759
  This is a subset. See the [wiki](wiki/Home.md) for the full env-var reference and the RARV-C closure knobs (`LOKI_INJECT_FINDINGS`, `LOKI_OVERRIDE_COUNCIL`, `LOKI_AUTO_LEARNINGS`, `LOKI_HANDOFF_MD`).
758
760
 
@@ -776,12 +778,15 @@ See [BMAD Integration Validation](docs/architecture/bmad-integration-validation.
776
778
  <details>
777
779
  <summary><strong>Enterprise Features</strong></summary>
778
780
 
779
- Enterprise features are included but require env var activation. Self-audit: 35/45 capabilities working, 0 broken, 1,314 tests passing.
781
+ Enterprise features are included but require env var activation.
780
782
 
781
783
  ```bash
782
- export LOKI_TLS_ENABLED=true
783
- export LOKI_OIDC_PROVIDER=google
784
- export LOKI_AUDIT_ENABLED=true
784
+ export LOKI_ENTERPRISE_AUTH=true # token auth (dashboard/auth.py)
785
+ export LOKI_OIDC_ISSUER=https://accounts.google.com
786
+ export LOKI_OIDC_CLIENT_ID=your-client-id # OIDC needs issuer + client id
787
+ export LOKI_ENTERPRISE_AUDIT=true # force audit logging on
788
+ export LOKI_TLS_CERT=/path/cert.pem # HTTPS: set BOTH cert and key
789
+ export LOKI_TLS_KEY=/path/key.pem
785
790
  loki enterprise status
786
791
  ```
787
792
 
@@ -823,7 +828,7 @@ See [benchmarks/](benchmarks/) for methodology.
823
828
  | **Code Gen** | Full-stack apps from PRDs | Complex domain logic may need human review |
824
829
  | **Deploy** | Generates configs, Dockerfiles, CI/CD; `loki deploy` prints the exact deploy command | Does not deploy -- human runs the printed deploy command (Loki never runs a cloud CLI or git push) |
825
830
  | **Testing** | 8 automated quality gates | Test quality depends on AI assertions |
826
- | **Providers** | 4 providers with auto-failover | Non-Claude providers lack parallel agents |
831
+ | **Providers** | 5 providers with auto-failover | Non-Claude providers lack parallel agents |
827
832
  | **Dashboard** | Real-time single-machine monitoring | No multi-node clustering |
828
833
 
829
834
  > **What "autonomous" means:** The system runs RARV cycles without prompting. It does NOT access your cloud accounts, payment systems, or external services unless you provide credentials. Human oversight is expected for deployment, API keys, and critical decisions.
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: loki-mode
3
3
  description: Autonomous spec-driven build system with a built-in trust layer. It does not call work done until it is verified (RARV-C closure loop, 8 quality gates, completion council, verified-completion evidence gate). Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
4
4
  ---
5
5
 
6
- # Loki Mode v9.8.0
6
+ # Loki Mode v9.11.0
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -369,6 +369,7 @@ that cannot succeed.
369
369
  | `LOKI_CONFIDENCE_SPIKE_MIN` | `90` | Absolute level that counts as a spike on first arrival |
370
370
  | `LOKI_GOAL_SCORING=0` | on | Disable the goal-measurability advisory |
371
371
  | `LOKI_SMART_RETRY=0` | on | Retry every failure, including non-retryable ones |
372
+ | `LOKI_SIMPLE=1` | off | Strip the coaching half of the system prompt (-78%, ~1562 tokens/iteration). Experimental ablation arm. |
372
373
 
373
374
  - **Prompt-cache discipline.** The prompt is split into a cache-stable
374
375
  `<loki_system>` prefix and a volatile `<dynamic_context>` tail at an explicit
@@ -469,4 +470,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
469
470
 
470
471
  ---
471
472
 
472
- **v9.8.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
473
+ **v9.11.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 9.8.0
1
+ 9.12.0
package/autonomy/loki CHANGED
@@ -19316,7 +19316,40 @@ main() {
19316
19316
  # instead of re-checking every time a command is added.
19317
19317
  local _help_target="$1"
19318
19318
  shift
19319
- LOKI_HELP_ONLY=1 "$0" "$_help_target" --help "$@"
19319
+ # FORK BOMB GUARD, and this is not hypothetical: it filled the
19320
+ # process table with 3,788 chained `bash autonomy/loki --help
19321
+ # --help` processes on this machine, after which even `pkill`
19322
+ # could not fork.
19323
+ #
19324
+ # `loki help --help` sets _help_target="--help" and delegates as
19325
+ # `"$0" --help --help`. That re-enters THIS case, and "$@"
19326
+ # accumulates one more --help every pass, so the recursion is
19327
+ # unbounded and spawns a process per level.
19328
+ #
19329
+ # LOKI_HELP_ONLY was described above as making delegation "safe
19330
+ # by construction". It does -- against SIDE EFFECTS. It says
19331
+ # nothing about SELF-REFERENCE, which is a different hazard: the
19332
+ # danger is not that a command does something, it is that the
19333
+ # help router asks itself for help forever.
19334
+ #
19335
+ # A help-shaped target has no command help to delegate to, so
19336
+ # print the front page directly instead of recursing.
19337
+ case "$_help_target" in
19338
+ --help|-h|help|--h|-help)
19339
+ show_help
19340
+ ;;
19341
+ *)
19342
+ # Second, independent stop: if we are ALREADY inside a
19343
+ # delegated help call, do not delegate again. Belt and
19344
+ # braces, because the pattern list above is a blacklist
19345
+ # and a future spelling would slip past it.
19346
+ if [ "${LOKI_HELP_ONLY:-}" = "1" ]; then
19347
+ show_help
19348
+ else
19349
+ LOKI_HELP_ONLY=1 "$0" "$_help_target" --help "$@"
19350
+ fi
19351
+ ;;
19352
+ esac
19320
19353
  else
19321
19354
  show_help
19322
19355
  fi
@@ -33430,6 +33463,7 @@ cmd_bench() {
33430
33463
  echo " vs <task> Run all configured tools on a task-spec (head-to-head)"
33431
33464
  echo " list List available task-specs"
33432
33465
  echo " verify <file> Recompute task_hash + check tool versions for a result.json"
33466
+ echo " oracles Are the graders trustworthy? Hash-bound, no spend, no provider"
33433
33467
  echo " report <files> Build results.json + RESULTS.md from per-tool result-rows"
33434
33468
  echo ""
33435
33469
  echo "Options:"
@@ -33623,6 +33657,10 @@ cmd_proof() {
33623
33657
  echo ""
33624
33658
  echo "Subcommands:"
33625
33659
  echo " list List proof-of-run artifacts in .loki/proofs/"
33660
+ echo " releases [--json] Release history from git tags; version_is_ahead"
33661
+ echo " reads UNKNOWN when it cannot be computed"
33662
+ echo " phases [--json] Measured phase history from real phase_change"
33663
+ echo " events; unrecorded boundaries read UNKNOWN"
33626
33664
  echo " show <id> Pretty-print .loki/proofs/<id>/proof.json"
33627
33665
  echo " verify <id> Re-check a receipt against the repo (tamper + drift);"
33628
33666
  echo " exit 0 clean, 1 tamper/drift. Verify it yourself."
@@ -33645,6 +33683,89 @@ cmd_proof() {
33645
33683
  [ "$sub" = "" ] && exit 1
33646
33684
  exit 0
33647
33685
  ;;
33686
+ releases)
33687
+ # CLI PARITY with GET /api/operator/releases. Same reader
33688
+ # (dashboard/api_releases.py), so the two surfaces cannot disagree
33689
+ # about which versions shipped.
33690
+ _rel_json=0
33691
+ [ "${1:-}" = "--json" ] && _rel_json=1
33692
+ python3 - "$_rel_json" "$SKILL_DIR" <<'PYREL'
33693
+ import json, os, sys
33694
+ sys.dont_write_bytecode = True
33695
+ # Resolve the repo from THIS SCRIPT's location, not the cwd. Using getcwd()
33696
+ # made `loki proof releases` fail with "No module named dashboard" whenever it
33697
+ # was run from any other directory -- and it exited 0 while doing so, which is
33698
+ # a failure reported as success.
33699
+ # SKILL_DIR is the CLI's own install root, computed at loki:216. sys.argv[0]
33700
+ # is "-" inside a heredoc, so deriving the path from it does not work.
33701
+ _repo = sys.argv[2] if len(sys.argv) > 2 else ""
33702
+ for _cand in (_repo, os.getcwd()):
33703
+ if os.path.isdir(os.path.join(_cand, "dashboard")):
33704
+ sys.path.insert(0, _cand)
33705
+ break
33706
+ as_json = sys.argv[1] == "1"
33707
+ try:
33708
+ from dashboard import api_releases
33709
+ except Exception as exc:
33710
+ sys.stderr.write("release history unavailable: %s\n" % exc)
33711
+ raise SystemExit(2)
33712
+ env = api_releases.list_releases(os.getcwd())
33713
+ if as_json:
33714
+ print(json.dumps(env, indent=2))
33715
+ raise SystemExit(0)
33716
+ rows = env.get("releases") or []
33717
+ if not rows:
33718
+ print("no releases readable: %s" % (env.get("reason") or "unknown"))
33719
+ raise SystemExit(3)
33720
+ # version_is_ahead is None when it could not be computed. None is NOT False:
33721
+ # "I cannot compare" is a different claim from "it is not ahead".
33722
+ ahead = env.get("version_is_ahead")
33723
+ print("VERSION %s | newest tag %s | ahead: %s" % (
33724
+ env.get("version") or "UNKNOWN",
33725
+ env.get("newest_tag") or "UNKNOWN",
33726
+ "UNKNOWN" if ahead is None else ("yes" if ahead else "no")))
33727
+ for r in rows:
33728
+ print(" %-14s %s%s" % (r.get("tag"), r.get("date") or "date UNKNOWN",
33729
+ " (current)" if r.get("is_current") else ""))
33730
+ PYREL
33731
+ return $?
33732
+ ;;
33733
+ phases)
33734
+ # CLI PARITY with GET /api/operator/phases. Both call the SAME
33735
+ # reader (dashboard/api_phases.py), so the two surfaces cannot
33736
+ # drift into disagreeing about the same run.
33737
+ _phases_json=0
33738
+ [ "${1:-}" = "--json" ] && _phases_json=1
33739
+ python3 - "$loki_dir" "$_phases_json" <<'PYPHASES'
33740
+ import json, os, sys
33741
+ sys.dont_write_bytecode = True
33742
+ sys.path.insert(0, os.getcwd())
33743
+ loki_dir, as_json = sys.argv[1], sys.argv[2] == "1"
33744
+ try:
33745
+ from dashboard import api_phases
33746
+ except Exception as exc:
33747
+ sys.stderr.write("phase history unavailable: %s\n" % exc)
33748
+ raise SystemExit(2)
33749
+ env = api_phases.phase_history(loki_dir)
33750
+ if as_json:
33751
+ print(json.dumps(env, indent=2))
33752
+ raise SystemExit(0)
33753
+ segs = env.get("segments") or []
33754
+ if not segs:
33755
+ # An empty result states WHY: "no phases" and "could not read" are
33756
+ # different operator situations and must not print identically.
33757
+ print("no measured phase history: %s" % (env.get("reason") or "unknown"))
33758
+ raise SystemExit(3)
33759
+ lead = env.get("leading_phase")
33760
+ rows = ([lead] if lead else []) + list(segs)
33761
+ for seg in rows:
33762
+ print(" %-12s start=%-14s end=%s" % (
33763
+ seg.get("phase"),
33764
+ seg.get("start") if seg.get("start") is not None else "UNKNOWN",
33765
+ seg.get("end") if seg.get("end") is not None else "UNKNOWN"))
33766
+ PYPHASES
33767
+ return $?
33768
+ ;;
33648
33769
  list)
33649
33770
  if [ ! -d "$proofs_dir" ]; then
33650
33771
  echo -e "${YELLOW}No proofs found.${NC} Run 'loki start' to generate one."
package/autonomy/run.sh CHANGED
@@ -19874,8 +19874,47 @@ except Exception:
19874
19874
 
19875
19875
  # STATIC PREFIX (cache-stable across iterations).
19876
19876
  # Order is deterministic so the prefix is byte-identical for iter N and N+1.
19877
+ #
19878
+ # LOKI_SIMPLE=1 -- THE ABLATION ARM. Default off; the emitted bytes are
19879
+ # unchanged unless it is explicitly set, so parity fixtures do not move.
19880
+ #
19881
+ # WHY THIS EXISTS. Every instruction below was written to correct a model
19882
+ # that needed correcting. Anthropic deleted ~80% of Claude Code's system
19883
+ # prompt for Opus 5 on the finding that the corrections had become dead
19884
+ # weight -- and that the model measured slightly MORE capable without them.
19885
+ # Their method was ablation: delete, then add back only what a measured
19886
+ # failure demands. Nothing here had ever been measured at all.
19887
+ #
19888
+ # THE DISTINCTION THIS FLAG IS BUILT AROUND, and the reason it strips the
19889
+ # prefix while leaving the tail completely alone:
19890
+ #
19891
+ # The prefix is COACHING -- how to work. "Use a Reason-Act-Reflect-Verify
19892
+ # cycle", "execute all SDLC phases", "consult memory". A frontier model
19893
+ # does these natively; being told costs attention and buys nothing.
19894
+ #
19895
+ # The tail is STATE -- what happened. Which gate failed, what the
19896
+ # self-heal found, what the checklist still shows open. That is
19897
+ # information the model cannot derive from anywhere else, and deleting
19898
+ # it would be deleting the run's memory, not its lecture.
19899
+ #
19900
+ # So this ablates coaching ONLY. The dynamic tail below is untouched, and
19901
+ # so is every gate, receipt, and verification path: the trust core is not
19902
+ # prompt correction, and it is never an ablation arm.
19903
+ #
19904
+ # prd_anchor stays in both arms -- it names the task, which is the one
19905
+ # thing the model genuinely cannot infer.
19906
+ #
19907
+ # MEASURED, with its provenance: 8090 -> 1776 bytes (-78%) from a LIVE
19908
+ # build_prompt call under the fixture-1 ENVIRONMENT with a gate-failure
19909
+ # file present -- not from the fixture file itself, which is 7909 bytes.
19910
+ # The distinction matters because a number attributed to the wrong source
19911
+ # cannot be reproduced by the next person who tries.
19912
+ #
19913
+ # The strip is bounded: only the block below is gated, so the anchor and
19914
+ # the surrounding tags survive. Prefix size is a CEILING on the saving.
19877
19915
  printf '<loki_system>\n'
19878
19916
  printf '%s\n' "$prd_anchor"
19917
+ if [ "${LOKI_SIMPLE:-0}" != "1" ]; then
19879
19918
  printf '%s\n' "$rarv_instruction"
19880
19919
  printf '%s\n' "$sdlc_instruction"
19881
19920
  printf '%s\n' "$autonomous_suffix"
@@ -19885,6 +19924,7 @@ except Exception:
19885
19924
  printf '%s\n' "$compose_instruction"
19886
19925
  printf '%s\n' "$lsp_grounding_instruction"
19887
19926
  printf '%s\n' "$agents_md_instruction"
19927
+ fi
19888
19928
  # v8 (3c): goal-measurability advisory. Empty (and therefore not emitted at
19889
19929
  # all) for a measurable goal, an absent goal, or perpetual mode. Sits in the
19890
19930
  # static prefix because COMPLETION_PROMISE is fixed for the run, so it stays
@@ -25730,12 +25770,19 @@ except Exception:
25730
25770
  case "$_final_status" in
25731
25771
  council_approved|council_force_approved|deterministic_gates_passed|completion_promise_fulfilled|paused|interrupted|stopped)
25732
25772
  result=0 ;;
25733
- # force_stopped belongs HERE too, for the same reason. A council
25773
+ # force_stopped is in the result=20 arm below, NOT here. A council
25734
25774
  # force-stop (stagnation, or a flood of done-signals) means the run
25735
25775
  # gave up WITHOUT verifying the work -- the code already says so in
25736
25776
  # its header, its warning, and its refusal to open a PR. Reporting
25737
25777
  # it as a clean stop made it indistinguishable from success to the
25738
25778
  # only consumer that matters to automation: the exit code.
25779
+ #
25780
+ # This comment previously read "belongs HERE too" while the status
25781
+ # appeared in NEITHER arm, so it fell through to `*)` and returned
25782
+ # the incoming code unchanged -- a force-stop after a nonzero
25783
+ # iteration exited nonzero, and one after a zero exited 1. The
25784
+ # diagnosis was written and never applied; the wording is corrected
25785
+ # here so the comment cannot be read as describing current behavior.
25739
25786
  # budget_exceeded belongs HERE, not with the human-controlled stops.
25740
25787
  # It sat in the result=0 arm on the rationale that "a human will
25741
25788
  # resume", which is true of `paused` (a human pressed pause) and
@@ -25752,7 +25799,7 @@ except Exception:
25752
25799
  # The operator raises the cap (or narrows the spec) and submits a
25753
25800
  # NEW Job -- the same remedy as max_iterations_reached, which is why
25754
25801
  # it shares that code.
25755
- failed|max_iterations_reached|max_retries_exceeded|budget_exceeded|max_duration_reached|policy_blocked|inconclusive_spec_contradiction)
25802
+ failed|max_iterations_reached|max_retries_exceeded|budget_exceeded|max_duration_reached|policy_blocked|inconclusive_spec_contradiction|force_stopped)
25756
25803
  result=20 ;;
25757
25804
  *)
25758
25805
  # Unknown/running/exited terminal: leave $result as-is (nonzero on a
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "9.8.0"
10
+ __version__ = "9.12.0"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try: