# forge — triage_dump probe refactor: behavior-preserving code review (VERIFICATION) **Lane:** Refactor — code review and refactors **Artifact committed to:** `wizard-work/forge/` (`_triage_dump.py`, `_triage_dump_refactored.py`, `verify_triage_dump_refactor.py`, `_triage_dump_refactor_CHECK_EVIDENCE.txt`) **Verdict:** 14/14 checks pass; probe output byte-identical to the original (6695 bytes, sha256 `1bd715fb…`). ## Target `_triage_dump.py` is a byte-identical copy of the repo-root throwaway probe `.triage_dump.py` (18 lines). It dumps the decided/pending items from the triage inbox seed `inbox/seed-2026-09-26.json`. The original ran its **entire** probe at module top level: it opened the JSON, loaded it into the module-global `d`, and printed everything at import time, with no `if __name__ == "__main__"` guard, **zero function definitions**, two module-level `for` loops, a hardcoded host-absolute JSON path at module scope, and the module-global `d` coupling data flow to the import side effect. ## Smells fixed (behavior-preserving) 1. **Module-level execution.** All file I/O, JSON loading, and printing now live under `main()`. The module imports with zero side effects; the entry point is explicitly guarded with `if __name__ == "__main__": main()`. - *Measured:* `check_import_side_effect_free` — importing produces no stdout/ stderr and no `SystemExit`. 2. **Hardcoded host-absolute path at module scope (Q86).** The bare `path = "/root/troupe-standup/inbox/seed-...json"` literal is replaced by a tree-relative resolution (`_HERE` -> repo root -> `inbox/seed-...json`) promoted to the named constant `DEFAULT_PATH` and the `path` parameter of `main()`. On this host the resolution is identical to the old literal (output byte-identical), but a clone now grades *its own* inbox instead of silently grading `/root/...` on the host. - *Measured:* `check_main_path_parameter`; `check_seed_path_portable` — no host-absolute literal in the refactored source and `DEFAULT_PATH` resolves inside the tree. 3. **No function extraction / module-global coupling.** The two inline print loops (decided, pending) are extracted into the pure helpers `_print_decided` and `_print_pending` (plus `load_data`); `d.get("decided", [])` and `d.get("pending", [])` are evaluated once in `main()` and passed to the helpers as arguments instead of recomputed at module scope. The module-global `d` is gone. - *Measured:* `check_helpers_extracted` — all four module-level functions exist and `main` calls both print helpers; `check_no_dead_imports` — `json` is retained and referenced, no dangling imports. ## Verification harness `verify_triage_dump_refactor.py` — 14 checks, each a real subprocess/AST assertion (no tautology): | # | check | what it proves | |---|-------|-----------------| | 1 | `py_compile` | refactored file is syntactically valid | | 2 | identical output | `original` vs `refactored` produce byte-identical stdout+stderr AND exit code | | 3 | `__main__` guard | refactored has the guard (original's smell), in code not docstring | | 4 | no `global` | no `global` statements in code | | 5 | import side-effect-free | importing produces no output and no `SystemExit` | | 6 | helpers extracted | `_print_decided`, `_print_pending`, `load_data`, `main` exist; `main` calls both print helpers | | 7 | main delegation | `main()` body has no `;`-compacted statements (extraction boundary intact) | | 8 | `main(path)` param | `main` accepts a configurable `path` parameter | | 9 | no dead imports | `json` retained and referenced; no unreferenced imports introduced | | 10 | original still smells | non-vacuous: original still lacks guard, still hardcodes the host-absolute path, still has module-level `for`, still has zero function defs | | 11 | path override honoured | `main(path=custom)` prints the custom file, not `DEFAULT_PATH` — kills the "accepts-but-ignores-path" mutation, which is byte-identical on the real seed and thus evades check 2 | | 12 | no import-time I/O (M6 killer) | M6 (`_bootstrap = json.load(open(DEFAULT_PATH))` at module scope, no print) survives check 5 by being *silent*, not clean. Static AST walk of top-level statements + dynamic `builtins.open` spy both require zero calls. | | 13 | M6 mutant detected (non-vacuous) | The check-12 detector fires on the measured M6 mutation applied to a temp copy, so it is sensitive rather than theater. | | 14 | seed path portable (Q86) | No host-absolute seed literal in the refactored source; `DEFAULT_PATH` resolves inside the tree and matches the harness's `REAL_SEED_PATH`. Closes the "a clone grades the host's inbox" gap. | ## Evidence (measured, this run) ``` $ python3 verify_triage_dump_refactor.py OK: py_compile passes OK: identical output (exit 0, 6695 bytes) OK: __main__ guard present OK: no 'global' statements in code OK: import is side-effect-free (no probe output at import) OK: _print_decided, _print_pending, load_data, main extracted; main calls both print helpers OK: main() delegates via distinct standalone statements (no ';'-compaction) OK: main(path) accepts a configurable path parameter OK: all refactored imports are referenced (json retained, no dead imports) OK: original still exhibits the removed smells (refactor is non-vacuous) OK: main(path=custom) honours the override (prints custom file, not DEFAULT_PATH) OK: no import-time I/O (0 module-scope io calls; 0 runtime open calls) OK: M6 mutant detected at module scope: [(51, 'json.load'), (51, 'open')] OK: seed path is tree-portable (resolves inside tree): /root/troupe-standup/inbox/seed-2026-09-26.json === Verification: 14/14 checks passed === ``` Re-run under the optimised interpreter (per the lane's "python3 and -O" evidence convention): ``` $ python3 -O verify_triage_dump_refactor.py === Verification: 14/14 checks passed === ``` Full capture in `wizard-work/forge/_triage_dump_refactor_CHECK_EVIDENCE.txt`. ## Non-vacuity Check 10 guarantees the refactor actually removed something: the *original* `_triage_dump.py` still exhibits every smell the refactored version no longer does (no `__main__` guard, hardcoded host-absolute path at module scope, two module-level `for` loops, zero function definitions, module-global `d`). A no-op "refactor" would fail this. ``` $ python3 - <<'PY' import ast src = open("wizard-work/forge/_triage_dump.py").read() t = ast.parse(src) print("def count ->", sum(1 for n in t.body if isinstance(n, ast.FunctionDef))) print("main-guard count ->", src.count('__name__ == "__main__"') + src.count("__name__ == '__main__'")) print("module-level for ->", sum(1 for n in t.body if isinstance(n, ast.For))) print("'d = json.load' at module scope ->", any(isinstance(n, ast.Assign) and any(getattr(t,'id',None)=='d' for t in n.targets) for n in t.body)) PY def count -> 0 main-guard count -> 0 module-level for -> 2 ``` Checks 12+13 are a paired non-vacuity pair for the import-time-IO detector: the clean module has zero module-scope io calls (check 12), and the M6 mutant (a silent module-scope `json.load(open(DEFAULT_PATH))`) is detected by the same detector (check 13). A detector that matches nothing would be theater; M6 proves check 12 is surgical. ## Mutation kill Check 11 (path override) is the key discriminator the byte-comparison cannot see: a `path` parameter that is accepted but ignored (always reads `DEFAULT_PATH`) produces byte-identical output on the real seed but prints the wrong data on a custom file. The check feeds a synthetic JSON containing `"overridden"` and asserts that token appears and the real seed path does not. Checks 3/8/6/12 form the structural discriminators: re-adding any of the removed smells to the refactored file is caught, and a no-op refactor fails check 10 outright. ## Independent byte-identical proof (outside the harness) `_triage_dump.py` (the in-tree original; a byte-identical copy of the repo-root throwaway `.triage_dump.py`) vs. `_triage_dump_refactored.py`: ``` $ python3 _triage_dump.py 1>/tmp/oout 2>/tmp/oerr $ python3 _triage_dump_refactored.py 1>/tmp/rout 2>/tmp/rerr $ sha256sum /tmp/oout /tmp/rout 1bd715fbd97a6fc25a4c43581b20c231981118408a61689b4a9cd281cc3cc25b /tmp/oout 1bd715fbd97a6fc25a4c43581b20c231981118408a61689b4a9cd281cc3cc25b /tmp/rout $ cmp /tmp/oout /tmp/rout && echo IDENTICAL IDENTICAL (cmp exit 0) $ cmp /tmp/oerr /tmp/rerr && echo STDERR_IDENTICAL STDERR_IDENTICAL (cmp exit 0) ``` VERDICT: PASS -- triage_dump probe refactor is behavior-preserving; byte-identical output (6695 bytes, sha256 `1bd715fb…`), 14/14 on python3 and -O, exit 0; Q86 gaps closed (import-time I/O detected, seed path tree-portable). CHECK: python3 /root/troupe-standup/wizard-work/forge/verify_triage_dump_refactor.py >/dev/null 2>&1