chore(release): bump 2.5.0 -> 2.5.1
- pyproject: patch bump (cross-OS e2e wiring harness + Windows portability fixes landed this week; CHANGELOG [2026.W23] documents the work) - tests/CROSS_OS_TESTING.md: add manual layer-3 cross-OS acceptance checklist (living draft; refined as real Win/Mac VM runs surface gaps) - prax dashboard: drop commons_mentions from quick-status calc Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
80aac59423
commit
8bd270287d
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "aipass"
|
||||
version = "2.5.0"
|
||||
version = "2.5.1"
|
||||
description = "A local multi-agent framework where your AI agents keep their memory, work together, and never ask you to re-explain context"
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
|
||||
@@ -203,21 +203,16 @@ def _calculate_quick_status_standalone(sections: Dict) -> Dict:
|
||||
"""
|
||||
ai_mail = sections.get("ai_mail", {})
|
||||
flow = sections.get("flow", {})
|
||||
commons = sections.get("commons_activity", {})
|
||||
|
||||
new_mail_raw = ai_mail.get("new", ai_mail.get("unread", 0))
|
||||
opened_raw = ai_mail.get("opened", 0)
|
||||
active_plans_raw = flow.get("active_plans", 0)
|
||||
commons_mentions_raw = commons.get("mentions", 0)
|
||||
|
||||
new_mail = len(new_mail_raw) if isinstance(new_mail_raw, list) else int(new_mail_raw or 0)
|
||||
opened_mail = len(opened_raw) if isinstance(opened_raw, list) else int(opened_raw or 0)
|
||||
active_plans = len(active_plans_raw) if isinstance(active_plans_raw, list) else int(active_plans_raw or 0)
|
||||
commons_mentions = (
|
||||
len(commons_mentions_raw) if isinstance(commons_mentions_raw, list) else int(commons_mentions_raw or 0)
|
||||
)
|
||||
|
||||
action_required = new_mail > 0 or active_plans > 0 or commons_mentions > 0
|
||||
action_required = new_mail > 0 or active_plans > 0
|
||||
|
||||
parts = []
|
||||
if new_mail > 0:
|
||||
@@ -226,14 +221,11 @@ def _calculate_quick_status_standalone(sections: Dict) -> Dict:
|
||||
parts.append(f"{opened_mail} opened")
|
||||
if active_plans > 0:
|
||||
parts.append(f"{active_plans} active plans")
|
||||
if commons_mentions > 0:
|
||||
parts.append(f"{commons_mentions} mentions")
|
||||
|
||||
return {
|
||||
"new_mail": new_mail,
|
||||
"opened_mail": opened_mail,
|
||||
"active_plans": active_plans,
|
||||
"commons_mentions": commons_mentions,
|
||||
"action_required": action_required,
|
||||
"summary": ", ".join(parts) if parts else "All clear",
|
||||
}
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
# AIPass Cross-OS Acceptance Checklist
|
||||
|
||||
**Purpose:** the definition of *"AIPass works on this OS."* Follow this top-to-bottom on any
|
||||
fresh machine or VM (Windows / macOS / Linux) to verify a real end-to-end install — the things
|
||||
automated CI structurally cannot reach (full install, interactive flows, background daemons,
|
||||
audible hooks). Copy a **Run Record** (bottom of this file) per machine and fill it in.
|
||||
|
||||
> Code is truth. A green checkbox here means *you watched it work on that OS*, not that it should.
|
||||
|
||||
---
|
||||
|
||||
## The 3 layers of cross-OS confidence
|
||||
|
||||
| Layer | What | Where it runs | Catches |
|
||||
|-------|------|---------------|---------|
|
||||
| 1 — **Static** | `drone @seedgo` Windows-compat scan | any OS, no execution | POSIX-only patterns (`os.kill`, `start_new_session`, `/tmp`, `fcntl`…) before you run |
|
||||
| 2 — **Automated** | `pytest tests/e2e` (the `e2e-wheel.yml` 4-tier gate) | CI on ubuntu+windows+macos, and locally | the wiring contract: clean-wheel install → `aipass init` scaffold → hook fires → `drone` routes |
|
||||
| 3 — **Manual** | **this checklist** | a real box / VM, by hand | full install, interactive `init run`, daemons, sound, per-branch smoke |
|
||||
|
||||
Layers 1–2 are free and run on every push. **This file is layer 3** — the human acceptance pass
|
||||
you do when you get hardware (a VM, a borrowed Mac, a new laptop).
|
||||
|
||||
---
|
||||
|
||||
## How to use
|
||||
|
||||
1. **Capture output.** Run your shell session into a log so any crash traceback is saved:
|
||||
- Linux/macOS: `script -q aipass-crossos-$(uname -s).log` (then run the checks, `exit` when done)
|
||||
- Windows PowerShell: `Start-Transcript -Path aipass-crossos-win.log` … `Stop-Transcript`
|
||||
2. Work through **Phase 0 → 7**, then the **Per-branch matrix**.
|
||||
3. For every check: run the command, compare to **Expected**, tick ⬜ → ✅ / ❌.
|
||||
4. On ❌: note the exact error in the Run Record, check the **Known gap registry** (it may be a
|
||||
tracked one), and if new, file it / email the owning branch.
|
||||
5. Paste the completed Run Record into the PR / DPLAN-0194 thread.
|
||||
|
||||
**Legend:** ✅ pass · ❌ fail · ⏭️ skipped (state why) · ⚠️ known-gap watch item
|
||||
|
||||
---
|
||||
|
||||
## Phase 0 — Environment capture (record before anything)
|
||||
|
||||
| # | Capture | Command |
|
||||
|---|---------|---------|
|
||||
| 0.1 | OS + version | `uname -a` / Win: `cmd /c ver` + `systeminfo \| findstr /B /C:"OS"` |
|
||||
| 0.2 | Arch | `uname -m` / Win: `echo %PROCESSOR_ARCHITECTURE%` |
|
||||
| 0.3 | Python | `python3 --version` (Win: `python --version`) — **must be 3.10+** |
|
||||
| 0.4 | Shell + terminal | which shell; is it Windows Terminal / cmd / PowerShell / iTerm? |
|
||||
| 0.5 | `AIPASS_HOME` | `echo $AIPASS_HOME` (Win: `echo %AIPASS_HOME%`) — note set/unset |
|
||||
| 0.6 | Git | `git --version` |
|
||||
|
||||
> **Why terminal matters:** the cp1252 stdout class of bug (fixed S190) only bites when stdout is
|
||||
> a *legacy/captured* stream. Record whether you're on UTF-8-capable Windows Terminal vs legacy
|
||||
> conhost — reds can differ.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — Clean install ⬜
|
||||
|
||||
| # | Step | Expected | Watch |
|
||||
|---|------|----------|-------|
|
||||
| 1.1 | Fresh clone or wheel copy onto the box | files present | — |
|
||||
| 1.2 | Run `setup.sh` (or `pip install -e ".[dev]"`) | exits 0; `.venv` created with pip | ⚠️ **Windows `.venv` symlink WinError 1314** — needs `os.symlink` guarded w/ copy/junction fallback (DPLAN-0194 gap) |
|
||||
| 1.3 | `drone --version` and `aipass --version` | both print a version, exit 0 | ⚠️ `.venv/bin` vs `Scripts` path resolution |
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Automated wiring (run the e2e suite on the real box) ⬜
|
||||
|
||||
| # | Step | Expected |
|
||||
|---|------|----------|
|
||||
| 2.1 | `pip install build pytest` | installed |
|
||||
| 2.2 | `python -m pytest tests/e2e -v` | **14 passed** (T0 install / T1 init scaffold / T2a hook fire / T3 drone routing) |
|
||||
|
||||
> This re-runs the CI gate on *real* hardware. If CI is green but this is red, the difference is
|
||||
> the machine (real console, real paths) — exactly what we're hunting.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — `aipass init` (real scaffold + interactive) ⬜
|
||||
|
||||
| # | Command | Expected | Watch |
|
||||
|---|---------|----------|-------|
|
||||
| 3.1 | `aipass init /tmp/demo demo` (Win: a temp path) | creates `DEMO_REGISTRY.json`, `.aipass/`, `.claude/settings.json`, `src/demo/` + prints `✓ Project initialized` | ⚠️ cp1252 banner crash (fixed S190 — verify it stays fixed) |
|
||||
| 3.2 | `aipass init run --dry-run` | shows the 12-stage plan, no writes | — |
|
||||
| 3.3 | `aipass init run --non-interactive` (in a throwaway dir) | completes all stages headless | ⚠️ symlink/daemon steps |
|
||||
| 3.4 | `aipass init run` (interactive, manual) | prompts render + accept input; completes | ⚠️ **interactive PTY** — never machine-tested; pexpect territory |
|
||||
| 3.5 | `aipass doctor` | health report renders, exit 0 | — |
|
||||
|
||||
> **@aipass is its own process — the user-facing concierge / onboarding CLI** (`init`, `doctor`,
|
||||
> scanner). It's the front door you run to *bootstrap* a project, so it's invoked directly as
|
||||
> `aipass …` and is **by design not routed through `drone @aipass`** (unlike the other 12 branches).
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — `drone` routing ⬜
|
||||
|
||||
| # | Command | Expected |
|
||||
|---|---------|----------|
|
||||
| 4.1 | `drone systems` | lists all registered branches + modules |
|
||||
| 4.2 | `drone @ai_mail --help` | help text, **exit 0** (real registry-branch subprocess — the T3 path) |
|
||||
| 4.3 | `drone @seedgo --help` | help text, exit 0 (in-process module path) |
|
||||
| 4.4 | `drone @ai_mail inbox` | inbox renders (empty is fine) |
|
||||
|
||||
---
|
||||
|
||||
## Phase 5 — Daemons / background processes ⬜
|
||||
|
||||
| # | Command | Expected | Watch |
|
||||
|---|---------|----------|-------|
|
||||
| 5.1 | `drone @ai_mail dispatch @devpulse "x-os test" "ping"` then `drone @ai_mail inbox` | mail sent; target woken | ⚠️ **`start_new_session=` POSIX kwarg** in ai_mail/flow daemon spawn |
|
||||
| 5.2 | `drone @devpulse watchdog --help` then arm a watchdog | polls lock, exits clean | ⚠️ **`os.kill` POSIX-only**; inotify vs Win file-watch |
|
||||
| 5.3 | `drone @prax monitor` (then quit) | live dashboard renders | ⚠️ interactive / curses-style on Win |
|
||||
|
||||
---
|
||||
|
||||
## Phase 6 — Hooks + sound ⬜
|
||||
|
||||
| # | Step | Expected | Watch |
|
||||
|---|------|----------|-------|
|
||||
| 6.1 | Trigger `rm_gate` (attempt a raw `rm -rf` via the agent / fire the bridge) | blocked; `src/aipass/hooks/logs/engine.jsonl` gains a record | — |
|
||||
| 6.2 | A hook with sound fires | audible cue plays | ⚠️ **`aplay` is Linux-only** — needs `afplay` (macOS) / `winsound` (Windows) |
|
||||
| 6.3 | `drone @hooks hookstatus` | per-project hook config renders | ⚠️ hardcoded `/tmp` paths |
|
||||
| 6.4 | `drone @hooks hooksound` (mute/unmute) | toggles without error | — |
|
||||
|
||||
---
|
||||
|
||||
## Phase 7 — Interactive layer (manual, hardest to automate) ⬜
|
||||
|
||||
| # | Step | Expected | Watch |
|
||||
|---|------|----------|-------|
|
||||
| 7.1 | Launch an agent session in a terminal | starts, prompt usable | ⚠️ tmux (Linux/mac) vs Windows terminal multiplexer |
|
||||
| 7.2 | `aipass init run` full interactive (if not done in 3.4) | all 12 stages accept input | ⚠️ PTY/pexpect |
|
||||
| 7.3 | Any prompt-driven flow (`--bypass`/flags where available) | bypassable for headless | — |
|
||||
|
||||
---
|
||||
|
||||
## Per-branch smoke matrix (all 13 branches)
|
||||
|
||||
Run each branch's `drone @<branch> --help` first (the universal *resolve → subprocess → execute →
|
||||
print* proof), then the listed **read-only** commands. ⚠️ = mutates state / side-effect — run only
|
||||
deliberately. Every command should **exit 0** and render readable (non-mojibake) output on the OS
|
||||
under test.
|
||||
|
||||
> **† aipass is the exception** — it's the standalone user-facing concierge CLI, invoked directly
|
||||
> (`aipass …`), **not** routed through `drone`. So it has no `drone @aipass --help` row; smoke it
|
||||
> with the `aipass` command itself. The other 12 branches all route through `drone`.
|
||||
|
||||
| Branch | `--help` ⬜ | Read-only smoke | Side-effect (run deliberately) |
|
||||
|--------|:---------:|-----------------|--------------------------------|
|
||||
| **drone** | ⬜ | `drone systems` · `drone list` · `drone --version` | `drone scan @<b>` · `drone activate @<b>` |
|
||||
| **seedgo** | ⬜ | `drone @seedgo audit` · `drone @seedgo standards_query` · `drone @seedgo diagnostics` | `drone @seedgo audit aipass` (full scan) |
|
||||
| **prax** | ⬜ | `drone @prax status` · `drone @prax dashboard` · `drone @prax log-audit` | `drone @prax monitor` (interactive) |
|
||||
| **cli** | ⬜ | `drone @cli` · `drone @cli display` · `drone @cli templates` | `drone @cli display demo` |
|
||||
| **ai_mail** | ⬜ | `drone @ai_mail inbox` · `drone @ai_mail sent` · `drone @ai_mail contacts` | ⚠️ `dispatch` / `email` / `reply` / `close` |
|
||||
| **api** | ⬜ | `drone @api status` · `drone @api stats` · `drone @api models` · `drone @api list-providers` | ⚠️ `get-key` / `validate` / `call` (touch keys/network) |
|
||||
| **flow** | ⬜ | `drone @flow list` · `drone @flow list open` | ⚠️ `create` / `close` / `restore` / `aggregate` |
|
||||
| **spawn** | ⬜ | `drone @spawn --help` · `drone @spawn sync-registry` | ⚠️ `create` / `update` / `delete` (use `--dry-run`) |
|
||||
| **trigger** | ⬜ | `drone @trigger errors` · `drone @trigger core` | ⚠️ `medic` toggle |
|
||||
| **memory** | ⬜ | `drone @memory search "test"` · `drone @memory verify` | ⚠️ `rollover` · `watch` (daemon) |
|
||||
| **aipass** † | (n/a) | `aipass --version` · `aipass --help` · `aipass init --help` · `aipass doctor` | ⚠️ `aipass init …` (scaffolds) |
|
||||
| **hooks** | ⬜ | `drone @hooks hookstatus` · `drone @hooks engine` | ⚠️ `hooksound` (mute) · `claude` (bridge) |
|
||||
| **devpulse** | ⬜ | `drone @devpulse feedback` · `drone @devpulse watchdog --help` | ⚠️ `watchdog agent @<b>` (arms wake) |
|
||||
|
||||
---
|
||||
|
||||
## Known cross-OS gap registry (living — update as fixed)
|
||||
|
||||
Tracks every confirmed/suspected portability gap so a red here is "expected, tracked" not a mystery.
|
||||
Source of truth: **DPLAN-0194**. Status: ✅ fixed · 🔧 owner assigned · ❓ suspected/untested.
|
||||
|
||||
| # | Gap | OS | Symptom | Owner | Status |
|
||||
|---|-----|----|---------| ------|--------|
|
||||
| 1 | cp1252 stdout + Rich in CLI entry points | Win | `UnicodeEncodeError('charmap')` on `aipass init` banner & `drone @branch` print | aipass/drone | ✅ S190 (`reconfigure(utf-8)` at entry) |
|
||||
| 2 | `.venv` symlink | Win | `setup.sh`/`init` → WinError 1314 (no symlink priv) | aipass | ❓ untested (CI left `AIPASS_HOME` unset) |
|
||||
| 3 | `start_new_session=` kwarg | Win | daemon spawn throws (POSIX-only) | ai_mail / flow | ❓ |
|
||||
| 4 | `os.kill` | Win | watchdog / daemon stop throws | flow + others | ❓ |
|
||||
| 5 | `.venv/bin` vs `Scripts` | Win | path resolution misses console scripts | memory / drone / ai_mail | ❓ |
|
||||
| 6 | hardcoded `/tmp` | Win | scratch-dir writes fail | hooks / seedgo | ❓ |
|
||||
| 7 | `aplay`-only audio | Win/mac | hook sound silent / errors | hooks (+ template hooks) | ❓ (mac needs `afplay`, Win `winsound`) |
|
||||
| 8 | `shell=True` usage | Win | quoting/semantics differ | hooks | ❓ |
|
||||
| 9 | `route_command` masks errors | all | real exceptions printed as "Unknown command" | aipass | 🔧 recommended (not fixed — hid gap #1 for hours) |
|
||||
|
||||
> @seedgo's `windows_compat_check.py` already scans for several of these statically — extending it
|
||||
> to flag the cp1252/entry-point pattern (#1) and the `aplay`/`/tmp`/`os.kill` patterns is **P2**.
|
||||
|
||||
---
|
||||
|
||||
## Run Record (copy one block per machine/run)
|
||||
|
||||
```
|
||||
─────────────────────────────────────────────
|
||||
AIPass Cross-OS Run Record
|
||||
Machine/VM :
|
||||
OS + version :
|
||||
Arch :
|
||||
Python :
|
||||
Shell / term :
|
||||
AIPASS_HOME :
|
||||
Commit (drone @git log -1) :
|
||||
Tester : Date :
|
||||
─────────────────────────────────────────────
|
||||
Phase 0 env capture .......... ✅ / ❌
|
||||
Phase 1 clean install ........ ✅ / ❌ notes:
|
||||
Phase 2 e2e suite (14/14) .... ✅ / ❌ notes:
|
||||
Phase 3 aipass init .......... ✅ / ❌ notes:
|
||||
Phase 4 drone routing ........ ✅ / ❌ notes:
|
||||
Phase 5 daemons .............. ✅ / ❌ notes:
|
||||
Phase 6 hooks + sound ........ ✅ / ❌ notes:
|
||||
Phase 7 interactive .......... ✅ / ❌ notes:
|
||||
Per-branch matrix (13) ....... ✅ / ❌ reds:
|
||||
─────────────────────────────────────────────
|
||||
New gaps found (file + assign):
|
||||
|
||||
Overall verdict: PASS / PARTIAL / FAIL
|
||||
─────────────────────────────────────────────
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Layer 3 of cross-OS confidence. Pairs with `tests/e2e/` (layer 2) and `drone @seedgo` Windows-compat scan (layer 1). See DPLAN-0194 for the full strategy.*
|
||||
Reference in New Issue
Block a user