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

harness health evidence is inconsistent with audit outcome

Error message

harness health evidence is inconsistent with audit outcome

What it means

After integrity verification passes, the store checks the audit event_type is internally consistent with status and asserted: 'promoted' requires status=='healthy' && asserted true; 'promotion_rolled_back' requires status=='unhealthy' && asserted false; 'health_check_error_rolled_back' requires status=='error'. Any other combination is a state-machine violation.

Source

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

        }
        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",
            _ => false,
        };
        if !event_consistent {
            anyhow::bail!("harness health evidence is inconsistent with audit outcome");
        }
        if let Some(evaluation_id) = entry.evaluation_id {
            let evaluation: (Option<String>, Option<String>, Option<bool>, Option<String>, bool) = self.conn.query_row(
                "SELECT health_evidence_json, health_evidence_sha256, asserted_health, health_check_status, legacy_unverifiable FROM harness_evaluations WHERE id = ?1",
                [evaluation_id],
                |row| Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?, row.get(4)?)),
            )?;
            if evaluation
                != (
                    Some(json.clone()),
                    Some(digest.clone()),
                    Some(asserted),
                    Some(status.clone()),
                    false,
                )
            {
                anyhow::bail!("audit health evidence does not match its evaluation");
            }

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Re-derive the correct event_type from the actual outcome (healthy/unhealthy/error) and rewrite the row.
  2. Centralize event_type + status + asserted computation in one place so they cannot drift apart.
  3. Add a CHECK constraint encoding the state machine so the DB rejects inconsistent rows at write time.
Defensive patterns

Strategy: validation

Validate before calling

fn event_type_consistent(event_type: &str, status: &str, asserted: bool) -> bool {
    match event_type {
        "promoted" => status == "healthy" && asserted,
        "promotion_rolled_back" => status == "unhealthy" && !asserted,
        "health_check_error_rolled_back" => status == "error",
        _ => false,
    }
}

if !event_type_consistent(&entry.event_type, &entry.health_check_status, entry.asserted_health.unwrap_or(false)) {
    return Err(anyhow::anyhow!("audit event_type/status/asserted inconsistent"));
}

Type guard

fn audit_outcome_is_consistent(event_type: &str, status: &str, asserted: bool) -> bool {
    event_type_consistent(event_type, status, asserted)
}

Try / catch

match verify_audit_entry(&store, &entry) {
    Ok(()) => { /* ok */ }
    Err(e) if e.to_string().contains("inconsistent with audit outcome") => {
        // re-derive the correct event_type from status/asserted and rewrite the row
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: An audit row whose (event_type, health_check_status, asserted_health) triple is impossible per the promotion state machine, e.g. event_type='promoted' with status='unhealthy'.

Common situations: A write path selected the wrong event_type for the outcome; a manual row edit changed one field; a bug in the event_type match expression that produced inconsistent values.

Related errors


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