impl WorkContract {
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub fn acknowledge_legacy_debt(&mut self, project_path: &Path) -> Result<()> {
let timestamp = chrono::Utc::now().format("%Y%m%d%H%M%S").to_string();
let mut debt_items: Vec<DebtItem> = Vec::new();
if self.baseline_coverage < self.thresholds.min_coverage_pct {
let ticket_id = format!("DEBT-COV-{}", timestamp);
debt_items.push(DebtItem {
ticket_id: ticket_id.clone(),
category: "coverage".to_string(),
description: format!(
"Coverage {:.1}% is below required {:.1}%",
self.baseline_coverage, self.thresholds.min_coverage_pct
),
current_value: self.baseline_coverage,
required_value: self.thresholds.min_coverage_pct,
});
for claim in &mut self.claims {
if claim.falsification_method == FalsificationMethod::AbsoluteCoverage {
claim.override_info = Some(OverrideInfo {
reason: "Legacy Debt: Project predates strict coverage requirements"
.to_string(),
ticket_id: ticket_id.clone(),
timestamp: chrono::Utc::now(),
});
}
}
}
let large_files: Vec<_> = self
.baseline_file_manifest
.files
.iter()
.filter(|(_, entry)| entry.lines > self.thresholds.max_file_lines)
.map(|(path, entry)| (path.clone(), entry.lines))
.collect();
if !large_files.is_empty() {
let ticket_id = format!("DEBT-SIZE-{}", timestamp);
let details: Vec<String> = large_files
.iter()
.take(10)
.map(|(p, lines)| format!("{}: {} lines", p.display(), lines))
.collect();
debt_items.push(DebtItem {
ticket_id: ticket_id.clone(),
category: "file_size".to_string(),
description: format!(
"{} file(s) exceed {} line limit: {}",
large_files.len(),
self.thresholds.max_file_lines,
details.join(", ")
),
current_value: large_files.len() as f64,
required_value: 0.0,
});
for claim in &mut self.claims {
if claim.falsification_method == FalsificationMethod::FileSizeRegression {
claim.override_info = Some(OverrideInfo {
reason: "Legacy Debt: Large files predate strict size requirements"
.to_string(),
ticket_id: ticket_id.clone(),
timestamp: chrono::Utc::now(),
});
}
}
}
if !debt_items.is_empty() {
write_debt_tickets(project_path, &debt_items)?;
}
Ok(())
}
}
fn write_debt_tickets(project_path: &Path, debt_items: &[DebtItem]) -> Result<()> {
let tickets_dir = project_path.join(".pmat-tickets");
std::fs::create_dir_all(&tickets_dir)?;
for item in debt_items {
let ticket_path = tickets_dir.join(format!("{}.yaml", item.ticket_id));
let yaml_content = format!(
r#"# PMAT Legacy Debt Ticket
# Auto-generated by `pmat comply upgrade`
# DO NOT DELETE - Required for Popperian falsification override
ticket_id: "{}"
category: "{}"
created_at: "{}"
status: "open"
description: |
{}
metrics:
current: {:.2}
required: {:.2}
gap: {:.2}
resolution:
# Update this section when addressing the debt
plan: "TBD"
target_date: null
completed_at: null
"#,
item.ticket_id,
item.category,
chrono::Utc::now().to_rfc3339(),
item.description,
item.current_value,
item.required_value,
item.required_value - item.current_value,
);
std::fs::write(&ticket_path, yaml_content)?;
println!(" Created debt ticket: {}", ticket_path.display());
}
Ok(())
}
#[derive(Debug)]
struct DebtItem {
ticket_id: String,
category: String,
description: String,
current_value: f64,
required_value: f64,
}