const AGENT_CONTRACT_PATTERNS: &[&str] = &[
"contract-first",
"provable-contract",
"NEVER write code before",
"NEVER.*code.*before.*contract",
"CB-1400",
"verification_level",
"pmat comply",
];
const AI_COAUTHOR_PATTERNS: &[&str] = &[
"Co-Authored-By: Claude",
"Co-Authored-By: Copilot",
"Co-Authored-By: GPT",
"Co-Authored-By: Gemini",
"Co-Authored-By: Cursor",
"Co-Authored-By: Cody",
"Co-Authored-By: Devin",
"Co-Authored-By: Codex",
"generated by ai",
"ai-generated",
];
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub(crate) fn check_agent_contract_existence(project_path: &Path) -> ComplianceCheck {
let agent_files = [
"CLAUDE.md",
"GEMINI.md",
"AGENTS.md",
"AGENT.md",
".claude/CLAUDE.md",
];
let mut found_agent_files = Vec::new();
let mut files_with_contract_ref = Vec::new();
let mut files_missing_contract_ref = Vec::new();
for agent_file in &agent_files {
let path = project_path.join(agent_file);
if path.exists() {
found_agent_files.push(*agent_file);
if let Ok(content) = fs::read_to_string(&path) {
let content_lower = content.to_lowercase();
let has_contract_ref = AGENT_CONTRACT_PATTERNS
.iter()
.any(|p| content_lower.contains(&p.to_lowercase()));
if has_contract_ref {
files_with_contract_ref.push(*agent_file);
} else {
files_missing_contract_ref.push(*agent_file);
}
}
}
}
if found_agent_files.is_empty() {
return ComplianceCheck {
name: "CB-1400: Agent Contract Existence".into(),
status: CheckStatus::Skip,
message: "No agent context files found (CLAUDE.md, AGENTS.md, etc.)".into(),
severity: Severity::Info,
};
}
if files_missing_contract_ref.is_empty() {
ComplianceCheck {
name: "CB-1400: Agent Contract Existence".into(),
status: CheckStatus::Pass,
message: format!(
"{}/{} agent context file(s) reference contract-first design",
files_with_contract_ref.len(),
found_agent_files.len()
),
severity: Severity::Info,
}
} else {
ComplianceCheck {
name: "CB-1400: Agent Contract Existence".into(),
status: CheckStatus::Fail,
message: format!(
"{} agent context file(s) lack contract-first reference: {}",
files_missing_contract_ref.len(),
files_missing_contract_ref.join(", ")
),
severity: Severity::Error,
}
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub(crate) fn check_agent_contract_falsifiability(project_path: &Path) -> ComplianceCheck {
let work_dir = project_path.join(".pmat-work");
if !work_dir.exists() {
return ComplianceCheck {
name: "CB-1401: Agent Contract Falsifiability".into(),
status: CheckStatus::Skip,
message: "No .pmat-work/ directory found".into(),
severity: Severity::Info,
};
}
let mut total_contracts = 0usize;
let mut contracts_with_evidence = 0usize;
let mut contracts_without_evidence = Vec::new();
if let Ok(entries) = fs::read_dir(&work_dir) {
for entry in entries.flatten() {
let contract_path = entry.path().join("contract.json");
if !contract_path.exists() {
continue;
}
total_contracts += 1;
if let Ok(content) = fs::read_to_string(&contract_path) {
let has_evidence = content.contains("\"evidence\":")
&& !content.contains("\"evidence\": \"\"")
&& !content.contains("\"evidence\":\"\"");
let has_dbc = content.contains("\"require\":")
|| content.contains("\"ensure\":")
|| content.contains("\"invariant\":");
let has_claims = content.contains("\"claims\":")
|| content.contains("\"falsifiable_claims\":");
if (has_evidence && has_dbc) || has_claims {
contracts_with_evidence += 1;
} else {
let id = entry
.file_name()
.to_string_lossy()
.to_string();
if contracts_without_evidence.len() < 5 {
contracts_without_evidence.push(id);
}
}
}
}
}
if total_contracts == 0 {
return ComplianceCheck {
name: "CB-1401: Agent Contract Falsifiability".into(),
status: CheckStatus::Skip,
message: "No work contracts found in .pmat-work/".into(),
severity: Severity::Info,
};
}
if contracts_without_evidence.is_empty() {
ComplianceCheck {
name: "CB-1401: Agent Contract Falsifiability".into(),
status: CheckStatus::Pass,
message: format!(
"{}/{} work contract(s) have falsifiable claims with evidence",
contracts_with_evidence, total_contracts
),
severity: Severity::Info,
}
} else {
ComplianceCheck {
name: "CB-1401: Agent Contract Falsifiability".into(),
status: CheckStatus::Fail,
message: format!(
"{} contract(s) lack falsifiable evidence: {}",
contracts_without_evidence.len(),
contracts_without_evidence.join(", ")
),
severity: Severity::Error,
}
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub(crate) fn check_agent_verification_level(project_path: &Path) -> ComplianceCheck {
let work_dir = project_path.join(".pmat-work");
if !work_dir.exists() {
return ComplianceCheck {
name: "CB-1402: Agent Verification Level".into(),
status: CheckStatus::Skip,
message: "No .pmat-work/ directory found".into(),
severity: Severity::Info,
};
}
let mut total_contracts = 0usize;
let mut l0_contracts = Vec::new();
let mut no_level_contracts = Vec::new();
if let Ok(entries) = fs::read_dir(&work_dir) {
for entry in entries.flatten() {
let contract_path = entry.path().join("contract.json");
if !contract_path.exists() {
continue;
}
total_contracts += 1;
if let Ok(content) = fs::read_to_string(&contract_path) {
let id = entry.file_name().to_string_lossy().to_string();
if content.contains("\"verification_level\"") {
if (content.contains("\"L0\"") || content.contains("\"l0\""))
&& l0_contracts.len() < 5
{
l0_contracts.push(id);
}
} else {
if no_level_contracts.len() < 5 {
no_level_contracts.push(id);
}
}
}
}
}
if total_contracts == 0 {
return ComplianceCheck {
name: "CB-1402: Agent Verification Level".into(),
status: CheckStatus::Skip,
message: "No work contracts found".into(),
severity: Severity::Info,
};
}
if !l0_contracts.is_empty() {
ComplianceCheck {
name: "CB-1402: Agent Verification Level".into(),
status: CheckStatus::Fail,
message: format!(
"{} contract(s) at L0 (paper-only) — autonomous agents require >= L1: {}",
l0_contracts.len(),
l0_contracts.join(", ")
),
severity: Severity::Error,
}
} else if !no_level_contracts.is_empty() {
ComplianceCheck {
name: "CB-1402: Agent Verification Level".into(),
status: CheckStatus::Warn,
message: format!(
"{} contract(s) missing verification_level field: {}",
no_level_contracts.len(),
no_level_contracts.join(", ")
),
severity: Severity::Warning,
}
} else {
ComplianceCheck {
name: "CB-1402: Agent Verification Level".into(),
status: CheckStatus::Pass,
message: format!(
"{} work contract(s) at verification level >= L1",
total_contracts
),
severity: Severity::Info,
}
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub(crate) fn check_assume_guarantee_chain(project_path: &Path) -> ComplianceCheck {
let work_dir = project_path.join(".pmat-work");
if !work_dir.exists() {
return ComplianceCheck {
name: "CB-1403: Assume-Guarantee Chain".into(),
status: CheckStatus::Skip,
message: "No .pmat-work/ directory found".into(),
severity: Severity::Info,
};
}
let mut chained_contracts = 0usize;
let mut total_contracts = 0usize;
if let Ok(entries) = fs::read_dir(&work_dir) {
for entry in entries.flatten() {
let contract_path = entry.path().join("contract.json");
if !contract_path.exists() {
continue;
}
total_contracts += 1;
if let Ok(content) = fs::read_to_string(&contract_path) {
let has_chain_ref = content.contains("\"iteration\":")
&& !content.contains("\"iteration\": 1")
&& !content.contains("\"iteration\":1");
let has_parent = content.contains("\"parent_agent\"")
|| content.contains("\"depends_on\"");
let has_refs_pattern = content.contains("Refs PMAT-")
|| content.contains("refs PMAT-");
if has_chain_ref || has_parent || has_refs_pattern {
chained_contracts += 1;
}
}
}
}
if total_contracts == 0 {
return ComplianceCheck {
name: "CB-1403: Assume-Guarantee Chain".into(),
status: CheckStatus::Skip,
message: "No work contracts found".into(),
severity: Severity::Info,
};
}
ComplianceCheck {
name: "CB-1403: Assume-Guarantee Chain".into(),
status: CheckStatus::Pass,
message: format!(
"{}/{} contract(s) participate in assume-guarantee chains",
chained_contracts, total_contracts
),
severity: Severity::Info,
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub(crate) fn check_agent_comply_usage(project_path: &Path) -> ComplianceCheck {
let work_dir = project_path.join(".pmat-work");
if !work_dir.exists() {
return ComplianceCheck {
name: "CB-1404: Agent Comply Usage".into(),
status: CheckStatus::Skip,
message: "No .pmat-work/ directory found".into(),
severity: Severity::Info,
};
}
let mut total_contracts = 0usize;
let mut contracts_with_receipts = 0usize;
if let Ok(entries) = fs::read_dir(&work_dir) {
for entry in entries.flatten() {
let contract_path = entry.path().join("contract.json");
if !contract_path.exists() {
continue;
}
total_contracts += 1;
let has_falsification = entry.path().join("falsification").exists()
&& fs::read_dir(entry.path().join("falsification"))
.map(|d| d.count() > 0)
.unwrap_or(false);
let has_checkpoints = entry.path().join("checkpoints").exists()
&& fs::read_dir(entry.path().join("checkpoints"))
.map(|d| d.count() > 0)
.unwrap_or(false);
if has_falsification || has_checkpoints {
contracts_with_receipts += 1;
}
}
}
if total_contracts == 0 {
return ComplianceCheck {
name: "CB-1404: Agent Comply Usage".into(),
status: CheckStatus::Skip,
message: "No work contracts found".into(),
severity: Severity::Info,
};
}
let ratio = contracts_with_receipts as f64 / total_contracts as f64;
if ratio >= 0.8 {
ComplianceCheck {
name: "CB-1404: Agent Comply Usage".into(),
status: CheckStatus::Pass,
message: format!(
"{}/{} contract(s) have falsification receipts (comply was run)",
contracts_with_receipts, total_contracts
),
severity: Severity::Info,
}
} else {
ComplianceCheck {
name: "CB-1404: Agent Comply Usage".into(),
status: CheckStatus::Warn,
message: format!(
"Only {}/{} contract(s) have receipts — agents should run pmat comply before completing",
contracts_with_receipts, total_contracts
),
severity: Severity::Warning,
}
}
}
#[cfg(test)]
mod tests_agent_contracts {
use super::*;
#[test]
fn test_cb1400_skip_no_agent_files() {
let tmp = tempfile::tempdir().expect("create tempdir");
let result = check_agent_contract_existence(tmp.path());
assert_eq!(result.status, CheckStatus::Skip);
assert!(result.message.contains("No agent context files"));
}
#[test]
fn test_cb1400_pass_claude_md_with_contract_ref() {
let tmp = tempfile::tempdir().expect("create tempdir");
std::fs::write(
tmp.path().join("CLAUDE.md"),
"# Instructions\n\nUse contract-first design.\npmat comply check required.\n",
)
.unwrap();
let result = check_agent_contract_existence(tmp.path());
assert_eq!(result.status, CheckStatus::Pass);
assert!(result.message.contains("1/1"));
}
#[test]
fn test_cb1400_fail_agent_file_without_contract_ref() {
let tmp = tempfile::tempdir().expect("create tempdir");
std::fs::write(
tmp.path().join("CLAUDE.md"),
"# Instructions\n\nJust write code.\n",
)
.unwrap();
let result = check_agent_contract_existence(tmp.path());
assert_eq!(result.status, CheckStatus::Fail);
assert!(result.message.contains("CLAUDE.md"));
}
#[test]
fn test_cb1400_mixed_agent_files() {
let tmp = tempfile::tempdir().expect("create tempdir");
std::fs::write(
tmp.path().join("CLAUDE.md"),
"# Instructions\nUse contract-first approach.\n",
)
.unwrap();
std::fs::write(
tmp.path().join("AGENTS.md"),
"# Agent Protocol\nNo contract references here.\n",
)
.unwrap();
let result = check_agent_contract_existence(tmp.path());
assert_eq!(result.status, CheckStatus::Fail);
assert!(result.message.contains("AGENTS.md"));
}
#[test]
fn test_cb1401_skip_no_work_dir() {
let tmp = tempfile::tempdir().expect("create tempdir");
let result = check_agent_contract_falsifiability(tmp.path());
assert_eq!(result.status, CheckStatus::Skip);
}
#[test]
fn test_cb1401_pass_contract_with_evidence() {
let tmp = tempfile::tempdir().expect("create tempdir");
let work_dir = tmp.path().join(".pmat-work").join("PMAT-001");
std::fs::create_dir_all(&work_dir).unwrap();
std::fs::write(
work_dir.join("contract.json"),
r#"{"require": [{"description": "builds", "evidence": "cargo build"}],
"ensure": [{"description": "tests pass", "evidence": "cargo test"}],
"claims": [{"method": "Test"}]}"#,
)
.unwrap();
let result = check_agent_contract_falsifiability(tmp.path());
assert_eq!(result.status, CheckStatus::Pass);
}
#[test]
fn test_cb1401_fail_contract_without_evidence() {
let tmp = tempfile::tempdir().expect("create tempdir");
let work_dir = tmp.path().join(".pmat-work").join("PMAT-001");
std::fs::create_dir_all(&work_dir).unwrap();
std::fs::write(
work_dir.join("contract.json"),
r#"{"title": "Just a title", "status": "planned"}"#,
)
.unwrap();
let result = check_agent_contract_falsifiability(tmp.path());
assert_eq!(result.status, CheckStatus::Fail);
assert!(result.message.contains("PMAT-001"));
}
#[test]
fn test_cb1402_skip_no_work_dir() {
let tmp = tempfile::tempdir().expect("create tempdir");
let result = check_agent_verification_level(tmp.path());
assert_eq!(result.status, CheckStatus::Skip);
}
#[test]
fn test_cb1402_pass_l3_contract() {
let tmp = tempfile::tempdir().expect("create tempdir");
let work_dir = tmp.path().join(".pmat-work").join("PMAT-002");
std::fs::create_dir_all(&work_dir).unwrap();
std::fs::write(
work_dir.join("contract.json"),
r#"{"verification_level": "L3", "require": []}"#,
)
.unwrap();
let result = check_agent_verification_level(tmp.path());
assert_eq!(result.status, CheckStatus::Pass);
}
#[test]
fn test_cb1402_fail_l0_contract() {
let tmp = tempfile::tempdir().expect("create tempdir");
let work_dir = tmp.path().join(".pmat-work").join("PMAT-003");
std::fs::create_dir_all(&work_dir).unwrap();
std::fs::write(
work_dir.join("contract.json"),
r#"{"verification_level": "L0", "require": []}"#,
)
.unwrap();
let result = check_agent_verification_level(tmp.path());
assert_eq!(result.status, CheckStatus::Fail);
assert!(result.message.contains("L0"));
}
#[test]
fn test_cb1402_warn_no_level() {
let tmp = tempfile::tempdir().expect("create tempdir");
let work_dir = tmp.path().join(".pmat-work").join("PMAT-004");
std::fs::create_dir_all(&work_dir).unwrap();
std::fs::write(
work_dir.join("contract.json"),
r#"{"require": [], "ensure": []}"#,
)
.unwrap();
let result = check_agent_verification_level(tmp.path());
assert_eq!(result.status, CheckStatus::Warn);
assert!(result.message.contains("missing verification_level"));
}
#[test]
fn test_cb1403_skip_no_work_dir() {
let tmp = tempfile::tempdir().expect("create tempdir");
let result = check_assume_guarantee_chain(tmp.path());
assert_eq!(result.status, CheckStatus::Skip);
}
#[test]
fn test_cb1403_pass_with_refs() {
let tmp = tempfile::tempdir().expect("create tempdir");
let work_dir = tmp.path().join(".pmat-work").join("PMAT-005");
std::fs::create_dir_all(&work_dir).unwrap();
std::fs::write(
work_dir.join("contract.json"),
r#"{"title": "Test", "iteration": 2, "require": []}"#,
)
.unwrap();
let result = check_assume_guarantee_chain(tmp.path());
assert_eq!(result.status, CheckStatus::Pass);
assert!(result.message.contains("1/1"));
}
#[test]
fn test_cb1404_skip_no_work_dir() {
let tmp = tempfile::tempdir().expect("create tempdir");
let result = check_agent_comply_usage(tmp.path());
assert_eq!(result.status, CheckStatus::Skip);
}
#[test]
fn test_cb1404_pass_with_receipts() {
let tmp = tempfile::tempdir().expect("create tempdir");
let work_dir = tmp.path().join(".pmat-work").join("PMAT-010");
let receipt_dir = work_dir.join("falsification");
std::fs::create_dir_all(&receipt_dir).unwrap();
std::fs::write(work_dir.join("contract.json"), r#"{"version": "5.0"}"#).unwrap();
std::fs::write(receipt_dir.join("receipt-1.json"), "{}").unwrap();
let result = check_agent_comply_usage(tmp.path());
assert_eq!(result.status, CheckStatus::Pass);
}
#[test]
fn test_cb1404_pass_with_checkpoints() {
let tmp = tempfile::tempdir().expect("create tempdir");
let work_dir = tmp.path().join(".pmat-work").join("PMAT-010b");
let checkpoint_dir = work_dir.join("checkpoints");
std::fs::create_dir_all(&checkpoint_dir).unwrap();
std::fs::write(work_dir.join("contract.json"), r#"{"version": "5.0"}"#).unwrap();
std::fs::write(checkpoint_dir.join("checkpoint-1.json"), "{}").unwrap();
let result = check_agent_comply_usage(tmp.path());
assert_eq!(result.status, CheckStatus::Pass);
}
#[test]
fn test_cb1404_warn_no_receipts() {
let tmp = tempfile::tempdir().expect("create tempdir");
let work_dir = tmp.path().join(".pmat-work").join("PMAT-011");
std::fs::create_dir_all(&work_dir).unwrap();
std::fs::write(work_dir.join("contract.json"), r#"{"version": "5.0"}"#).unwrap();
let result = check_agent_comply_usage(tmp.path());
assert_eq!(result.status, CheckStatus::Warn);
}
}