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.
@@ -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
+ ```