chore: coverage floor + ruff lint + pip-audit CVE gates; cover sigstore trust-root; bump vulnerable deps#80
Merged
Conversation
…p deps Raise trust-root coverage and add the missing CI enforcement gates. Coverage - New tests/test_signing_unit.py (25 tests) drives signing.py's internal sign/verify paths directly, mocking the sigstore boundary (no network/OIDC). signing.py line coverage 61% -> 99%; whole-project 75% -> ~86%. - Enforce coverage in CI: pytest --cov=mcp_warden --cov-fail-under=80. - Capture subprocess coverage of guard_list_gate.py (0% -> ~89%) via [tool.coverage.run] parallel=true + COVERAGE_PROCESS_START, so the guard child spawned by the strict-abort tests is measured (no longer a 0% artifact). Lint - Add [tool.ruff] (E,W,F,I,B; line-length=100; ignore E501,B008) and a ruff lint job in the CI workflow. Fixed all surfaced violations (unused imports, import order, B904 raise-from, E702, F841). guard.py's GUARD_STRICT_EXIT and res_net.py's SSRF_NETWORKS re-exports are preserved via # noqa: F401 (both are consumed by tests / res_rules re-export; NOT dead). CVE - Add a fail-closed pip-audit gate to deps-locked that audits the resolved dependency closure. Deps - Bump the hash-locked dev/CI closure: pydantic-settings 2.14.1 -> 2.14.2 (clears GHSA-4xgf-cpjx-pc3j), mcp 1.27.2 -> 1.28.1, cryptography -> 49.0.0, anyio 4.13.0 -> 4.14.2, others. Add pytest-cov to the dev extra.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Raises coverage on the sigstore trust-root and adds the three missing CI enforcement gates (coverage floor, lint, CVE), plus a security dependency bump.
Coverage
src/mcp_warden/signing.py(trust root)src/mcp_warden/guard_list_gate.pytests/test_signing_unit.py(25 tests) drives the internal sign/verify code paths insigning.pyby mocking the pinned sigstore boundary symbols (_ClientTrustConfig,_SigningContext,_Verifier,_policy,_IdentityToken,_detect_credential,_Bundle). No real network, OIDC, TUF, or Fulcio/Rekor traffic. Covers the sign path (ambient + explicit token), the verify path (identity/issuer plumbing), and every fail-closed branch (unavailable, bad/empty token, signing failure, verification error, malformed bundle, version-window warning).pytest --cov=mcp_warden --cov-report=term-missing --cov-fail-under=80. Floor pinned at a round 80 — below the ~86% actual so it can only rise, never silently regress.guard_list_gate.pyonly ever runs inside the guard child spawned bytests/fixtures/fault_guard_launcher.py, so the in-process run reported it at 0%. Fixed with[tool.coverage.run] parallel = true+COVERAGE_PROCESS_START=pyproject.toml(fires the coverage.pthhook in the subprocess); pytest-cov combines the parallel data files. Real coverage now captured (0% → 89%).Lint gate (ruff)
[tool.ruff](selectE,W,F,I,B;line-length = 100; ignoreE501and the typer/FastAPIB008default-call idiom), modeled on conclave's config.Lint (ruff)CI job runsruff check ..B904raise-from,E702,F841).guard.py:GUARD_STRICT_EXITandres_net.py:SSRF_NETWORKSare preserved with# noqa: F401— both are live re-exports (consumed bytests/test_guard_strict.pyandres_rules.pyrespectively), not dead code.CVE gate (pip-audit)
pip-audit --skip-editablestep to thedeps-lockedworkflow that audits the resolved, hash-locked dependency closure and fails on any advisory. Mirrors conclave's fail-closed job.Dependency bump (security)
pydantic-settings2.14.1 → 2.14.2 — clears GHSA-4xgf-cpjx-pc3j.mcp1.27.2 → 1.28.1,cryptography→ 49.0.0,anyio4.13.0 → 4.14.2, plus current minors;pytest-covadded to thedevextra.requirements-dev.lockregenerated (hash-locked) and verified idempotent against thedeps-lockedin-sync check.Local verification
586 passed, 2 skippedwith--cov-fail-under=80satisfied (total 86.36%).ruff check .clean.pip-auditclean (no known vulnerabilities).Note on the "dead import"
The task flagged
res_net.py:14 SSRF_NETWORKSas an unused import to delete. It is not dead —res_rules.pyre-exports it fromres_net(under its own# noqa: F401), and removing it broke the import chain repo-wide. Kept it as a documented re-export with# noqa: F401instead, matching the existing pattern.🤖 Generated with Claude Code
https://claude.ai/code/session_01QofWZ4MivqEKPevjSYuwdk