#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkContract {
#[serde(default = "default_contract_version")]
pub version: String,
pub work_item_id: String,
pub created_at: chrono::DateTime<chrono::Utc>,
pub baseline_commit: String,
pub baseline_tdg: f64,
pub baseline_coverage: f64,
pub baseline_rust_score: Option<f64>,
pub baseline_file_manifest: FileManifest,
pub thresholds: ContractThresholds,
pub claims: Vec<FalsifiableClaim>,
#[serde(default)]
pub profile: Option<ContractProfile>,
#[serde(default)]
pub require: Vec<ContractClause>,
#[serde(default)]
pub ensure: Vec<ContractClause>,
#[serde(default)]
pub invariant: Vec<ContractClause>,
#[serde(default)]
pub excluded_claims: Vec<ExcludedClaim>,
#[serde(default = "default_iteration")]
pub iteration: u32,
#[serde(default)]
pub inherited_postconditions: Vec<ContractClause>,
#[serde(default)]
pub contract_quality: Option<ContractQuality>,
#[serde(default)]
pub contract_score: Option<ContractScore>,
#[serde(default = "default_verification_level")]
pub verification_level: String,
#[serde(default)]
pub references: WorkReferences,
#[serde(default)]
pub chain_of_thought: Vec<ChainOfThoughtStep>,
#[serde(default)]
pub implements: Vec<ContractBinding>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ContractBinding {
pub contract: String,
pub equation: String,
pub file: PathBuf,
pub sha: String,
pub bound_at: chrono::DateTime<chrono::Utc>,
}
impl ContractBinding {
pub fn parse_token(token: &str) -> Option<(String, String)> {
let mut parts = token.splitn(2, '/');
let contract = parts.next()?.trim();
let equation = parts.next()?.trim();
if contract.is_empty() || equation.is_empty() {
return None;
}
Some((contract.to_string(), equation.to_string()))
}
pub fn key(&self) -> String {
format!("{}/{}", self.contract, self.equation)
}
}
fn default_verification_level() -> String {
"L3".to_string()
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct WorkReferences {
#[serde(default)]
pub arxiv: Vec<String>,
#[serde(default)]
pub spec_sections: Vec<String>,
#[serde(default)]
pub five_whys_id: Option<String>,
#[serde(default)]
pub oracle_context: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChainOfThoughtStep {
pub step: u32,
pub question: String,
pub answer: String,
}
fn default_contract_version() -> String {
"4.0".to_string()
}
fn default_iteration() -> u32 {
1
}
impl WorkContract {
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn new(work_item_id: String, baseline_commit: String) -> Self {
Self {
version: "4.0".to_string(),
work_item_id,
created_at: chrono::Utc::now(),
baseline_commit,
baseline_tdg: 0.0,
baseline_coverage: 0.0,
baseline_rust_score: None,
baseline_file_manifest: FileManifest::default(),
thresholds: ContractThresholds::default(),
claims: Self::default_claims(),
profile: None,
require: Vec::new(),
ensure: Vec::new(),
invariant: Vec::new(),
excluded_claims: Vec::new(),
iteration: 1,
inherited_postconditions: Vec::new(),
contract_quality: None,
contract_score: None,
verification_level: default_verification_level(),
references: WorkReferences::default(),
chain_of_thought: Vec::new(),
implements: Vec::new(),
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub fn with_dbc(
work_item_id: String,
baseline_commit: String,
project_path: &Path,
without: &[String],
iteration: u32,
) -> Result<Self, anyhow::Error> {
let config = DbcConfig::load(project_path);
let profile = config.profile_override.clone()
.unwrap_or_else(|| ContractProfile::detect(project_path));
let missing_tools = check_toolchain(&profile, project_path);
if !missing_tools.is_empty() {
let missing_names: Vec<_> = missing_tools.iter().map(|t| t.name.as_str()).collect();
anyhow::bail!(
"Toolchain precondition failure for {} profile: {} missing tool(s): {}\n\
Options:\n\
1. Install missing tools\n\
2. Downgrade: pmat work start <id> --profile universal\n\
3. Exclude: pmat work start <id> --without {}",
profile.name(),
missing_tools.len(),
missing_names.join(", "),
missing_tools.iter().map(|t| t.claim_id.as_str()).collect::<Vec<_>>().join(","),
);
}
let all_clauses = claims_for_profile(&profile, &config);
let applicable_count = all_clauses.len();
let (require, ensure, invariant) = classify_claims(&all_clauses);
let (require, excluded_r) = apply_exclusions(require, without);
let (ensure, excluded_e) = apply_exclusions(ensure, without);
let (invariant, excluded_i) = apply_exclusions(invariant, without);
let excluded_claims: Vec<ExcludedClaim> =
[excluded_r, excluded_e, excluded_i].concat();
let active_count = require.len() + ensure.len() + invariant.len();
let quality = ContractQuality::calculate(active_count, applicable_count);
let flat_claims = Self::default_claims();
let mut contract = Self {
version: "5.0".to_string(),
work_item_id,
created_at: chrono::Utc::now(),
baseline_commit,
baseline_tdg: 0.0,
baseline_coverage: 0.0,
baseline_rust_score: None,
baseline_file_manifest: FileManifest::default(),
thresholds: ContractThresholds::default(),
claims: flat_claims,
profile: Some(profile),
require,
ensure,
invariant,
excluded_claims,
iteration,
inherited_postconditions: Vec::new(),
contract_quality: Some(quality),
contract_score: None,
verification_level: default_verification_level(),
references: WorkReferences::default(),
chain_of_thought: Vec::new(),
implements: Vec::new(),
};
if iteration > 1 {
let prior_iteration = iteration - 1;
if let Ok(prior) = Self::load(project_path, &contract.work_item_id) {
if prior.iteration == prior_iteration {
if let Err(violation) = validate_subcontracting(&prior.ensure, &contract.ensure) {
anyhow::bail!(
"Subcontracting violation (iteration {} vs {}): {}\n\
Postconditions must not weaken between iterations.\n\
Fix: strengthen or maintain all postconditions from iteration {}.",
prior_iteration,
iteration,
violation,
prior_iteration,
);
}
contract.inherited_postconditions = prior.ensure.clone();
}
}
}
Ok(contract)
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn is_dbc(&self) -> bool {
self.version == "5.0" && self.profile.is_some()
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn triad_claim_count(&self) -> usize {
self.require.len() + self.ensure.len() + self.invariant.len()
}
fn default_claims() -> Vec<FalsifiableClaim> {
vec![
FalsifiableClaim {
hypothesis: "All baseline files still exist".to_string(),
falsification_method: FalsificationMethod::ManifestIntegrity,
evidence_required: EvidenceType::FileList(vec![]),
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "The falsifier is active and detecting (Meta-Check)".to_string(),
falsification_method: FalsificationMethod::MetaFalsification,
evidence_required: EvidenceType::CounterExample { details: "".into() },
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "No coverage exclusion gaming".to_string(),
falsification_method: FalsificationMethod::CoverageGaming,
evidence_required: EvidenceType::FileList(vec![]),
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "All changed lines are covered".to_string(),
falsification_method: FalsificationMethod::DifferentialCoverage,
evidence_required: EvidenceType::NumericComparison {
actual: 0.0,
threshold: 100.0,
},
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "Total coverage >= 95%".to_string(),
falsification_method: FalsificationMethod::AbsoluteCoverage,
evidence_required: EvidenceType::NumericComparison {
actual: 0.0,
threshold: 95.0,
},
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "TDG score >= baseline".to_string(),
falsification_method: FalsificationMethod::TdgRegression,
evidence_required: EvidenceType::NumericComparison {
actual: 0.0,
threshold: 0.0,
},
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "No function exceeds complexity 20".to_string(),
falsification_method: FalsificationMethod::ComplexityRegression,
evidence_required: EvidenceType::NumericComparison {
actual: 0.0,
threshold: 20.0,
},
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "No vulnerable dependencies added".to_string(),
falsification_method: FalsificationMethod::SupplyChainIntegrity,
evidence_required: EvidenceType::CounterExample { details: "".into() },
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "No file exceeds 500 lines".to_string(),
falsification_method: FalsificationMethod::FileSizeRegression,
evidence_required: EvidenceType::NumericComparison {
actual: 0.0,
threshold: 500.0,
},
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "Spec & Roadmap Quality".to_string(),
falsification_method: FalsificationMethod::SpecQuality,
evidence_required: EvidenceType::NumericComparison {
actual: 0.0,
threshold: 95.0,
},
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "All changes pushed".to_string(),
falsification_method: FalsificationMethod::GitHubSync,
evidence_required: EvidenceType::GitState {
unpushed_commits: 0,
dirty_files: 0,
},
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "All examples compile and run".to_string(),
falsification_method: FalsificationMethod::ExamplesCompile,
evidence_required: EvidenceType::CounterExample { details: "".into() },
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "pmat-book validation passes".to_string(),
falsification_method: FalsificationMethod::BookValidation,
evidence_required: EvidenceType::CounterExample { details: "".into() },
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "No new SATD markers (TODO/FIXME/HACK)".to_string(),
falsification_method: FalsificationMethod::SatdDetection,
evidence_required: EvidenceType::FileList(vec![]),
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "No new dead code introduced".to_string(),
falsification_method: FalsificationMethod::DeadCodeDetection,
evidence_required: EvidenceType::FileList(vec![]),
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "All files have >= 95% coverage".to_string(),
falsification_method: FalsificationMethod::PerFileCoverage,
evidence_required: EvidenceType::FileList(vec![]),
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "make lint passes".to_string(),
falsification_method: FalsificationMethod::LintPass,
evidence_required: EvidenceType::BooleanCheck(false),
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "All match arm variants have test coverage".to_string(),
falsification_method: FalsificationMethod::VariantCoverage,
evidence_required: EvidenceType::FileList(vec![]),
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "No fix-after-fix chains exceed limit".to_string(),
falsification_method: FalsificationMethod::FixChainLimit,
evidence_required: EvidenceType::NumericComparison {
actual: 0.0,
threshold: 3.0,
},
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "Cross-crate integration tests pass".to_string(),
falsification_method: FalsificationMethod::CrossCrateParity,
evidence_required: EvidenceType::BooleanCheck(false),
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "No performance regressions detected".to_string(),
falsification_method: FalsificationMethod::RegressionGate,
evidence_required: EvidenceType::NumericComparison {
actual: 0.0,
threshold: 0.0,
},
result: None,
override_info: None,
},
FalsifiableClaim {
hypothesis: "No incomplete proofs (sorry) introduced".to_string(),
falsification_method: FalsificationMethod::FormalProofVerification,
evidence_required: EvidenceType::NumericComparison {
actual: 0.0,
threshold: 0.0,
},
result: None,
override_info: None,
},
]
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub fn load(project_path: &Path, work_item_id: &str) -> Result<Self> {
let contract_path = Self::contract_path(project_path, work_item_id);
let content = std::fs::read_to_string(&contract_path)
.with_context(|| format!("Failed to load contract from {}", contract_path.display()))?;
serde_json::from_str(&content).context("Failed to parse contract JSON")
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub fn save(&self, project_path: &Path) -> Result<PathBuf> {
let contract_dir = project_path.join(".pmat-work").join(&self.work_item_id);
std::fs::create_dir_all(&contract_dir)?;
let contract_path = contract_dir.join("contract.json");
let json = serde_json::to_string_pretty(self)?;
std::fs::write(&contract_path, json)?;
Ok(contract_path)
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub fn contract_path(project_path: &Path, work_item_id: &str) -> PathBuf {
project_path
.join(".pmat-work")
.join(work_item_id)
.join("contract.json")
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub fn exists(project_path: &Path, work_item_id: &str) -> bool {
Self::contract_path(project_path, work_item_id).exists()
}
}