affaan-m/ECC · error · anyhow::Error

incomplete harness health evidence integrity metadata

Error message

incomplete harness health evidence integrity metadata

What it means

An audit entry's four health-evidence fields are partially populated (some NULL, some not). The integrity model requires them to be all-present or all-absent together; a partial set cannot be verified and indicates a malformed write.

Source

Thrown at ecc2/src/session/store.rs:5596

        let fields = (
            &entry.health_evidence_json,
            &entry.health_evidence_sha256,
            entry.asserted_health,
            &entry.health_check_status,
        );
        if matches!(fields, (None, None, None, None)) {
            if entry.legacy_unverifiable
                || matches!(
                    entry.event_type.as_str(),
                    "initial_activation" | "promotion_rejected"
                )
            {
                return Ok(());
            }
            anyhow::bail!("missing harness health evidence integrity metadata");
        }
        let (Some(json), Some(digest), Some(asserted), Some(status)) = fields else {
            anyhow::bail!("incomplete harness health evidence integrity metadata");
        };
        if json.len() > 8192 {
            anyhow::bail!("harness health evidence exceeds integrity verification bound");
        }
        let snapshot: HealthEvidenceSnapshot = serde_json::from_str(json)?;
        let snapshot_candidate_id =
            Self::resolve_harness_candidate_id(&self.conn, &snapshot.candidate_id)?;
        if snapshot.canonical_json()? != *json
            || snapshot.digest()? != *digest
            || snapshot.asserted_healthy != asserted
            || snapshot_candidate_id != entry.candidate_id
        {
            anyhow::bail!("harness health evidence integrity verification failed");
        }
        let event_consistent = match entry.event_type.as_str() {
            "promoted" => status == "healthy" && asserted,
            "promotion_rolled_back" => status == "unhealthy" && !asserted,
            "health_check_error_rolled_back" => status == "error",

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Rewrite the row so all four fields are set together (or all NULL only for legacy_unverifiable / initial_activation / promotion_rejected rows).
  2. Audit every INSERT into harness_eval_audit to confirm it populates the four fields as one atomic group.
  3. Add a CHECK constraint (all four NULL or all four NOT NULL) to catch malformed writes at the DB layer.
Defensive patterns

Strategy: validation

Validate before calling

// Confirm all four fields are present together (or all absent for exempt rows).
let present = [json.is_some(), digest.is_some(), asserted.is_some(), status.is_some()];
let all_present = present.iter().all(|b| *b);
let all_absent = present.iter().all(|b| !*b);
if !all_present && !all_absent {
    return Err(anyhow::anyhow!("audit row {id} has partially-populated health evidence"));
}

Type guard

fn health_fields_consistent(json: Option<&str>, digest: Option<&str>, asserted: Option<bool>, status: Option<&str>) -> bool {
    let p = [json.is_some(), digest.is_some(), asserted.is_some(), status.is_some()];
    p.iter().all(|b| *b) || p.iter().all(|b| !*b)
}

Try / catch

match verify_audit_entry(&store, &entry) {
    Ok(()) => { /* ok */ }
    Err(e) if e.to_string().contains("incomplete harness health evidence integrity metadata") => {
        // rewrite the row so all four fields are set together (or all NULL + legacy_unverifiable)
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: An audit row where the tuple (health_evidence_json, health_evidence_sha256, asserted_health, health_check_status) has a mix of Some and None, so the let-else (Some, Some, Some, Some) destructure fails.

Common situations: An INSERT that set json+digest but not asserted/status (or any subset); a schema migration that backfilled one column but not the others; a bug in the audit-writing code path.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/4e15b41333fce421. Report an issue: GitHub.