Commit Graph
540 Commits
Author SHA1 Message Date
AIOSAIand@cli fd2f2be2dd feat(cli): feat(cli): bootstrap ships hooks + /memo to new projects (DPLAN-0139 Track D)
Co-Authored-By: @cli <cli@aipass>
2026-04-22 09:56:16 -07:00
AIOSAIand@seedgo 60c8515985 feat(system): feat(seedgo): audit cleanup — hooks.py + hooks_ext.py + README (DPLAN-0139 close-out)
Co-Authored-By: @seedgo <seedgo@aipass>
2026-04-22 09:49:07 -07:00
AIOSAIand@devpulse 2e89a923b6 feat(system): fix(dispatch): switch default model from sonnet to opus 4.6 — all dispatched agents now run on Opus 4.6 (DPLAN-0141 Phase 1)
Co-Authored-By: @devpulse <devpulse@aipass>
2026-04-22 09:42:49 -07:00
AIPass a2ca38f557 Merge pull request #382 from AIOSAI/system/devpulse-docs-lowercase-shouting-imperatives-in-localglobal
feat(system): docs: lowercase shouting imperatives in local+global prompts (volume isn't the fix)
2026-04-22 09:38:16 -07:00
AIOSAIand@devpulse c2805e6963 feat(system): docs: lowercase shouting imperatives in local+global prompts (volume isn't the fix)
Co-Authored-By: @devpulse <devpulse@aipass>
2026-04-21 15:41:10 -07:00
AIOSAIand@devpulse 262bfd368d feat(system): feat(seedgo): audit cleanup — hooks.py + hooks_ext.py + new handlers/hooks/ (rescue from @seedgo silent-finish)
Co-Authored-By: @devpulse <devpulse@aipass>
2026-04-21 15:36:02 -07:00
AIOSAIand@devpulse 8ff5b5c426 feat(system): docs(drone): update README — document status_handler_gitpython.py (DPLAN-0140)
Co-Authored-By: @devpulse <devpulse@aipass>
2026-04-21 13:24:47 -07:00
AIOSAIand@devpulse ab30282532 feat(system): fix(drone): resolve 8 pyright type errors in status_handler_gitpython.py — TYPE_CHECKING pattern, logger.info, None handling (audit cleanup)
Co-Authored-By: @devpulse <devpulse@aipass>
2026-04-21 12:16:18 -07:00
AIOSAIand@devpulse f90816a29b feat(system): docs+settings: drill no-merge rule + add git branch-creation deny patterns (Track F repo-side)
Co-Authored-By: @devpulse <devpulse@aipass>
2026-04-21 10:07:40 -07:00
AIOSAIand@devpulse be1a2697d6 feat(system): feat(drone): DPLAN-0139 Track F — git main-only enforcement
Co-Authored-By: @devpulse <devpulse@aipass>
2026-04-21 09:06:53 -07:00
AIPass 806014ca07 Merge pull request #376 from AIOSAI/system/devpulse-docs-drill-main-only-git-rule-into-global-prompt-c
feat(system): docs: drill main-only git rule into global prompt, CLAUDE.md, devpulse local prompt (S101 fix)
2026-04-21 08:41:05 -07:00
AIOSAIand@devpulse d1a0be6630 feat(system): docs: drill main-only git rule into global prompt, CLAUDE.md, devpulse local prompt (S101 fix)
Co-Authored-By: @devpulse <devpulse@aipass>
2026-04-21 08:40:34 -07:00
AIPass bd92bb8351 Merge pull request #373 from AIOSAI/citizen/seedgo-hook-test-suite-track-b
feat(hooks): DPLAN-0139 Track B — hook test suite unification
2026-04-21 08:30:30 -07:00
AIOSAI 52c3effd86 merge main into #373 — take Track B version of hooks.py (superset of Track A) 2026-04-21 08:30:08 -07:00
AIPass b418e7087f Merge pull request #372 from AIOSAI/citizen/seedgo-hook-consolidation-track-a
feat(hooks): DPLAN-0139 Track A — hook consolidation
2026-04-21 08:28:59 -07:00
AIOSAI 3e5bb8cc0f merge main into #372 — take main versions of auto_fix_diagnostics + pre_edit_gate (supersets of Track A baseline) 2026-04-21 08:28:39 -07:00
AIPass e213d68afa Merge pull request #370 from AIOSAI/citizen/seedgo-ruff-checklist-gap
feat(seedgo+hooks): close ruff F401 checklist gap — hard-block lint in pre-edit gate
2026-04-21 08:27:38 -07:00
AIOSAI 16be5ab96e merge main into #370 — take Track E v1.3.0 (compatible with #370's auto_fix lint additions) 2026-04-21 08:26:59 -07:00
AIPass 1a19e7388e Merge pull request #371 from AIOSAI/citizen/seedgo-hook-probe-suite
feat(seedgo+hooks): DPLAN-0139 Track H — hook probe suite + drone @seedgo hooks probe
2026-04-21 08:24:27 -07:00
AIPass 16fa4e0906 Merge pull request #368 from padddypaddypaddy-boop/fix/mac-test-symlink-resolve
fix(drone): resolve tempdir fixture in registry_handler tests — unblock Mac (issue #360 finding A1)
2026-04-21 08:24:12 -07:00
AIPass 2d77d65204 Merge pull request #374 from AIOSAI/proto/drone-dplan-0140-phase1
proto(drone): DPLAN-0140 Phase 1 — GitPython @git status prototype + investigation
2026-04-21 08:21:11 -07:00
AIPass 378db873ca Merge pull request #375 from AIOSAI/citizen/seedgo-track-e-single-path
feat(hooks+seedgo): DPLAN-0139 Track E — single-path enforcement
2026-04-21 08:20:59 -07:00
AIOSAIandClaude Sonnet 4.6 49c599062e feat(hooks+seedgo): DPLAN-0139 Track E — single-path enforcement
Adds physical blockers so agents cannot bypass the correct delivery paths:

1. pre_edit_gate.py v1.3.0 (.claude/hooks/) — two new Track E rules:
   - Rule 1: block any write to *.ai_mail.local/inbox.json (use drone @ai_mail email)
   - Rule 2: block cross-branch writes unless CWD branch is in TRUSTED_CROSS_WRITERS

2. permissions.py (seedgo/apps/modules/) — single source of truth:
   - TRUSTED_CROSS_WRITERS = ("devpulse", "seedgo", "spawn")
   - is_trusted_caller(name), identify_caller(cwd)

3. drone auth.py — ALLOWED_CALLERS now imported from permissions.py
   (extended from ["devpulse"] to all three trusted cross-writers)

4. ai_mail delivery.py — deliver_to_inbox_file() helper added:
   - Single canonical path for direct-path inbox writes, always fires notify-send
   - reply.py _deliver_via_reply_path() backdoor routes through this helper

5. inbox_audit.py (seedgo/apps/modules/) — drone @seedgo audit inbox-ids:
   - Scans all inbox.json files for non-8-hex message ids
   - Alerts with drone @ai_mail email command when violations found

6. test_hooks_track_e.py — 26 tests, all passing (359 total in suite)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 08:18:07 -07:00
AIOSAIand@drone 5dd66bd05b proto(drone): DPLAN-0140 Phase 1 — GitPython @git status prototype + investigation
Phase 1 deliverables:
- Subprocess audit: ~44 calls across 8 files inventoried
- Library comparison: GitPython recommended (maturity, pure-Python, Windows support)
- Prototype: status_handler_gitpython.py implements get_branch_status() via GitPython
- Benchmark results: subprocess 13.9ms avg vs GitPython 27.9ms avg (acceptable delta)
- Pathspec scope limitation documented (hit by @seedgo PRs #371-#373)
- Phase 2 surface expansion priorities listed

Co-Authored-By: @drone <drone@aipass>
2026-04-21 00:42:25 -07:00
AIOSAI d46a649cc0 feat(seedgo+hooks): DPLAN-0139 Track B — hook test suite unification
- hooks.py v1.1.0: new test and list subcommands
- hooks_ext.py: cmd_hooks_test (pytest per test file, Rich table) +
  cmd_hooks_list (reads ~/.claude/settings.json + .claude/settings.json,
  shows all wired hooks with version, event, matcher, exists status)
- Version headers added to notification_sound.py, stop_sound.py,
  tool_use_sound.py (all 10 hooks now have version headers)
- test_hooks_utility.py: 14 smoke tests for 7 previously uncovered hooks
  (branch_prompt_loader, email_notification, identity_injector, pre_compact,
  notification_sound, stop_sound, tool_use_sound)
- test_hooks_track_b.py: 7 tests for hooks test + hooks list subcommands
- 443 total tests passing (422 → 443)

Note: drone @git pr scope bug (DPLAN-0140) hit again — raw git/gh used.
2026-04-21 00:31:08 -07:00
AIOSAI 56555aff12 feat(seedgo+hooks): DPLAN-0139 Track H — hook probe suite + drone @seedgo hooks probe
Adds an observational probe harness for every Claude Code hook event type.
Used to verify hook wiring, scaffold new hooks, and answer Q12 (subagent
hook propagation / env-var matrix).

## What ships

**7 probe scripts** at `.claude/hooks/probes/`:
- probe_pre_tool_use.py, probe_post_tool_use.py, probe_user_prompt_submit.py
- probe_subagent_stop.py, probe_pre_compact.py, probe_stop.py, probe_notification.py

Each probe: reads stdin JSON, appends one entry to last_ping.jsonl
(APPEND mode, never overwrites), exits 0 always. Fields recorded:
event, tool, cwd, agent_id, timestamp, script_elapsed_ms, cli_version,
env_has_claude_project_dir, env_has_aipass_home.

Pure stdlib, no aipass imports. Silent fail on any exception.
OPT-IN — not auto-wired in settings.json (each probe docstring has
the settings.json snippet to enable it).

**drone @seedgo hooks probe** — new seedgo module (apps/modules/hooks.py):
- No flags: reads last_ping.jsonl, prints Rich [PROBE] table of recent entries
- --subagent: spawns claude -p headless, reads probe log, reports whether
  PostToolUse / SubagentStop fired (definitive Q12 data for headless mode)
- --matrix: analyzes last_ping.jsonl by event type, reports env var
  propagation patterns, writes Q12_findings_2026-04-20.md

**Tests**: 69 new tests in tests/test_hooks_probe.py covering stdin parse,
output shape, malformed input resilience, and module dispatch.
402 total tests pass.

**README.md** at .claude/hooks/probes/README.md — enable instructions,
example output, flag reference.

last_ping.jsonl added to .gitignore (live log, not source).
2026-04-21 00:13:18 -07:00
AIOSAI fe3e07f791 feat(seedgo+hooks): DPLAN-0139 Track A — hook consolidation
- auto_fix_diagnostics.py v5.3.0: [SILENT-FIX] label, IDE fallback with
  loud stderr announce when pyright unavailable, ruff lint hard-block
- pre_edit_gate.py v1.2.0: added to AIPass/.claude/hooks/ + wired to
  PreToolUse in ~/.claude/settings.json (first time gate runs in production)
- Delete .claude/global_hooks/ (v4.3.0 stale, nothing references it)
- MANIFEST.in + pyproject.toml force-include: .claude/hooks/ in pip wheel
  at aipass/_hooks/ — verified via pip wheel build
- 20 new tests (test_hooks_track_a.py): auto_fix, pre_edit_gate,
  subagent_stop_gate — all pass (422 total)

Note: drone @git pr scope bug (DPLAN-0140) blocked staging .claude/hooks/
changes — raw git used. ~/.claude/settings.json PreToolUse update is
out-of-repo (not in this commit).
2026-04-21 00:06:40 -07:00
AIOSAI a06421a35d feat(seedgo+hooks): DPLAN-0139 Track H — hook probe suite + drone @seedgo hooks probe
Adds an observational probe harness for every Claude Code hook event type.
Used to verify hook wiring, scaffold new hooks, and answer Q12 (subagent
hook propagation / env-var matrix).

## What ships

**7 probe scripts** at `.claude/hooks/probes/`:
- probe_pre_tool_use.py, probe_post_tool_use.py, probe_user_prompt_submit.py
- probe_subagent_stop.py, probe_pre_compact.py, probe_stop.py, probe_notification.py

Each probe: reads stdin JSON, appends one entry to last_ping.jsonl
(APPEND mode, never overwrites), exits 0 always. Fields recorded:
event, tool, cwd, agent_id, timestamp, script_elapsed_ms, cli_version,
env_has_claude_project_dir, env_has_aipass_home.

Pure stdlib, no aipass imports. Silent fail on any exception.
OPT-IN — not auto-wired in settings.json (each probe docstring has
the settings.json snippet to enable it).

**drone @seedgo hooks probe** — new seedgo module (apps/modules/hooks.py):
- No flags: reads last_ping.jsonl, prints Rich [PROBE] table of recent entries
- --subagent: spawns claude -p headless, reads probe log, reports whether
  PostToolUse / SubagentStop fired (definitive Q12 data for headless mode)
- --matrix: analyzes last_ping.jsonl by event type, reports env var
  propagation patterns, writes Q12_findings_2026-04-20.md

**Tests**: 69 new tests in tests/test_hooks_probe.py covering stdin parse,
output shape, malformed input resilience, and module dispatch.
402 total tests pass.

**README.md** at .claude/hooks/probes/README.md — enable instructions,
example output, flag reference.

last_ping.jsonl added to .gitignore (live log, not source).
2026-04-20 23:44:58 -07:00
AIOSAI d5053abb9d feat(seedgo+hooks): close ruff F401 checklist gap — hard-block lint errors in pre-edit gate
ruff_check was branch_level only so drone @seedgo checklist <file> skipped
it entirely. F401 unused imports slipped through to main twice (PRs #349,
#357) because neither checklist nor the pre-edit gate caught them per-file.

Changes:
- ruff_check.py v1.1.0: add check_module() for single-file ruff runs +
  _find_ruff_bypass_from_file() to locate .seedgo/ruff_bypass.json from
  any file path. AUDIT_SCOPE stays branch_level (audit pipeline unchanged).
- checklist.py: update _is_applicable() — branch_level checkers that also
  implement check_module() are now eligible for per-file checklist runs.
  ruff_check gains per-file enforcement; dead_code/test_quality/unused_function
  remain skipped (genuinely need full branch context).
- auto_fix_diagnostics.py v5.2.0: add run_ruff_lint_structured() — runs
  ruff --output-format=json and saves violations as {line, message} dicts
  alongside pyright errors in the state file. Pre-edit gate now hard-blocks
  on F401/lint just like type errors.
- pre_edit_gate.py v1.2.0: generalize reason message from "type error(s)"
  to "error(s)" since state now contains lint violations too.

Verification: drone @seedgo checklist <F401 file> now shows ✗ ruff: 2
violation(s) — F401 L1/L2. 333 seedgo tests pass.
2026-04-20 17:37:31 -07:00
AIPass 32b97c45cc Merge branch 'main' into fix/mac-test-symlink-resolve 2026-04-20 17:09:45 -07:00
AIPass fc4b5801a1 Merge pull request #369 from AIOSAI/system/devpulse-choreaimail-remove-unused-imports-in-test-files-un
feat(system): chore(ai_mail): remove unused imports in test files — unblock CI for PR #368
2026-04-20 17:09:18 -07:00
AIOSAIand@devpulse 714b059403 feat(system): chore(ai_mail): remove unused imports in test files — unblock CI for PR #368
Co-Authored-By: @devpulse <devpulse@aipass>
2026-04-20 17:08:21 -07:00
PaddyandClaude Opus 4.7 e9fed96518 fix(drone): resolve tempdir fixture in registry_handler tests — unblock Mac (issue #360 finding A1)
Two tests failed on macOS due to the /var/folders → /private/var/folders symlink:
- test_relative_paths_resolved (line 126: string startswith mismatch)
- test_find_registry_from_child_dir (line 377: Path == comparison)

Root cause: tempfile.mkdtemp() returns the unresolved /var/folders/... form on Mac. Production code (PR #361 / 8a5fbf6) correctly calls Path.resolve() which follows the symlink and canonicalizes to /private/var/folders/.... The test fixture's registry_dir stored the unresolved form, so one side of each comparison had /private/ and the other didn't.

One-line fix: .resolve() the fixture path too so both sides are canonical on every platform.

Platform behavior:
- Linux: no-op (no symlink, path already canonical) — was passing, stays passing
- macOS: follows /var/folders → /private/var/folders — was failing (2/33), now passing (33/33)
- Windows: normalizes short-path to long-path consistently with production code — was passing, stays passing

Verified locally on macOS 12.7.6 Intel: 33/33 in test_registry_handler.py green after fix.

Surfaced during the Mac install feedback session on issue #360. Linux @devpulse green-lit the direct PR.

Follow-up recommendation (NOT this PR, separate cleanup): migrate registry_dir fixture to pytest's built-in tmp_path, which returns a pre-resolved Path. Eliminates the class of fixture bug entirely across the test suite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 14:54:37 -07:00
AIPass 7ce3c3ccc6 Merge pull request #367 from AIOSAI/system/devpulse-fixsetup-bootstrap-banner-count-15-11-reflects-act
feat(system): fix(setup): bootstrap banner count 15 → 11 — reflects actual core branch count (#360 finding B5)
2026-04-20 14:31:35 -07:00
AIOSAIand@devpulse a8abdedfa5 feat(system): fix(setup): bootstrap banner count 15 → 11 — reflects actual core branch count (#360 finding B5)
Co-Authored-By: @devpulse <devpulse@aipass>
2026-04-20 14:31:23 -07:00
AIPass f10ec5c619 Merge pull request #366 from AIOSAI/citizen/drone
feat(drone): UX fixes batch — sync --autostash, fix --dry-run + help, mail view N by index (B1/B2/B3)
2026-04-20 14:30:29 -07:00
AIOSAIand@drone 7860fdba13 feat(drone): UX fixes batch: sync --autostash, fix --dry-run + help, mail view N by index (B1/B2/B3 from issue #360)
Co-Authored-By: @drone <drone@aipass>
2026-04-20 14:28:37 -07:00
AIPass b30beb5d4a Merge pull request #365 from AIOSAI/memory/fix-json-handler-test-harness
fix(memory/tests): repair test_json_handler harness — KeyError on sys.modules (#360 finding A2)
2026-04-20 14:24:03 -07:00
AIOSAIandClaude Sonnet 4.6 960925b84a fix(memory/tests): repair test_json_handler harness — KeyError on sys.modules lookup
_get_json_handler() was reading sys.modules[] directly after _fresh_json_handler
had just popped the module out. importlib.import_module() replaces the lookup so
the module is actually imported fresh each test. Also removes dead reload/pop
code from the fixture that never ran. Fixes 27 failures (issue #360 finding A2).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 14:22:56 -07:00
AIPass a8164eb691 Merge pull request #364 from AIOSAI/system/devpulse-docspolicy-propagate-git-checkout-deny-rule-throug
feat(system): docs(policy): propagate git-checkout deny rule through global prompt + devpulse prompt + drone @git --help
2026-04-20 14:16:38 -07:00
AIOSAIand@devpulse 4211990cce feat(system): docs(policy): propagate git-checkout deny rule through global prompt + devpulse prompt + drone @git --help
Co-Authored-By: @devpulse <devpulse@aipass>
2026-04-20 14:16:26 -07:00
AIPass 78df75cc98 Merge pull request #363 from AIOSAI/system/devpulse-choredeny-add-git-checkout-to-bash-deny-list-enfor
feat(system): chore(deny): add git checkout to Bash deny list — enforces drone-only git policy via permission gate
2026-04-20 14:13:26 -07:00
AIOSAIand@devpulse d7f471809a feat(system): chore(deny): add git checkout to Bash deny list — enforces drone-only git policy via permission gate
Co-Authored-By: @devpulse <devpulse@aipass>
2026-04-20 14:13:04 -07:00
AIPass 3d3754283d Merge pull request #361 from AIOSAI/citizen/ai_mail
feat(ai_mail): fix(daemon): resolve relative registry branch paths to absolute before spawn — fix @ai_mail cwd=repo-root bug (issue #360 finding #3)
2026-04-20 13:08:03 -07:00
AIOSAIand@ai_mail 9287b36d52 feat(ai_mail): fix(daemon): resolve relative registry branch paths to absolute before spawn — fix @ai_mail cwd=repo-root bug (issue #360 finding #3)
Co-Authored-By: @ai_mail <ai_mail@aipass>
2026-04-20 13:06:24 -07:00
AIOSAIandClaude Sonnet 4.6 8a5fbf6152 feat(memory): add [memory] extras group — unblock contributor pytest (#360 finding #1)
- pyproject.toml: add memory = ["numpy>=2.0", "chromadb>=1.0"] optional-deps group
- setup.sh: install .[dev,memory] so fresh-clone pytest works end-to-end
- test_vector.py: gate with pytest.importorskip("numpy"/"chromadb") — skip cleanly without extras
- memory_watcher.py: _check_vector_deps() probes venv at startup; health report now honest when chromadb absent
- bypass.json: 4 entries covering test_vector.py seedgo false-positives (architecture/docs/encapsulation/meta)
- dispatch/daemon.py: resolve relative branch_path to absolute before use
- dispatch/dispatch_monitor.py: resolve lock_file path so claude cwd is always absolute

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 13:06:20 -07:00
AIPass 71f6226f0d Merge pull request #359 from AIOSAI/citizen/drone
feat(drone): switch merge_plugin from --squash to --merge (straight merge commits only)
2026-04-20 12:12:58 -07:00
AIOSAIand@drone 6ca052f915 feat(drone): switch merge_plugin from --squash to --merge (straight merge commits only)
Co-Authored-By: @drone <drone@aipass>
2026-04-20 12:11:00 -07:00
AIPassand@ai_mail 7feafdf660 feat(ai_mail): daemon: recognize AIPASS-TEST ping token — auto-ack without spawning (Phase 3.5 redo on fresh main) (#358)
Co-authored-by: @ai_mail <ai_mail@aipass>
2026-04-20 12:02:16 -07:00
AIPassand@ai_mail 6766ae6380 feat(ai_mail): wake: manual wake blocklist — protect @devpulse from cross-branch wakes (re-do of #352 on fresh main) (#357)
Co-authored-by: @ai_mail <ai_mail@aipass>
2026-04-20 11:50:12 -07:00