Releases: AIOSAI/AIPass
v2.6.0
[2026-06-23]
The 2.6.0 release — a large dev → main merge spanning several weeks (68 commits).
Headline changes below; the granular per-merge history is in the dated sections that follow.
Added
- Compass v2 — devpulse-owned SQLite/FTS5 rated-decision engine +
/compass
human-triggered capture (separate from @memory; DB gitignored). - Decentralized daemon scheduler — each branch owns
.daemon/schedule.json;
the daemon discovers and fires. - Telegram skill — the Dev-Pass bridge ported to a self-contained AIPass skill
that consumes services as opt-in imports. - Tiered prompt injection — Tier 0 kernel every turn + Tier 1 navmap by cadence,
replacing the single always-on global prompt. - seedgo
HARDCODED_PATHstandard (#37) — flags hardcoded home paths in source
and docstrings.
Changed
- @backup fully restored —
aipass.backup.*namespace, 9-stage Rich CLI,
versioned baseline + per-file diff engine, Google Drive sync +restore. - Memory subsystem unified — single-source config limits, char-limit edit-gate,
unified entry schema, rollover safety + the silent-rollover repair. - Legacy global prompt retired across every runtime — Claude (cadence) and Codex
(SessionStart) read the same tier files. - @daemon / @commons / @skills revived to working citizens.
- Public source genericized —
Patrick→user(private memories stay gitignored).
Fixed
- Secrets hardening — no secret value reaches stdout (cleared CodeQL #86-88,
py/clear-text-logging-sensitive-data). - Memory rollover was silently dead — the PreCompact hook now delegates to
drone @memory rollover; the v1 line-count / 600-line fallback removed entirely. - Hardcoded home paths removed (seedgo #37).
@memorysymbolic.pybuilds its
8 dash-encoded branch-path names at runtime (was a literal-home-patrick-);
@praxbranch_detector.pydocstrings genericized. Both back to 100%
Hardcoded_Path. - Green-CI fixes across Linux / Windows / macOS;
dispatch_monitorPID-429
substring bug; git post-merge friction (FF-only realign).
v2.5.3
[2026-06-11]
Fixed
- seedgo audit local↔CI parity (FPLAN-0261). The local
seedgoaudit could
silently diverge from CI, breaking the "pass locally first, then ship" gate.
Three independent causes, all closed without coupling any checker to git
(.gitignoreis git's concern, not the audit's): (1) usage-scanning checkers
(unused_function,dead_code, +4)rglob'd gitignored output dirs
(artifacts/,dropbox/), so a stray local file could mark a function "used"
that a clean checkout correctly flags — every per-checker skip list hoisted to
one sharedSOURCE_SKIP_DIRS(output dirs simply aren't source). (2) The
diagnosticsstandard shelled out to barepython3 -m pyright(system python,
no pyright) and, on the resulting JSON-parse failure, returned 0 errors = clean
— a silent false-green; now usessys.executableand fails loud. (3) pyright
resolved imports against PATH-python, so results flipped with.venvactivation
— pinned via--pythonpath sys.executable. The audit is now deterministic
local == CI (proven all-13-branches-100% in an unactivated shell). Also:drone
bypasses the test-only brokerstart_background(intentional API, not dead code). - windows-setup CI: guard Linux-only sandbox tests. The kernel-sandbox build
is Linux-only (bwrap,AF_UNIXsockets,openat2); the code already guards on
sys.platform, but four test surfaces ran unconditionally and failed on
windows-latest. Module-levelpytestmark = pytest.mark.skipif(sys.platform != "linux", …)ondrone/tests/test_broker.pyandhooks/tests/test_sandbox.py;
scoped guards on the remainingAF_UNIXbroker-socket tests —
ai_mail/.../test_dispatch_monitor.py::TestBrokerRealE2E(class) and
aipass/.../test_sandbox_check.py::TestCheckBrokerAlivesocket-connect tests
(method-level, so the graceful no-broker paths still run on Windows). All skip on
Windows and run unchanged on Linux. windows-setup was green pre-sandbox-merge
(00edd8b) and red since (0b4ba63); this closes it. - Broker
start_backgroundconnect-before-bind race.drone's out-of-sandbox
broker daemon started viastart_background(), which returned before the
AF_UNIXsocket was bound — callers then raced the bind, and on a slower machine
create_identified_connection()hitFileNotFoundError(socket not yet present).
Deterministic locally (test_delete_nested_file0/5), green in CI only by timing
luck — latent flakiness. Fixed with athreading.Eventset right afterlisten();
start_background(timeout=5.0)now blocks on it and raises if the socket never
binds, so callers never guess asleep. Removed the 4 blindtime.sleep(0.15)
waits from the broker tests. Verified 55/55 broker tests, formerly-failing test 10/10.
Added
-
aipass initdetects missing Claude Code. Stage 6 (CLI choice) now checks
shutil.which("claude")when the picked CLI is Claude Code. If absent: interactive
runs promptInstall now? [Y/n]and run the canonical installer on yes (native
claude.ai/install.sh, PowerShell on Windows,npmfallback, 300s timeout, loud on
failure); non-interactive runs warn and continue. The whole system routes through
Claude Code (hook bridge, dispatch, prompt injection), so init no longer silently
assumes the runtime is present. Only fires when the chosen CLI isclaude. -
Kernel filesystem boundary for agent containment (DPLAN-0202 / FPLAN-0250).
Every autonomous agent can now launch inside a kernel-enforced mount namespace
(@anthropic-ai/sandbox-runtime→ bwrap+seccomp) where reads stay fully open
(the shared live filesystem is preserved — a bind-mount, not isolation: own-tree
writes land live on the real FS instantly) but deletes/overwrites of protected
paths (.git, sibling branch trees) fail at the kernel no matter how the call is
phrased —rm,python os.remove,find -delete, Write tool all hit EROFS.
/tmpand the agent's own tree stay writable;.gitis RW for devpulse, RO for
builders. A per-role policy generator (@hooks build_policy) derives each branch's
writable/RO map from its passport. Privileged deletes route through an
out-of-sandbox drone-broker daemon: identity-scoped allowlist,openat2
RESOLVE_BENEATH path re-resolution (confused-deputy proof), HMAC identity handshake
over a pre-connected inherited fd, JSONL audit.aipass doctorgained a Sandbox
check group (bwrap present+functional, node, srt, rg, broker socket) that is LOUD
when the flag is on and a prereq is missing — never a silent unsandboxed launch.
Proven by a live 16-check red-team suite. Inert by default — gated behind
AIPASS_SANDBOX_ENABLED(off); flag-off is byte-identical to the old dispatch path. -
rm_gate demoted to guardrail. Now framed honestly as early-feedback that
catches the accidentalrm -rfand teachesdrone rm— belt-and-suspenders, with
the kernel sandbox as the actual filesystem boundary. -
Prompt-injection cadence — fire the big loaders every Nth turn. The global
and branch prompts are large and were re-injected on every turn even though a
prior copy stays in the conversation. They now fire together every 5th turn
(config-tunable viahooks_json/custom_config/cadence_config.json), with a
per-session turn counter that resets on a new session and after compaction so
context is always rebuilt when it's actually needed. Identity and the mail flag
stay every-turn (tiny, want freshness). Cuts recurring per-turn context cost. -
Hook fire/skip observability. Cadence emits a structured
[HOOKS] cadence fired|skipped loader= turn= period= offset=line; the prax
monitor renders hook events distinctly so the cadence is visible live. -
Slim global prompt — context-on-demand. The always-injected global prompt
was rewritten from a ~13.8KB encyclopedia into a ~7.8KB navigation map
(DPLAN-0201):dronepinned as the router, the framework tree, all 13 agents
as short bios, and one drilled reflex — rundrone @agent --helpbefore using
a branch. Detail now lives in each agent's--help, fetched on demand. This
also dissolves the harness ~10k-char truncation that was silently dropping the
old prompt's tail; the slim prompt injects whole. Backup retained alongside.
Changed
- Shared leaf library re-homed:
aipass.common→aipass.aipass.shared(FPLAN-0260).
src/aipass/common/was the only non-citizen directory in the agent namespace —
a shared lib (json_handler / json_ops / registry_discovery, extracted in
TDPLAN-0006 P2) parked as a sibling to the agents with no owner. Per @seedgo
design review it now lives inside its steward atsrc/aipass/aipass/shared/,
owned by @aipass; @Spawn imports across (same blessed shared-infra category as
aipass.prax/aipass.cli). Content byte-identical; ~9 import/doc sites updated
across aipass+spawn. A new subprocess guard test pins the bootstrap-safety
invariant: importingshared/loads zero branch dependencies, soaipass init
keeps working pre-drone on fresh machines. Note:aipass.commonshipped in the
v2.5.2 wheel; it was internal plumbing — no deprecation shim. - Action-gated hook sound. Piper now speaks only when a hook actually does
something — handlers return asoundkey the engine plays, instead of
announcing on every invocation. Skipped loaders are silent. Quieter and honest. - README: hardcoded metrics → live badges + qualitative. Version is now a
live PyPI badge, test/PR counts replaced with a codecov coverage badge (75%
minimum) and qualitative wording — no more stale numbers to hand-maintain.
Fixed
- Cadence counter separate-process race. Each
UserPromptSubmithook runs as
its own OS process, so a module-level turn cache double-incremented and the
loaders leapfrogged (firing erratically instead of together). Fixed with an
mtime debounce + transcript-size token +flockso the counter advances exactly
once per real turn, verified against the live execution model. auto_fixran no diagnostics. A leftoverspeak()call (its import removed
in the sound refactor) raisedNameErroron every edit, swallowed by the
handler's broadexcept— so auto-fix silently surfaced nothing on any
.py/.jsonedit. Removed the dead call; diagnostics run again.- Hook events never colored in the monitor. The prax log-watcher's
_HOOK_PATTERNrequired anaction=field that cadence never emits (it logs
the action as the bare second word,fired/skipped), so extraction failed
and events fell through to plain rendering instead of the styled
bold-green ⚡ / dim · treatment. Fixed the regex to capture the bare action
word and enriched the event detail (period, offset, short session id).
Security
- Least-privilege token on the
e2e-wheelworkflow.e2e-wheel.ymlwas the
one CI workflow missing a top-levelpermissions:block (it was added during
the cross-OS work after PR #624 hardened the others), so it ran with the
default broadGITHUB_TOKENscopes — dropping the OpenSSF Scorecard
Token-Permissions check to 0. Addedpermissions: contents: read; the
workflow only reads the repo to build and smoke-test the wheel. - Signed GitHub Releases via Sigstore (keyless). The release workflow now
signs the built wheel + sdist withsigstore/gh-action-sigstore-python
(keyless OIDC — no signing key is generated, stored, or held by anyone) and
attaches the resulting.sigstore.jsonbundles to the GitHub Release. PyPI
uploads were already attested via Trusted Publishing; this extends verifiable
provenance to artifacts pulled from GitHub Releases and satisfies the OpenSSF
Scorecard Signed-Releases check. First proof lands on the nextv*tag.
v2.5.2
[2026.W24] - 2026-06-08
Security
- Least-privilege token on the
e2e-wheelworkflow.e2e-wheel.ymlwas the
one CI workflow missing a top-levelpermissions:block (it was added during
the cross-OS work after PR #624 hardened the others), so it ran with the
default broadGITHUB_TOKENscopes — dropping the OpenSSF Scorecard
Token-Permissions check to 0. Addedpermissions: contents: read; the
workflow only reads the repo to build and smoke-test the wheel. - Signed GitHub Releases via Sigstore (keyless). The release workflow now
signs the built wheel + sdist withsigstore/gh-action-sigstore-python
(keyless OIDC — no signing key is generated, stored, or held by anyone) and
attaches the resulting.sigstore.jsonbundles to the GitHub Release. PyPI
uploads were already attested via Trusted Publishing; this extends verifiable
provenance to artifacts pulled from GitHub Releases and satisfies the OpenSSF
Scorecard Signed-Releases check. First proof lands on the nextv*tag.
v2.5.1
[2026.W23] - 2026-06-02
Fixed
aipass initscaffold correctness. A freshaipass initnow generates a
project-specificAGENTS.md(newagents_md()generator) instead of falling
back to copying AIPass's own repo-rootAGENTS.mdboilerplate — Codex users
were getting the wrong file. ProjectREADME.mdquick-start/structure paths
now reflect the realsrc/<package>/<agent>/layout.- First-agent default name
my-agent→my_agent.aipass initseeded its
default agent with a hyphen, the lone source of a long-standing dir-vs-module
mismatch (the directory kept the hyphen while the importable module,@address
and registry name all normalize to underscore). Defaulting tomy_agentmakes
directory, module,@addressand the README example all consistent. - Dead
citizenship.registry_pathremoved from spawn templates. The field
pointed at a non-existent.aipass/registry.json; it was never read anywhere
(registry is located byfind_registry()glob), so it's dropped from the
builderandbirthrightpassport templates.
Removed
- The entire STATUS flow is decommissioned (TDPLAN-0007). The per-branch
hand-maintainedSTATUS.local.mdbeacon and the auto-aggregated central
STATUS.md(853 lines / 70 KB nobody read) are gone — deleted from disk
across all 13 branches and scrubbed from every prompt, doc, startup protocol,
/prep+/memoskill, the compact-recovery hook, the email footer, and
aipass init/ spawn scaffolding. Live branch state was already fully covered
byDASHBOARD.local.json(prax) and history by.trinity/local.json. The
status-sync engine is kept intact but inert — made dormant by unwiring its
3-line trigger registration (trigger registry.py), so the code stays
revivable. The one thing STATUS uniquely gave us — a quick scratch todo — is
replaced by an operationaltodos[]section in.trinity/local.json
(@memory-owned schema, capped, never vectorized by rollover), pushed to all 13
branches and surfaced as atodo_counton the dashboard. Shipped as one
coordinated cross-branch change (memory, prax, trigger, aipass, spawn, hooks,
ai_mail, seedgo + devpulse).
Changed
- All 13 branches at seedgo 100% under the new introspection standard.
Wrappedprint_introspection()output in Rich markup across ai_mail, drone,
spawn, trigger, prax and devpulse (the rest were already compliant) —
presentation only, no logic change — sodrone @branchwith no args renders
consistent styled output everywhere. - CLI polish for human-facing output.
drone @hooks --helprewritten (Rich,
withhooksound on/off/statusnow surfaced);drone @spawnrepair help
clarified as distinct fromupdateand showing the preview/--applyflow;
drone restores Rich colour on human-facing routed output (--help,
introspection,status) via the inherit path. - Spawn backups land in one namespace
.spawn/.recovery/(TDPLAN-0006 P4).
Spawn's pre-merge JSON backups previously dropped a.recovery/directory at
each branch root (which had accumulated 242 stale auto-generatedDASHBOARD
backups across 10 branches).aipass.common.json_ops.backup_jsongained an
optionalbackup_dirparameter (default unchanged), and spawn's update engine
now directs backups to{branch}/.spawn/.recovery/— tucked under the
spawn-managed.spawn/dir instead of cluttering the branch root. Memory stays
in the safety net (the engine simply never touches.trinity//DASHBOARDon
update, so it never needs to back them up). Stale.recovery/backups cleaned
up. (315 tests, seedgo 100%.) - No more cross-branch engine imports —
aipass init updatecalls spawn via
subprocess (TDPLAN-0006 P3).init_flow.pypreviously did
from aipass.spawn.apps.modules.sync_registry import sync_registry— the one
place aipass reached directly into spawn's Python. Replaced with a subprocess
call to the already-existingdrone @spawn sync-registry --fix(same pattern as
aipass init agent→drone @spawn create), preserving graceful degradation
(a missingdrone, non-zero exit, or timeout is silently skipped — registry
sync never hard-fails an update). The aipass branch now has zero direct
imports of another branch's engine code; the remaining cross-branch imports are
shared service layers only (cli Rich UI, prax logging, trigger events). (438
tests, seedgo 100%.) aipass.commonshared library — dedup spawn/aipass scaffold machinery
(TDPLAN-0006 P2).@spawnand@aipasseach carried their own copy of the
JSON merge/handler utilities and registry discovery. Extracted them into a new
branch-free packagesrc/aipass/common/(json_ops=deep_merge+
backup_json;json_handler.JsonHandler;registry_discovery.find_registry)
that both branches now import.aipass.commonimports zero branch code, so
aipass/bootstrap.py(which runs before the drone runtime exists) can depend on
it without breaking the pre-infrastructure constraint. The duplicated copies are
deleted (spawn keeps a thin re-export shim; aipass'sjson_handlershrank
254 → 88 lines). Thesave_jsoncontract is unified to raiseValueError
on invalid structure across both branches. (313 spawn + 434 aipass tests, both
seedgo 100%.)
Fixed
- Flow plan-type self-serve UX — register override, help, orphan cleanup.
Explicitdrone @flow register <dir> <PREFIX>now overrides an auto-derived
prefix instead of silently failing (guarded — refuses if the auto-registered
type already holds plans), so custom prefixes are settable when adding a new
plan type.create/templates --helprewritten to dynamically list registered
types + templates and document the add-a-new-type workflow. Stale orphan plan
registries removed; deadprefix_exists()dropped. (728 tests, seedgo 100%.) drone @spawn updateno longer scrambles branches (#636, critical — TDPLAN-0006
P0+P1). The update engine compared a freshly-created branch against the class
template by content hash with rename-detection, and because the CREATE path
regenerated template-registry IDs in filesystem-walk order (≠ the master's
hand-crafted IDs), a branch created seconds earlier produced 30 proposed renames
that rotated identity/memory dirs into each other
(apps→.trinity→.seedgo→.claude→.archive→.aipass), turnedREADMEinto
DASHBOARD, and deep-merged stale template into live.trinity/memory —
update <class> --allwould have destroyed every citizen in one command. Rebuilt
update_ops.py(v2.0) on an explicit named-managed-files + path-based model:
.trinity/*,DASHBOARD.local.json,artifacts/birth_certificate.jsonand
.seedgo/bypass.jsonare delivered on create only and never touched on update;
the create==update invariant now yields 0 renames / 0 merges on a fresh branch.
The old ID-based engine (change_detection.py,reconcile.py) is deleted.- Destructive spawn ops are now dry-run by default (TDPLAN-0006 P0).
drone @spawn updateanddrone @spawn repairpreview by default and require an explicit
--applyto write — forgetting a flag is now a safe no-op instead of irreversible
damage (--dry-runkept as an alias).aipass doctorrepair suggestions emit the
matching--applyform.
Added
- Introspection Rich-formatting standard (seedgo). New
check_introspection_rich_formattingchecker enforces that each branch's
print_introspection()output uses Rich markup (delegation-aware — it walks
_-prefixed helper functions), keeping no-argdrone @branchoutput styled and
consistent. Documented inintrospection.md; all 13 branches brought into
compliance (see Changed). - Playbook plan type (
PBPLAN) — reusable SOP checklists (flow). A new
playbook_planstemplate family for throwaway, vectorize-on-close operational
runbooks (first SOP: the Sunday merge). Drop a.mdunder
templates/playbook_plans/, register once, then
drone @flow create . "subject" <sop>stamps a run to tick through and close. - Memory-pool auto-processing (TDPLAN-0005) — dropped files in
memory/memory_pool/are now vectorized and archived automatically on
session-start and pre-compact, instead of requiring a manual
drone @memory pool process. A 3-branch build:@memorygains an intake
handler +poolmodule (processes then empties the pool,keep_recent=0),
@hooksadds alifecycle/auto_processhandler (session-guarded via
CLAUDE_CODE_SESSION_ID, since Claude Code has no SessionStart hook), and
@triggergains event #15 (memory_pool_auto_processed) with a Medic error
path. Runtime pool dirs (memory_pool/,memory_pool_archive/) are now
gitignored. - HVTracker badge added to the README badge cluster, linking to the public
agent profile at hvtracker.net (closes #628). git_gateread-verb allowlist — raw read-only git for every branch. The
PreToolUsegit_gatepreviously blocked all raw git (forcingdrone @git
even for harmless reads), which left agents unable to inspect what git ships —
the exact forensics needed to diagnose the audit gap above. It now allows 22
read-only verbs raw (ls-files,ls-tree,show,cat-file,rev-parse,
rev-list,log,status,diff,blame,archive,grep, …) while
write operations staydrone-gated. Global options (-C,-c,--git-dir,
…) are skipped when extracting the verb, and chained commands are split on
&&/||/;/|so a read piped into a write still blocks the whole line.
(81 tests)- Cross-OS end-to-end WIRING test (
tests/e2e/,e2e-wheel.yml) — the first
CI gate that proves real AIPass wiring (not units-with-mocks) by building the
wheel, installing it into a clean venv, and asserting a 4-tier ladder: package
install + console scripts (T0),aipass init...
v2.5.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.jsonby walking
up from CWD. (DPLAN-0190 Phase B)- Hooks activate in every project —
aipass initnow 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 doctornow checks for the config's presence. Dead hook-script
shipping (_ship_hooks) removed. (DPLAN-0190 Phase A) - README logo — centered logo image replaces plain
# AIPassheader.
Newassets/logo.pngadded to the repo. - OpenSSF Scorecard —
.github/workflows/scorecard.ymlruns the official
OSSF Scorecard action on push tomainand weekly. Publishes a public security
health score at scorecard.dev with a README badge. Actions pinned by SHA. - GitHub Releases —
publish.ymlnow cuts a GitHub Release on eachv*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
inAIPASS_REGISTRY.json.drone systemsshows 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 hardcodingsrc/aipass/. Cross-branch write protection and branch
detection work for anysrc/<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 indrone systemsalongside
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 viaimportlibfromhooks.jsonpaths, never statically
imported. (DPLAN-0191)
Release
- Version 2.5.0 published to PyPI. Trusted publishing via GitHub Actions
(publish.ymltriggers onv*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 fromsetup.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.