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 +2 -2
- package/VERSION +1 -1
- package/autonomy/completion-council.sh +79 -15
- package/autonomy/loki +9 -4
- package/autonomy/run.sh +22 -3
- package/dashboard/__init__.py +1 -1
- package/docs/dev/architecture-reference.md +99 -0
- package/docs/dev/project-structure.md +134 -0
- package/docs/dev/release-checklist.md +157 -0
- package/docs/dev/research-foundation.md +29 -0
- package/docs/dev/tmp-cleanup.md +157 -0
- package/docs/v10/BOARD.md +95 -76
- package/docs/v10/DECISIONS.md +14 -0
- package/docs/v10/METRICS.md +33 -0
- package/docs/v10/OPERATING-MODEL.md +47 -0
- package/docs/v10/PROGRESS.md +173 -0
- package/docs/v10/SWARM.md +24 -0
- package/loki-ts/dist/loki.js +2 -2
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
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.
|
|
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.
|
|
473
|
+
**v9.59.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
9.
|
|
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
|
-
|
|
3488
|
-
|
|
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
|
-
|
|
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"
|
|
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
|
-
|
|
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
|
|
3736
|
-
#
|
|
3737
|
-
|
|
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
|
-
|
|
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"
|
|
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
|
|
4013
|
-
|
|
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"
|
|
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"
|
|
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
|
-
|
|
33949
|
-
|
|
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
|
-
|
|
34093
|
-
|
|
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.
|
|
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
|
-
|
|
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"
|
package/dashboard/__init__.py
CHANGED
|
@@ -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.
|