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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions