weavatrix-refactor-plan 0.1.1

Evidence metadata, validation profiles, and canonical fingerprints for Weavatrix refactor plans
Documentation
use crate::{MAX_PLAN_OPERATION_BYTES, PlanError, PlanErrorCode};

/// Hard ceilings applied before a refactor plan can be fingerprinted or executed.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct RefactorPlanLimits {
    pub max_operations: usize,
    pub max_paths: usize,
    pub max_path_bytes: usize,
    pub max_operation_bytes: usize,
    pub max_edits_per_file: usize,
    pub max_total_edits: usize,
    pub max_create_bytes_per_file: usize,
    pub max_total_create_bytes: usize,
    pub max_total_text_bytes: usize,
    pub max_extension_bytes: usize,
    pub max_extension_nodes: usize,
    pub max_extension_depth: usize,
    pub max_evidence_entries: usize,
    pub max_evidence_text_bytes: usize,
    pub max_code_bytes: usize,
}

impl Default for RefactorPlanLimits {
    fn default() -> Self {
        const MIB: usize = 1024 * 1024;
        Self {
            max_operations: 64,
            max_paths: 64,
            max_path_bytes: 4_096,
            max_operation_bytes: 4_096,
            max_edits_per_file: 2_000,
            max_total_edits: 128_000,
            max_create_bytes_per_file: 64 * MIB,
            max_total_create_bytes: 256 * MIB,
            max_total_text_bytes: 384 * MIB,
            max_extension_bytes: 256 * 1024,
            max_extension_nodes: 4_096,
            max_extension_depth: 32,
            max_evidence_entries: 10_000,
            max_evidence_text_bytes: 8 * MIB,
            max_code_bytes: 256,
        }
    }
}

impl RefactorPlanLimits {
    pub(crate) fn validate(self) -> Result<(), PlanError> {
        let values = [
            self.max_operations,
            self.max_paths,
            self.max_path_bytes,
            self.max_operation_bytes,
            self.max_edits_per_file,
            self.max_total_edits,
            self.max_create_bytes_per_file,
            self.max_total_create_bytes,
            self.max_total_text_bytes,
            self.max_extension_bytes,
            self.max_extension_nodes,
            self.max_extension_depth,
            self.max_evidence_entries,
            self.max_evidence_text_bytes,
            self.max_code_bytes,
        ];
        if values.contains(&0)
            || self.max_total_create_bytes < self.max_create_bytes_per_file
            || self.max_operation_bytes > MAX_PLAN_OPERATION_BYTES
        {
            return Err(PlanError::new(
                PlanErrorCode::InvalidPlan,
                "refactor plan limits must be nonzero, internally consistent, and within absolute ceilings",
            ));
        }
        Ok(())
    }
}

/// Bounded statistics established by structural validation.
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct PlanStats {
    pub operations: usize,
    pub paths: usize,
    pub edits: usize,
    pub edit_text_bytes: usize,
    pub create_bytes: usize,
}