From 7811381d54eed14bc053261e15a2a19f55e1d85a Mon Sep 17 00:00:00 2001 From: AIOSAI Date: Sat, 18 Jul 2026 22:10:05 -0700 Subject: [PATCH] =?UTF-8?q?fix(hooks-tests):=20stop=20test=5Flog=5Fwrite?= =?UTF-8?q?=5Ffailure=5Fdoes=5Fnot=5Fcrash=20minting=20MagicMock/LOG=5FFIL?= =?UTF-8?q?E=20dirs=20=E2=80=94=20bare-Mock=20LOG=5FFILE=20patch=20reached?= =?UTF-8?q?=20prax=20append=5Fjsonl's=20real=20mkdir=20via=20mock=20fspath?= =?UTF-8?q?;=20now=20patches=20a=20real=20tmp=20path.=20100/100=20green,?= =?UTF-8?q?=20clean-CWD=20verified=20zero=20dirs=20minted.=20S324=20scan?= =?UTF-8?q?=20finding,=20FYI=20mailed=20@hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 7 + .../docs/discovery/S324_scan_report.html | 173 ++++++++++++++++++ src/aipass/hooks/tests/test_engine.py | 8 +- 3 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 src/aipass/devpulse/docs/discovery/S324_scan_report.html diff --git a/CHANGELOG.md b/CHANGELOG.md index aa0b68cc..f435b45f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,13 @@ PyPI version — not the changelog header. ## [2026-07-18] +**fix(tests)** — the immortal `MagicMock/LOG_FILE/` directory is dead: a hooks +engine test patched `diagnostics.LOG_FILE` with a bare Mock, and prax's +`append_jsonl` turned the mock's fspath into a real `mkdir` — every test run +re-minted an empty `MagicMock/LOG_FILE/` in the runner's CWD (found in repo +root, devpulse, and hooks). Test now patches a real tmp path; 100/100 green, +clean-CWD run verified to mint nothing. + **docs** — merge playbook gains a site drift-check step (DPLAN-0249 follow-on): every merge run now asks whether install commands, onboarding flow, agent count, or the platform/CLI story changed — if yes, aipass.ai must be updated the same diff --git a/src/aipass/devpulse/docs/discovery/S324_scan_report.html b/src/aipass/devpulse/docs/discovery/S324_scan_report.html new file mode 100644 index 00000000..2886220b --- /dev/null +++ b/src/aipass/devpulse/docs/discovery/S324_scan_report.html @@ -0,0 +1,173 @@ +S324 Advisory Scan — AIPass + + + +
+
+

Session S324 · Advisory Scan · Read-only

+

The scanners CI never runs said 1,419 problems. Verification melted it to a handful.

+

Patrick's ask: "look in ur tools folder run some random scan see what surfaces." Ran the April-era advisory scanners — the ones deliberately NOT wired into seedgo's audit — across all 17 branches, then read every scary number in context before believing it. The tree is clean where it counts; most of the raw count is archive noise and scanner age.

+

Date 2026-07-18Agent @devpulseScanners fallback · stale-terms · readme-freshnessBranches 17/17Files changed 0

+
+ +
+
1,419
raw findings, all scanners
+
16
fallbacks actually in live code
+
2/2
sampled live hits = defensible on read
+
1
genuine surprise (MagicMock leak)
+
+ + +
+

How the numbers melt

raw → verified
+
+ + + + + +
ScannerRawAfter contextVerdict
Silent fallbacks6116 live · 45 = devpulse dropbox/ quarantine copiesmostly archive noise
  ↳ of the 16 live16@trigger 11 · @cli 2 · @skills 2 (tests) · @spawn 1 (template)@trigger needs owner triage
Stale terminology1,358~600 genuinely dead names · rest = valid .ai_mail.local/ refsneeds live-code filter
README freshness15/17 staledates lag the front-door code weekinformational
+
+

Why sampling flipped the verdict

+

Both @trigger hits I read in full are recursion-safe meta-logging guards — "if logging this warning fails, don't crash the error pipeline" — one even carries a # seedgo:bypass meta-logging marker. The @spawn template hit is a two-prefix import probe that surfaces real failures later, not a swallow. The scanner predates the bypass convention, so it re-alarms on code the standards system already acquitted.

+
+
+ + +
+

What actually surfaced

5 findings
+
+ +
+
S324-1Medium · real · unowned + A test leaked a Mock onto disk: MagicMock/LOG_FILE/ sits in devpulse's branch root
+

Empty, untracked, born Jul 11 03:31 (a night-shift test run). Something called mkdir on a path built from an unpatched Mock().LOG_FILE. Four candidate offenders mock a LOG_FILE attribute: ai_mail test_daemon.py / test_dispatch_status.py, hooks test_engine.py, seedgo test_checkers_batch3.py. Cheap hunt: run each suite from a scratch CWD and watch which one mints the dir. Until then it's clutter that will regrow after cleanup.

+
+ +
+
S324-2Medium · owner call + @trigger: 11 bare except Exception: pass in live event handlers — 9 still unread
+

The error-detection branch swallowing exceptions is worth eyes on principle. The 2 I sampled are legitimate meta-logging guards; the other 9 (in error_detected, runaway_handler, plan_file, pr_status_sync, memory_pool, registry, startup) deserve the same context read by their owner. Concern, not prescription — @trigger designs the fix if any is real.

+
+ +
+
S324-3Low · tooling debt + The advisory scanners are aging out of the conventions they audit
+

April-era tools: the fallback scanner doesn't honor seedgo:bypass markers (false alarms on acquitted code), the stale scanner counts valid .ai_mail.local/ usage in its headline, and none of them exclude dropbox/ / .archive/ quarantine dirs — which is where 45 of 61 "fallbacks" came from. A bypass-aware, archive-excluding refresh would make raw counts trustworthy again.

+
+ +
+
S324-4Low · unfiltered + ~600 dead-name references still in the tree: dev central 243 · branch_registry 211 · ai_central 131 · cortex 13
+

Not yet split between live code (worth fixing) and historical plans/archives (should keep their old names — never rewrite history). A filtered live-code pass is the prerequisite before this number means anything. Public-repo angle: strangers reading live code shouldn't meet four generations of naming.

+
+ +
+
S324-5Verified good + Where it counts, the tree is clean
+

Devpulse live code: zero silent fallbacks — all 45 flagged were quarantined pollution captures in dropbox/, doing exactly what quarantine is for. The 10 hard checkers born from this same tools folder already run inside drone @seedgo audit, where all 17 branches sit at 100%. The advisory layer found no criticals, no highs, nothing live-broken.

+
+ +
+
+ + +
+

Report lineage

where this fits
+

Sibling of docs/discovery/S304_report.html (Jul 12 — the 124-finding autonomous discovery walk; two criticals from it, medic-off and the rollover off-by-one, were since fixed and Patrick-monitored respectively). The other big HTML artifact of the week is artifacts/ux_flow_graph.html (3.5 MB, the v4 install-to-chat UX graph). Same-day context: PR #703 (merge-playbook drift-check step) is CI-green and awaiting Patrick's merge word; gif session prepped in artifacts/gif_recording_plan.md.

+
+ + +
diff --git a/src/aipass/hooks/tests/test_engine.py b/src/aipass/hooks/tests/test_engine.py index 0b920eeb..0d433c40 100644 --- a/src/aipass/hooks/tests/test_engine.py +++ b/src/aipass/hooks/tests/test_engine.py @@ -435,10 +435,12 @@ class TestErrorResilience: config = find_project_config() assert config is None - def test_log_write_failure_does_not_crash(self, mock_logger): + def test_log_write_failure_does_not_crash(self, tmp_path, mock_logger): + # A bare-Mock LOG_FILE leaks a real MagicMock/LOG_FILE/ dir into the CWD + # via append_jsonl's Path(...).parent.mkdir — use a real tmp path. + log_file = tmp_path / "engine.jsonl" with patch("builtins.open", side_effect=OSError("disk full")): - with patch("aipass.hooks.apps.handlers.config.diagnostics.LOG_FILE") as mock_path: - mock_path.parent.mkdir = MagicMock() + with patch("aipass.hooks.apps.handlers.config.diagnostics.LOG_FILE", log_file): _log({"event": "Test"})