This repository has been archived on 2026-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
orchestrator/security-review/checkers/fixtures/dependency-cve
Adam Moussa f09c94a821
feat(secrev): Plane-1 Phase 2 — coordinator + dependency-cve checker (#16)
* fix(agent-team): read SLACK_CHANNEL_ID, aligning code with deploy doc + systemd

run-team.py read os.environ['SLACK_CHANNEL'] while DEPLOY-R720.md and the
coordinator systemd unit both document SLACK_CHANNEL_ID; the mismatch would
silently default the live Slack transport channel to empty. Standardize on
SLACK_CHANNEL_ID (decision locked 2026-06-18).

* feat(secrev): dependency-cve Plane-1 Tier-1 checker (OSV, ALARM-only)

Read-only checker on the Phase-0 substrate: scans $MIRROR_DIR mirrors for
pinned deps (requirements/poetry/Pipfile/package-lock/yarn/csproj across
PyPI/npm/NuGet), cross-refs OSV querybatch (live) or an offline advisory
fixture (canary). Mode-600 reports, ALARM-only, --canary asserts 2 planted
vulns (jinja2 2.11.2, lodash 4.17.15). Complements Dependabot. Not provisioned.

* feat(secrev): Plane-1 checker coordinator (shared budget, rotation, dedup)

Coordinator (design §5/§6.7) orchestrating Tier-1 checkers under one shared
budget ledger + versioned rotation/coverage state (atomic write + schema/hash/
logical-consistency integrity, park-on-corrupt). Canary-suite-first
(COMPLACENCY skip), fan-out under the shared cap with defer-not-drop, COVERAGE
alarm past MAX_CYCLE_NIGHTS, cross-checker dedup/prioritize, ALARM-only routing.
--squeeze-dry-run proves deferral-not-drop + COVERAGE alarm. Not provisioned.

* fix(secrev): hide dependency-cve canary manifests from dependency-review

The canary fixtures intentionally pin known-vulnerable deps (jinja2 2.11.2,
lodash 4.17.15) so the checker has something to detect. GitHub's dependency
graph parsed those fixture manifests as real project deps, failing the
dependency-review PR gate (fail-on-severity: high). Store the manifests with a
.fixture suffix so the dependency graph ignores them; the --canary materializer
strips the suffix in its temp work area before scanning, so detection is
unchanged (still 2/2). No advisory allowlist, no change to the shared org
reusable workflow — the real gate stays strict for actual deps.
2026-06-18 15:08:58 -04:00
..
clean-repo feat(secrev): Plane-1 Phase 2 — coordinator + dependency-cve checker (#16) 2026-06-18 15:08:58 -04:00
vuln-js-repo feat(secrev): Plane-1 Phase 2 — coordinator + dependency-cve checker (#16) 2026-06-18 15:08:58 -04:00
vuln-py-repo feat(secrev): Plane-1 Phase 2 — coordinator + dependency-cve checker (#16) 2026-06-18 15:08:58 -04:00
EXPECTED_VULN_COUNT feat(secrev): Plane-1 Phase 2 — coordinator + dependency-cve checker (#16) 2026-06-18 15:08:58 -04:00
osv-advisories.json feat(secrev): Plane-1 Phase 2 — coordinator + dependency-cve checker (#16) 2026-06-18 15:08:58 -04:00
README.md feat(secrev): Plane-1 Phase 2 — coordinator + dependency-cve checker (#16) 2026-06-18 15:08:58 -04:00

dependency-cve canary fixtures

Planted-vulnerable-dependency corpus for checkers/dependency-cve.sh --canary (offline, no network/token). The checker asserts the total vulnerable-dependency count equals EXPECTED_VULN_COUNT (anti-complacency floor, design §6.4). If extraction or matching regresses (a parser stops firing, or the advisory match breaks), the count drops and the canary FAILS (exit 3).

Offline advisory source

OSV needs the network, so the canary CANNOT call api.osv.dev. Instead, --canary (and the --advisories-file PATH override) makes the checker consult the local osv-advisories.json fixture INSTEAD of the network — keyed by ECOSYSTEM|package|version. This keeps the canary fully offline and deterministic. The fixture mirrors real advisory ids/summaries/fixed-versions so a finding looks like a live one, but nothing is fetched.

Fixture repos (each a real git checkout; dotgit/ is renamed to .git/ at run time)

The git metadata is shipped as dotgit/ (not .git/) so these commit into the orchestrator repo WITHOUT becoming nested submodules — the SAME trick compliance-drift fixtures use. The checker copies each fixture to a temp area and renames dotgit → .git before scanning.

Fixture Ecosystem Pinned deps Vulnerable match Count
vuln-py-repo PyPI (requirements.txt) flask==2.0.1, jinja2==2.11.2, requests==2.31.0 jinja2==2.11.2 → GHSA-g3rq-g295-4j3m 1
vuln-js-repo npm (package-lock.json) lodash 4.17.15, left-pad 1.3.0 lodash 4.17.15 → GHSA-p6mc-m468-83gw 1
clean-repo PyPI (requirements.txt) requests==2.31.0, urllib3==2.2.1 none (no advisory entry) 0

Total = 2 (EXPECTED_VULN_COUNT). Two ecosystems are exercised (PyPI + npm) so a regression in either parser is caught.

When you add/remove a parser, a fixture, or an advisory entry, update the fixture(s), osv-advisories.json, and EXPECTED_VULN_COUNT in the same commit (the canary edit is itself caught on the next run — design §6.4).

Manifest naming: the dependency manifests are stored with a .fixture suffix (requirements.txt.fixture, package-lock.json.fixture) so GitHub's dependency graph / the dependency-review CI action does NOT parse the deliberately-vulnerable canary pins as real project dependencies (which would fail the PR gate). The checker's --canary materialization strips the .fixture suffix in its temp work area before scanning, so the per-ecosystem parsers still dispatch on the real names. Keep this suffix on any new manifest fixture.