loki-mode 9.56.0 → 9.57.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.57.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.57.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 9.56.0
1
+ 9.57.0
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.57.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.
@@ -0,0 +1,157 @@
1
+ # Release checklist and local CI
2
+
3
+ Moved out of CLAUDE.md (S-78) to keep the root file short. Updated in this
4
+ pass to remove two items that `docs/v10/DECISIONS.md` D25 and
5
+ `docs/LOKI-10-BUILD-PROMPT.md` section 1 have superseded:
6
+ - `git add -A` in step 4 is replaced with staging by name (repo rule, always).
7
+ - Per-merge pushing is replaced by the release-train model (D25): batch
8
+ approved merges locally, push once per train, freeze main until Tests, Bun
9
+ Parity and Security Audit are all green on that exact SHA, then release.
10
+ "Wait for user approval before commit" from the old workflow is superseded
11
+ by the standing authorization in `docs/LOKI-10-BUILD-PROMPT.md` section 1
12
+ for sessions operating under that program; outside it, ask as normal.
13
+
14
+ ## Local CI Before Every Push
15
+
16
+ **The FAST tier is the release gate. The FULL tier is not a blocker.**
17
+
18
+ Founder decision 2026-07-31: GitHub CI runs Tests in ~31s and Release in ~2min
19
+ via 4-way sharding. The local FULL tier takes ~27min with no sharding, too
20
+ slow for an hourly-or-faster release cadence.
21
+
22
+ - **Before push/release: `bash scripts/local-ci.sh`** (fast tier, default).
23
+ - **Do NOT block a release on `LOCAL_CI_TIER=full`.** Ship, let GitHub Actions
24
+ verify, and fix what it finds in the next release train.
25
+ - Run the FULL tier when diagnosing something specific, or on a quiet cycle,
26
+ not as a release precondition.
27
+
28
+ **Why the fast tier and not nothing.** Of seven real defects found on
29
+ 2026-07-31, four were caught by the local gate ALONE. The sharpest is dist
30
+ freshness: CI never validates that the committed `loki-ts/dist/loki.js`
31
+ matches src; when that slipped, three releases shipped the wrong version.
32
+
33
+ **The packaged artifact is the blind spot (2026-08-01).** Everything works
34
+ from a git checkout, so no in-repo test and no GitHub CI job can see:
35
+ - quality-gate detector test files missing from npm's `files[]` (v8.38.0)
36
+ - committed `dist/loki.js` hardcoded to a stale version for 27 releases (v8.40.0)
37
+ - `npm pack` content checks that tolerate losing required artifacts (v9.11.0)
38
+
39
+ Rules that generalize past packaging:
40
+ 1. A check that guards the shipped artifact must run in the FAST tier.
41
+ 2. Assert each required thing individually, never a count.
42
+ 3. Guard against vacuity (an empty capture that makes every assertion pass;
43
+ `npm pack`'s listing is on STDERR).
44
+
45
+ `LOCAL_CI_SHARDS` (default 4) controls local sharding; `LOCAL_CI_SERIAL=1`
46
+ forces serial for diagnosis.
47
+
48
+ After a release ships, run post-release distribution validation:
49
+ - npm: `npm pack loki-mode@<VERSION>`, untar, run `bash package/bin/loki version`
50
+ - Docker: `docker pull asklokesh/loki-mode:<VERSION>`, `docker run --rm <img> version`,
51
+ `doctor --json`, `status --json`
52
+ - Brew: WebFetch the live formula, verify version + sha256
53
+ - Both routes (Bun + LOKI_LEGACY_BASH=1) on each channel
54
+
55
+ Cleanup after every local-ci run and post-release validation uses
56
+ `loki_run_tmp_cleanup` (see `docs/dev/tmp-cleanup.md`).
57
+
58
+ ## Release Workflow
59
+
60
+ **Step 0 (always first): `bash scripts/local-ci.sh`** -- pre-push gate.
61
+
62
+ ### 1. Version Bump - ALL Files
63
+
64
+ ```
65
+ VERSION # Single line: X.Y.Z
66
+ package.json # "version": "X.Y.Z"
67
+ SKILL.md # Header (line ~6) AND footer (last line)
68
+ Dockerfile # LABEL version= AND org.opencontainers.image.version (both, or it drifts)
69
+ Dockerfile.sandbox # Same two labels
70
+ plugins/loki-mode/.claude-plugin/plugin.json # "version": "X.Y.Z" (marketplace.json carries no version)
71
+ server.json # "version" AND packages[loki-mode].version (MCP registry manifest; enforced by tests/test-server-json-current.sh)
72
+ vscode-extension/package.json # DEPRECATED v7.2.0, no longer published; bump only if vendoring
73
+ CLAUDE.md # Version pointer, if present
74
+ dashboard/__init__.py # __version__ = "X.Y.Z"
75
+ mcp/__init__.py # __version__ = "X.Y.Z"
76
+ CHANGELOG.md # Add new version entry at top
77
+ docs/INSTALLATION.md # Version header
78
+ wiki/Home.md, wiki/_Sidebar.md, wiki/API-Reference.md
79
+ README.md, docker-compose.yml # Docker image tags (MAJOR/MINOR bumps)
80
+ ```
81
+
82
+ ### 2. Build Dashboard Frontend
83
+
84
+ ```bash
85
+ cd dashboard-ui && npm ci && npm run build:all && cd ..
86
+ ls -la dashboard/static/index.html # verify >100KB
87
+ ```
88
+ `npm publish`'s `prepublishOnly` also triggers this build automatically.
89
+
90
+ ### 3. Run Tests
91
+
92
+ ```bash
93
+ bash -n autonomy/run.sh
94
+ bash -n autonomy/loki
95
+ python3 -c "import ast, os; [ast.parse(open(f'dashboard/{f}').read()) for f in os.listdir('dashboard') if f.endswith('.py')]"
96
+ python3 -c "import json; json.load(open('package.json')); print('JSON OK')"
97
+ cd dashboard-ui && npx playwright test && cd .. # requires dashboard on 57374
98
+ ```
99
+
100
+ ### 3a. Pre-Publish Validation (MANDATORY)
101
+
102
+ ```bash
103
+ npm pack --dry-run 2>&1 | grep -E "web-app/dist|dashboard/static" || echo "FAIL: expected files missing"
104
+ git ls-files web-app/dist/index.html | grep -q . || echo "FAIL: web-app/dist/ not tracked"
105
+ git ls-files dashboard/static/index.html | grep -q . || echo "FAIL: dashboard/static/ not tracked"
106
+ npm pack && npm install -g ./loki-mode-*.tgz
107
+ loki --version
108
+ loki web --no-open &
109
+ sleep 3
110
+ curl -s http://127.0.0.1:57374/ | grep -q "Loki" && echo "PASS: web app serves" || echo "FAIL"
111
+ curl -s http://127.0.0.1:57374/api/status | python3 -c "import json,sys; json.load(sys.stdin)" 2>/dev/null && echo "PASS: API responds" || echo "FAIL"
112
+ loki web stop
113
+ npm install -g loki-mode
114
+ rm -f loki-mode-*.tgz
115
+ ```
116
+ If any check fails, do not release; fix the root cause first.
117
+
118
+ ### 4. Commit and land (release-train model, D25)
119
+
120
+ Stage files by name (never `git add -A` or `git add .`), commit with the
121
+ repo-local `asklokesh` identity, no co-author. Batch approved merges locally;
122
+ push once per train (`git push origin main`); wait for Tests, Bun Parity and
123
+ Security Audit to go green on that exact SHA before bumping VERSION and
124
+ releasing. GitHub Actions then creates the tag, the GitHub Release, publishes
125
+ npm, builds/pushes Docker, and updates the Homebrew tap. Do not manually
126
+ create tags.
127
+
128
+ ### 5. Verify ALL Distribution Channels
129
+
130
+ ```bash
131
+ gh run list --limit 1 && gh run watch <run-id>
132
+ npm view loki-mode version
133
+ npm pack loki-mode --dry-run 2>&1 | grep dashboard/static
134
+ docker pull asklokesh/loki-mode:X.Y.Z && docker run --rm asklokesh/loki-mode:X.Y.Z loki version
135
+ brew update && brew info loki-mode
136
+ gh release view vX.Y.Z
137
+ ```
138
+
139
+ ### Distribution Channel Checklist
140
+
141
+ | Channel | Dashboard API | Dashboard Frontend | Memory System | Skills/References |
142
+ |---------|--------------------------|------------------------------|---------------|-------------------|
143
+ | npm | `dashboard/*.py` | `dashboard/static/index.html`| `memory/` | `skills/`, `references/` |
144
+ | Docker | `COPY dashboard/` | Built in Dockerfile or committed | `memory/` | `skills/`, `references/` |
145
+ | Homebrew| Full tarball | Full tarball | Full tarball | Full tarball |
146
+ | VSCode | DEPRECATED v7.2.0 -- no longer published | -- | -- | -- |
147
+ | Release | Skill-only zip | N/A | N/A | `references/` |
148
+
149
+ ### Credentials (GitHub Secrets)
150
+ `NPM_TOKEN`, `DOCKERHUB_USERNAME` / `DOCKERHUB_TOKEN`, `HOMEBREW_TAP_TOKEN`.
151
+
152
+ ## Testing
153
+
154
+ ```bash
155
+ ./benchmarks/run-benchmarks.sh humaneval --execute --loki
156
+ ./benchmarks/run-benchmarks.sh swebench --execute --loki
157
+ ```
@@ -0,0 +1,29 @@
1
+ # Research foundation
2
+
3
+ Moved out of CLAUDE.md (S-78) to keep the root file short. Content unchanged.
4
+
5
+ Built on 2025 research from three major AI labs:
6
+
7
+ **OpenAI:**
8
+ - Agents SDK (guardrails, tripwires, handoffs, tracing)
9
+ - AGENTS.md / Agentic AI Foundation (AAIF) standards
10
+
11
+ **Google DeepMind:**
12
+ - SIMA 2 (self-improvement, hierarchical reasoning)
13
+ - Google DeepMind Robotics (VLA models, planning)
14
+ - Dreamer 4 (world model training)
15
+ - Scalable Oversight via Debate
16
+
17
+ **Anthropic:**
18
+ - Constitutional AI (principles-based self-critique)
19
+ - Alignment Faking Detection (sleeper agent probes)
20
+ - Claude Code Best Practices (Explore-Plan-Code)
21
+
22
+ **Academic:**
23
+ - CONSENSAGENT (anti-sycophancy)
24
+ - GoalAct (hierarchical planning)
25
+ - A-Mem/MIRIX (memory systems)
26
+ - Multi-Agent Reflexion (MAR)
27
+ - NVIDIA ToolOrchestra (efficiency metrics)
28
+
29
+ See `references/openai-patterns.md`, `references/lab-research-patterns.md`, and `references/advanced-patterns.md`.
@@ -0,0 +1,157 @@
1
+ # Temp directory and process cleanup (mandatory helpers)
2
+
3
+ Moved out of CLAUDE.md (S-78) to keep the root file short. Content unchanged.
4
+ CLAUDE.md still states the invariant; this file holds the runnable helpers.
5
+
6
+ ## Test and Resource Cleanup (MANDATORY - NEVER SKIP)
7
+
8
+ **Before reporting ANY task as done, run ALL cleanup steps below. No exceptions.**
9
+
10
+ 1. **Create one run-owned temp directory before the first temp write.** Keep
11
+ every archive, package extraction, log, PID file, and test fixture for the
12
+ task below this directory. Never use fixed names or shared globs under
13
+ `/tmp`.
14
+
15
+ 2. **Stop only processes started by the current task.** Retain their exact PIDs
16
+ below `$LOKI_RUN_TMP` and signal those PIDs individually. Do not use
17
+ `pkill`, a shared-port sweep, or a name-pattern kill as cleanup.
18
+
19
+ 3. **Remove only the validated run-owned directory.** Use the helpers below.
20
+ Cleanup fails closed unless the target is a direct child of the canonical
21
+ temp root, has the exact ownership marker created with it, is owned by the
22
+ current UID, still carries the private permissions the helper set (`700`
23
+ for the directory, `600` for the marker), is not a symlink, and is not a
24
+ Git worktree. Never replace this with a wildcard deletion under `/tmp` or
25
+ `$TMPDIR`.
26
+
27
+ ```bash
28
+ loki_run_tmp_create() {
29
+ local temp_root marker
30
+
31
+ if [ -n "${LOKI_RUN_TMP:-}" ]; then
32
+ printf '%s\n' "LOKI_RUN_TMP is already set; refusing to replace it" >&2
33
+ return 64
34
+ fi
35
+
36
+ temp_root="$(cd "${TMPDIR:-/tmp}" 2>/dev/null && pwd -P)" || {
37
+ printf '%s\n' "Cannot resolve the temp root" >&2
38
+ return 64
39
+ }
40
+ LOKI_RUN_TMP="$(mktemp -d "${temp_root}/loki-run.XXXXXXXX")" || return 1
41
+ marker="${LOKI_RUN_TMP}/.loki-run-owned"
42
+
43
+ chmod 700 "$LOKI_RUN_TMP" || {
44
+ rmdir "$LOKI_RUN_TMP" 2>/dev/null || true
45
+ unset LOKI_RUN_TMP
46
+ return 1
47
+ }
48
+ if ! printf '%s\n' "$LOKI_RUN_TMP" >"$marker" || ! chmod 600 "$marker"; then
49
+ rm -f -- "$marker"
50
+ rmdir "$LOKI_RUN_TMP" 2>/dev/null || true
51
+ unset LOKI_RUN_TMP
52
+ return 1
53
+ fi
54
+ export LOKI_RUN_TMP
55
+ }
56
+
57
+ # Read one numeric stat field portably. GNU uses -c, BSD uses -f, and each
58
+ # MISPARSES the other's flag: GNU -f means --file-system and still prints a
59
+ # filesystem block on stdout while exiting non-zero, so a bare `a || b`
60
+ # fallback captures that block and concatenates the real value onto it.
61
+ # Validate the captured value instead of trusting exit status or stream, so a
62
+ # usage string, a filesystem block, an empty result, or a concatenation of any
63
+ # of those is rejected on every platform.
64
+ loki_run_tmp_stat_field() {
65
+ local gnu_fmt="$1" bsd_fmt="$2" path="$3" value
66
+
67
+ value="$(stat -c "$gnu_fmt" -- "$path" 2>/dev/null)" || value=''
68
+ case "$value" in
69
+ '' | *[!0-9]*) value="$(stat -f "$bsd_fmt" -- "$path" 2>/dev/null)" || value='' ;;
70
+ esac
71
+ case "$value" in
72
+ '' | *[!0-9]*) return 1 ;;
73
+ esac
74
+ printf '%s\n' "$value"
75
+ }
76
+
77
+ loki_run_tmp_cleanup() {
78
+ local target temp_root marker marker_value target_real
79
+ local target_uid marker_uid target_mode marker_mode current_uid
80
+
81
+ target="${LOKI_RUN_TMP:-}"
82
+ [ -n "$target" ] || return 0
83
+ temp_root="$(cd "${TMPDIR:-/tmp}" 2>/dev/null && pwd -P)" || return 64
84
+
85
+ case "$target" in
86
+ "${temp_root}"/loki-run.*) ;;
87
+ *)
88
+ printf '%s\n' "Refusing cleanup outside the run-owned temp namespace: $target" >&2
89
+ return 64
90
+ ;;
91
+ esac
92
+ [ "$(dirname -- "$target")" = "$temp_root" ] || return 64
93
+ [ -d "$target" ] && [ ! -L "$target" ] || return 64
94
+
95
+ marker="${target}/.loki-run-owned"
96
+ [ -f "$marker" ] && [ ! -L "$marker" ] || return 64
97
+ IFS= read -r marker_value <"$marker" || return 64
98
+ [ "$marker_value" = "$target" ] || return 64
99
+
100
+ current_uid="$(id -u)" || return 64
101
+ target_uid="$(loki_run_tmp_stat_field '%u' '%u' "$target")" || return 64
102
+ marker_uid="$(loki_run_tmp_stat_field '%u' '%u' "$marker")" || return 64
103
+ [ "$target_uid" = "$current_uid" ] && [ "$marker_uid" = "$current_uid" ] || return 64
104
+
105
+ # Refuse anything readable, writable, or executable by group or other. Only
106
+ # the low three permission digits are compared: GNU '%a' includes the
107
+ # setuid/setgid/sticky digit and BSD '%Lp' does not, and `mktemp -d` under a
108
+ # setgid temp root inherits g+s that a three-digit `chmod 700` preserves.
109
+ # Comparing the raw value against "700" would therefore read 2700 on Linux,
110
+ # refuse, and leak the very directory this helper exists to remove.
111
+ target_mode="$(loki_run_tmp_stat_field '%a' '%Lp' "$target")" || return 64
112
+ marker_mode="$(loki_run_tmp_stat_field '%a' '%Lp' "$marker")" || return 64
113
+ # Keep the last three digits, zero-padded, then require exactly 700/600.
114
+ target_mode="00${target_mode}"
115
+ marker_mode="00${marker_mode}"
116
+ [ "${target_mode#"${target_mode%???}"}" = "700" ] || return 64
117
+ [ "${marker_mode#"${marker_mode%???}"}" = "600" ] || return 64
118
+
119
+ target_real="$(cd "$target" 2>/dev/null && pwd -P)" || return 64
120
+ [ "$target_real" = "$target" ] || return 64
121
+ [ "$(dirname -- "$target_real")" = "$temp_root" ] || return 64
122
+
123
+ # A linked worktree has a .git file; a primary worktree has a .git
124
+ # directory. Refuse both, including a broken .git symlink.
125
+ if [ -e "${target}/.git" ] || [ -L "${target}/.git" ]; then
126
+ printf '%s\n' "Refusing to remove a Git worktree: $target" >&2
127
+ return 64
128
+ fi
129
+
130
+ rm -rf -- "$target"
131
+ [ ! -e "$target" ] || return 1
132
+ unset LOKI_RUN_TMP
133
+ }
134
+ ```
135
+
136
+ 4. **Verify exact cleanup.** Confirm each recorded PID is gone and the saved
137
+ `$LOKI_RUN_TMP` path no longer exists. Do not scan or delete other users'
138
+ or runs' temp paths.
139
+
140
+ 5. **Report cleanup status** to the user in the task completion message,
141
+ including only the explicit run-owned path and process IDs handled.
142
+
143
+ ## Feedback Loop Requirement (before documenting a new feature)
144
+
145
+ 1. **Verify it exists** - check files, run commands, test endpoints.
146
+ 2. **Run feedback loop** - Task tool with Opus to review claims for accuracy.
147
+ 3. **Be factual only** - never document features that don't work yet.
148
+ 4. **Mark planned features** - use "Coming Soon" or "Planned" labels.
149
+
150
+ ```bash
151
+ # Before documenting "npm install -g loki-mode"
152
+ npm view loki-mode # Does package exist on registry?
153
+ # Before documenting a CLI command
154
+ which loki && loki --help
155
+ # Before documenting a file path
156
+ ls -la path/to/file
157
+ ```