loki-mode 9.56.0 → 9.59.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.
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.56.0
6
+ # Loki Mode v9.59.0
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
- **v9.56.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
473
+ **v9.59.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 9.56.0
1
+ 9.59.0
@@ -72,6 +72,38 @@ for _cc_cand in "$_LOKI_CC_DIR/lib/secret-scan.sh" "${SCRIPT_DIR:-}/lib/secret-s
72
72
  done
73
73
  unset _LOKI_CC_DIR _cc_cand
74
74
 
75
+ # BACKLOG 134: the three test-result readers (council_heuristic_review,
76
+ # council_evaluate_member, council_devils_advocate_review) resolve their
77
+ # interpreter through run.sh's _loki_snapshot_py_tool and run it -I -S: -E alone
78
+ # still loads user site-packages, whose .pth "import" lines run before any
79
+ # sys.path scrub and can forge json.load (see that function's comment in
80
+ # run.sh for the full rationale and accepted gaps). run.sh sources this file
81
+ # BEFORE it defines _loki_snapshot_py_tool, so in production run.sh's own
82
+ # definition replaces this one; the copy below only serves callers that source
83
+ # this file on its own (tests). run.sh is the source of truth: keep this copy
84
+ # byte-identical to it.
85
+ declare -F _loki_snapshot_py_tool >/dev/null 2>&1 || \
86
+ _loki_snapshot_py_tool() {
87
+ local c
88
+ for c in /usr/bin/python3 /bin/python3; do
89
+ [ -x "$c" ] && [ ! -d "$c" ] && "$c" -I -S -c '' >/dev/null 2>&1 && { printf '%s\n' "$c"; return 0; }
90
+ done
91
+ local dir
92
+ local IFS=:
93
+ for dir in $PATH; do
94
+ case "$dir" in
95
+ /*) ;;
96
+ *) continue ;;
97
+ esac
98
+ if [ -x "$dir/python3" ] && [ ! -d "$dir/python3" ] \
99
+ && "$dir/python3" -I -S -c '' >/dev/null 2>&1; then
100
+ printf '%s\n' "$dir/python3"
101
+ return 0
102
+ fi
103
+ done
104
+ return 1
105
+ }
106
+
75
107
  # Council configuration
76
108
  COUNCIL_ENABLED=${LOKI_COUNCIL_ENABLED:-true}
77
109
  COUNCIL_SIZE=${LOKI_COUNCIL_SIZE:-3}
@@ -3484,8 +3516,10 @@ council_heuristic_review() {
3484
3516
  # evidence -> REJECT (keep iterating), never a heuristic APPROVE.
3485
3517
  local _tr_file=".loki/quality/test-results.json"
3486
3518
  local _tests_ok=0
3487
- if [ -f "$_tr_file" ] && command -v python3 >/dev/null 2>&1; then
3488
- _tests_ok=$(_TR="$_tr_file" python3 -E -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]
3519
+ local _tr_py=""
3520
+ [ -f "$_tr_file" ] && _tr_py="$(_loki_snapshot_py_tool)" || _tr_py=""
3521
+ if [ -n "$_tr_py" ]; then
3522
+ _tests_ok=$(_TR="$_tr_file" "$_tr_py" -I -S -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]
3489
3523
  import json, os
3490
3524
  try:
3491
3525
  with open(os.environ['_TR']) as f:
@@ -3668,9 +3702,11 @@ council_evaluate_member() {
3668
3702
  local tr_file="$loki_dir/quality/test-results.json"
3669
3703
  local test_evidence="absent" # absent | pass | fail | inconclusive
3670
3704
  local test_runner_seen="none"
3671
- if [ -f "$tr_file" ]; then
3705
+ local _tr_py=""
3706
+ [ -f "$tr_file" ] && _tr_py="$(_loki_snapshot_py_tool)" || _tr_py=""
3707
+ if [ -n "$_tr_py" ]; then
3672
3708
  local _tr_status
3673
- _tr_status=$(_TR_FILE="$tr_file" python3 -E -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]
3709
+ _tr_status=$(_TR_FILE="$tr_file" "$_tr_py" -I -S -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]
3674
3710
  import json, os, sys
3675
3711
  try:
3676
3712
  with open(os.environ['_TR_FILE']) as f:
@@ -3727,14 +3763,25 @@ else:
3727
3763
  # Cases 6 and 7, with Case 8 as the positive control proving this
3728
3764
  # can still reach COMPLETE when every queue really is empty.
3729
3765
  local unfinished=0
3730
- local _q _qcount
3766
+ local _q _qcount _q_py=""
3731
3767
  for _q in pending in-progress blocked; do
3732
3768
  [ -f "$loki_dir/queue/${_q}.json" ] || continue
3733
- _qcount=$(_QUEUE_FILE="$loki_dir/queue/${_q}.json" python3 -E -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]; import json, os
3769
+ # Same -I -S interpreter as the test-result readers: a user-site
3770
+ # .pth must not be able to make this count read 0.
3771
+ [ -n "$_q_py" ] || _q_py="$(_loki_snapshot_py_tool)" || _q_py=""
3772
+ _qcount=""
3773
+ [ -n "$_q_py" ] && _qcount=$(_QUEUE_FILE="$loki_dir/queue/${_q}.json" "$_q_py" -I -S -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]; import json, os
3734
3774
  d = json.load(open(os.environ['_QUEUE_FILE']))
3735
- print(len(d.get('tasks', d) if isinstance(d, dict) else d))" 2>/dev/null || echo "0")
3736
- # Guard against a non-numeric read (malformed file, python absent).
3737
- case "$_qcount" in ''|*[!0-9]*) _qcount=0 ;; esac
3775
+ print(len(d.get('tasks', d) if isinstance(d, dict) else d))" 2>/dev/null)
3776
+ # Fail closed: a present queue file whose count cannot be read
3777
+ # (malformed file, no interpreter) is not evidence it is empty.
3778
+ case "$_qcount" in
3779
+ ''|*[!0-9]*)
3780
+ blocked="true"
3781
+ reasons="${reasons}${_q} queue count unreadable; "
3782
+ continue
3783
+ ;;
3784
+ esac
3738
3785
  if [ "$_qcount" -gt 0 ]; then
3739
3786
  unfinished=$((unfinished + _qcount))
3740
3787
  blocked="true"
@@ -3969,9 +4016,11 @@ council_devils_advocate_review() {
3969
4016
  # (nothing writes .loki/logs/test-*.log, so an empty glob is the normal case
3970
4017
  # and must never veto a unanimous COMPLETE on its own).
3971
4018
  local tr_file="$loki_dir/quality/test-results.json"
3972
- if [ -f "$tr_file" ]; then
4019
+ local _tr_py=""
4020
+ [ -f "$tr_file" ] && _tr_py="$(_loki_snapshot_py_tool)" || _tr_py=""
4021
+ if [ -n "$_tr_py" ]; then
3973
4022
  local _tr_status
3974
- _tr_status=$(_TR_FILE="$tr_file" python3 -E -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]
4023
+ _tr_status=$(_TR_FILE="$tr_file" "$_tr_py" -I -S -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]
3975
4024
  import json, os, sys
3976
4025
  try:
3977
4026
  with open(os.environ['_TR_FILE']) as f:
@@ -3994,6 +4043,8 @@ else:
3994
4043
  ((issues_found++))
3995
4044
  issue_details="${issue_details}structured test results red (pass==false); "
3996
4045
  fi
4046
+ elif [ -f "$tr_file" ]; then
4047
+ ((issues_found++)); issue_details="${issue_details}test results unreadable (no isolated python3); "
3997
4048
  fi
3998
4049
  # Additional source: any legacy test log that shows no pass indicator is a red
3999
4050
  # signal. Missing logs are NOT counted (this path is not written by the runner).
@@ -4009,8 +4060,18 @@ else:
4009
4060
  # Skeptical check 2: Are there still failing tasks in the queue?
4010
4061
  if [ -f "$loki_dir/queue/failed.json" ]; then
4011
4062
  local failed_count
4012
- failed_count=$(_QUEUE_FILE="$loki_dir/queue/failed.json" python3 -E -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]; import json, os; print(len(json.load(open(os.environ['_QUEUE_FILE']))))" 2>/dev/null || echo "0")
4013
- if [ "$failed_count" -gt 0 ]; then
4063
+ local failed_count="" _fq_py=""
4064
+ _fq_py="$(_loki_snapshot_py_tool)" || _fq_py=""
4065
+ [ -n "$_fq_py" ] && failed_count=$(_QUEUE_FILE="$loki_dir/queue/failed.json" "$_fq_py" -I -S -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]; import json, os; print(len(json.load(open(os.environ['_QUEUE_FILE']))))" 2>/dev/null)
4066
+ # Fail closed: an unreadable failed-queue count (malformed, no
4067
+ # interpreter) vetoes instead of reading as zero.
4068
+ case "$failed_count" in
4069
+ ''|*[!0-9]*)
4070
+ ((issues_found++))
4071
+ issue_details="${issue_details}failed queue count unreadable; "
4072
+ ;;
4073
+ esac
4074
+ if [ "${failed_count:-0}" -gt 0 ] 2>/dev/null; then
4014
4075
  ((issues_found++))
4015
4076
  issue_details="${issue_details}$failed_count tasks in failed queue; "
4016
4077
  fi
@@ -4492,8 +4553,11 @@ _council_convergence_evidence_green() {
4492
4553
  # Affirmative test-green is REQUIRED: a real runner that passed. A missing
4493
4554
  # file or runner=="none" (no suite) is NOT affirmative evidence -> not green.
4494
4555
  [ -f "$tr_file" ] || return 1
4556
+ # -I -S interpreter (see _loki_snapshot_py_tool); none resolvable -> not green.
4557
+ local _cv_py
4558
+ _cv_py="$(_loki_snapshot_py_tool)" || return 1
4495
4559
  local tr_state
4496
- tr_state=$(_TR_FILE="$tr_file" python3 -E -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]
4560
+ tr_state=$(_TR_FILE="$tr_file" "$_cv_py" -I -S -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]
4497
4561
  import json, os, sys
4498
4562
  try:
4499
4563
  with open(os.environ['_TR_FILE']) as f:
@@ -4516,7 +4580,7 @@ print('yes' if (runner != 'none' and passed is True
4516
4580
  local results_file="${TARGET_DIR:-.}/.loki/checklist/verification-results.json"
4517
4581
  if [ -f "$results_file" ]; then
4518
4582
  local cl_state
4519
- cl_state=$(_RESULTS_FILE="$results_file" python3 -E -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]
4583
+ cl_state=$(_RESULTS_FILE="$results_file" "$_cv_py" -I -S -c "import sys; sys.path[:] = [p for p in sys.path if p not in ('', '.')]
4520
4584
  import json, os, sys
4521
4585
  try:
4522
4586
  with open(os.environ['_RESULTS_FILE']) as f:
package/autonomy/loki CHANGED
@@ -33945,8 +33945,10 @@ except Exception:
33945
33945
  # Only scan added lines (starting with "+") to avoid flagging deleted code
33946
33946
  while IFS= read -r match; do
33947
33947
  [ -z "$match" ] && continue
33948
- local ml
33949
- ml=$(echo "$match" | cut -d: -f1)
33948
+ # grep -n emits "N:content"; take the number before the first
33949
+ # colon without forking echo+cut per line (matters at finding
33950
+ # counts in the thousands+).
33951
+ local ml="${match%%:*}"
33950
33952
  _ci_add_finding "diff" "$ml" "$sev" "$cat" "$finding" "$suggestion"
33951
33953
  done < <(printf '%s\n' "$diff_content" \
33952
33954
  | grep -n '^+' \
@@ -34089,8 +34091,11 @@ TEST_SUGGEST_PY
34089
34091
  # --- Tally findings ---
34090
34092
  local count_critical=0 count_high=0 count_medium=0 count_low=0 count_info=0
34091
34093
  for f in "${findings[@]+"${findings[@]}"}"; do
34092
- local sev
34093
- sev=$(echo "$f" | cut -d'|' -f3)
34094
+ # "file|line|sev|cat|finding|suggestion" (see _ci_add_finding above).
34095
+ # No echo+cut fork per finding -- this loop runs once per finding and
34096
+ # dominated the runtime at the fixture's old ARG_MAX-scale sizes.
34097
+ local sev _tally_file _tally_line _tally_cat _tally_finding _tally_suggestion
34098
+ IFS='|' read -r _tally_file _tally_line sev _tally_cat _tally_finding _tally_suggestion <<< "$f"
34094
34099
  case "$sev" in
34095
34100
  CRITICAL) count_critical=$((count_critical + 1)) ;;
34096
34101
  HIGH) count_high=$((count_high + 1)) ;;
package/autonomy/run.sh CHANGED
@@ -9218,10 +9218,27 @@ setup_agent_branch() {
9218
9218
 
9219
9219
  # Record the user's own untracked and gitignored files so
9220
9220
  # commit_session_changes and the receipt leave them alone.
9221
- local snap_ok=1 leftover=""
9221
+ local snap_ok=1 leftover="" gittool=""
9222
9222
  if ! _loki_snapshot_or_fail_closed; then
9223
9223
  snap_ok=0
9224
- rm -f .loki/state/preexisting-untracked.z .loki/state/preexisting-untracked.sha.z 2>/dev/null
9224
+ rm -f .loki/state/preexisting-untracked.sha.z 2>/dev/null
9225
+ # BACKLOG 88: the receipt (workspace_diff._preexisting_untracked) reads
9226
+ # preexisting-untracked.z on its own, independent of
9227
+ # _LOKI_SNAPSHOT_THIS_RUN below. Leaving it absent after a failed
9228
+ # snapshot (old code: `rm -f` here too) makes the receipt treat EVERY
9229
+ # currently-untracked file as this run's own work, even though nothing
9230
+ # is actually committed -- a pre-existing file the user never touched
9231
+ # gets named as the run's. `ls-files --others --exclude-standard` needs
9232
+ # no --no-renames or --ignored=matching, so it still works on the git
9233
+ # that just failed the richer `status` call above, giving the receipt a
9234
+ # names-only fallback list. Ignored files are not covered by this
9235
+ # fallback (old-git territory), so it is partial, not a full snapshot;
9236
+ # the commit path is untouched (snap_ok stays 0, _LOKI_SNAPSHOT_THIS_RUN
9237
+ # is never set below), so this still fails closed.
9238
+ gittool="$(_loki_snapshot_git_tool)" && \
9239
+ "$gittool" ls-files --others --exclude-standard -z > .loki/state/preexisting-untracked.z.tmp 2>/dev/null && \
9240
+ mv .loki/state/preexisting-untracked.z.tmp .loki/state/preexisting-untracked.z \
9241
+ || rm -f .loki/state/preexisting-untracked.z .loki/state/preexisting-untracked.z.tmp 2>/dev/null
9225
9242
  log_warn "Could not record pre-existing untracked files; this session will commit nothing (review and commit manually)"
9226
9243
  fi
9227
9244
 
@@ -10317,7 +10334,9 @@ _loki_untrack_agent_committed_user_files() {
10317
10334
  fi
10318
10335
  rm -f "$rec.added"
10319
10336
  if [ ! -s "$rec.new" ]; then
10320
- rm -f "$rec.new"
10337
+ # BACKLOG 102: zero hits this session -- clear a stale record left by
10338
+ # an earlier session, or it persists forever with nothing to read it.
10339
+ rm -f "$rec.new" "$rec"
10321
10340
  return 0
10322
10341
  fi
10323
10342
  mv -f "$rec.new" "$rec"
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "9.56.0"
10
+ __version__ = "9.59.0"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -0,0 +1,99 @@
1
+ # Architecture reference: gates, healing, memory, harness knobs
2
+
3
+ Moved out of CLAUDE.md (S-78) to keep the root file short. Content unchanged
4
+ except where noted.
5
+
6
+ ## Quality Gates (8 gates; see `skills/quality-gates.md` for the canonical table)
7
+ 1. Static analysis (CodeQL, ESLint)
8
+ 2. Test suite pass/fail (red blocks; coverage % not measured in this release)
9
+ 3. Blind 3-reviewer code review with severity blocking (Critical/High = BLOCK; Medium/Low advisory)
10
+ 4. Anti-sycophancy / Devil's Advocate (on unanimous PASS)
11
+ 5. Mock-integrity detector (HIGH blocks)
12
+ 6. Test-mutation detector (HIGH blocks)
13
+ 7. Documentation coverage
14
+ 8. Magic Modules debate (ADVISORY by default on both routes; bash enforces only with `LOKI_GATE_MAGIC_DEBATE_BLOCKING=true`, Bun self-skips unless `LOKI_GATE_MAGIC_DEBATE="true"`)
15
+
16
+ Conditional auditor (not numbered): Backward-compatibility / legacy-healing-auditor (healing mode only - behavioral preservation, v6.67.0).
17
+
18
+ Note (v10): `docs/v10/DECISIONS.md` D12 refines the review rule above -- unanimous
19
+ APPROVE is still required, and a reproduced blocking finding always vetoes
20
+ regardless of vote count. D13 requires every council/review agent to pin its
21
+ model explicitly rather than inherit the session model.
22
+
23
+ ## Legacy System Healing (introduced v6.67.0)
24
+ - **Current in v7.18.0**: Still active, no breaking changes since v6.67.0. Note: in v7.4.20 the `legacy-healing-auditor` reviewer was gated on healing-mode signals to avoid firing on non-healing changes.
25
+ - **Inspired by**: Amazon AGI Lab's "How Agentic AI Helps Heal Systems We Can't Replace"
26
+ - **CLI**: `loki heal <path> [--phase archaeology|stabilize|isolate|modernize|validate]` (`autonomy/loki:9916`)
27
+ - **Principles**: Friction-as-semantics, failure-first learning, universal adapters, incremental healing, institutional knowledge preservation
28
+ - **Artifacts**: `.loki/healing/` (friction-map.json, failure-modes.json, institutional-knowledge.md)
29
+ - **Review**: `legacy-healing-auditor` specialist added to code review pool (gated)
30
+ - **Gate**: backward-compatibility / legacy-healing auditor (healing mode; not one of the 8 numbered gates) blocks removal of unclassified friction
31
+ - **Hooks**: `hook_pre_healing_modify()` (`autonomy/hooks/migration-hooks.sh:283`), `hook_post_healing_modify()` (`:328`), `hook_healing_phase_gate()` (`:386`)
32
+ - **Memory**: `FrictionPoint` and `FailureMode` schemas for healing-specific memory entries
33
+ - **Skill**: `skills/healing.md` | **Reference**: `references/legacy-healing-patterns.md`
34
+
35
+ ## Memory System (core complete v5.15.0; managed-memory + RAG injector v7.1.0+)
36
+ - **Episodic**: Specific interaction traces (`.loki/memory/episodic/`)
37
+ - **Semantic**: Generalized patterns (`.loki/memory/semantic/`)
38
+ - **Procedural**: Learned skills (`.loki/memory/skills/`)
39
+ - **Progressive Disclosure**: 3-layer loading (index, timeline, full details)
40
+ - **Token Economics**: Discovery vs read token tracking
41
+ - **Vector Search**: Optional embedding-based similarity (sentence-transformers)
42
+ - **Cross-project + RAG injection**: `memory/cross_project.py`, `memory/rag_injector.py`, `memory/knowledge_graph.py` (added v7.x)
43
+ - **Managed memory client**: `memory/managed_memory/` -- gated on `LOKI_MANAGED_MEMORY=true`. See `skills/memory.md`.
44
+ - **CLI**: `loki memory index|timeline|consolidate|economics|retrieve|episode|pattern|skill|vectors`
45
+ - **API**: REST endpoints at `/api/memory/*`
46
+ - **Implementation**: `memory/` Python package (15 modules) with RARV integration
47
+
48
+ ## Metrics System (ToolOrchestra-inspired)
49
+ - **Efficiency**: Task cost tracking (`.loki/metrics/efficiency/`)
50
+
51
+ ## v8 Harness Intelligence (v8.0.0)
52
+
53
+ Four measured-harness disciplines on the trust core. None can weaken a gate.
54
+
55
+ - **Prompt-cache discipline**: the prompt splits into a cache-stable
56
+ `<loki_system>` prefix and a volatile `<dynamic_context>` tail at
57
+ `[CACHE_BREAKPOINT]`. **Any new always-on instruction MUST go in the prefix**
58
+ or it busts the cache every iteration.
59
+ Two accuracy notes, because an earlier version of this bullet overstated it:
60
+ explicit `cache_control` on that split lives in `sdk_invoker.ts` (the raw-SDK
61
+ judge path) and is **opt-in, default OFF** behind `LOKI_SDK_PROMPT_CACHE=1`.
62
+ On the main agent path the Agent SDK's `query()` takes a plain string, so the
63
+ split is not applied there and the SDK/CLI does its own caching internally.
64
+ On the bash route the `[CACHE_BREAKPOINT]` marker is a documentation anchor
65
+ that orders the prompt; it sets no `cache_control` header. The ordering rule
66
+ above still matters on every route -- a stable prefix is what any cache, ours
67
+ or the CLI's, can reuse.
68
+ - **Confidence-spike re-check** (`loki-ts/src/runner/council.ts`): delays the
69
+ done-signal force-stop by ONE iteration when self-reported confidence spikes.
70
+ Strictly additive (never skips a gate), never delays the stagnation valve,
71
+ one-shot so a re-spiking run cannot postpone the valve forever.
72
+ `LOKI_CONFIDENCE_SPIKE=0` / `_DELTA` (40) / `_MIN` (90).
73
+ - **Goal scoring** (`loki-ts/src/runner/goal_score.ts`): flags a
74
+ `COMPLETION_PROMISE` with no measurable target. Advisory only. Suppressed for
75
+ an absent goal and in perpetual mode. **Byte-mirrored in `autonomy/run.sh`** --
76
+ edit BOTH or the `build_prompt` parity fixtures diverge. `LOKI_GOAL_SCORING=0`.
77
+ - **Smart retry** (`loki-ts/src/runner/retry_class.ts`): exits early on a
78
+ positively-identified permanent failure. **Fail-safe direction is
79
+ load-bearing**: unrecognized failures stay TRANSIENT and retry as before; rate
80
+ limits are explicitly excluded from the permanent set. Never invert this
81
+ default. `LOKI_SMART_RETRY=0`.
82
+
83
+ Observability: SDK failures emit a structured `capability_degraded` record to
84
+ `.loki/events.jsonl`; `.loki/app-runner/first-preview.json` records
85
+ time-to-first-preview write-once (bash route only).
86
+
87
+ ## Phase 1 / RARV-C Closure Env Vars
88
+
89
+ Default-on in the Bun runner (see `CHANGELOG.md` v7.x entries; documented in `skills/quality-gates.md:88-110`). Set to `0` to disable; set to `1` to force-enable on the bash route.
90
+
91
+ - `LOKI_INJECT_FINDINGS` -- inject structured per-finding records into the next-iteration prompt; persists `.loki/state/findings-<iter>.json` after aggregation.
92
+ - `LOKI_OVERRIDE_COUNCIL` -- enable the 3-judge override council on a BLOCK verdict. Requires `LOKI_INJECT_FINDINGS=1` (operator setting only this var alone is a no-op).
93
+ **The BLOCK-LIFT arm only adjudicates on the Bun route** (`LOKI_SDK_LOOP=1`, or `LOKI_SDK_MODE=full`). A plain `loki start` takes the BASH route (`bin/loki:325`; `LOKI_SDK_MODE` defaults to `off`), where the override lands in a stub that returns `REJECT_OVERRIDE` for every record (`loki-ts/src/commands/internal_phase1.ts:215-227`). Counter-evidence is still parsed and an `override-<iter>.json` transcript is still written, so the feature looks live in the artifacts while never being able to lift a BLOCK.
94
+ This fail-closed direction is DELIBERATE, not a bug: on the agent-authored route the gated agent writes its own counter-evidence, so mechanical verification is forgeable. On bash the only exits from a Critical/High BLOCK are to fix the finding or to use the human-escape path (`rm .loki/PAUSE`). Documented here because the heading above says "default-on" and, for this one knob's block-lift, that is true only on Bun.
95
+ - `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.
96
+ **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.
97
+ - `LOKI_HANDOFF_MD` -- write a structured handoff doc before iteration close.
98
+
99
+ 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.
@@ -0,0 +1,134 @@
1
+ # Project structure and codebase knowledge graph
2
+
3
+ Moved out of CLAUDE.md (S-78) to keep the root file short. Content unchanged.
4
+
5
+ ## Project Structure
6
+
7
+ ```
8
+ SKILL.md # Slim core skill (~410 lines) - progressive disclosure
9
+ providers/ # Multi-provider support (5 providers)
10
+ claude.sh # Claude Code - full features (Tier 1)
11
+ cline.sh # Cline - Tier 2
12
+ codex.sh # OpenAI Codex CLI - degraded mode (Tier 3)
13
+ aider.sh # Aider - degraded mode (Tier 3)
14
+ opencode.sh # opencode - model-agnostic mode
15
+ loader.sh # Provider loader utility
16
+ models.sh # Model name registry
17
+ memory/ # Memory system (core v5.15.0; cross-project + RAG injector v7.1.0+; 15 modules)
18
+ engine.py # Core memory engine
19
+ schemas.py # Pydantic schemas
20
+ storage.py # Storage backend
21
+ retrieval.py # Task-aware retrieval
22
+ consolidation.py # Episodic-to-semantic pipeline
23
+ token_economics.py # Token usage tracking
24
+ embeddings.py # Vector embeddings (optional)
25
+ vector_index.py # Vector search index
26
+ layers/ # Progressive disclosure implementation
27
+ skills/ # On-demand skill modules (v3.0 architecture)
28
+ 00-index.md # Module selection rules and routing
29
+ model-selection.md # Task tool, parallelization, thinking modes
30
+ providers.md # Multi-provider documentation
31
+ quality-gates.md # 8-gate system, velocity-quality balance
32
+ healing.md # Legacy system healing (Amazon AGI Lab patterns)
33
+ testing.md # Playwright, E2E, property-based testing
34
+ production.md # HN patterns, CI/CD, context management
35
+ troubleshooting.md # Common issues, red flags, fallbacks
36
+ agents.md # 41 agent types, structured prompting
37
+ artifacts.md # Generation, code transformation
38
+ patterns-advanced.md # OptiMind, k8s-valkey, Constitutional AI
39
+ parallel-workflows.md # Git worktrees, parallel streams, auto-merge
40
+ github-integration.md # GitHub issue import, PR creation, notifications
41
+ sdlc-fleet.md # Six-role standing fleet pattern (see CLAUDE.md)
42
+ references/ # Detailed documentation (21 files)
43
+ legacy-healing-patterns.md # Amazon AGI Lab: friction, adapters, archaeology
44
+ openai-patterns.md # OpenAI Agents SDK: guardrails, tripwires, handoffs
45
+ lab-research-patterns.md # DeepMind + Anthropic: Constitutional AI, debate
46
+ production-patterns.md # HN 2025: What actually works in production
47
+ advanced-patterns.md # 2025 research patterns (MAR, Iter-VF, GoalAct)
48
+ tool-orchestration.md # ToolOrchestra-inspired efficiency & rewards
49
+ memory-system.md # Episodic/semantic memory architecture
50
+ quality-control.md # Code review, anti-sycophancy, guardrails
51
+ agent-types.md # 41 specialized agent definitions
52
+ sdlc-phases.md # Full SDLC workflow
53
+ task-queue.md # Queue system, circuit breakers
54
+ core-workflow.md # RARV cycle, autonomy rules
55
+ deployment.md # Cloud deployment instructions
56
+ business-ops.md # Business operation workflows
57
+ mcp-integration.md # MCP server capabilities
58
+ competitive-analysis.md # Auto-Claude, MemOS, Dexter comparison
59
+ confidence-routing.md # Model selection by confidence
60
+ cursor-learnings.md # Cursor scaling patterns
61
+ prompt-repetition.md # Haiku prompt optimization
62
+ agents.md # Agent dispatch patterns
63
+ events/ # Unified Event Bus (v5.17.0)
64
+ bus.py # Python event bus
65
+ bus.ts # TypeScript event bus
66
+ emit.sh # Bash helper for emitting events
67
+ docs/ # Architecture documentation
68
+ SYNERGY-ROADMAP.md # 5-pillar tool integration architecture
69
+ v10/ # v10 program: OPERATING-MODEL.md, DECISIONS.md, BOARD.md, BACKLOG.md, PROGRESS.md
70
+ dev/ # Developer reference docs (this file and its siblings)
71
+ autonomy/ # Runtime and autonomous execution
72
+ context-tracker.py # Context window usage tracking
73
+ notification-checker.py # Notification trigger evaluation
74
+ templates/ # 21 PRD templates (saas, cli, discord-bot, etc.)
75
+ benchmarks/ # SWE-bench and HumanEval benchmarks
76
+ ```
77
+
78
+ ## Codebase Knowledge Graph (Quick Reference)
79
+
80
+ ### Top-Level File Map
81
+
82
+ Line counts approximate; re-run `wc -l` for exact.
83
+
84
+ | File | Lines | Role |
85
+ |---|---|---|
86
+ | `autonomy/loki` | ~32,700 | CLI (102 cmd_ functions, dispatch at `loki:main`) |
87
+ | `autonomy/run.sh` | ~20,400 | Orchestration engine (RARV loop) |
88
+ | `autonomy/completion-council.sh` | ~3,800 | Completion detection (council voting) |
89
+ | `dashboard/server.py` | ~11,500 | FastAPI (100+ endpoints, WebSocket) |
90
+ | `memory/retrieval.py` | ~2,100 | Task-aware memory retrieval |
91
+ | `memory/storage.py` | ~2,000 | File-based memory backend |
92
+ | `memory/engine.py` | ~1,600 | Memory orchestrator |
93
+ | `memory/consolidation.py` | ~1,100 | Episodic-to-semantic pipeline |
94
+ | `mcp/server.py` | ~2,700 | MCP server (36 tools: 28 in-file + 7 magic + 1 gated managed; +3 resources, 2 prompts) |
95
+ | `providers/loader.sh` | ~185 | Provider loader |
96
+
97
+ ### Key Function Lookup
98
+
99
+ Verified against v7.5.13 source on 2026-04-29. Line numbers drift; re-verify with `grep -n` before relying on them.
100
+
101
+ | Function | Location | Purpose |
102
+ |---|---|---|
103
+ | `cmd_start()` | `autonomy/loki` | Start autonomous execution |
104
+ | `main()` (CLI) | `autonomy/loki` | CLI dispatch |
105
+ | `main()` (runner) | `autonomy/run.sh` | Runner entry point |
106
+ | `run_autonomous()` | `autonomy/run.sh` | Main iteration loop |
107
+ | `build_prompt()` | `autonomy/run.sh` | Prompt construction |
108
+ | `save_state()` | `autonomy/run.sh` | Persist state |
109
+ | `council_should_stop()` | `autonomy/completion-council.sh` | Completion decision |
110
+ | `run_code_review()` | `autonomy/run.sh` | 3-reviewer code review |
111
+ | `create_checkpoint()` | `autonomy/run.sh` | Snapshot state |
112
+ | `store_episode_trace()` | `autonomy/run.sh` | Memory storage bridge |
113
+ | `check_human_intervention()` | `autonomy/run.sh` | PAUSE/STOP/INPUT signals |
114
+ | `detect_complexity()` | `autonomy/run.sh` | Auto-detect project complexity |
115
+ | `get_rarv_tier()` | `autonomy/run.sh` | Map iteration to model tier |
116
+ | `check_budget_limit()` | `autonomy/run.sh` | Budget circuit breaker |
117
+ | `is_rate_limited()` | `autonomy/run.sh` | Rate limit detection |
118
+ | `cmd_heal()` | `autonomy/loki` | Legacy system healing |
119
+ | `hook_pre_healing_modify()` | `autonomy/hooks/migration-hooks.sh` | Friction safety gate |
120
+ | `hook_post_healing_modify()` | `autonomy/hooks/migration-hooks.sh` | Characterization test verification |
121
+ | `hook_healing_phase_gate()` | `autonomy/hooks/migration-hooks.sh` | Healing phase transition gate |
122
+
123
+ ### Critical Data Flow
124
+
125
+ A PRD enters via `loki start` (`autonomy/loki:622`), which execs `run.sh`. The `run_autonomous()` loop (`autonomy/run.sh:10253`) builds prompts via `build_prompt()` (`autonomy/run.sh:8987`) injecting RARV instructions, SDLC phases, memory context, queue tasks, and checklist status. The provider is invoked (Claude via `-p` flag, Codex via `exec --sandbox workspace-write` with `CODEX_MODEL_REASONING_EFFORT` env var, Cline/Aider sequentially). Post-iteration, the system runs checklist verification, app runner management, playwright smoke tests, and code review. Completion is determined by a council vote (`council_should_stop` at `autonomy/completion-council.sh:1605`), completion promise text, or max iterations. All components communicate through `.loki/` filesystem state files.
126
+
127
+ **Deprecated entrypoints:**
128
+ - `loki run <issue-ref>` is a deprecated alias for `loki start <issue-ref>` since v6.84.0. Emits a `cli_command_deprecated` telemetry event. See `autonomy/loki:4436-4456`. Prefer `loki start`.
129
+
130
+ The fuller codebase knowledge graph lives in local Claude project memory
131
+ (`~/.claude/projects/<sanitized-repo-path>/memory/CODEBASE-KNOWLEDGE-GRAPH.md`),
132
+ not in this repository. It is not tracked in git and is not shipped in the npm
133
+ package, so it resolves only on a machine where that memory exists. The tables
134
+ above are the in-repo reference and are the authority for anyone else.