cli.py 345 -> 222 and _verifier.py 347 -> 228, via _cli_checks.py and
_verifier_support.py.
The cli seam cut straight through code covered by its per-file-ignores.
Rather than copy S607 and PERF203 onto a second entry, both are fixed:
systemctl is resolved with shutil.which, and the readiness poll no
longer carries a try/except in its body now that the probe is its own
function. Both ignores are deleted from meta/pyproject.toml and ruff
passes without them - the repo has two fewer suppressions than before.
The which() fix adds a systemctl-is-None branch, so the pass count goes
216 -> 217: one new test for it, no existing test touched. Coverage is
back at 100% by covering the branch, not excluding it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
New python_pkg/code_tutor package that turns an unfamiliar codebase into
an interactive lesson: analyse code into items (_analyzer), order them
dependency-first (_plan_builder), pose reimplement challenges
(_challenge + _challenge_support), verify user implementations with tests
and coverage (_verifier), track progress (_progress/_session), and offer
local-LLM hints (_llm), driven by a Typer/Rich CLI (cli).
- meta/pyproject.toml + .pre-commit-config.yaml + meta/requirements.txt:
add anthropic/rich/typer deps, a cli.py per-file-ignore (Typer B008 etc),
and code_tutor-specific ruff/pylint/mypy tuning.
- _challenge.py and its tests are split across _challenge_support.py and
test_challenge_part2/part3.py to stay under the 500-line file cap.
Verification: pytest 631 passed at 100% line+branch coverage; every file
<=500 lines; pre-commit (ruff ALL, mypy strict, pylint 10/10, bandit,
evidence + multi-file contract) green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RRCdR4D8SaVrN2xraMQxM