pub struct TaskRow {
pub task: &'static str,
pub command: &'static str,
pub note: Option<&'static str>,
#[cfg_attr(
not(test),
allow(
dead_code,
reason = "read only by the schema drift tests via try_parse_from"
)
)]
pub probe: &'static [&'static str],
}
pub const TASK_MATRIX: &[TaskRow] = &[
TaskRow {
task: "delete an \"unused\" export or file",
command: "fallow dead-code --trace <file>:<export>",
note: None,
probe: &["dead-code", "--trace", "src/index.ts:foo"],
},
TaskRow {
task: "delete an \"unused\" dependency",
command: "fallow dead-code --trace-dependency <name>",
note: None,
probe: &["dead-code", "--trace-dependency", "lodash"],
},
TaskRow {
task: "commit or open a PR",
command: "fallow audit --base <ref>",
note: None,
probe: &["audit", "--base", "main"],
},
TaskRow {
task: "prioritize refactoring",
command: "fallow health --hotspots --targets",
note: None,
probe: &["health", "--hotspots", "--targets"],
},
TaskRow {
task: "ask who owns code",
command: "fallow health --ownership",
note: None,
probe: &["health", "--ownership"],
},
TaskRow {
task: "check untested-but-reachable code",
command: "fallow health --coverage-gaps",
note: None,
probe: &["health", "--coverage-gaps"],
},
TaskRow {
task: "consolidate duplication",
command: "fallow dupes --trace dup:<fingerprint>",
note: None,
probe: &["dupes", "--trace", "dup:abc123"],
},
TaskRow {
task: "find feature flags",
command: "fallow flags",
note: None,
probe: &["flags"],
},
TaskRow {
task: "surface security candidates",
command: "fallow security",
note: None,
probe: &["security"],
},
TaskRow {
task: "understand a finding",
command: "fallow explain <issue-type>",
note: None,
probe: &["explain", "unused-export"],
},
TaskRow {
task: "scope a monorepo",
command: "--workspace <glob> / --changed-workspaces <ref>",
note: Some("global flags, prefix any command"),
probe: &[],
},
];
#[cfg_attr(
not(test),
allow(
dead_code,
reason = "read only by the matrix exclusion tests in this crate"
)
)]
pub const MUTATING_COMMANDS: &[&str] = &["fix", "init", "hooks", "migrate", "setup-hooks", "watch"];
#[must_use]
pub fn render_task_matrix_markdown() -> String {
use std::fmt::Write as _;
let mut out = String::with_capacity(1024);
out.push_str("| When the agent is about to... | Run |\n");
out.push_str("|---|---|\n");
for row in TASK_MATRIX {
let suffix = match row.note {
Some(note) => format!(" ({note})"),
None => String::new(),
};
let _ = writeln!(out, "| {} | `{}`{suffix} |", row.task, row.command);
}
out
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn matrix_is_non_empty() {
assert!(!TASK_MATRIX.is_empty());
}
#[test]
fn render_contains_every_command() {
let table = render_task_matrix_markdown();
assert!(table.contains("When the agent is about to..."));
for row in TASK_MATRIX {
assert!(
table.contains(row.command),
"rendered table missing command {}",
row.command
);
}
}
#[test]
fn matrix_excludes_mutating_commands() {
for row in TASK_MATRIX {
let after_fallow = row.command.strip_prefix("fallow ").unwrap_or(row.command);
let first_token = after_fallow.split_whitespace().next().unwrap_or("");
assert!(
!MUTATING_COMMANDS.contains(&first_token),
"task matrix row '{}' names mutating command '{first_token}'",
row.task
);
}
}
}