Skip to content

Commit 68aa30f

Browse files
hyperpolymathclaude
andcommitted
feat(sweep-tracker): hierarchical estate-sweep Markdown report
Adds `panic-attack sweep-tracker` subcommand that renders an issue-#32 shaped sweep tracker by joining per-finding hexads (issue #33 S1) with campaign-state hexads (issue #33 S2). Distinct from `campaign status`: that is a flat per-finding table; this is a hierarchical checklist grouped by repo and/or category, with an estate-wide summary header. Flags: - `--verisimdb-dir DIR` : hexad store root (default `verisimdb-data`) - `--output FILE` : write Markdown to file instead of stdout - `--by-repo` : emit only the "By repo" section - `--by-category` : emit only the "By category" section - no flag : emit both sections (default) Output is deterministic — repos alphabetically, findings within each repo sorted by (rule_id, file, line). A finding with no campaign hexad shows state `open`; with one, shows the latest state plus PR URL (rendered as `#<num>` link) or dismissal reason. Tests cover empty store, by-repo grouping, by-category grouping, campaign-state join (open / pr-merged / dismissed), deterministic ordering, both-shape ordering, and PR-number label extraction. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d6e41dc commit 68aa30f

3 files changed

Lines changed: 726 additions & 0 deletions

File tree

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ pub mod panll;
3535
pub mod report;
3636
pub mod signatures;
3737
pub mod storage;
38+
pub mod sweep_tracker;
3839
pub mod types;

src/main.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ mod panll;
3030
mod report;
3131
mod signatures;
3232
mod storage;
33+
mod sweep_tracker;
3334
mod types;
3435

3536
extern crate walkdir;
@@ -753,6 +754,30 @@ enum Commands {
753754
#[command(subcommand)]
754755
action: CampaignAction,
755756
},
757+
758+
/// Sweep-tracker: render an issue-#32-style estate-sweep Markdown report.
759+
///
760+
/// Joins per-finding hexads (issue #33 S1) with campaign-state hexads
761+
/// (issue #33 S2) and groups them by repo and/or category. Distinct
762+
/// from `campaign status`: that is a flat per-finding table; this is
763+
/// a hierarchical sweep checklist.
764+
SweepTracker {
765+
/// VeriSimDB data directory (default: `verisimdb-data`).
766+
#[arg(long, value_name = "DIR", default_value = "verisimdb-data")]
767+
verisimdb_dir: PathBuf,
768+
769+
/// Write the Markdown to a file instead of stdout.
770+
#[arg(short, long, value_name = "FILE")]
771+
output: Option<PathBuf>,
772+
773+
/// Emit only the "By repo" section.
774+
#[arg(long, group = "sweep_shape", default_value_t = false)]
775+
by_repo: bool,
776+
777+
/// Emit only the "By category" section.
778+
#[arg(long, group = "sweep_shape", default_value_t = false)]
779+
by_category: bool,
780+
},
756781
}
757782

758783
#[derive(Subcommand)]
@@ -2451,6 +2476,28 @@ fn run_main() -> Result<()> {
24512476
return Ok(());
24522477
}
24532478

2479+
Commands::SweepTracker {
2480+
verisimdb_dir,
2481+
output,
2482+
by_repo,
2483+
by_category,
2484+
} => {
2485+
let shape = match (by_repo, by_category) {
2486+
(true, false) => sweep_tracker::ReportShape::ByRepo,
2487+
(false, true) => sweep_tracker::ReportShape::ByCategory,
2488+
_ => sweep_tracker::ReportShape::Both,
2489+
};
2490+
let md = sweep_tracker::render_report(&verisimdb_dir, shape)?;
2491+
match output {
2492+
Some(path) => {
2493+
std::fs::write(&path, &md)?;
2494+
qprintln!(cli.quiet, "Sweep tracker written to {}", path.display());
2495+
}
2496+
None => print!("{}", md),
2497+
}
2498+
return Ok(());
2499+
}
2500+
24542501
Commands::Temporal { action } => {
24552502
match action {
24562503
TemporalAction::List { verisimdb_dir } => {

0 commit comments

Comments
 (0)