weavatrix-rust 2.0.1

Protocol-independent Rust repository intelligence: typed evidence graphs for impact, architecture, APIs, Git, search, and memory
Documentation
use super::{
    BTreeSet, DEFAULT_RUNTIME_REPORTS, MAX_RUNTIME_OBSERVATIONS, MAX_RUNTIME_REPORT_BYTES,
    Observation, RUNTIME_SCHEMA, RepositoryState, Value, fs, json, normalize_runtime_observation,
    otlp_event_observations, safe_repository_path, timestamp_millis,
};

#[derive(Debug, Default)]
pub(super) struct RuntimeAggregate {
    pub(super) reports: Vec<Value>,
    pub(super) reasons: Vec<String>,
    pub(super) absence_reasons: Vec<String>,
    pub(super) present: bool,
    pub(super) observation_count: usize,
    pub(super) resolved_locations: BTreeSet<(String, String, u32)>,
}

impl RuntimeAggregate {
    pub(super) fn status(&self) -> &'static str {
        if !self.present {
            "NOT_PROVIDED"
        } else if self.reasons.is_empty() {
            "COMPLETE"
        } else {
            "REJECTED"
        }
    }
}

pub(super) fn load_and_merge_runtime(
    repository: &str,
    state: &RepositoryState,
    args: &Value,
    observations: &mut Vec<Observation>,
    aggregate: &mut RuntimeAggregate,
) {
    let loaded = load_runtime_evidence(repository, state, args);
    aggregate.observation_count += loaded.observations.len();
    aggregate.present |= loaded.present;
    if loaded.present {
        aggregate.reasons.extend(loaded.reasons.iter().cloned());
    } else {
        aggregate
            .absence_reasons
            .extend(loaded.reasons.iter().cloned());
    }
    for runtime in loaded.observations {
        if !runtime.path.is_empty() && runtime.line > 0 {
            aggregate.resolved_locations.insert((
                repository.to_owned(),
                runtime.path.clone(),
                runtime.line,
            ));
        }
        if let Some(existing) = observations.iter_mut().find(|existing| {
            existing.repository == runtime.repository
                && existing.transport == runtime.transport
                && existing.entity == runtime.entity
                && existing.role == runtime.role
                && existing.resource == runtime.resource
        }) {
            existing.runtime_observed = true;
        } else {
            observations.push(runtime);
        }
    }
    aggregate.reports.push(json!({
        "repository": repository,
        "status": loaded.status,
        "present": loaded.present,
        "file": loaded.file,
        "generatedAt": loaded.generated_at,
        "repositoryRevision": loaded.repository_revision,
        "coverage": loaded.coverage,
        "observationCount": loaded.observation_count,
        "reasons": loaded.reasons
    }));
}

pub(super) struct RuntimeLoad {
    pub(super) status: &'static str,
    pub(super) present: bool,
    pub(super) file: Option<String>,
    pub(super) generated_at: Option<String>,
    pub(super) repository_revision: Option<String>,
    pub(super) coverage: Value,
    pub(super) observations: Vec<Observation>,
    pub(super) observation_count: usize,
    pub(super) reasons: Vec<String>,
}

pub(super) fn load_runtime_evidence(
    repository: &str,
    state: &RepositoryState,
    args: &Value,
) -> RuntimeLoad {
    let explicit = args
        .get("runtime_evidence_files")
        .and_then(|files| {
            files
                .get(repository)
                .or_else(|| files.get(state.root().to_string_lossy().as_ref()))
        })
        .and_then(Value::as_str)
        .map(str::to_owned);
    let candidates = explicit
        .as_deref()
        .map_or_else(|| DEFAULT_RUNTIME_REPORTS.to_vec(), |file| vec![file]);
    for candidate in candidates {
        let Some(path) = safe_repository_path(state.root(), candidate) else {
            if explicit.is_some() {
                return runtime_error(
                    Some(candidate.to_owned()),
                    format!("{repository}: runtime evidence path escapes the repository"),
                );
            }
            continue;
        };
        let Ok(metadata) = fs::metadata(&path) else {
            if explicit.is_some() {
                return runtime_error(
                    Some(candidate.to_owned()),
                    format!("{repository}: runtime evidence file is unreadable"),
                );
            }
            continue;
        };
        if metadata.len() > MAX_RUNTIME_REPORT_BYTES {
            return runtime_error(
                Some(candidate.to_owned()),
                format!("{repository}: runtime evidence exceeds {MAX_RUNTIME_REPORT_BYTES} bytes"),
            );
        }
        let Ok(bytes) = fs::read(&path) else {
            return runtime_error(
                Some(candidate.to_owned()),
                format!("{repository}: runtime evidence file is unreadable"),
            );
        };
        let Ok(report) = blazingly_json::from_slice::<Value>(&bytes) else {
            return runtime_error(
                Some(candidate.to_owned()),
                format!("{repository}: runtime evidence is invalid JSON"),
            );
        };
        return validate_runtime_report(repository, state, args, candidate, &report);
    }
    runtime_error(
        None,
        format!("{repository}: no revision-bound runtime transport evidence was found"),
    )
}

pub(super) fn runtime_error(file: Option<String>, reason: String) -> RuntimeLoad {
    let present = file.is_some();
    RuntimeLoad {
        status: if present { "REJECTED" } else { "NOT_PROVIDED" },
        present,
        file,
        generated_at: None,
        repository_revision: None,
        coverage: json!({}),
        observations: Vec::new(),
        observation_count: 0,
        reasons: vec![reason],
    }
}

pub(super) fn validate_runtime_report(
    repository: &str,
    state: &RepositoryState,
    args: &Value,
    file: &str,
    report: &Value,
) -> RuntimeLoad {
    let RuntimeMetadata {
        mut reasons,
        usable,
        revision,
        generated_at,
    } = validate_runtime_metadata(repository, state, args, report);
    let coverage_status = report
        .pointer("/coverage/event")
        .and_then(Value::as_str)
        .unwrap_or("NOT_CHECKED")
        .to_ascii_uppercase();
    if coverage_status != "COMPLETE" {
        reasons.push(format!(
            "{repository}: event runtime capture is {coverage_status}"
        ));
    }
    let coverage = json!({"event": coverage_status});
    let raw = report["observations"]
        .as_array()
        .into_iter()
        .flatten()
        .cloned()
        .chain(otlp_event_observations(report))
        .take(MAX_RUNTIME_OBSERVATIONS)
        .collect::<Vec<_>>();
    let observations = if usable {
        raw.iter()
            .filter_map(|item| normalize_runtime_observation(repository, state, item))
            .collect::<Vec<_>>()
    } else {
        Vec::new()
    };
    if usable && raw.len() != observations.len() {
        reasons.push(format!(
            "{repository}: {} invalid runtime event observation(s) were ignored",
            raw.len().saturating_sub(observations.len())
        ));
    }
    RuntimeLoad {
        status: if reasons.is_empty() {
            "COMPLETE"
        } else {
            "REJECTED"
        },
        present: true,
        file: Some(file.to_owned()),
        generated_at,
        repository_revision: revision,
        coverage,
        observation_count: observations.len(),
        observations,
        reasons,
    }
}

struct RuntimeMetadata {
    reasons: Vec<String>,
    usable: bool,
    revision: Option<String>,
    generated_at: Option<String>,
}

fn validate_runtime_metadata(
    repository: &str,
    state: &RepositoryState,
    args: &Value,
    report: &Value,
) -> RuntimeMetadata {
    let mut reasons = Vec::new();
    let mut usable = true;
    if report["schema"].as_str() != Some(RUNTIME_SCHEMA) {
        reasons.push(format!(
            "{repository}: runtime evidence schema is not recognized"
        ));
        usable = false;
    }
    let revision = report["repositoryRevision"].as_str().map(str::to_owned);
    if revision.as_deref() != Some(state.snapshot().revision.as_str()) {
        reasons.push(format!(
            "{repository}: runtime evidence revision does not match the active graph"
        ));
        usable = false;
    }
    let generated_at = report["generatedAt"].as_str().map(str::to_owned);
    let generated_millis = report.get("generatedAt").and_then(timestamp_millis);
    let now_millis = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .ok()
        .and_then(|duration| u64::try_from(duration.as_millis()).ok())
        .unwrap_or(0);
    let max_age_hours = args
        .get("runtime_evidence_max_age_hours")
        .and_then(Value::as_u64)
        .unwrap_or(168)
        .clamp(1, 8_760);
    let max_age_millis = max_age_hours.saturating_mul(3_600_000);
    match generated_millis {
        None => {
            reasons.push(format!(
                "{repository}: runtime evidence generatedAt is invalid"
            ));
            usable = false;
        }
        Some(generated)
            if generated > now_millis.saturating_add(300_000)
                || now_millis.saturating_sub(generated) > max_age_millis =>
        {
            reasons.push(format!(
                "{repository}: runtime evidence is stale or from the future"
            ));
            usable = false;
        }
        Some(_) => {}
    }
    RuntimeMetadata {
        reasons,
        usable,
        revision,
        generated_at,
    }
}