2508 Commits
Author SHA1 Message Date
AkitaOnRails e2d7d17d90 fix(run): allow same-owner lease recovery
Refs #795
2026-10-01 16:18:44 -03:00
AkitaOnRails ae1eabe7e0 docs(scope): retain session-aware project routing
Closes #943.
2026-10-01 14:53:36 -03:00
AkitaOnRails 11f7061c51 docs(changelog): record release archive drift guard 2026-10-01 14:33:15 -03:00
AkitaOnRails 37f89020db Merge pull request #1029 from rubenlr/fix/1025-upgrade-packaging-allowlist 2026-10-01 14:31:05 -03:00
Test defc9337cb fix(tests): update ai-jail script to handle --dry-run option and increment migration version
This commit modifies the ai-jail script to properly handle the `--dry-run` option without affecting the jail arguments file. Additionally, it updates the migration version assertion in the API credentials tests from 70 to 71, ensuring consistency with the latest migration changes.
2026-10-01 20:10:41 +03:00
Test a36e9d1e84 fix(upgrade): update release archive allowlist to include packaging, docs, and crates directories
This change addresses an issue where the `ai-memory upgrade` command rejected official Linux/macOS release tarballs due to missing entries in the extraction allowlist. The allowlist now includes top-level directories and files that are part of the release archives, ensuring successful extraction and installation. Additionally, tests have been added to verify the integrity of the allowlist against the release workflow configuration.
2026-10-01 20:05:26 +03:00
AkitaOnRails 53985bddc4 Merge pull request #1028 from MarconiVini/fix/upgrade-deleted-hook-path
Harden the shared renderer and preserve the loaded upgrade config.
2026-10-01 14:03:58 -03:00
AkitaOnRails a1255e3486 test(wrapper): pin container fixtures to script hooks 2026-10-01 13:56:51 -03:00
AkitaOnRails 9e5bfe9f9c fix(upgrade): accept complete release archives
Fixes #1025
2026-10-01 13:54:42 -03:00
Marcos SantiniandClaude Code 51fbd692b7 fix(upgrade): keep refreshed hooks pointing at the replaced binary path
`ai-memory upgrade` replaced its own binary and then re-rendered the staged
hook configs from the same, now exe-deleted process. On Linux the kernel
reports `/proc/<pid>/exe` as `<path> (deleted)` once the inode is unlinked,
and that string was embedded verbatim into every hook command, so all nine
hooks failed with `not found` until the suffix was stripped by hand (#1027).

Two layers:

- the staged-hook refresh now re-runs `install-hooks --apply` from the
  freshly installed binary as child processes, so rendering happens in a
  process whose own exe is valid;
- hook rendering centralizes the executable resolution in one helper that
  strips the kernel's ` (deleted)` marker and falls back to the bare
  `ai-memory` command name when the resolved path is missing, instead of
  baking a dead absolute path into every hook.

Verified: 5 new unit tests (marker strip, the corruption-window strip,
missing-path fallback, live-exe sanity, refresh command shape); full CLI lib
suite (1215 passed); and an end-to-end sandbox run where the fixed binary
self-upgrades from a local release and the rewritten settings stay clean.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-01 13:51:46 -03:00
AkitaOnRails 2ee5642815 fix(wrapper): enforce capture policy in hook installs
Fixes #1002
2026-10-01 13:45:52 -03:00
AkitaOnRails 15a26421a3 fix(workstream): recover stale Codex daemon runs
Fixes #987
2026-10-01 13:40:39 -03:00
AkitaOnRails 6d723d946d Merge remote-tracking branch 'pr/1026' into resolution/main-2026-10-01
# Conflicts:
#	CHANGELOG.md
2026-10-01 12:32:28 -03:00
uxidevandClaude Opus 5.5 61e15cc756 docs: reference #1026 in the CHANGELOG entry
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:25:38 +09:00
uxidevandClaude Opus 5.5 2a9f12deae docs: document FutureInfra as an openai-compat provider
Add a FutureInfra example to the openai-compat section of docs/install.md, list it in docs/llm-providers.md, and add an [Unreleased] CHANGELOG entry. Docs only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:24:59 +09:00
AkitaOnRails 2303527a96 fix(run): make jail preflight path portable 2026-10-01 12:24:39 -03:00
AkitaOnRails 7f8b95fea5 fix(run): preflight ai-jail availability 2026-10-01 12:24:19 -03:00
AkitaOnRails 3dce1c503f fix(ci): remove redundant test import 2026-10-01 12:17:12 -03:00
AkitaOnRails a69bf66072 Merge remote-tracking branch 'refs/remotes/pr/1024' into resolution/main-2026-10-01
# Conflicts:
#	CHANGELOG.md
2026-10-01 12:14:42 -03:00
AkitaOnRails 8b0fe5a929 Merge remote-tracking branch 'refs/remotes/pr/1023' into resolution/main-2026-10-01
# Conflicts:
#	CHANGELOG.md
2026-10-01 12:14:06 -03:00
AkitaOnRails 0966ecc230 fix(capture): keep invalid-marker diagnostics panic-free (#1021) 2026-10-01 12:12:24 -03:00
AkitaOnRails 1be2c929cb Merge remote-tracking branch 'refs/remotes/pr/1021' into resolution/main-2026-10-01 2026-10-01 12:09:58 -03:00
AkitaOnRails 112f2c03d2 Merge remote-tracking branch 'refs/remotes/pr/1020' into resolution/main-2026-10-01 2026-10-01 12:09:47 -03:00
Jovinull 3236aea8c1 fix(run): default the jail's ssh toggle from the push URL and host aliases 2026-10-01 10:27:12 -03:00
Jovinull 28e555660a fix(hooks): keep the script marker walks at a $HOME with a trailing separator 2026-10-01 10:27:09 -03:00
Maxsuel Einstein 3039163b0e doctor: warn when [capture] is invalid, based on policy state not parse-only
Review on #1004 (part A) found two real problems with the original
warning:

1. The wording implied a leak ("secret-redaction rule is NOT
   applying"). An invalid marker fails CLOSED: capture_policy turns
   every file and shell tool event into MetadataOnly until the marker
   is fixed. Nothing leaks -- content is reduced to metadata, not
   exposed. Reworded to say exactly that.

2. The check was parse-only (capture_config_problem used to just ask
   "did the TOML parse"), which misses a `[capture]` table that parses
   as valid TOML and has a valid shape, but whose `ignore_paths` still
   gets rejected by `compile` -- an unsupported glob character
   (`ignore_paths = ["secrets/{a,b}"]`), too many patterns, or a `~/`
   pattern with no home directory to expand it. That case reported
   `problem=None` even though `capture_policy(cwd).state()` was
   already `Invalid`.

Fix: `capture_policy(cwd).state()` is now the single source of truth
for whether the marker has a problem -- the exact state the live hook
path itself resolves to, not a separate parse-only re-derivation. A
verbose parse (`read_capture_config_verbose`) still supplies the
reason text for a TOML/shape failure; a new
`describe_invalid_capture_config` (mirrors `compile`'s own validation,
now returning descriptive `Result<_, String>` errors instead of `()`)
supplies the reason for a config that parses but doesn't compile, so
the message names the specific rejected pattern and why.

`CapturePolicy` gains a `state()` accessor for this purpose; the hot
hook path is unaffected (same resolution, same fail-closed behavior,
just an added read of a field it already computes).

Tests: 8 new (3 in hook_capture.rs's capture_config_problem, including
a regression test for the exact dropped-`#`-in-a-comment TOML shape
found in practice, with a neutral fixture this time; 5 in
capture_policy.rs covering `state()` and `describe_invalid_capture_config`
across every PolicyState, including the parses-but-rejected-glob case
this fix exists for).

CHANGELOG entry added under [Unreleased].
2026-10-01 09:06:39 -03:00
Maxsuel Einstein ebf942c6d7 test(hooks): grok, kimi-code and pool never fetch a handoff at session-start
Follow-up to #1001 (#998's real fix), per review on the superseded #1009:
the negative case -- that grok, kimi-code and pool must never call
/handoff from session-start at all -- isn't covered by #1001, which
only touches the eight bundles that do fetch one.

Each of the three documents why in its own session-start.sh: Grok and
Kimi Code discard SessionStart stdout (Kimi delivers the brief from
user-prompt-submit.sh instead), and Pool's own comment says fetching
there would be destructive and silently lose an undelivered handoff.
A regression here would burn a single-use handoff with nothing to
show for it on the harness side.

Runs each real shipped script against a PATH curl shim (same pattern
the existing antigravity and grok post-tool-use cases already use) and
asserts exactly one request -- the capture POST -- with no /handoff
GET anywhere in it.

Verified: 108 -> 114 assertions passing under busybox sh (also checked
against upstream main pre-#1001 state to confirm the +6 delta is exactly
this addition, no loss elsewhere); 137 -> 143 under Git Bash. shellcheck
clean (every existing finding in the file predates this change).
2026-10-01 08:44:43 -03:00
AkitaOnRailsandClaude Opus 5.5 7580b74d0f test(run): give the jail e2e fixture the OS's own sandbox backend
usable_ai_jail requires bwrap on Linux but sandbox-exec on macOS, and the
fixture's PATH holds only its own fakes, so on the macOS runner ai-jail read
as unusable and --jail correctly failed closed. Write the backend the host OS
needs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
v2.5.2
2026-10-01 04:06:53 -03:00
AkitaOnRailsandClaude Opus 5.5 dfbcfc21a5 chore(release): 2.5.2
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-10-01 03:48:34 -03:00
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 56c2a60358 docs(changelog): reference GHSA-gf78-hf8g-vffm for #999
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-10-01 03:00:10 -03:00
AkitaOnRails 4720291893 Merge fix/wiki-racy-read-enoent: retry a walk that read a vanished file
# Conflicts:
#	CHANGELOG.md
2026-10-01 02:51:07 -03:00
AkitaOnRails 2de6227e0f Merge docs/2.5.2-audit-fixes: frontend-api, windows, Codex daemon drift 2026-10-01 02:51:07 -03:00
AkitaOnRails a502068ebe Merge PR #1008: docs: design proposal for offer-not-claim handoff delivery (#959) 2026-10-01 02:51:07 -03:00
AkitaOnRails dfed757b4e Merge PR #1006: fix(wiki): write the index file on every checkpoint (#983)
# Conflicts:
#	CHANGELOG.md
2026-10-01 02:51:07 -03:00
AkitaOnRails ae62d18827 Merge PR #1001: fix(hooks): send the [briefing] keys on the session-start handoff GET
# Conflicts:
#	CHANGELOG.md
2026-10-01 02:51:07 -03:00
AkitaOnRails daeca8108e Merge PR #756: fix(cli): apply message send admission and post-commit observers
# Conflicts:
#	CHANGELOG.md
2026-10-01 02:51:07 -03:00
AkitaOnRails aeb81aef14 Merge PR #999: fix(read_page): include_related only walks pages the caller may read 2026-10-01 02:51:06 -03:00
AkitaOnRails 9bcfabd60e Merge PR #1014: chore(deps): bump astral-sh/setup-uv from 10.1.0 to 10.2.0 2026-10-01 02:50:37 -03:00
AkitaOnRails d1baad60e3 Merge PR #1013: chore(deps): bump docker/setup-qemu-action from 4.2.0 to 4.4.0 2026-10-01 02:50:37 -03:00
AkitaOnRails 0bca7e30e2 Merge PR #1012: chore(deps): bump docker/build-push-action from 7.3.0 to 7.4.0 2026-10-01 02:50:36 -03:00
AkitaOnRails 86ab639cf2 Merge PR #1011: chore(deps): bump docker/setup-buildx-action from 4.3.0 to 4.4.1 2026-10-01 02:50:36 -03:00
AkitaOnRailsandClaude Opus 5.5 af8ed952e7 fix(wiki): retry a commit whose walk read a file that vanished mid-scan
is_racy_read only recognized libgit2's Filesystem-class "file changed before
we could read it", so the Os-class "failed to read file into stream" (ENOENT:
listed by the walk, gone when streamed in — e.g. an atomic writer's temp file
renamed away) failed the checkpoint outright instead of taking the bounded
racy-read retry. Seen as an intermittent
concurrent_commits_queue_instead_of_failing failure on a loaded CI runner
(v2.5.1 RC dispatch run). Classifier unit test covers both racy shapes and
two non-racy controls; it fails with the old single-branch check.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-10-01 02:50:21 -03:00
AkitaOnRailsandClaude Opus 5.5 013bf691fd docs: fix audited drift in frontend-api, windows, and Codex managed runs
- frontend-api.md (#986): the list, search, and recent routes return bare
  JSON arrays, not `{ "workspaces": … }`-style wrappers (the route tests
  assert `as_array()`); a page read returns `body_markdown`, not `body`; a
  search hit carries workspace/project/kind and no `id`.
- windows.md (#758): native `ai-memory upgrade` is done (#801/#802), not
  in-progress.
- managed-workstreams.md + support matrix (#987): document the Codex shared
  daemon handing hooks a stale AI_MEMORY_RUN_ID and the `--no-daemon`
  workaround until the server-side fix lands.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-10-01 02:47:14 -03:00
AkitaOnRailsandClaude Opus 5.5 18c6949fcc docs(design): fold maintainer review into the offer-not-claim proposal (#959)
Accept the design with corrections verified against the code: note the
existing live-source skip (LIVE_BATON_QUIET_PERIOD) and handoff expiry
(expire_same_cwd_auto_handoffs + post-claim sweep), so open question 5 is
mostly answered; require the notice to name the exact handoff_id; keep the
managed-run ledger claim at session start in offer mode; weigh a per-project
marker key over a server-wide switch; let an explicit accept by id ignore
to_agent; fix the memory_handoff_pop reference.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-10-01 02:43:38 -03:00
AkitaOnRails 4c7bc5b7ad Merge main into #1006 (resolve CHANGELOG against the stamped [2.5.1])
# Conflicts:
#	CHANGELOG.md
2026-10-01 02:41:21 -03:00
AkitaOnRails 949b5ae657 Merge main into #1001 (resolve CHANGELOG against the stamped [2.5.1])
# Conflicts:
#	CHANGELOG.md
2026-10-01 02:41:21 -03:00
AkitaOnRailsandClaude Opus 5.5 8addf87969 fix(admin): refuse a rejected message send with 403, add boundary row 8e
An admission refusal is a policy decision, as on the MCP path
(invalid_request), not a server fault, so the admin send route now answers 403
instead of 500, and the reject test asserts that status. Records the
MCP/admin admission parity as security-boundaries row 8e; the reject test
fails when the send authorizes against an op the webhook does not subscribe
to.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
2026-10-01 02:40:19 -03:00
AkitaOnRails 02c414e534 Merge main into #756 (resolve CHANGELOG against the stamped [2.5.1])
# Conflicts:
#	CHANGELOG.md
2026-10-01 02:39:10 -03:00