You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Issue #130: Close the guard bypasses red-teaming found, and fix my own claims
Red-teaming the branch found that my Step 1 change traded a false refusal
for two real money-safety holes. Verified against master, which refused
both:
PYTEST_ADDOPTS=tests/integration/test_x.py pytest -> collected 2
pytest -o testpaths=tests/integration/test_x.py -> collected 2
Cause: `config.invocation_params.args` is only what the operator typed.
`testpaths`, `-o testpaths=` and PYTEST_ADDOPTS all feed `config.args`
without appearing there. Reading the typed argv makes the guard blind to
every indirect route.
The right fix was in the config, not the guard. Reading `config.args` is
safe now precisely because Step 2 set `testpaths = ["tests"]`, so the
guard is back on the effective target list. Also fixed, and pre-existing
(#109): relative paths were resolved only against rootdir, so from within
tests/ the path `integration/test_x.py` went unrecognised. All plausible
bases are now tried. `--pyargs` and `-p` address modules by dotted name and
never looked like paths; both are now translated and checked.
Measured after the change -- refused: explicit dir, explicit file, node id,
-o testpaths, PYTEST_ADDOPTS, --pyargs, cwd-relative. Still allowed and
must be: bare `pytest` (0 integration nodes collected) and the
CLUSTRIX_ALLOW_BILLABLE=1 opt-in. `-p` cannot be blocked before the import
it triggers -- no conftest hook runs that early -- but the run is now
refused before any test executes, which is where the cost is; it also fails
on its own here, since tests/ is not a package.
Four parametrized regression tests cover the indirect routes. Three fail
against the old guard, confirming they are not decorative.
Corrections to my own earlier work in this PR:
* "the 224 in tests/real_world/" was wrong and had been committed as a
code comment in scripts/pre_push_check.py. 224 counts decorator lines;
tests/real_world/ collects 388 tests. That comment's rationale was also
wrong: the old bare `pytest` was not "harmless while no config applied",
it aborted on master in seconds with a collection error and gated
nothing. Fixing that SyntaxError is what let collection succeed and made
the runtime problem visible.
* test_no_shadowing_config_file_exists forbade tox.ini and setup.cfg.
pytest checks those *after* pyproject.toml, so neither can shadow it --
verified. The test also failed on an ordinary pytest-free setup.cfg
holding flake8 config. Now limited to pytest.ini/.pytest.ini, and it
checks the repo tree rather than the resolved rootdir.
* test_bare_pytest_is_not_refused_by_the_guard described the guard source
that no longer exists; rewritten to state the actual invariant.
* coverage_detailed_report.txt was removed from .gitignore: nothing in the
repo writes it, so the justification given was unsupported.
Unrelated CI fix found while verifying: .github/workflows/fast_ci.yml
installs pytest without pytest-timeout, then runs pytest with
--timeout=60. It exits 4 with "unrecognized arguments" and has been
failing on every run, including on master. Added the plugin.
Restored the `filterwarnings` block from the deleted pytest.ini, which was
never migrated. It only suppresses third-party paramiko/cryptography noise.
The five markers pytest.ini also declared are deliberately not migrated:
tests/real_world/conftest.py registers them with addinivalue_line where
they are used.
tests/unit/ 79 passed. 1674 collected, 0 errors. flake8 91 (master: 92).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012gTBDPK16HUZ3kHQ2QyjuU
0 commit comments