8.6 KiB
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)
- 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 withif __name__ == "__main__": main().- Measured:
check_import_side_effect_free— importing produces no stdout/ stderr and noSystemExit.
- Measured:
- 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 constantDEFAULT_PATHand thepathparameter ofmain(). 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 andDEFAULT_PATHresolves inside the tree.
- Measured:
- No function extraction / module-global coupling. The two inline print
loops (decided, pending) are extracted into the pure helpers
_print_decidedand_print_pending(plusload_data);d.get("decided", [])andd.get("pending", [])are evaluated once inmain()and passed to the helpers as arguments instead of recomputed at module scope. The module-globaldis gone.- Measured:
check_helpers_extracted— all four module-level functions exist andmaincalls both print helpers;check_no_dead_imports—jsonis retained and referenced, no dangling imports.
- Measured:
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