forjar 1.4.2

Rust-native Infrastructure as Code — bare-metal first, BLAKE3 state, provenance tracing
Documentation
//! FJ-1352: Contract YAML scaffolder for missing kernel contracts.
//!
//! Generates canonical contract YAML stubs for kernel operations that
//! lack provable contracts, following the established contract format.

use super::hf_config::KernelRequirement;
use std::path::Path;

/// A generated contract stub ready to be written to disk.
#[derive(Debug, Clone, PartialEq)]
pub struct ContractStub {
    /// Output filename (e.g., "softmax-kernel-v1.yaml").
    pub filename: String,
    /// Generated YAML contract content.
    pub yaml_content: String,
}

/// Generate contract YAML stubs for missing kernel operations.
pub fn scaffold_contracts(missing: &[KernelRequirement], author: &str) -> Vec<ContractStub> {
    missing
        .iter()
        .map(|req| {
            let yaml = format!(
                concat!(
                    "# Provable contract stub for {op}\n",
                    "# Generated by forjar — fill in equations and proof obligations\n",
                    "\n",
                    "metadata:\n",
                    "  name: {contract}\n",
                    "  version: \"0.1.0-stub\"\n",
                    "  author: \"{author}\"\n",
                    "  kernel_op: {op}\n",
                    "\n",
                    "equations:\n",
                    "  - id: EQ-{op_upper}-01\n",
                    "    description: \"TODO: Define primary equation for {op}\"\n",
                    "    formula: \"TODO\"\n",
                    "\n",
                    "proof_obligations:\n",
                    "  - id: PO-{op_upper}-01\n",
                    "    equation: EQ-{op_upper}-01\n",
                    "    description: \"TODO: Define proof obligation\"\n",
                    "    strategy: \"TODO\"\n",
                    "\n",
                    "falsification_tests:\n",
                    "  - id: FALSIFY-{op_upper}-001\n",
                    "    equation: EQ-{op_upper}-01\n",
                    "    description: \"TODO: Define falsification test\"\n",
                    "    input: \"TODO\"\n",
                    "    expected: \"TODO\"\n",
                ),
                op = req.op,
                contract = req.contract,
                author = author,
                op_upper = req.op.to_uppercase(),
            );
            ContractStub {
                filename: format!("{}.yaml", req.contract),
                yaml_content: yaml,
            }
        })
        .collect()
}

/// Write contract stubs to disk. Skips files that already exist (no overwrite).
/// Returns the list of filenames that were actually written.
pub fn write_stubs(stubs: &[ContractStub], output_dir: &Path) -> Result<Vec<String>, String> {
    std::fs::create_dir_all(output_dir)
        .map_err(|e| format!("create dir {}: {e}", output_dir.display()))?;

    let mut written = Vec::new();
    for stub in stubs {
        let path = output_dir.join(&stub.filename);
        if path.exists() {
            continue;
        }
        std::fs::write(&path, &stub.yaml_content)
            .map_err(|e| format!("write {}: {e}", path.display()))?;
        written.push(stub.filename.clone());
    }
    Ok(written)
}