Skip to content

feat: watch mode #57

@bordumb

Description

@bordumb

Command: cargo capsec watch

Value proposition: Catch ambient authority introduction at the moment of authorship, not in CI ten minutes later. Like cargo clippy --fix running in the background, but for capability boundaries.

Could maybe be an IDE plugin

Devil's Advocate:
Why not just add a pre-commit hook and call it a day?

User stories:

  • As a developer working on a sans-IO core module, I want immediate feedback when I accidentally add a std::fs::read call, so I can fix it before committing.
  • As a team lead, I want developers to see capability violations in their terminal while coding, so the audit becomes part of the development loop rather than a CI gate.

Tasks

2.1 — File watcher integration

Add notify (or watchexec-events) as an optional dependency behind a watch feature flag. Watch src/ directories for .rs file changes.

#[derive(clap::Args)]
pub struct WatchArgs {
    /// Path to workspace root
    #[arg(short, long, default_value = ".")]
    pub path: PathBuf,
    /// Minimum risk level to report
    #[arg(long, default_value = "low")]
    pub min_risk: String,
    /// Clear terminal on each re-scan
    #[arg(long)]
    pub clear: bool,
    /// Debounce interval in milliseconds
    #[arg(long, default_value_t = 300)]
    pub debounce_ms: u64,
}

2.2 — Incremental scanning

Don't re-scan the entire workspace on every file save. Maintain a cache of ParsedFile + Vec<Finding> per source file. When a file changes:

  1. Re-parse only that file.
  2. Re-run detection on only that file.
  3. Merge findings with the cached results from other files.
  4. Re-render output.

Data structure:

struct WatchState {
    /// file path → (parsed, findings, last_modified)
    file_cache: HashMap<PathBuf, (ParsedFile, Vec<Finding>, SystemTime)>,
    /// Aggregate findings across all files
    all_findings: Vec<Finding>,
}

2.3 — Terminal output for watch mode

Use a compact, continuously-updated output format. Show:

  • A status line: Watching 42 files | 7 findings (2 new) | last scan: 0.3s ago
  • Only new/changed findings since the last successful scan, highlighted.
  • A full summary on first run or when --clear is set.

Consider using crossterm or ratatui for cursor control, but a simple clear-and-reprint approach works fine for v1.

2.4 — Integration with cargo capsec audit --diff

When watch mode detects a new finding that didn't exist in the baseline, highlight it differently. This makes the baseline-driven workflow seamless: save a baseline, start watch mode, see only regressions.

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