loki-mode 7.104.4 → 7.105.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 +27 -1
- package/autonomy/run.sh +24 -1
- package/dashboard/__init__.py +1 -1
- package/dashboard/server.py +102 -52
- package/docs/FOUNDER-STATUS-AND-DECISIONS-2026-07-01.md +106 -0
- package/docs/INSTALLATION.md +1 -1
- package/docs/SPEED-DIAGNOSIS-2026-07-01.md +61 -0
- package/docs/TOP-100-BACKLOG.md +122 -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 v7.
|
|
6
|
+
# Loki Mode v7.105.0
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -408,4 +408,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
|
|
|
408
408
|
|
|
409
409
|
---
|
|
410
410
|
|
|
411
|
-
**v7.
|
|
411
|
+
**v7.105.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
7.
|
|
1
|
+
7.105.0
|
|
@@ -3226,10 +3226,36 @@ council_should_stop() {
|
|
|
3226
3226
|
circuit_triggered=true
|
|
3227
3227
|
fi
|
|
3228
3228
|
|
|
3229
|
-
# Only run council at check intervals OR if circuit breaker triggered
|
|
3229
|
+
# Only run council at check intervals OR if circuit breaker triggered OR the
|
|
3230
|
+
# agent has EXPLICITLY claimed completion this iteration (v7.105.0 convergence
|
|
3231
|
+
# fix). Rationale, measured from real build telemetry (docs/SPEED-DIAGNOSIS):
|
|
3232
|
+
# a build could be verifiably done at iteration 1 (reviews non-blocking, tests
|
|
3233
|
+
# green, checklist complete) yet the council was not even allowed to evaluate
|
|
3234
|
+
# until the next 5-iteration boundary -- so the loop ground out "next
|
|
3235
|
+
# improvement" iterations the user never asked for (14 iterations for a job
|
|
3236
|
+
# done in ~1). An explicit completion CLAIM is the strongest possible signal
|
|
3237
|
+
# that it is worth asking the council NOW. This changes only WHEN the council
|
|
3238
|
+
# evaluates, never WHETHER it must approve: MIN_ITERATIONS below, the hard
|
|
3239
|
+
# checklist gate, the evidence gate, the aggregate vote, and the devil's
|
|
3240
|
+
# advocate all still run unchanged. A premature or unearned claim is still
|
|
3241
|
+
# rejected (returns 1, loop continues); it is never a forced green.
|
|
3242
|
+
#
|
|
3243
|
+
# The claim signal is the structured one (loki_complete_task MCP tool ->
|
|
3244
|
+
# .loki/signals/COMPLETION_REQUESTED, or the runner exporting
|
|
3245
|
+
# LOKI_COMPLETION_CLAIMED=1 for this iteration), NOT the fuzzy log-grep the
|
|
3246
|
+
# circuit breaker uses -- so it fires on a real, intentional claim only.
|
|
3247
|
+
local completion_claimed=false
|
|
3248
|
+
if [ "${LOKI_COMPLETION_CLAIMED:-0}" = "1" ] \
|
|
3249
|
+
|| [ -f "${TARGET_DIR:-.}/.loki/signals/COMPLETION_REQUESTED" ]; then
|
|
3250
|
+
completion_claimed=true
|
|
3251
|
+
fi
|
|
3252
|
+
|
|
3230
3253
|
local should_check=false
|
|
3231
3254
|
if [ "$circuit_triggered" = "true" ]; then
|
|
3232
3255
|
should_check=true
|
|
3256
|
+
elif [ "$completion_claimed" = "true" ]; then
|
|
3257
|
+
should_check=true
|
|
3258
|
+
log_info "[Council] Completion claimed this iteration -- evaluating now (not deferring to the ${COUNCIL_CHECK_INTERVAL}-iteration interval)"
|
|
3233
3259
|
elif [ $((ITERATION_COUNT % COUNCIL_CHECK_INTERVAL)) -eq 0 ]; then
|
|
3234
3260
|
should_check=true
|
|
3235
3261
|
fi
|
package/autonomy/run.sh
CHANGED
|
@@ -17530,7 +17530,30 @@ else:
|
|
|
17530
17530
|
if type ensure_completion_test_evidence &>/dev/null; then
|
|
17531
17531
|
ensure_completion_test_evidence || true
|
|
17532
17532
|
fi
|
|
17533
|
-
if
|
|
17533
|
+
# v7.105.0 convergence: if the agent EXPLICITLY claimed completion this
|
|
17534
|
+
# iteration (structured loki_complete_task / COMPLETION_REQUESTED
|
|
17535
|
+
# signal), tell the council to evaluate NOW instead of deferring to the
|
|
17536
|
+
# 5-iteration check interval. The council still must approve (MIN_
|
|
17537
|
+
# ITERATIONS + hard checklist + evidence gate + vote + devil's advocate
|
|
17538
|
+
# all unchanged); this only stops an already-verified build from
|
|
17539
|
+
# grinding needless "next improvement" iterations. Scoped to this call.
|
|
17540
|
+
#
|
|
17541
|
+
# CRITICAL (council-review finding): we must PEEK at the claim signal
|
|
17542
|
+
# NON-DESTRUCTIVELY. check_task_completion_signal() CONSUMES the signal
|
|
17543
|
+
# (rm -f on read), and the DEFAULT completion-promise route below
|
|
17544
|
+
# (v6.82.0, the live gate-based acceptance path) also consumes it -- so
|
|
17545
|
+
# calling the consuming detector here would drop the claim before that
|
|
17546
|
+
# route sees it, re-introducing the v7.28 "claim drop" bug. Instead we
|
|
17547
|
+
# only test the signal FILES' existence (the same two paths
|
|
17548
|
+
# check_task_completion_signal reads), leaving consumption to the
|
|
17549
|
+
# existing single owner. The council side likewise peeks
|
|
17550
|
+
# ($TARGET_DIR/.loki/signals/COMPLETION_REQUESTED) without consuming.
|
|
17551
|
+
local _loki_completion_claimed=0
|
|
17552
|
+
if [ -f "${TARGET_DIR:-.}/.loki/signals/TASK_COMPLETION_CLAIMED" ] \
|
|
17553
|
+
|| [ -f "${TARGET_DIR:-.}/.loki/signals/COMPLETION_REQUESTED" ]; then
|
|
17554
|
+
_loki_completion_claimed=1
|
|
17555
|
+
fi
|
|
17556
|
+
if type council_should_stop &>/dev/null && LOKI_COMPLETION_CLAIMED="$_loki_completion_claimed" council_should_stop; then
|
|
17534
17557
|
# bash-F1: council_should_stop returns 0 from a genuine approval
|
|
17535
17558
|
# AND from two force-stop safety valves (stagnation flood /
|
|
17536
17559
|
# repeated done-signals). A force-stop is NOT a verified-complete
|
package/dashboard/__init__.py
CHANGED
package/dashboard/server.py
CHANGED
|
@@ -5007,41 +5007,79 @@ def _sanitize_agent_id(agent_id: str) -> str:
|
|
|
5007
5007
|
)
|
|
5008
5008
|
return agent_id
|
|
5009
5009
|
|
|
5010
|
+
|
|
5011
|
+
# --- Memory file enumeration (single source of truth) ------------------------
|
|
5012
|
+
# v7.104.5 (PR #178 follow-up): the memory store writes episodes and skills into
|
|
5013
|
+
# DATED subdirectories (episodic/YYYY-MM-DD/*.json, skills/*/*.json), so a flat
|
|
5014
|
+
# .glob("*.json") finds nothing and every endpoint that used it under-reported.
|
|
5015
|
+
# PR #178 fixed only /api/memory/summary; the sibling /api/memory/episodes and
|
|
5016
|
+
# the skills listings still used a flat glob, so the count and the drill-in list
|
|
5017
|
+
# disagreed (summary said 28, the list returned 0) -- a trust-eroding
|
|
5018
|
+
# inconsistency. These two helpers are the ONE way to enumerate memory files, so
|
|
5019
|
+
# counts and lists can never diverge again. Both recurse and skip .lock files.
|
|
5020
|
+
def _memory_episode_files(ep_dir) -> list:
|
|
5021
|
+
"""All episode JSON files under episodic/ (recursing dated subdirs), sorted."""
|
|
5022
|
+
try:
|
|
5023
|
+
return sorted(p for p in ep_dir.rglob("*.json") if not p.name.endswith(".lock"))
|
|
5024
|
+
except Exception:
|
|
5025
|
+
return []
|
|
5026
|
+
|
|
5027
|
+
|
|
5028
|
+
def _memory_skill_files(skills_dir) -> list:
|
|
5029
|
+
"""All skill JSON files under skills/ (recursing subdirs), sorted."""
|
|
5030
|
+
try:
|
|
5031
|
+
return sorted(p for p in skills_dir.rglob("*.json") if not p.name.endswith(".lock"))
|
|
5032
|
+
except Exception:
|
|
5033
|
+
return []
|
|
5034
|
+
|
|
5035
|
+
|
|
5010
5036
|
@app.get("/api/memory/summary", dependencies=[Depends(auth.require_scope("read"))])
|
|
5011
5037
|
async def get_memory_summary():
|
|
5012
5038
|
"""Get memory system summary from .loki/memory/."""
|
|
5013
|
-
# Try SQLite backend first for accurate counts
|
|
5039
|
+
# Try SQLite backend first for accurate counts.
|
|
5040
|
+
# NOTE (PR #178, @iizotov): _get_memory_storage() returns a SQLiteMemoryStorage
|
|
5041
|
+
# object whenever the module imports, even if no .db file exists yet. On a
|
|
5042
|
+
# JSON-backed project that yields all-zero stats, so we must NOT return here on
|
|
5043
|
+
# empty counts -- otherwise the JSON file fallback below never runs and the
|
|
5044
|
+
# dashboard shows 0 episodes/patterns/skills even though they exist on disk.
|
|
5045
|
+
# Only trust SQLite when it actually reports data; else fall through to JSON.
|
|
5014
5046
|
storage = _get_memory_storage()
|
|
5015
5047
|
if storage is not None:
|
|
5016
5048
|
try:
|
|
5017
5049
|
stats = storage.get_stats()
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5050
|
+
total = (
|
|
5051
|
+
stats.get("episode_count", 0)
|
|
5052
|
+
+ stats.get("pattern_count", 0)
|
|
5053
|
+
+ stats.get("skill_count", 0)
|
|
5054
|
+
)
|
|
5055
|
+
if total > 0:
|
|
5056
|
+
summary = {
|
|
5057
|
+
"episodic": {"count": stats.get("episode_count", 0), "latestDate": None},
|
|
5058
|
+
"semantic": {"patterns": stats.get("pattern_count", 0), "antiPatterns": 0},
|
|
5059
|
+
"procedural": {"skills": stats.get("skill_count", 0)},
|
|
5060
|
+
"backend": "sqlite",
|
|
5061
|
+
}
|
|
5062
|
+
# Get latest episode date
|
|
5063
|
+
episode_ids = storage.list_episodes(limit=1)
|
|
5064
|
+
if episode_ids:
|
|
5065
|
+
ep = storage.load_episode(episode_ids[0])
|
|
5066
|
+
if ep:
|
|
5067
|
+
summary["episodic"]["latestDate"] = ep.get("timestamp", "")
|
|
5068
|
+
# Token economics from JSON (not in SQLite)
|
|
5069
|
+
econ_file = _get_loki_dir() / "memory" / "token_economics.json"
|
|
5070
|
+
if econ_file.exists():
|
|
5071
|
+
try:
|
|
5072
|
+
econ = json.loads(econ_file.read_text())
|
|
5073
|
+
summary["tokenEconomics"] = {
|
|
5074
|
+
"discoveryTokens": econ.get("discoveryTokens", 0),
|
|
5075
|
+
"readTokens": econ.get("readTokens", 0),
|
|
5076
|
+
"savingsPercent": econ.get("savingsPercent", 0),
|
|
5077
|
+
}
|
|
5078
|
+
except Exception:
|
|
5079
|
+
summary["tokenEconomics"] = {"discoveryTokens": 0, "readTokens": 0, "savingsPercent": 0}
|
|
5080
|
+
else:
|
|
5041
5081
|
summary["tokenEconomics"] = {"discoveryTokens": 0, "readTokens": 0, "savingsPercent": 0}
|
|
5042
|
-
|
|
5043
|
-
summary["tokenEconomics"] = {"discoveryTokens": 0, "readTokens": 0, "savingsPercent": 0}
|
|
5044
|
-
return summary
|
|
5082
|
+
return summary
|
|
5045
5083
|
except Exception:
|
|
5046
5084
|
pass
|
|
5047
5085
|
|
|
@@ -5057,14 +5095,28 @@ async def get_memory_summary():
|
|
|
5057
5095
|
|
|
5058
5096
|
ep_dir = memory_dir / "episodic"
|
|
5059
5097
|
if ep_dir.exists():
|
|
5060
|
-
|
|
5098
|
+
# Episodes are stored under dated subdirectories (episodic/YYYY-MM-DD/*.json),
|
|
5099
|
+
# so a flat glob("*.json") finds nothing (PR #178, @iizotov). Recurse and
|
|
5100
|
+
# ignore .lock files. Shared with /api/memory/episodes via _memory_episode_
|
|
5101
|
+
# files() so the summary count and the drill-in list can never disagree.
|
|
5102
|
+
episodes = _memory_episode_files(ep_dir)
|
|
5061
5103
|
summary["episodic"]["count"] = len(episodes)
|
|
5062
5104
|
if episodes:
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5105
|
+
# latestDate must be the newest by RECORDED TIMESTAMP, not by filename
|
|
5106
|
+
# sort: intra-day filenames carry a hash tiebreak, not a time, so a
|
|
5107
|
+
# filename sort can report the wrong episode (observed ~15h off). Pick
|
|
5108
|
+
# the max parsed timestamp; fall back to the last file only if no
|
|
5109
|
+
# timestamp is readable, so an honest value is preferred over a
|
|
5110
|
+
# confidently-wrong one.
|
|
5111
|
+
latest_ts = ""
|
|
5112
|
+
for _epf in episodes:
|
|
5113
|
+
try:
|
|
5114
|
+
_ts = json.loads(_epf.read_text()).get("timestamp", "")
|
|
5115
|
+
if isinstance(_ts, str) and _ts > latest_ts:
|
|
5116
|
+
latest_ts = _ts
|
|
5117
|
+
except Exception:
|
|
5118
|
+
continue
|
|
5119
|
+
summary["episodic"]["latestDate"] = latest_ts or None
|
|
5068
5120
|
|
|
5069
5121
|
sem_dir = memory_dir / "semantic"
|
|
5070
5122
|
patterns_file = sem_dir / "patterns.json"
|
|
@@ -5084,7 +5136,7 @@ async def get_memory_summary():
|
|
|
5084
5136
|
|
|
5085
5137
|
skills_dir = memory_dir / "skills"
|
|
5086
5138
|
if skills_dir.exists():
|
|
5087
|
-
summary["procedural"]["skills"] = len(
|
|
5139
|
+
summary["procedural"]["skills"] = len(_memory_skill_files(skills_dir))
|
|
5088
5140
|
|
|
5089
5141
|
econ_file = memory_dir / "token_economics.json"
|
|
5090
5142
|
if econ_file.exists():
|
|
@@ -5122,20 +5174,22 @@ async def list_episodes(limit: int = Query(default=50, ge=1, le=1000)):
|
|
|
5122
5174
|
except Exception:
|
|
5123
5175
|
pass
|
|
5124
5176
|
|
|
5125
|
-
# Fallback to JSON files
|
|
5126
|
-
|
|
5177
|
+
# Fallback to JSON files. Enumerate via the shared helper (recurses the
|
|
5178
|
+
# dated subdirs) so this list agrees with /api/memory/summary's count --
|
|
5179
|
+
# the flat glob here was the exact parity gap PR #178's review flagged
|
|
5180
|
+
# (summary said 28, this returned 0). Read each file, then return the
|
|
5181
|
+
# newest `limit` by RECORDED timestamp (not filename, whose intra-day
|
|
5182
|
+
# tiebreak is a hash, not a time).
|
|
5127
5183
|
ep_dir = _get_loki_dir() / "memory" / "episodic"
|
|
5128
|
-
|
|
5184
|
+
loaded = []
|
|
5129
5185
|
if ep_dir.exists():
|
|
5130
|
-
|
|
5131
|
-
# nlargest by filename (timestamps sort lexicographically) avoids full sort
|
|
5132
|
-
files = heapq.nlargest(limit, all_files, key=lambda f: f.name)
|
|
5133
|
-
for f in files:
|
|
5186
|
+
for f in _memory_episode_files(ep_dir):
|
|
5134
5187
|
try:
|
|
5135
|
-
|
|
5188
|
+
loaded.append(json.loads(f.read_text()))
|
|
5136
5189
|
except Exception:
|
|
5137
5190
|
pass
|
|
5138
|
-
|
|
5191
|
+
loaded.sort(key=lambda e: e.get("timestamp", "") if isinstance(e, dict) else "", reverse=True)
|
|
5192
|
+
return loaded[:limit]
|
|
5139
5193
|
|
|
5140
5194
|
return await asyncio.to_thread(_load_episodes)
|
|
5141
5195
|
|
|
@@ -5159,7 +5213,7 @@ async def get_episode(episode_id: str):
|
|
|
5159
5213
|
if not ep_dir.exists():
|
|
5160
5214
|
raise HTTPException(status_code=404, detail="Episode not found")
|
|
5161
5215
|
real_loki = os.path.realpath(str(loki_dir))
|
|
5162
|
-
for f in ep_dir
|
|
5216
|
+
for f in _memory_episode_files(ep_dir):
|
|
5163
5217
|
resolved = os.path.realpath(f)
|
|
5164
5218
|
if not resolved.startswith(real_loki + os.sep) and resolved != real_loki:
|
|
5165
5219
|
raise HTTPException(status_code=403, detail="Access denied")
|
|
@@ -5235,7 +5289,7 @@ async def list_skills():
|
|
|
5235
5289
|
skills_dir = _get_loki_dir() / "memory" / "skills"
|
|
5236
5290
|
skills = []
|
|
5237
5291
|
if skills_dir.exists():
|
|
5238
|
-
for f in
|
|
5292
|
+
for f in _memory_skill_files(skills_dir):
|
|
5239
5293
|
try:
|
|
5240
5294
|
skills.append(json.loads(f.read_text()))
|
|
5241
5295
|
except Exception:
|
|
@@ -5253,7 +5307,7 @@ async def get_skill(skill_id: str):
|
|
|
5253
5307
|
if not skills_dir.exists():
|
|
5254
5308
|
raise HTTPException(status_code=404, detail="Skill not found")
|
|
5255
5309
|
real_loki = os.path.realpath(str(loki_dir))
|
|
5256
|
-
for f in skills_dir
|
|
5310
|
+
for f in _memory_skill_files(skills_dir):
|
|
5257
5311
|
resolved = os.path.realpath(f)
|
|
5258
5312
|
if not resolved.startswith(real_loki + os.sep) and resolved != real_loki:
|
|
5259
5313
|
raise HTTPException(status_code=403, detail="Access denied")
|
|
@@ -5699,11 +5753,7 @@ async def get_memory_stats():
|
|
|
5699
5753
|
ep_count = 0
|
|
5700
5754
|
ep_dir = memory_dir / "episodic"
|
|
5701
5755
|
if ep_dir.exists():
|
|
5702
|
-
|
|
5703
|
-
if d.is_dir():
|
|
5704
|
-
ep_count += len(list(d.glob("*.json")))
|
|
5705
|
-
elif d.suffix == ".json":
|
|
5706
|
-
ep_count += 1
|
|
5756
|
+
ep_count = len(_memory_episode_files(ep_dir))
|
|
5707
5757
|
|
|
5708
5758
|
pat_count = 0
|
|
5709
5759
|
patterns_file = memory_dir / "semantic" / "patterns.json"
|
|
@@ -5717,7 +5767,7 @@ async def get_memory_stats():
|
|
|
5717
5767
|
skill_count = 0
|
|
5718
5768
|
skills_dir = memory_dir / "skills"
|
|
5719
5769
|
if skills_dir.exists():
|
|
5720
|
-
skill_count = len(
|
|
5770
|
+
skill_count = len(_memory_skill_files(skills_dir))
|
|
5721
5771
|
|
|
5722
5772
|
return {
|
|
5723
5773
|
"backend": "json",
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Founder Status + Decision List (2026-07-01)
|
|
2
|
+
|
|
3
|
+
The consolidated "where everything stands + the decisions only you can make" report.
|
|
4
|
+
Written after: 5 patch releases shipped, top-100 backlog enumerated + triaged, ecosystem
|
|
5
|
+
currency assessed, no-HITL product principle recorded.
|
|
6
|
+
|
|
7
|
+
## 1. Shipped this session (all live on npm/Docker/GH, council-gated)
|
|
8
|
+
|
|
9
|
+
| Version | What | Verified |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| v7.104.2 | Native/Keychain Claude login recognized; `loki start` no longer false-blocks a logged-in user; `loki doctor` confirms login (bash+Bun parity) | reproduced + 8-case test + live Docker |
|
|
12
|
+
| v7.104.3 | Task-list accuracy: honest done column, no empty cards / dups / fake-green (failed iters honestly labeled) | live vs real anonima, browser screenshots, council 3/3 |
|
|
13
|
+
| v7.104.4 | `/api/tasks` never 500s on malformed dashboard-state.json | RED/GREEN-proven test |
|
|
14
|
+
| v7.104.5 | Memory panel correct + self-consistent on JSON-backed projects (completes PR #178, @iizotov co-authored, PR closed with thank-you) | live vs anonima, parity tests |
|
|
15
|
+
| (earlier) v7.104.2 auth + v7.104.3 task-list | (same as above; two-patch train) | |
|
|
16
|
+
|
|
17
|
+
Also: closed issue #177 (spam advisory). PR #178 merged-in-substance + contributor thanked.
|
|
18
|
+
|
|
19
|
+
## 2. Backlog reality (honest)
|
|
20
|
+
|
|
21
|
+
The top-100 was enumerated (116 raw -> 100 ranked) and then TRIAGED against current source.
|
|
22
|
+
Key finding: **the autonomous critical/high queue is essentially ALREADY DONE.**
|
|
23
|
+
|
|
24
|
+
| Rank | Item | Triage verdict |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| 1 | run.sh self-delete EXIT trap | already fixed (guarded to /tmp/loki-run-*; verified safe) |
|
|
27
|
+
| 2 | saas cross-tenant leak + stuck-Building | CLOSED (commits a7667d0/44f7c29/8b05b36; 187/187 tests) |
|
|
28
|
+
| 9 | anti-fake-green + gate parity | shipped (verify 282 tests; coherentStatus guard) |
|
|
29
|
+
| 10 | VS-7 worker cutover | CLOSED (commit e6b96ed; BFF 181 + worker 102 tests) |
|
|
30
|
+
| 17 | base_unreachable suppresses empty_diff | already wired (completion-council.sh:1616) |
|
|
31
|
+
| 22 | 3 parallel reviewers | already implemented (run.sh:10461-10954) |
|
|
32
|
+
|
|
33
|
+
The autonomous well is mostly dry BECAUSE the real remaining leverage is founder-gated
|
|
34
|
+
(the trust-as-product / enterprise surface). That is the honest headline: the next 10x is
|
|
35
|
+
not another patch, it is the decisions below.
|
|
36
|
+
|
|
37
|
+
## 3. Ecosystem currency (what loki CONSUMES from the Claude ecosystem)
|
|
38
|
+
|
|
39
|
+
CLI invocation contract (claude 2.1.198): STABLE, no drift. Auth: fixed this session.
|
|
40
|
+
Model catalog: current (opus-4-8, sonnet-5, haiku-4-5, fable-5). Real deltas are small and
|
|
41
|
+
tracked in docs/ECOSYSTEM-CURRENCY-PLAN.json (EC-1..EC-4). Adjacent Anthropic PRODUCTS
|
|
42
|
+
(Managed Agents, Claude Tag, loop-engineering, agent identity) assessed as peer/inspiration
|
|
43
|
+
categories, NOT dependencies -- declined with reason (the CTO triage move).
|
|
44
|
+
|
|
45
|
+
The one real net-new build from this: **EC-1, the external-tool contract adapter + drift
|
|
46
|
+
test** -- the keychain incident this session proves it would catch a user-facing break
|
|
47
|
+
before a user does. Building autonomously now.
|
|
48
|
+
|
|
49
|
+
## 4. DECISIONS ONLY YOU CAN MAKE (founder-gated, prepped to one-approval-away)
|
|
50
|
+
|
|
51
|
+
These are the real blockers to "easiest to integrate with anyone" + the trust-as-product moat.
|
|
52
|
+
Per the no-HITL principle, these are the LEGITIMATE exceptions: irreversible / strategic /
|
|
53
|
+
brand / legal / spend decisions a human must own. Each is ready for a one-word go.
|
|
54
|
+
|
|
55
|
+
### A. Autonomi Verify productization (the trust-as-product core)
|
|
56
|
+
1. **License decision (rank 5, S, BLOCKS everything commercial).** BUSL-1.1 vs open for
|
|
57
|
+
@autonomi/verify. No hosted/commercial launch until decided. DECISION: which license?
|
|
58
|
+
2. **npm registry + package name (rank 4, M).** @autonomi/verify is currently unpublishable
|
|
59
|
+
(private:true, no exports/types/build, .ts bin). And a naming collision exists
|
|
60
|
+
(loki-vaas vs loki-verify bin vs `loki verify` subcommand, rank 13). DECISION: publish to
|
|
61
|
+
public npm as `@autonomi/verify`? Confirm the brand/bin name to resolve the collision.
|
|
62
|
+
-> Once decided, I can make it genuinely npm-installable + fix the collision autonomously.
|
|
63
|
+
3. **Hosted /verify deploy (rank 6, M + rank 36/42 sandbox).** The signed neutral REST
|
|
64
|
+
endpoint is the category-defining asset but not deployed (Bun.serve-only, ephemeral key).
|
|
65
|
+
DECISION: deploy target (Fly/Render/AWS/your infra) + signing-key storage (secret manager)?
|
|
66
|
+
-> I can stage the Node entry + Dockerfile + serve script + 12-factor key guard to
|
|
67
|
+
one-command-deploy; I will NOT deploy or spend without your go.
|
|
68
|
+
4. **wire verifyCompletion() pipeline (rank 3, XL).** The SDK/MCP verdict path is stubbed;
|
|
69
|
+
the whole value prop is unreachable until gate->integrity->council->cost->sign is wired.
|
|
70
|
+
Depends on (2)/(3) decisions. Large; I can start once the license + registry are set.
|
|
71
|
+
|
|
72
|
+
### B. Enterprise scale (needed for any enterprise sale)
|
|
73
|
+
5. **RBAC / SSO / API-key auth / metering (rank 15, XL)** + **on-prem persistence backend
|
|
74
|
+
(rank 16, L, Postgres/SQLite)** + **sandbox backend (rank 14, L, gVisor/Firecracker/Kata)**.
|
|
75
|
+
DECISION: which enterprise deploy shape do we target first (hosted multi-tenant vs on-prem)?
|
|
76
|
+
That choice sequences 14/15/16/36/42. -> I can build the PersistenceBackend interface +
|
|
77
|
+
RBAC scaffolding once you pick the shape.
|
|
78
|
+
6. **GitHub App verification integration (rank 46, L, greenfield).** DECISION: build now or later?
|
|
79
|
+
|
|
80
|
+
### C. Benchmark spend
|
|
81
|
+
7. **SWE-bench Pro 119 resume (issue #174, paused 35/119).** Resume harness exists. DECISION:
|
|
82
|
+
spend the compute to finish? (This is a $ + time decision, hence gated.)
|
|
83
|
+
|
|
84
|
+
### D. Outreach (rank/issue #172, low-risk but external-posting)
|
|
85
|
+
8. MCP registry submission + Glama claim + awesome-list PRs. I can prepare the submissions;
|
|
86
|
+
the actual external POSTS need your nod (per action rules). DECISION: proceed with posts?
|
|
87
|
+
|
|
88
|
+
## 5. What I am doing autonomously RIGHT NOW (no decision needed)
|
|
89
|
+
- EC-1 external-contract adapter + drift test (the one real net-new build).
|
|
90
|
+
- Small no-HITL audit: find every place the PRODUCT hard-stops/prompts a human; fix genuine
|
|
91
|
+
gaps so it decides from model+memory+cross-project context (degrading to honest-inconclusive,
|
|
92
|
+
never fake-green). Not a speculative refactor -- a triage + targeted fixes.
|
|
93
|
+
- NOT building: dashboard steering (#44) -- it is a human-in-the-loop feature, deprioritized by
|
|
94
|
+
the no-HITL mandate; architect plan is durable and waits. NOT building "autonomous-everywhere"
|
|
95
|
+
as a speculative refactor.
|
|
96
|
+
|
|
97
|
+
## 6. The one-line asks
|
|
98
|
+
Reply with any subset:
|
|
99
|
+
- **License:** BUSL / MIT / Apache / other for @autonomi/verify
|
|
100
|
+
- **npm:** publish `@autonomi/verify` publicly? + confirm bin name (resolve loki-verify collision)
|
|
101
|
+
- **Hosted deploy:** target + key storage (or "not yet")
|
|
102
|
+
- **Enterprise shape:** hosted-multitenant-first vs on-prem-first (sequences the enterprise stories)
|
|
103
|
+
- **SWE-bench:** spend to finish 119? (yes/no)
|
|
104
|
+
- **Outreach:** post the MCP-registry/Glama/awesome-list submissions? (yes/no)
|
|
105
|
+
|
|
106
|
+
Everything else, I continue autonomously.
|
package/docs/INSTALLATION.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The flagship product of [Autonomi](https://www.autonomi.dev/). Loki Mode is a spec-driven autonomous builder with a built-in trust layer that takes any spec to a deployed product and verifies completion with evidence (quality gates plus a completion council), not just a "done" claim. Complete installation instructions for all platforms and use cases.
|
|
4
4
|
|
|
5
|
-
**Version:** v7.
|
|
5
|
+
**Version:** v7.105.0
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Loki Build Speed Diagnosis (2026-07-01)
|
|
2
|
+
|
|
3
|
+
Measured from real build telemetry (anonima `.loki/events.jsonl`, stage_complete +
|
|
4
|
+
iteration timeline), NOT from reading run.sh. Method per advisor: measure before optimizing.
|
|
5
|
+
|
|
6
|
+
## Data hygiene
|
|
7
|
+
anonima's events.jsonl contained **9 interleaved builds/sessions** (9 session_starts) plus
|
|
8
|
+
session-long manual poking. Naive sums ("5 min/iter x 14") are contaminated. Split on
|
|
9
|
+
session_start and analyzed the real ones.
|
|
10
|
+
|
|
11
|
+
## The pathological build (session 3): the smoking gun
|
|
12
|
+
A simple topic-based chat app. 14 ACT iterations, ~97 min of real work (idle gaps excluded).
|
|
13
|
+
|
|
14
|
+
| iteration | real work |
|
|
15
|
+
|---|---|
|
|
16
|
+
| 1 | 2.1 min |
|
|
17
|
+
| 6 | 9.9 min |
|
|
18
|
+
| 10 | 15.3 min |
|
|
19
|
+
| 12 | **29.6 min** |
|
|
20
|
+
| (others) | 3-6 min each |
|
|
21
|
+
|
|
22
|
+
**13 completion claims across 14 iterations.** The FIRST claim already stated:
|
|
23
|
+
"All PRD requirements implemented and tests passing. Evidence: npm test => 19/19 pass...
|
|
24
|
+
PRD checklist (14 items) fully implemented." Yet the loop ran 13 more iterations.
|
|
25
|
+
|
|
26
|
+
## Root cause: NON-CONVERGENCE, not per-stage slowness
|
|
27
|
+
- **Code review / 3-reviewer council is NOT the bottleneck** (0.1-2.8 min per iteration,
|
|
28
|
+
mostly <1 min). Cutting the council would harm accuracy for ~no speed gain. Ruled out.
|
|
29
|
+
- **The bottleneck is iteration COUNT + a few pathological iterations.** The app was
|
|
30
|
+
essentially done early (real passing tests, checklist complete) but the RARV loop's
|
|
31
|
+
"there is NEVER a finished state -- always find the next improvement" behavior kept it
|
|
32
|
+
grinding polish iterations. For a user who wants a fullstack app fast, this is THE
|
|
33
|
+
frustration: loki keeps going after done.
|
|
34
|
+
- iter 10 (15 min) and iter 12 (30 min) did disproportionate work -- candidate over-scoping
|
|
35
|
+
or re-analysis; needs per-iteration content inspection.
|
|
36
|
+
|
|
37
|
+
## Buckets (advisor framework)
|
|
38
|
+
1. **WASTE (cut freely):** polish iterations after genuine completion; the PRD-reuse
|
|
39
|
+
spurious-update re-reconciliation (already diagnosed, design fix pending). These add
|
|
40
|
+
wall-clock with no trust value.
|
|
41
|
+
2. **VERIFICATION COST (keep -- this is the product):** council, gates, completion vote.
|
|
42
|
+
Fast already. The moat. Do NOT cut for speed.
|
|
43
|
+
3. **STALE SCAFFOLDING (test per-stage):** machinery built for weaker models may be dead
|
|
44
|
+
weight on Opus 4.8 / Sonnet 5 (cf. Anthropic's "context resets became dead weight on
|
|
45
|
+
Opus 4.5"). Hypothesis -- must be tested against the benchmark, not assumed.
|
|
46
|
+
|
|
47
|
+
## The fix direction (speed AND accuracy, never speed-by-cutting-verification)
|
|
48
|
+
**Convergence:** stop as soon as the completion council genuinely agrees it is done
|
|
49
|
+
(honest verified completion), instead of running "next improvement" iterations. This is a
|
|
50
|
+
SPEED win that INCREASES trust alignment (stop when verified-done = the moat working), not a
|
|
51
|
+
verification cut. The user's mandate is "accuracy AND speed"; convergence delivers both.
|
|
52
|
+
|
|
53
|
+
## HARD PREREQUISITE (before any council/RARV-C change): the benchmark
|
|
54
|
+
Both the speed directive and the "update council/RARV-C to latest research, show before/after
|
|
55
|
+
accuracy" directive require a **clean reproducible benchmark on a fixed spec** emitting
|
|
56
|
+
wall-clock + iteration count + completion verdict + pass/fail vs known acceptance criteria.
|
|
57
|
+
Without it, changing the verification core is unmeasurable churn on the moat (architecture-
|
|
58
|
+
level fake-green). Build the benchmark FIRST, capture before-numbers, fix the clearest waste
|
|
59
|
+
(convergence), re-run, show real before->after. Then gate any council/RARV-C change on that
|
|
60
|
+
benchmark, one named change at a time, kept only if accuracy goes up and wall-clock does not
|
|
61
|
+
regress.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Loki + Autonomi: Top-100 Backlog (Master Plan)
|
|
2
|
+
|
|
3
|
+
Generated 2026-07-01 by the top100-backlog-enumeration ultracode workflow (7 agents, 116 raw items -> 100 ranked). North star: easiest to integrate with anyone; ranked by leverage toward zero-friction adoption, modularization, enterprise-grade, and scale.
|
|
4
|
+
|
|
5
|
+
## Themes
|
|
6
|
+
- Trust and correctness bugs (data-loss, cross-tenant, fake-green safety)
|
|
7
|
+
- Autonomi Verify productization (stub -> shipped: gate/council/cost/sign wiring)
|
|
8
|
+
- Zero-friction adoption (reduce user setup and error surface)
|
|
9
|
+
- Modularization (extract libraries, break monoliths, fix import boundaries)
|
|
10
|
+
- Enterprise-scale and multi-tenant (RBAC/SSO/persistence/sandbox, mostly founder-gated)
|
|
11
|
+
- autonomi-saas evidence and proof pipeline (receipt phases, correlation, worker cutover)
|
|
12
|
+
- CI, test, and distribution hardening (coverage, unreachable tests, publish gates)
|
|
13
|
+
- Runtime-agnostic and Bun migration (bash sunset, write-path port)
|
|
14
|
+
|
|
15
|
+
## Legend
|
|
16
|
+
- **gate**: autonomous (I execute) | founder-gated (prep to one-approval-away) | community
|
|
17
|
+
- **effort**: S/M/L/XL | **value**: critical/high/medium/low
|
|
18
|
+
|
|
19
|
+
## Full ranked list
|
|
20
|
+
|
|
21
|
+
| # | value | eff | gate | area | item |
|
|
22
|
+
|---|---|---|---|---|---|
|
|
23
|
+
| 1 | critical | S | autonomous | engine | run.sh self-delete EXIT trap nukes canonical source on LOKI_RUNNING_FROM_TEMP |
|
|
24
|
+
| 2 | critical | M | autonomous | saas | autonomi-saas proof correlation: cross-tenant leak + stuck-Building fix (per-build run_id) |
|
|
25
|
+
| 3 | critical | XL | founder-gated | verify | Verify: verifyCompletion() stub throws not-implemented (wire gate->integrity->council->cost->sign pipeline) |
|
|
26
|
+
| 4 | critical | M | founder-gated | verify | Verify: npm @autonomi/verify unpublishable (private:true, no exports/types/build, .ts bin, undeclared zod) |
|
|
27
|
+
| 5 | critical | S | founder-gated | saas | Verify: BUSL-1.1 vs open licensing undecided (blocks hosted/commercial launch) |
|
|
28
|
+
| 6 | critical | M | founder-gated | saas | Verify: hosted /verify REST API not deployed (Node entry + Dockerfile + serve script + persistent signing key) |
|
|
29
|
+
| 7 | critical | M | autonomous | modularization | Verify: extract verification-core library (port council_evidence_gate to TS) |
|
|
30
|
+
| 8 | critical | S | autonomous | verify | Verify: 5 deterministic gates parity with completion-council.sh (staged, verify + ship) |
|
|
31
|
+
| 9 | critical | S | autonomous | saas | autonomi-saas anti-fake-green safety: verdict strictly from engine honesty.headline (verify + guard) |
|
|
32
|
+
| 10 | critical | M | autonomous | saas | autonomi-saas VS-7 worker cutover: BFF enqueues, worker sole executor (verify live e2e) |
|
|
33
|
+
| 11 | high | M | founder-gated | verify | Signed neutral records on SDK/MCP path (verifyCompletion returns UNSIGNED_SENTINEL; only REST signs) |
|
|
34
|
+
| 12 | medium | S | autonomous | verify | Verify: fix embed import boundary (review/* drags LLM council into offline core; refresh regresses) |
|
|
35
|
+
| 13 | high | S | founder-gated | verify | Verify: resolve naming collision (loki-vaas vs loki-verify bin vs loki verify subcommand) |
|
|
36
|
+
| 14 | critical | L | founder-gated | engine | Sandbox backend implementation (createSandbox throws; choose gVisor/Firecracker/Kata) |
|
|
37
|
+
| 15 | critical | XL | founder-gated | enterprise | Enterprise RBAC / SSO / API-key auth / metering (hosted + on-prem control plane) |
|
|
38
|
+
| 16 | high | L | founder-gated | enterprise | On-prem persistence backend interface + first prod store (Postgres/SQLite) |
|
|
39
|
+
| 17 | high | S | autonomous | engine | base_unreachable signal in ObservedDiff (suppress empty_diff false-block once sandbox lands) |
|
|
40
|
+
| 18 | high | M | founder-gated | engine | Real Anthropic LLM provider wiring for production verify (council against live model) |
|
|
41
|
+
| 19 | high | M | founder-gated | verify | Verify: LLM council wired into default verdict path (module exists, verifyCompletion stub does not invoke) |
|
|
42
|
+
| 20 | high | S | autonomous | engine | Signed verification records + ed25519 audit trail (staged, verify + ship) |
|
|
43
|
+
| 21 | high | M | autonomous | verify | Golden-output conformance corpus for byte-identical CLI-invariance across implementations |
|
|
44
|
+
| 22 | high | M | autonomous | engine | Code review gate: run 3 parallel reviewers (currently single-reviewer path) |
|
|
45
|
+
| 23 | high | S | founder-gated | saas | HTTP /verify endpoint production wiring (handler complete, README lists as planned) |
|
|
46
|
+
| 24 | high | S | autonomous | saas | MCP verify tools (verify_completion, run_evidence_gate) wiring + distribution (staged) |
|
|
47
|
+
| 25 | high | M | community | test | Memory failure-loop (FAILURE_MEMORY) persistence bug (strict-xfail; recency read incomplete) |
|
|
48
|
+
| 26 | high | XL | autonomous | engine | Bun runtime Phase 2: migrate write-path commands (feat/bun-migration) |
|
|
49
|
+
| 27 | high | M | autonomous | cli | Bash runtime sunset (loki run-shell removal, Phase 6, after clean soak) |
|
|
50
|
+
| 28 | high | M | community | saas | autonomi-saas Evidence Receipt Phase 2: screenshot capture + BFF stream route (in progress) |
|
|
51
|
+
| 29 | high | M | community | saas | autonomi-saas Evidence Receipt Phase 3: test results from engine workspace |
|
|
52
|
+
| 30 | high | L | autonomous | saas | autonomi-saas Cost tab + budget-breaker UX (web + enforcement audit) |
|
|
53
|
+
| 31 | high | S | community | saas | autonomi-saas BFF overlays stored saas_evidence onto engine proof (verify) |
|
|
54
|
+
| 32 | medium | M | founder-gated | saas | E4 no-server run output capture for CLI/library builds (bounded inline + artifact) |
|
|
55
|
+
| 33 | high | M | autonomous | dashboard | Prompt Optimizer: wire real LLM-as-judge (currently heuristic-only) |
|
|
56
|
+
| 34 | high | M | community | engine | Cost-honesty check implementation (normalizeModel + quote==dispatched) |
|
|
57
|
+
| 35 | high | S | community | saas | POST /cost-honesty API handler (blocked on cost core) |
|
|
58
|
+
| 36 | critical | L | founder-gated | saas | Hosted metered runner with per-verification container sandbox |
|
|
59
|
+
| 37 | high | M | community | ci | CI parity-matrix flake root-cause (state cooldown after test-cli-commands.sh) |
|
|
60
|
+
| 38 | high | M | community | ci | Post-release smoke sign-off gate before npm/Docker go public |
|
|
61
|
+
| 39 | high | M | community | test | Document the 3 pre-existing failing shell tests (no public known-failures list) |
|
|
62
|
+
| 40 | medium | S | autonomous | dashboard | PR #178: dashboard memory summary reports 0 on JSON-backed projects |
|
|
63
|
+
| 41 | high | M | community | test | ARM64 runtime verification (emulation-only in CI; needs real Apple Silicon run) |
|
|
64
|
+
| 42 | high | XL | founder-gated | saas | Multi-tenant sandbox backend (gVisor/Firecracker/Kata) selection spike |
|
|
65
|
+
| 43 | critical | L | community | test | Real provider end-to-end tests (cost + secrets + duration make CI-unreachable) |
|
|
66
|
+
| 44 | high | XL | founder-gated | enterprise | Enterprise deploy: object-store sync + queue fleet modes + #691 --config loader |
|
|
67
|
+
| 45 | high | M | founder-gated | enterprise | Compliance scanner (loki-verify) converged as module in trust-layer SKU |
|
|
68
|
+
| 46 | high | L | founder-gated | saas | GitHub App verification integration (webhook wrapper, greenfield) |
|
|
69
|
+
| 47 | high | L | community | test | Long-duration stress tests (leak/queue-churn) unreachable in CI |
|
|
70
|
+
| 48 | medium | L | community | saas | autonomi-saas Evidence Receipt Phase 4: clip + full test-log streaming + build_artifacts table |
|
|
71
|
+
| 49 | high | XL | community | test | SWE-bench Pro 119 resume (paused 35/119) |
|
|
72
|
+
| 50 | medium | M | autonomous | engine | Multi-reviewer completion council option in hosted verify (council:true dropped today) |
|
|
73
|
+
| 51 | medium | M | autonomous | engine | Integrity detectors (mock-only, tautological, test-weakening) wired into evidence block |
|
|
74
|
+
| 52 | medium | S | community | test | Bun test coverage threshold enforcement on branches (70% baseline exists) |
|
|
75
|
+
| 53 | medium | L | autonomous | dashboard | Dashboard mid-run steering / builder control (mid-flight model switch exists, broader control deferred) |
|
|
76
|
+
| 54 | medium | S | community | test | Dashboard static-asset freshness gate in local-ci (like loki-ts/dist) |
|
|
77
|
+
| 55 | medium | L | community | test | Windows/WSL runtime verification (no Windows CI runner) |
|
|
78
|
+
| 56 | low | M | autonomous | cli | KPI reporting (loki report kpis) on bash legacy route (Bun-only today) |
|
|
79
|
+
| 57 | medium | M | autonomous | cli | Voice mode (Issue #85) |
|
|
80
|
+
| 58 | medium | M | community | test | Mutation testing (stryker) workflow re-enable + fix stale 5-provider assertions |
|
|
81
|
+
| 59 | medium | XL | founder-gated | engine | Managed Agents multiagent path (LOKI_EXPERIMENTAL_MANAGED_*, research preview) |
|
|
82
|
+
| 60 | low | M | autonomous | engine | Sentrux iteration-loop auto-gating (manual-only today) |
|
|
83
|
+
| 61 | medium | S | founder-gated | adoption | npm registry publish prep for @autonomi/verify SDK (distribution wiring) |
|
|
84
|
+
| 62 | low | M | founder-gated | adoption | Disclosed default-on PostHog telemetry (Phase L, blocked + deferred) |
|
|
85
|
+
| 63 | medium | S | community | saas | MCP check_cost_honesty tool registration (deferred until cost core lands) |
|
|
86
|
+
| 64 | medium | L | founder-gated | dashboard | Hosted dashboard with shareable verification badges |
|
|
87
|
+
| 65 | medium | M | founder-gated | adoption | MCP registry submission + Glama claim + awesome-list PRs |
|
|
88
|
+
| 66 | medium | M | autonomous | saas | autonomi-saas UI/UX pass: build-watching pane + finished cues from trust verdict |
|
|
89
|
+
| 67 | medium | XL | autonomous | dashboard | Server.py route modularization (~10K-line monolith, no domain separation) |
|
|
90
|
+
| 68 | medium | L | autonomous | dashboard | Large dashboard-ui components modularization (5 files 1K-1.9K lines) |
|
|
91
|
+
| 69 | medium | L | founder-gated | engine | Wave-13 deferred trust fixes + PRD-reuse spurious-update design fix |
|
|
92
|
+
| 70 | medium | M | community | dashboard | Dashboard dark-toggle iframe theme not following SPA (harness/product parity) |
|
|
93
|
+
| 71 | medium | M | community | ci | Sonnet-5 calibration follow-ups: test-verify --hosted + gate missing-tool handling |
|
|
94
|
+
| 72 | medium | S | community | ci | Integrity audit (SBOM/provenance) blocking on publish (currently informational) |
|
|
95
|
+
| 73 | medium | S | community | distribution | Python SDK version pre-check before publish (mismatch risk if publish fails post-tag) |
|
|
96
|
+
| 74 | medium | S | community | ci | Docker buildx early-detection for uncommitted loki-ts/dist (silent COPY failure risk) |
|
|
97
|
+
| 75 | medium | S | community | ci | loki-enterprise workflow enabled in main CI (dispatch-only today) |
|
|
98
|
+
| 76 | medium | S | community | distribution | Brew tap real-install verification on clean macOS host post-release |
|
|
99
|
+
| 77 | low | L | founder-gated | perf | Horizontal scaling / distributed rate-limit + persistence (in-memory today) |
|
|
100
|
+
| 78 | low | S | community | saas | Optional build_artifacts table for enumeration/lifecycle/reaping (deferred) |
|
|
101
|
+
| 79 | medium | S | community | saas | Headless browser (playwright-core) dep + Docker image size cap for screenshot capture |
|
|
102
|
+
| 80 | low | M | community | engine | Wave-8/9 deferred tail: spawn_timeout removal, heredoc guards, MED/LOW findings |
|
|
103
|
+
| 81 | medium | L | community | adoption | v7.19.1 traction: uncertainty-gated escalation + shareable proof + integrate 8 tutorials |
|
|
104
|
+
| 82 | medium | M | autonomous | verify | Benchmarks HumanEval/SWE-bench: publish results (runners + datasets exist) |
|
|
105
|
+
| 83 | low | S | autonomous | cli | loki run removal (deprecated alias for loki start, next major) |
|
|
106
|
+
| 84 | low | S | autonomous | cli | Fable model tier wiring (collapses to Opus until API-available) |
|
|
107
|
+
| 85 | low | S | community | distribution | Homepage/blog release update automation (Slack-notify-only today) |
|
|
108
|
+
| 86 | low | S | community | distribution | Wiki-sync scheduled trigger (manual/dispatch only, skips without API key) |
|
|
109
|
+
| 87 | low | L | autonomous | dashboard | Dashboard React app: implement four stub views (experimental app) |
|
|
110
|
+
| 88 | low | S | community | test | Embeddings edge-case tests run without numpy (skip today) |
|
|
111
|
+
| 89 | low | S | community | test | Hybrid-search test runs without chromadb skip |
|
|
112
|
+
| 90 | low | S | community | test | PID-recycling test platform-portability (ps lstart skip for pid 1) |
|
|
113
|
+
| 91 | low | S | community | test | Cloud integration tests (aider-cloud) run in a credentialed gated job |
|
|
114
|
+
| 92 | low | S | community | test | Sentrux real-binary nightly promoted from best-effort to tracked |
|
|
115
|
+
| 93 | low | S | community | test | Model-catalog probe: surface staleness in tests (issue-create skipped without admin scope) |
|
|
116
|
+
| 94 | low | S | community | test | Phase 6 readiness check re-enable (cron disabled; issues disabled on repo) |
|
|
117
|
+
| 95 | low | S | community | distribution | TS/Bun SDK (@loki-mode/sdk) discoverability from main package/docs |
|
|
118
|
+
| 96 | low | S | community | distribution | Docker Hub description update resilience (PAT scope failures non-blocking) |
|
|
119
|
+
| 97 | low | S | community | distribution | VS Code extension: keep source marked deprecated, not silently removed |
|
|
120
|
+
| 98 | low | S | autonomous | dashboard | Web-app docs: fill video placeholder (coming-soon text) |
|
|
121
|
+
| 99 | low | M | autonomous | cli | C# provider support (roslyn analyzers + dotnet build, deferred) |
|
|
122
|
+
| 100 | low | XL | founder-gated | engine | BMAD-METHOD v6 integration (net-new, needs founder planning) |
|
package/loki-ts/dist/loki.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var X8=Object.defineProperty;var K8=($)=>$;function q8($,Q){this[$]=K8.bind(null,Q)}var b=($,Q)=>{for(var Z in Q)X8($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:q8.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var J$=import.meta.require;var v1={};b(v1,{lokiDir:()=>P,homeLokiDir:()=>T$,findRepoRootForVersion:()=>e$,REPO_ROOT:()=>h});import{resolve as r,dirname as i$}from"path";import{fileURLToPath as J8}from"url";import{existsSync as x$}from"fs";import{homedir as V8}from"os";function W8(){let $=y1;for(let Q=0;Q<6;Q++){if(x$(r($,"VERSION"))&&x$(r($,"autonomy/run.sh")))return $;let Z=i$($);if(Z===$)break;$=Z}return r(y1,"..","..","..")}function e$($){let Q=$;for(let Z=0;Z<6;Z++){if(x$(r(Q,"VERSION"))&&x$(r(Q,"autonomy/run.sh")))return Q;let z=i$(Q);if(z===Q)break;Q=z}return r($,"..","..","..")}function P(){return process.env.LOKI_DIR??r(process.cwd(),".loki")}function T$(){return r(V8(),".loki")}var y1,h;var C=L(()=>{y1=i$(J8(import.meta.url));h=W8()});import{readFileSync as U8}from"fs";import{resolve as H8,dirname as G8}from"path";import{fileURLToPath as B8}from"url";function N$(){if(Q$!==null)return Q$;let $="7.
|
|
2
|
+
var X8=Object.defineProperty;var K8=($)=>$;function q8($,Q){this[$]=K8.bind(null,Q)}var b=($,Q)=>{for(var Z in Q)X8($,Z,{get:Q[Z],enumerable:!0,configurable:!0,set:q8.bind(Q,Z)})};var L=($,Q)=>()=>($&&(Q=$($=0)),Q);var J$=import.meta.require;var v1={};b(v1,{lokiDir:()=>P,homeLokiDir:()=>T$,findRepoRootForVersion:()=>e$,REPO_ROOT:()=>h});import{resolve as r,dirname as i$}from"path";import{fileURLToPath as J8}from"url";import{existsSync as x$}from"fs";import{homedir as V8}from"os";function W8(){let $=y1;for(let Q=0;Q<6;Q++){if(x$(r($,"VERSION"))&&x$(r($,"autonomy/run.sh")))return $;let Z=i$($);if(Z===$)break;$=Z}return r(y1,"..","..","..")}function e$($){let Q=$;for(let Z=0;Z<6;Z++){if(x$(r(Q,"VERSION"))&&x$(r(Q,"autonomy/run.sh")))return Q;let z=i$(Q);if(z===Q)break;Q=z}return r($,"..","..","..")}function P(){return process.env.LOKI_DIR??r(process.cwd(),".loki")}function T$(){return r(V8(),".loki")}var y1,h;var C=L(()=>{y1=i$(J8(import.meta.url));h=W8()});import{readFileSync as U8}from"fs";import{resolve as H8,dirname as G8}from"path";import{fileURLToPath as B8}from"url";function N$(){if(Q$!==null)return Q$;let $="7.105.0";if(typeof $==="string"&&$.length>0)return Q$=$,Q$;try{let Q=G8(B8(import.meta.url)),Z=e$(Q);Q$=U8(H8(Z,"VERSION"),"utf-8").trim()}catch{Q$="unknown"}return Q$}var Q$=null;var $1=L(()=>{C()});var c1={};b(c1,{runOrThrow:()=>x8,run:()=>F,readStreamCapped:()=>u1,commandVersion:()=>S8,commandExists:()=>f,ShellError:()=>Q1,MAX_STDOUT_BYTES:()=>f1});async function u1($,Q=f1){let Z=$.getReader(),z=new TextDecoder,X="",q=0;try{while(q<Q){let{done:K,value:W}=await Z.read();if(K)break;if(!W)continue;if(q+=W.byteLength,q>Q){let V=W.byteLength-(q-Q);X+=z.decode(W.subarray(0,V),{stream:!0});break}X+=z.decode(W,{stream:!0})}X+=z.decode()}finally{try{await Z.cancel()}catch{}Z.releaseLock()}return X}async function F($,Q={}){let Z=Bun.spawn({cmd:[...$],stdout:"pipe",stderr:"pipe",env:Q.env?{...process.env,...Q.env}:process.env,cwd:Q.cwd}),z,X;if(Q.timeoutMs&&Q.timeoutMs>0)z=setTimeout(()=>{try{Z.kill("SIGTERM")}catch{}X=setTimeout(()=>{try{Z.kill("SIGKILL")}catch{}},2000)},Q.timeoutMs);try{let[q,K,W]=await Promise.all([u1(Z.stdout),new Response(Z.stderr).text(),Z.exited]);return{stdout:q,stderr:K,exitCode:W}}finally{if(z)clearTimeout(z);if(X)clearTimeout(X)}}async function x8($,Q={}){let Z=await F($,Q);if(Z.exitCode!==0)throw new Q1(`command failed (${Z.exitCode}): ${$.join(" ")}`,Z.exitCode,Z.stdout,Z.stderr);return Z}async function f($){let Q=N8($),Z=await F(["sh","-c",`command -v ${Q}`],{timeoutMs:5000});if(Z.exitCode===0)return Z.stdout.trim()||null;return null}function N8($){if(!/^[A-Za-z0-9._/-]+$/.test($))throw Error(`refused to shell-escape suspect token: ${$}`);return $}async function S8($,Q="--version"){if(!await f($))return null;let z=await F([$,Q],{timeoutMs:5000});if(z.exitCode!==0)return null;return((z.stdout||z.stderr).split(/\r?\n/)[0]?.trim()??"")||null}var f1=16777216,Q1;var d=L(()=>{Q1=class Q1 extends Error{message;exitCode;stdout;stderr;constructor($,Q,Z,z){super($);this.message=$;this.exitCode=Q;this.stdout=Z;this.stderr=z;this.name="ShellError"}}});function t($){return D8?"":$}var D8,T,S,_,nZ,I,k,y,J;var c=L(()=>{D8=(process.env.NO_COLOR??"").length>0;T=t("\x1B[0;31m"),S=t("\x1B[0;32m"),_=t("\x1B[1;33m"),nZ=t("\x1B[0;34m"),I=t("\x1B[0;36m"),k=t("\x1B[1m"),y=t("\x1B[2m"),J=t("\x1B[0m")});import{existsSync as c8}from"fs";async function Z$(){if(A$!==void 0)return A$;let $="/opt/homebrew/bin/python3.12";if(c8($))return A$=$,$;let Q=await f("python3.12");if(Q)return A$=Q,Q;let Z=await f("python3");return A$=Z,Z}async function z$($,Q={}){let Z=await Z$();if(!Z)return{stdout:"",stderr:"python3 not found",exitCode:127};return F([Z,"-c",$],Q)}var A$;var V$=L(()=>{d()});var J0={};b(J0,{runStatus:()=>U3});import{existsSync as v,readFileSync as U$,readdirSync as e1,statSync as $0}from"fs";import{resolve as D,basename as Q3}from"path";import{homedir as Z3}from"os";function Q0($){let Q=Math.trunc($);if(Q>=1e6)return`${(Math.trunc(Q/1e6*10)/10).toFixed(1)}M`;if(Q>=1000)return`${(Math.trunc(Q/1000*10)/10).toFixed(1)}K`;return String(Q)}function Z0($,Q,Z){if(Q===0)return null;let z=Math.trunc($*100/Q),X=Math.trunc($*D$/Q);if(X>D$)X=D$;let q=D$-X,K=S;if(z>=80)K=T;else if(z>=50)K=_;let W="=".repeat(Math.max(0,X))+" ".repeat(Math.max(0,q)),V=Q0($),U=Q0(Q);return` ${k}${Z}${J} ${K}[${W}]${J} ${z}% (${V} / ${U})`}async function X3(){if(await f("jq"))return!0;return process.stdout.write(`${T}Error: jq is required but not installed.${J}
|
|
3
3
|
`),process.stdout.write(`Install with:
|
|
4
4
|
`),process.stdout.write(` brew install jq (macOS)
|
|
5
5
|
`),process.stdout.write(` apt install jq (Debian/Ubuntu)
|
|
@@ -805,4 +805,4 @@ Set LOKI_LEGACY_BASH=1 to force the bash CLI for every command.
|
|
|
805
805
|
`),2}default:return process.stderr.write(`Unknown command: ${Q}
|
|
806
806
|
`),process.stderr.write(z8),2}}i1();process.on("SIGINT",()=>process.exit(130));process.on("SIGTERM",()=>process.exit(143));var EZ=await RZ(Bun.argv.slice(2));process.exit(EZ);
|
|
807
807
|
|
|
808
|
-
//# debugId=
|
|
808
|
+
//# debugId=80BB634E7BCAD6EC64756E2164756E21
|
package/mcp/__init__.py
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loki-mode",
|
|
3
3
|
"mcpName": "io.github.asklokesh/loki-mode",
|
|
4
|
-
"version": "7.
|
|
4
|
+
"version": "7.105.0",
|
|
5
5
|
"description": "Loki Mode by Autonomi. Autonomous spec-to-product system: takes a PRD, GitHub issue, OpenAPI/JSON/YAML, or one-line brief to a deployed app via the RARV-C closure loop with 8 quality gates. Provider-agnostic (Claude Code, OpenAI Codex, Cline, Aider).",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"agent",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "loki-mode",
|
|
4
4
|
"displayName": "Loki Mode",
|
|
5
|
-
"version": "7.
|
|
5
|
+
"version": "7.105.0",
|
|
6
6
|
"description": "Autonomous spec-to-product build system with a built-in trust layer (RARV-C closure loop, 8 quality gates, completion council). Ships Loki's spec-hardening, drift-detection, and deterministic PR verification commands plus the Loki MCP server.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Autonomi",
|