17 Commits
Author SHA1 Message Date
AkitaOnRailsandClaude Opus 5.5 80a78d0255 fix(run): make an explicit ai-jail selection exact with --no-X for unselected rows
The checklist and `--jail=LIST` emitted only enabled toggles, so the user's
own ai-jail config (e.g. a global `~/.ai-jail` enabling `docker`) could still
mount what an unchecked row or an explicit list left out, and the summary
line misreported it.

- Interactive checklist: `marked_choices` passes every row the user saw,
  checked as `--X` and unchecked as `--no-X`.
- `--jail=LIST` (including `none`): after the named entries, every visible
  checklist row the list did not name is forced off with `--no-X`. Rows that
  are not visible (absent credentials, CLI-only toggles) are never forced.
- Bare `--jail` is unchanged: smart-default rows only, the rest left to the
  user's ai-jail config, because no selection was shown.
- `JailToggleChoice::implied` marks rows forced off by omission, so the
  summary names the user's own `no-X` entries and says "everything else in
  the checklist off" for the rest.
- Tests: an adversarial unit test (unchecked docker row and `--jail=none`
  yield `--no-docker` / `--no-*` for every visible row, with bare `--jail`
  as the control); parse, checklist, summary and end-to-end expectations
  updated, the latter platform-aware for the Linux-only rows.
- Docs: design §5 semantics, cookbook, support matrix, CHANGELOG.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-10-01 03:42:50 -03:00
AkitaOnRailsandClaude Opus 5.5 7e0ec65899 feat(run): choose ai-jail toggles with --jail[=LIST], --no-jail, and a checklist
`ai-memory run` can now decide which ai-jail credentials and capabilities a
jailed session gets, from the CLI or an interactive checklist, with smart
defaults so Enter does the friendly thing.

- ai-memory-workstream/jail.rs: a toggle table (credential mounts github,
  aws, kube, gcloud, docker-config; ssh; worktree; docker, gpu, display,
  pictures, tailscale; CLI-only audio, x11, host-shm, terminal-passthrough,
  update-check, mise, toolchains), support detection from the installed
  ai-jail's `--help` (exact `--X` tokens, so `--docker` never matches
  `--docker-config`), injected host facts (home, SSH agent, origin URL,
  linked worktree, project `.ai-jail` presence), the checklist with smart
  defaults, and the `--jail=` list parser (`no-X`, `all`, `none`; reserved
  security switches and ai-memory-owned flags refused).
- build_ai_jail_invocation emits the chosen `--X`/`--no-X` and a
  `--no-save-config` baseline before the `--`, so ai-jail never writes the
  run's transient flags into the repository's `.ai-jail`.
- inspect_repository reports the `origin` URL and whether the cwd is a
  linked worktree.
- run.rs: `--jail[=TOGGLES]` / `--no-jail` (also stripped when they land in
  the native argv), a pure jail_decision table, an explicit `--jail` re-exec
  before the managed run is prepared (failing closed when ai-jail is not
  usable), and the line-based checklist after the `--yolo` offer. A project
  `.ai-jail` replaces the checklist and the bare-`--jail` defaults.
- Tests: unit coverage for parsing, support detection, defaults, the
  decision table, flag stripping, and the checklist grammar; a real
  `ai-jail --dry-run` over every toggle the installed ai-jail advertises;
  end-to-end runs of the built binary with fake ai-jail/bwrap/claude and a
  mock server, including PTY runs of the offer, the checklist, a project
  `.ai-jail`, and `--yolo --no-jail`.
- Docs: design §5, cookbook yolo recipe, support matrix, CHANGELOG.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-10-01 03:32:13 -03:00
AkitaOnRailsandClaude Opus 5.5 ae676d4918 fix(run): ai-jail re-exec/offer, --true-yolo semantics, and relaunch after an interrupted run
ai-jail integration (`ai-memory run --yolo`):
- The re-exec built `ai-jail <flags> <exe> run …` with no `--`. ai-jail
  rejects one of its own flags after the command and `run` shares flag names
  with it, so `run claude --yolo --env GH_TOKEN=…` aborted. The invocation now
  emits `--` before the wrapped exe (forwarding a colliding flag additionally
  needs ai-jail >= 2.4.2, whose guard honors the separator; the cross-tool
  test gates on that version).
- The offer only checked for a file named ai-jail: Windows could show it, a
  host without bwrap/sandbox-exec was offered a jail that cannot start, and a
  ~/.local/bin-only install was offered and then not found by the bare
  `Command::new("ai-jail")` re-exec after the run was already cancelled.
  usable_ai_jail(os, lookup) now returns the exact binary to exec only on
  Linux/macOS with the backend present; otherwise no question is asked.

--true-yolo:
- It now implies --yolo (warning, ai-jail offer, harness dangerous mode):
  alone it used to apply Claude's bypassPermissions with no warning. It is
  interchangeable with --yolo for non-Claude harnesses, and recognized after
  native arguments (`run claude --model opus --true-yolo`), where clap leaves
  it in the native argv and it was forwarded to Claude as an unknown option.
- The claude_true_yolo config key only upgrades an explicit yolo launch, as
  its doc comment stated, instead of bypassing permissions on every run.
- Removed what never worked: three CLAUDE_CODE_DISABLE_*RM* env vars Claude
  Code does not read (absent from the 2.1.280 binary and its env reference),
  and an empty permissions.ask array that cannot clear ask rules from other
  scopes (Claude unions them). Docs now state that Claude honors explicit ask
  rules and its command-safety checks in every permission mode.

Relaunch after an interrupted run:
- A launcher killed before releasing its lease (terminal closed, ai-jail
  torn down) left the workstream held for up to 90s and the next launch failed
  after a 5s retry. An interactive launch now parses the holder and expiry from
  the 409, waits for that lease to lapse (bounded by one lease; Ctrl-C aborts),
  then proceeds. A holder that renews meanwhile is reported as live and never
  displaced; the server's busy check stays the only arbiter (security
  inventory row 13b). Non-interactive launches keep the short window.

Tests: usable_ai_jail OS/backend/Windows/exact-path, `--` placement and the
colliding-flag regression (unit + real ai-jail --dry-run), the yolo_modes
table, --true-yolo in both argv positions via real clap parses, the reduced
true-yolo argv, and HTTP-level held-lease wait / renewed-owner / Ctrl-C cases.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-10-01 01:53:49 -03:00
Talysson de Oliveira Cassiano cf21fcb351 docs: document per-repository server profiles (#992)
marker-file.md gains a section on the `server` key: registering
profiles, the fail-closed rules, inheritance and the walk boundary with
the allowlist-mode caveat that comes with it, check-capture output,
which integrations route or drop, what `uninstall` removes, that two
profiles may share a URL with different tokens (one server, several
identities under #708), and two known limits (older binaries draining a
shared spool; MCP and `ai-memory run` still using the install server).

install.md, cookbook.md, security.md and the README point to it,
security-boundaries.md adds row 11d, and CHANGELOG records the feature
and the backfill fix; the Kimi `{}` fix reached release/2.5 through the
cherry-pick to main (#996), so its commit is no longer part of this branch.
2026-09-30 18:19:10 +00:00
AkitaOnRailsandClaude Opus 4.8 80888360e2 feat(run): warn before --yolo, offer ai-jail, add Claude true-yolo (#983)
ai-memory run --yolo now, on an interactive TTY only (never in hook/CI/
detached paths):

- warns that --yolo runs every tool call unconfirmed, [Y/n] default-yes;
- offers to re-run inside ai-jail when it is installed, re-execing the
  original argv under `ai-jail --network --agent-state --env <NAME>…`
  (--network shares the host net namespace so the loopback ai-memory server
  stays reachable; only already-set credential/config env is forwarded);
- skips both prompts when already inside ai-jail (Linux hostname ai-sandbox
  / macOS PS1 (jail) ; fails open to showing the warning; Windows never).

Opt-in Claude "true yolo" (--true-yolo / [config] claude_true_yolo,
AI_MEMORY_CLAUDE_TRUE_YOLO) silences the pauses --dangerously-skip-permissions
leaves: sets the CLAUDE_CODE_DISABLE_*_RM_* env vars and injects
--settings bypassPermissions. Claude-only, off by default, sandbox-first.

Detection and argv assembly are pure/OS-explicit (ai-memory-workstream::jail)
with unit tests for every branch; a CLI integration suite asserts the argv
against the real ai-jail via --dry-run (skips cleanly when ai-jail/bwrap are
absent). Design: docs/design-yolo-safety-ai-jail.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-29 15:24:14 -03:00
Éverton Toffanetto 66b7567aae fix(uninstall): clear auto-wire sentinels and keep the hook bearer for partial uninstalls
`ai-memory uninstall` left the `ai-memory run` auto-wire sentinels behind, so
the next managed launch skipped wiring and captured nothing. Removing hooks or
MCP now deletes every sentinel and lists them in the dry-run plan.
`--only mcp|instructions|skills` no longer deletes the stored hook bearer the
still-installed hooks read.

Refs #820
2026-09-25 00:06:30 -03:00
Éverton Toffanetto 7d81d60721 chore(uninstall): move the auto-wire sentinel sweep to its own change 2026-09-24 23:29:04 -03:00
Éverton Toffanetto 6295dd814b fix(run): wire hooks and MCP where the launch environment points
`ai-memory run --env/--env-file` values reached the spawned harness and
native-session resolution but not first-launch auto-wire, so hooks and MCP
landed in the default config home, and a sentinel keyed only on agent and
version skipped a second account on the same version. Auto-wire now resolves
every install target from the launch environment, the Codex MCP entry follows
`CODEX_HOME`, and the sentinel also keys on the resolved hook and MCP paths.

Fixes found on the same paths: OMP profile and PI_CONFIG_DIR resolution,
blank relocation values, uninstall leaving sentinels behind, the Crush
context packet (default context files and the global crushrc), the Crush data
directory lookup, session discovery with concurrent launches in one checkout,
and Kiro v3 resume wiring. Spawned-server test fixtures now survive losing a
free port to another socket.

Refs #820
2026-09-24 19:03:13 -03:00
AkitaOnRailsandClaude Opus 4.8 115895cbe1 feat(lint): make the A5 contradiction-similarity band configurable
The zero-LLM contradiction detector in memory_lint used a hardcoded
absolute cosine band (0.4-0.75). On a single-language or single-domain
store the background similarity floor is elevated, so the fixed band
admits many same-domain-but-unrelated pairs as noise, up to the 25-finding
cap.

Add contradiction_band_min / contradiction_band_max config keys (env:
AI_MEMORY_CONTRADICTION_BAND_MIN / _MAX), defaulting to the historical
0.4 / 0.75 so existing installs see no behavior change. Validated at
config load (finite, 0.0 <= min < max <= 1.0). Threaded through
LintOptions and into the three call sites that build it (admin HTTP
lint, the memory_lint MCP tool, and the scheduled lint tick).

Closes #853.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-23 14:58:04 -03:00
hiro-nikaitou 5838a94a06 docs(cookbook): note band false positives
Signed-off-by: hiro-nikaitou <vieteviete@proton.me>
2026-09-23 04:59:59 -04:00
AkitaOnRails ea95139c93 Merge release/2.4 into macos-app (retarget base; resolve CHANGELOG) 2026-09-20 16:37:11 -03:00
Thiago Macedo eadab8e4bd Add a macOS menu bar companion that bundles and governs the server.
The accessory app ships the ai-memory binary and hooks tree, starts the
existing LaunchAgent, and opens /web, status, config, and logs. Durable
data stays in Application Support so replacing the .app is an update.
2026-09-20 21:25:16 +02:00
AkitaOnRailsandClaude Opus 4.8 dd6e8e8848 docs(2.4): reflect shipped memory-aging feature set + re-assess competitive standing
Update user-facing docs for the 2.4 memory-aging program (decay curves,
extractive tier-down, cold-cluster dedup, contradiction flagging,
access-weighted retention, belief-strength confidence, and the opt-in LLM
"dream" pass) and re-run the competitive comparison against it.

- README: add "ages gracefully, without an LLM" + "can dream, if you let it"
  bullets; update the "Coming from another tool?" positioning for
  mcp-memory-service and Hindsight/OpenViking parity-plus (opt-in framing).
- comparison.md: move decay/compression/dedup/contradiction/dream/belief from
  unshipped to shipped in the field-validation section, camp table, and
  migration notes; add a "shipped but off, no proven win" fairness bullet.
- competitive-parity.md: move now-shipped items into the migration verdicts and
  the borrowed-ideas audit, noting our zero-LLM-default, reversible, file-first,
  R2/opt-in improvements over the sources borrowed from.
- research-2026-landscape.md: append 2.4-status notes to the mcp-memory-service,
  Hindsight, OpenViking, and Honcho §3 entries and R2/R7; add §6 in-repo sources.
- cookbook.md: add a "control what gets kept, aged, or consolidated" recipe.

All belief-strength/dream claims are framed as opt-in, off by default, and
R2-gated before default-on; no R2 eval has been run, so no measured recall or
quality delta is claimed. No competitor benchmark numbers invented.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-20 14:46:33 -03:00
AkitaOnRailsandClaude Opus 4.8 da8d07dcc9 feat(run): auto-install a harness's hooks + MCP on first ai-memory run
Managed launch is the recommended way to start a harness, so it should be the
path that makes capture "just work" — but it didn't: `ai-memory run kimi`
captured nothing if the Kimi hooks/MCP had never been manually installed.

`ai-memory run <harness>` now auto-installs that harness's ai-memory lifecycle
hooks and MCP server the first time it launches the harness, if they are not
already wired. It runs before the child spawns (so the harness picks up the
fresh hooks), is idempotent and one-time per harness + binary version (a
per-agent sentinel under <data_dir>/autowire-state/, keyed on the version so an
upgrade re-stages the fresh bundle), and is best-effort — an install failure
warns with the manual command and the harness still launches. It reuses the
existing install-hooks / install-mcp apply paths, which preserve unrelated user
config. Harnesses with no installer support (Crush) are skipped cleanly; Pi
wires hooks but has no MCP client to write.

On by default; opt out with `ai-memory run --no-autowire` (accepted before or
after the harness, so it is never forwarded to the child), AI_MEMORY_RUN_AUTOWIRE=false,
or run_autowire = false. Manual install-hooks/install-mcp remain for harnesses
never launched through run. Documented as the preferred launch path ("if in
doubt, run with ai-memory") in the README and managed-workstreams docs.

Tests: harness->AgentChoice mapping completeness (+ Crush skip, Pi no-MCP),
sentinel keying by agent+version, a real install-through-the-installers test
asserting hooks + MCP land AND unrelated user config is preserved AND a gated
re-launch is byte-identical (paths injected so it never touches real $HOME),
unsupported-harness-writes-nothing, present-sentinel-short-circuits, and
--no-autowire parsing in both positions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-16 11:28:54 -03:00
AkitaOnRailsandClaude Opus 4.8 c380278ef6 feat(cli): boot-time backfill of pre-hook local history (on by default)
Capture is forward-only: hooks record only from install time. Installing
ai-memory in a project you've worked in for weeks left it amnesiac about the
very session you were resuming. This bootstraps an empty project's memory once
from the existing local harness transcripts.

New `ai-memory backfill`: for the current project it enumerates every supported
harness's local native sessions for this cwd (reusing the read-only workstream
adapters + doctor's harness set), and — only when the store is empty — replays
each transcript through `/hook/batch`, the same ingress live capture uses. Each
event becomes a real session + observations (session-start / user-prompt /
backfill-extension), attributed to the original harness and native session id,
so the history consolidates into pages and is searchable via memory_query. The
server sanitizes and bounds every event, so retroactive text crosses the same
trust boundary as live capture.

Automatic by default: the SessionStart hook spawns `ai-memory backfill --auto`
detached (never inline; session start is untouched) the first time a checkout is
opened, gated by a per-cwd sentinel so it runs at most once. It only ever
bootstraps an empty project (never overwrites an established one; live capture
from install-time forward and backfill of before-install history do not overlap),
and is hard-capped (newest 25 sessions, 50k events). Opt out with
AI_MEMORY_BACKFILL_ON_START=false / backfill_on_start = false; the manual command
always works (--dry-run, --force, --session, --json).

Also hardens doctor + backfill against a brand-new project: /admin/sessions/by-agent
returns 404 for a scope that has never been written to; both now read that as
"nothing captured" instead of erroring (found via a live smoke).

The ingest path was chosen empirically: an earlier revision imported through the
managed-workstream begin/finish endpoints, but a live smoke showed that populates
the `ai-memory run` continuity ledger, not the searchable memory pipeline
(observation count stayed 0). The /hook replay was verified end-to-end:
sessions 0->1, observations 0->5, pages 0->1, by-agent claude-code:1, and a
correct no-op on the second run. Design: docs/design-boot-backfill.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-16 11:01:08 -03:00
AkitaOnRailsandClaude Opus 4.8 56e94a18df feat(cli): add ai-memory doctor capture-coverage check
Capture is silently gated on each harness having an ai-memory hook installed:
a harness with no hook still writes its own local session transcripts, but
nothing reaches the server, and nothing reconciled "this harness ran here"
against "this harness captured nothing" (audit finding F1 — Kimi ran on a
project for weeks with no hook and zero captured sessions, invisibly).

`ai-memory doctor` makes that gap visible. For the current project it
enumerates every known harness's local native session store (reusing the
read-only ai-memory-workstream adapters, so the per-harness cwd/path encoding
stays in one place), asks the server for captured session counts per agent
(GET /admin/sessions/by-agent), and warns when a harness has recent local
sessions here but zero captured ones — printing the exact
`install-hooks --agent <name> --apply` to close it.

The verdict is deliberately conservative: only recent-local + zero-captured is
flagged. One captured session proves the hook works, a purely historical local
store is not actionable, and --resume session-id reuse means many local files
can map to one server session, so a partial count is never a "gap". Read-only
on the local side; supports --json, --since-days, --workspace/--project.

Tests: pure verdict logic (fold/aggregate/sort, Kiro v2+v3 folding, captured-
only agents, drop-empty) plus an end-to-end detector test that plants a real
Claude Code transcript under the actual ~/.claude/projects/<enc-cwd>/ layout
and asserts scan_local detects it and ignores a foreign-cwd transcript.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-15 23:16:18 -03:00
AkitaOnRailsandClaude Opus 4.8 3ff8b92d6e docs: add task-oriented cookbook cheat sheet (#726)
New docs/cookbook.md answers "what does ai-memory do and how do I use it" with
recipes: recall prior work, keep a rule a project must follow, import an existing
knowledge base (OKF norms/specs) and have a project read a specific document, and
two agents/repos working together. Linked from the README docs table and the
AGENTS.md documentation map.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-09-15 14:37:37 -03:00