Skip to content

Embed local verification collectors without ceding verdict authority #198

Description

@sarthakagrawal927

Why

CodeVetter should reuse maintained scanners where the collector is commodity logic, while keeping scope resolution, normalization, evidence identity, and the final verdict under CodeVetter control. The repository has qualified Gitleaks, cargo-audit/RustSec, and cargo-llvm-cov as local-first candidates, but none is yet part of the packaged verification product.

This is core verification work, not a new dashboard: it adds attributable dependency, secret, and changed-line coverage evidence to the primary CLI/bundle path.

What

Add one bounded product collector contract for an exact clean Git change, then integrate the three approved Rust/repository collectors behind explicit opt-in:

  • Gitleaks for redacted secret findings from the selected Git range.
  • cargo-audit/RustSec for Cargo.lock advisory evidence using a pinned local advisory database with fetching disabled during a run.
  • cargo-llvm-cov for Rust LCOV/region evidence only when the target repository already has the required Rust toolchain component and the user supplies an explicit test target.

No new desktop route or hosted service is in scope. Missing tools, databases, compiler components, or eligible targets produce explicit unavailable evidence; they never silently pass and never trigger installation or network access during verification.

Design

flowchart LR
    A[Exact clean Git change] --> B[CodeVetter scope and policy]
    B --> C[Gitleaks sidecar]
    B --> D[cargo-audit or RustSec collector]
    B --> E[cargo-llvm-cov sidecar]
    C --> F[Redacted normalized evidence]
    D --> F
    E --> F
    F --> G[Versioned verification bundle]
    G --> H[CodeVetter verdict policy]
Loading

The first slice belongs in the packaged codevetter CLI and shared Rust backend so CLI/MCP can reuse it. Sidecars resolve from explicit test overrides or the app bundle; arbitrary PATH discovery is not sufficient for release evidence. Every process runs without a shell, with a contained working directory, minimal environment, bounded output, timeout, kill-on-drop, and no implicit update/fetch behavior.

Packaging and runtime adoption are separate gates. A release may not claim a collector is bundled until every target artifact has an exact version, permissive license, publisher digest or attestation, Tauri resource declaration, nested-signature receipt, and final app-bundle smoke test.

Specs

Requirement: Collectors remain subordinate evidence

The system SHALL preserve CodeVetter-owned scope resolution, normalization, and verdict authority. A tool exit code or finding count SHALL NOT directly become the overall CodeVetter verdict.

Scenario: A collector reports findings

  • WHEN an enabled collector returns valid attributed output
  • THEN CodeVetter records the tool version, input revision/range, configuration identity, duration, status, findings, and limitations
  • AND applies its own explicit policy when composing the final verdict.

Requirement: Product collection is local and bounded

The product SHALL NOT upload source, manifests, lockfiles, coverage, or findings, and SHALL NOT fetch databases, tools, compiler components, or updates during a verification run.

Scenario: A local prerequisite is missing

  • WHEN a sidecar, advisory database, Cargo.lock, LLVM component, or eligible test target is unavailable
  • THEN that collector returns unavailable with an actionable reason
  • AND no install or network operation is attempted.

Requirement: Secret evidence is redacted

Gitleaks evidence SHALL contain rule and location metadata but SHALL NOT persist raw secret values in stdout, stderr, SARIF, JSON, logs, or the verification bundle.

Scenario: A secret-like value is detected

  • WHEN Gitleaks reports a finding in the exact selected change
  • THEN the normalized evidence retains repository-relative location and rule identity
  • AND drops or replaces the matched secret and surrounding secret-bearing content before persistence.

Requirement: Coverage measures changed executable lines

Rust coverage SHALL compare changed executable lines from the exact Git range with locally produced LCOV, preserve region-level JSON when available, and list uncovered changed lines. Project-wide percentages SHALL NOT substitute for changed-line coverage.

Scenario: A changed source file is absent from coverage

  • WHEN an eligible changed Rust source file has executable changed lines but no coverage record
  • THEN those lines are treated as uncovered rather than omitted from the denominator.

Requirement: Packaged artifacts are reproducible

Each bundled sidecar SHALL be version-pinned and verified from official release material before copying into Tauri binaries. Release CI SHALL verify the executables and their expected versions inside the final application bundle.

Scenario: Artifact identity differs

  • WHEN a download digest, attestation, license, target, version output, or final bundle path differs from the pinned contract
  • THEN preparation or release qualification fails before signing or publication.

Tasks

  • 1. Add a versioned normalized collector receipt and fail-closed preflight contract with fixture tests.
  • 2. Add supervised no-shell execution shared by collector adapters: contained cwd, minimal environment, timeout, bounded output, cancellation, and redaction.
  • 3. Integrate Gitleaks against an exact resolved Git range and prove raw secrets cannot enter persisted evidence.
  • 4. Integrate cargo-audit/RustSec with a pinned local advisory DB and prove a run makes no fetch request.
  • 5. Integrate cargo-llvm-cov with explicit target/toolchain preflight, LCOV parsing, changed-line intersection, and missing-file-as-uncovered behavior.
  • 6. Add exact-version artifact preparation for supported macOS targets with official digest/attestation and license checks.
  • 7. Wire qualified collectors into the packaged CLI receipt without adding a desktop route.
  • 8. Add CI contract tests and final app-bundle version/signature checks; measure bundle size, cold/warm latency, output bounds, and cleanup.
  • 9. Update canonical architecture/tooling docs and PROJECT_STATUS with only the proven slice.
  • 10. Run focused tests, Rust checks, dependency/license policy, secret scanning, CLI qualification, and release dry-run checks without deploying or releasing.

Boundaries

  • No hosted scanner, telemetry, source upload, automatic remediation, dependency install, database refresh, compiler-component install, deployment, or release.
  • No new UI surface.
  • No branch-coverage verdict for Rust.
  • Gitleaks action licensing does not apply because the product uses the MIT CLI binary, not gitleaks-action.
  • The first implementation must stay optional and claim-closed until packaged-artifact and real-repository receipts pass.

Spec-driven tracking issue. All design content lives here; no local OpenSpec files.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions