Files
AIPass/CHANGELOG.md
T
AIOSAI e63a4e9945 feat(#630): retire blanket rm deny + aipass doctor migration
Phase 2 of #630. The rm_gate hook + drone rm now own destructive-delete
protection (cross-provider, path-aware, teaching), so the Claude-only blanket
deny is redundant AND harmful (it short-circuits before the hook, suppressing
the teaching message).

- setup.sh: removed Bash(rm -rf*) + Bash(rm -r *) from git_deny (new installs)
- bootstrap.py: removed Bash(rm -rf *) shipped via aipass init (project settings)
- doctor_wire.reconcile_stale_deny(): aipass doctor WARNs on stale rules;
  --fix removes them (idempotent, preserves all else) — migration for existing
  installs (the 'aipass update should be trusted' goal)
- .aipass/project_hooks.json template: added rm_gate (new projects get it)

Tests: 8 reconcile + 432 aipass total, seedgo 99%. CHANGELOG W23.
2026-06-02 20:24:21 -07:00

14 KiB

Changelog

All notable changes to AIPass will be documented in this file.

The format is based on Keep a Changelog, and this project uses Calendar Versioning in the format YYYY.WNN (year and ISO week number).


[2026.W23] - 2026-06-02

Added

  • drone rm — provider-agnostic safe delete — a contained recursive delete that lets agents clean up scratch dirs without tripping the rm -rf block. Deletes are confined to the project root and the system temp dirs (/tmp and $TMPDIR), refusing anything outside (home, /etc, /, etc.). Even inside those roots it hard-refuses protected internals — .git, .trinity/, .aipass/, .codex/, .agents/, and sibling-branch worktrees — mirroring the filesystem boundary an OS-sandboxed agent (e.g. Codex) enforces, so behavior is consistent across CLIs. Pure-Python (shutil.rmtree), with a red-team test suite for containment escapes (symlinks, traversal, sibling branches). (#630)
  • rm_gate hook — block raw recursive rm, teach the safe path — a PreToolUse gate (mirroring git_gate) that blocks raw rm -r/-rf/-fr/ --recursive and redirects the agent to drone rm. Provider-agnostic (runs in the hook engine, not tied to Claude Code permission rules), conservative (unparseable targets are blocked, not allowed), and skips drone rm itself. This makes the safe-delete path discoverable at the moment of friction. (#630)

Changed

  • Retired the blanket rm deny from provider settings — setup.sh and aipass init no longer ship Bash(rm -rf*) / Bash(rm -r *) deny rules (they were mis-filed among git rules, blocked all /tmp cleanup, and gave a bare "permission denied" with no guidance). The rm_gate hook + drone rm now own this — cross-provider, path-aware, and they teach. aipass doctor detects the stale rules on existing installs and aipass doctor --fix removes them (idempotent, preserves all other rules). Claude Code still natively circuit-breaks rm -rf / and rm -rf ~. (#630)

Fixed

  • A release merge can no longer destroy the dev branch — drone @git merge passed --delete-branch to gh pr merge unconditionally, so merging a dev→main PR deleted the persistent dev branch on the remote and stranded the working tree on main (the next commit silently landing on main). Merge now looks up the PR's head ref and only deletes non-protected branches — dev and main are never deleted, and an undeterminable head ref fails safe (no delete). After a merge it returns the working tree to dev (loud warning if it can't). drone @git branches now runs fetch --prune before listing so it reflects the live remote instead of stale cached refs, and a new drone @git prune-temp cleans up merged temp PR branches. (#625)
  • drone @git status/diff show their scope — when scoped to a branch (no --all), output now appends "(showing scope — use --all for full repo)", so an empty scoped view is no longer mistaken for a clean repo. (#623)
  • External projects can call AIPass branches via drone — drone @api ... (and any drone @X) now resolves from a non-AIPass project CWD instead of being blocked with "path escapes project root." The resolver was validating a branch's path against the primary registry root even when the branch was found via the AIPASS_HOME fallback, so any external project (Vera Studio, Daemon) hit a false security block. resolve_branch() now validates containment against the registry the branch was actually found in. Security is unchanged — each branch is still contained within its own declaring registry's root; genuine path escapes remain blocked. (#618)
  • aipass <command> runs instead of printing an introspection banner — aipass is a user-facing binary, so aipass doctor (and every other command) must execute, not describe itself. All 7 modules (doctor, doctor_fix, doctor_wire, handoff, help_chat, init_flow, profile) previously hit a no-args→introspection gate (a standard meant for drone @branch <module> discovery) and showed a banner on bare invocation. Now bare invocation runs the command or shows usage; the introspection banner moved to --info. The seedgo introspection standard is bypassed for these binary-invoked modules (documented).
  • Dashboard plan counts no longer zeroed on refresh — a branch's active_plans was reset to 0 by every drone @prax dashboard refresh, because PLANS.central.json only held Flow's own plans (location==FLOW_ROOT filter). The central file is now comprehensive: all plans grouped per-branch, so refresh reports each branch's real count (e.g. devpulse now shows its 12 open plans instead of 0).

[2026.W22] - 2026-05-30

Added

  • drone @hooks status — read-only viewer for a project's hook config: master switch, every hook's enabled state per event group, matchers, and an enabled/total summary. Resolves the project's .aipass/hooks.json by walking up from CWD. (DPLAN-0190 Phase B)
  • Hooks activate in every project — aipass init now writes .aipass/hooks.json, so new projects fire the hook engine out of the box (previously: no config shipped, 0 hooks fired). aipass init update union-merges the template, preserving any per-hook on/off choices the user made. aipass doctor now checks for the config's presence. Dead hook-script shipping (_ship_hooks) removed. (DPLAN-0190 Phase A)
  • README logo — centered logo image replaces plain # AIPass header. New assets/logo.png added to the repo.
  • OpenSSF Scorecard — .github/workflows/scorecard.yml runs the official OSSF Scorecard action on push to main and weekly. Publishes a public security health score at scorecard.dev with a README badge. Actions pinned by SHA.
  • GitHub Releases — publish.yml now cuts a GitHub Release on each v* tag, with notes pulled from the top CHANGELOG section and the built dist attached. PyPI publish + GitHub Release now fire from the same tag.
  • Registry descriptions — all 13 branches now have one-liner descriptions in AIPASS_REGISTRY.json. drone systems shows what each agent does instead of blank lines. Closes #607.

Changed

  • Security gates fully project-aware — both the edit gate and the subagent stop gate now derive the package name dynamically from CWD instead of hardcoding src/aipass/. Cross-branch write protection and branch detection work for any src/<package>/<branch>/ project; previously the subagent gate silently no-opped outside AIPass. 9 new external-project tests. Closes #605.
  • Hooks branch promoted to service — registry profile changed from "AIPass Workshop" to "library" so it appears in drone systems alongside the other 12 services.
  • Hooks branch hardened to 100% seedgo — the @hooks citizen took full ownership of its branch: every handler verified wired + firing, README rewritten (two-tier provider/project model, dynamic-dispatch design, event table), 2 stale tests resolved (253 pass). Dead-code/unused-function flags documented as architectural bypasses — the 15 handlers are invoked dynamically via importlib from hooks.json paths, never statically imported. (DPLAN-0191)

Release

  • Version 2.5.0 published to PyPI. Trusted publishing via GitHub Actions (publish.yml triggers on v* tags — no manual twine upload needed). The same tag now also cuts a GitHub Release with these notes attached.

Removed

  • Gemini CLI full removal — deleted .gemini/ directory (5 files) and GEMINI.md. Stripped all references from setup.sh (~50 lines), README.md, bug-report.yml, aipass init (bootstrap/scaffold/test), hooks (README/prompt/passport), and prax monitoring (~300 lines). 21 files changed, -927 lines. Closes #608.

[2026.W21] - 2026-05-25

First weekly release. AIPass now follows a Sunday release cadence: changes accumulate on dev throughout the week and merge to main as a single versioned release with notes.

Added

  • Hook engine — a new centralized dispatch system for all hook execution. A thin bridge receives events from the AI provider (Claude, Codex, etc.) and routes them through a single Python engine that reads per-project configuration, executes the appropriate handlers, and logs every invocation. Replaces 14 standalone shell/Python scripts with native handler modules organized by domain: prompt injection, security enforcement, lifecycle management, and notifications.
  • Per-project hook configuration via .aipass/hooks.json. Each project can enable, disable, or customize individual hooks without touching provider-level settings. Previously hooks fired globally with no per-project control.
  • Audio feedback on hook events using Piper TTS. All 14 handlers produce distinct spoken audio cues so operators can monitor sessions without watching the terminal. A shared sound module (hooks/apps/sound.py) provides speak() and play() with built-in mute support. Toggle with drone @hooks hooksound on|off — muting silences all 14 handlers without skipping their functional logic.
  • Hooks agent — the 13th citizen in the AIPass registry, owning all hook infrastructure: the engine, bridge, handlers, and configuration schema.
  • Dashboard plugin for devpulse — aggregates git status, session history, and dispatch state into a single startup view. Wired into the session startup protocol so branch managers see current state immediately.
  • External log routing — prax now accepts structured log entries from any branch, not just its own modules. Hook executions, dispatches, and agent activity all flow into the central monitoring log.

Changed

  • Provider settings fully migrated to bridge pattern. All hook entries in the Claude provider configuration now call the bridge dispatcher instead of individual scripts. Each hook produces its own system-reminder to the model, preserving prompt injection fidelity (a single merged bridge was found to break prompt delivery due to Claude Code's output persistence threshold).
  • setup.sh rewritten to install hooks via the bridge pattern. The old version hardcoded 14 script paths; the new version writes a single bridge call per event type and validates that the bridge module exists.
  • Documentation sweep across .claude/README.md, SECURITY.md, the global prompt, and branch-level docs to reflect the new hook architecture. References to legacy .claude/hooks/ scripts replaced with the native handler locations.
  • aipass init update now correctly preserves user-customized hook settings during project updates instead of overwriting them.
  • Seedgo snapshot tests rebuilt — the provider hooks snapshot fixture and extraction logic were structurally broken (silently passing with zero results). Both the fixture format and the test assertions have been corrected.
  • Test suite updated for hook migration — test_git_gate.py imports from the new handler module; test_bootstrap.py no longer asserts that project initialization ships standalone hook scripts (it no longer does).

Fixed

  • Settings merge on project update — aipass init update was clobbering user hook configurations. The merge logic now layers AIPass defaults under existing user settings.
  • Python 3.10 test collision — a module/function name collision caused mock patch targets to fail on Python 3.10. Test targets corrected.
  • Dead code removal — removed an unused CLI __main__.py entrypoint and cleaned up .gitignore entries that were masking tracked files.
  • Codecov patch threshold lowered to 50% to reflect the project's current coverage baseline and stop false-negative CI failures.

Removed

  • 18 standalone hook scripts in .claude/hooks/ disabled (renamed with (disabled) suffix). Their logic now lives in native handler modules under src/aipass/hooks/apps/handlers/. The old files remain on disk for reference but are no longer executed.
  • drone hook-sounds plugin disabled. Sound control moved to hooks branch as drone @hooks hooksound on|off with full mute support for all 14 handlers (the old plugin only controlled 4).

Infrastructure

  • Provider manifest migrated to bridge pattern. provider_manifest.json now stores bridge commands ($AIPASS_HOME/...bridges/claude.py EventType) instead of standalone script names. doctor_wire.py auto-wires bridge entries directly — no longer copies scripts to ~/.claude/hooks/ or generates sys.executable paths. Doctor checks validate commands exist in provider settings instead of checking for script files on disk.
  • README v3 — rewritten for external users. Tighter problem/solution framing, collapsible agent details, Gemini CLI removed (untested), user-project perspective throughout.
  • Inline handoff (aipass init run Step 11) — new default stays in the current terminal via os.execvp instead of opening a new window. Users choose "stay here" or "new window." Enables single-terminal demo recordings. Closes #610.
  • Project-aware global prompt — the global prompt loader now detects whether CWD is inside AIPass or an external project. External projects receive their own lighter prompt (from .aipass/aipass_global_prompt.md) instead of the full AIPass-internal playbook. Fixes drone @prax errors in new projects.
  • Project CLAUDE.md template — aipass init now generates a project-specific CLAUDE.md from .aipass/project_CLAUDE.md instead of copying the AIPass-internal one. Removes the startup protocol reference to drone @prax dashboard refresh which doesn't exist in external projects.
  • Gemini CLI removed from aipass init CLI choices and handoff options. GEMINI.md no longer created for new projects. Gemini CLI is being retired upstream.
  • Demo GIF added to assets/demo.gif and referenced in README.

This is the first CHANGELOG entry. Prior work is documented in the repository's commit history and branch session logs.