Findings F-7/F-8 of the "Brownfield CLI/TUI Refactor Assessment" (local report, gitignored under _bmad-output/implementation-artifacts/).
Evidence
src/bmad_loop/__main__.py does not exist — python -m bmad_loop fails. The only entries are the console script (pyproject.toml:22, bmad-loop = "bmad_loop.cli:main") and the if __name__ == "__main__" guard at cli.py:2587-2588.
- Every CLI test calls
cli.main() in-process; nothing spawns a real interpreter, so packaging regressions (startup import cycles, broken script wiring) are invisible to the suite.
- Exit-code semantics are unpinned: typed errors (
PolicyError/GitError/BmadConfigError/SprintStatusError) and the broad backstop both return rc 1 (cli.py:2571-2584); argparse usage errors return rc 2.
Recommendation
- Add
src/bmad_loop/__main__.py delegating to cli.main() (~3 lines, mirroring the cli.py:2587-2588 guard).
- Add subprocess-based smoke tests:
python -m bmad_loop --version, --help, and one validate --json call — spawn a real interpreter via sys.executable, keep them xdist-safe.
- Add characterization tests pinning CURRENT exit codes: typed errors → 1, broad backstop → 1, argparse usage error → 2.
Strictly no behavior changes — these tests pin today's semantics as the guard rail for the exit-code-taxonomy work and the cli.py composition extraction.
Ordering
Session 2 of the refactor program — first code PR; everything later leans on these characterization tests.
Traps
- Existing CLI tests are all in-process
cli.main() calls; the new smoke tests must be the exception, not converted copies.
- Terse CHANGELOG line for
python -m support (user-visible).
Findings F-7/F-8 of the "Brownfield CLI/TUI Refactor Assessment" (local report, gitignored under
_bmad-output/implementation-artifacts/).Evidence
src/bmad_loop/__main__.pydoes not exist —python -m bmad_loopfails. The only entries are the console script (pyproject.toml:22,bmad-loop = "bmad_loop.cli:main") and theif __name__ == "__main__"guard atcli.py:2587-2588.cli.main()in-process; nothing spawns a real interpreter, so packaging regressions (startup import cycles, broken script wiring) are invisible to the suite.PolicyError/GitError/BmadConfigError/SprintStatusError) and the broad backstop both return rc 1 (cli.py:2571-2584); argparse usage errors return rc 2.Recommendation
src/bmad_loop/__main__.pydelegating tocli.main()(~3 lines, mirroring thecli.py:2587-2588guard).python -m bmad_loop --version,--help, and onevalidate --jsoncall — spawn a real interpreter viasys.executable, keep them xdist-safe.Strictly no behavior changes — these tests pin today's semantics as the guard rail for the exit-code-taxonomy work and the cli.py composition extraction.
Ordering
Session 2 of the refactor program — first code PR; everything later leans on these characterization tests.
Traps
cli.main()calls; the new smoke tests must be the exception, not converted copies.python -msupport (user-visible).