Install gate, Phase 0: vuln-api contract + test harness#110
Open
juangaitanv wants to merge 5 commits into
Open
Install gate, Phase 0: vuln-api contract + test harness#110juangaitanv wants to merge 5 commits into
juangaitanv wants to merge 5 commits into
Conversation
Running the suite from a git hook (e.g. pre-commit in a worktree) leaks GIT_DIR into the tests' subprocesses, pointing their git init at the developer's repo — locked mid-commit — instead of the temp dir.
The vuln-api client and its versioned contract (clean / vulnerable / malware / unknown verdicts, remediation data), harvested from the install-vuln-gate spike (dfac68e) and trimmed to phase scope: public unauthenticated lookups only, no retries, no user-facing command. - src/vuln_api: blocking client for /v1/packages/.../check with status mapping, identity guard, and PEP 503 request-time normalization - src/vuln_api_stub: in-process TCP stub, gated out of release builds via the test-stub feature + self dev-dependency - tests/common: shared GateHarness scaffold for later phases - tests/vuln_api_contract.rs: contract tests against the stub (hermetic) and the staging worker (#[ignore], deterministic targets documented in tests/fixtures/vuln_api/README.md)
…, staging CI Addresses Cursor review on #110. - vuln_api identity guard now applies the ecosystem's canonical-name rule to the response package_name before comparing, not just eq_ignore_ascii_case. A response echoing the stored spelling (`flask_cors` for a `flask-cors` request — PEP 503-equivalent) no longer trips the guard and fails the gate closed for valid pypi packages with `_`/`.` in their names. New unit test covers it. - tests/harness_smoke.rs exercises the GateHarness scaffold directly (fake package manager on PATH, registry stub, vuln-api stub) so the wiring can't silently regress before a later phase drives it end-to-end. - .github/workflows/staging-contract.yml runs the #[ignore]d staging contract tests on a daily schedule (non-blocking) so endpoint/schema/seed drift is caught out-of-band instead of shipping undetected.
cargo test runs the module's tests on parallel threads. Five of them bind ephemeral ports, and between port_is_available_reflects_current_port_usage's drop(listener) and its re-check, a concurrent :0 bind could be handed the just-freed port, flipping the second assert to false. Add a module-level PORT_TEST_LOCK that all five port-binding tests acquire. The async test scopes the guard to the synchronous reserve so no lock is held across .await (keeps clippy::await_holding_lock clean).
…riant docs, harness opt-out - pypi wire names now use the server's rule (lowercase + trim, worker.js normalizePackageName), NOT PEP 503: collapsing zope.interface to zope-interface missed the stored advisory row and read vulnerable dotted/underscored packages as clean. PEP 503 remains the identity-comparison rule (Ecosystem::request_name vs normalize_name), and the stub's key() now mirrors the server so the divergence can't be masked in tests again. - Module/auth docs no longer claim lookups are permanently unauthenticated: production /check requires a Corgea token (staging runs VULN_API_REQUIRE_AUTH=false); token wiring lands with authenticated mode. Test renamed public_check_sends_no_auth_headers. - GateHarness::without_vuln_api() opt-out for no-endpoint tests. - utils/api.rs get_source() delegates to the cached vuln_api::source().
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.
Phase 0 of the install-gate restart
First of a stacked series implementing
PRD.md(Gate Package Installs). The previous attempt (branchinstall-vuln-gate, 60+ commits, ~10.7k lines) built the right thing but was unreviewable as one PR. This restart lands one phase per PR, each with explicit exit criteria. Later phases stack on this branch as it merges.This PR is foundation only — no user-facing command ships here.
What's in scope (per the PRD)
The vuln-api client and its versioned contract, the in-process test stub, and the shared integration-test scaffold:
src/vuln_api/— blocking client forGET /v1/packages/{eco}/{name}/versions/{ver}/check. Independent of the shared CLI HTTP client (the host is user-configurable viaCORGEA_VULN_API_URL, so it must never replay Corgea cookies/redirects). Status mapping, a confused-deputy identity guard (the response's(eco, name, version)must match the request), and request-time PEP 503 name normalization so an alternate spelling can't miss and read as clean. Comparisons are case-insensitive — staging spells pypi"PyPI".src/vuln_api_stub/— minimal in-process TCP stub, gated out of release builds behind atest-stubcargo feature (enabled for every test build via a self dev-dependency). No standalone binary.tests/common/— theGateHarnessscaffold later phases build on (isolatedcorgea, private PATH of fake package managers, registry + vuln-api stubs).tests/fixtures/vuln_api/— the four committed contract bodies (clean / vulnerable / malware / unknown), matching the authoritative server serialization.tests/vuln_api_contract.rs— contract tests against the stub (hermetic, always on) and the staging worker (#[ignore], network).Deliberately out of scope (later phases): any user-facing command, auth/token handling, retries.
Exit criteria — met
cargo test../harness check(strict clippy, fmt, tests, suppression report) passes.Also included
A one-line prerequisite fix (
0e5beb4):tests/cli_deps.rs's git helper now scrubs inheritedGIT_*env. Running the suite from the pre-commit hook in a worktree leakedGIT_DIRinto the tests' subprocesses, pointing theirgit initat the developer's repo (locked mid-commit) instead of the temp dir. Required for the harness to pass cleanly under the commit hook.Review notes
https://cve-worker-staging.corgea.workers.dev) is the current default endpoint (DEFAULT_VULN_API_URL); the production-worker handoff and seed-data ownership are open questions in the PRD, not blockers for this phase.🤖 Generated with Claude Code