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

health evidence does not match candidate and evaluator

Error message

health evidence does not match candidate and evaluator

What it means

After health_evidence.verify() passes, promote_harness checks that the snapshot belongs to this exact promotion: health_evidence.candidate_id must equal the candidate_id argument and health_evidence.evaluator must equal the evaluator argument. A health snapshot captured for a different candidate or evaluator is rejected.

Source

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

        policy: PromotionPolicy,
        evidence_ref: &str,
        health_evidence: &HealthEvidenceSnapshot,
        health_check: F,
    ) -> Result<HarnessPromotionOutcome>
    where
        F: FnOnce(&str) -> Result<bool>,
    {
        if candidate_id.len() != 64
            || baseline_id.len() != 64
            || evaluator != "recorded-v1"
            || evidence_ref.trim().is_empty()
            || evidence_ref.len() > 4096
        {
            anyhow::bail!("valid candidate ids, recorded-v1 evaluator, and bounded evidence reference are required");
        }
        health_evidence.verify()?;
        if health_evidence.candidate_id != candidate_id || health_evidence.evaluator != evaluator {
            anyhow::bail!("health evidence does not match candidate and evaluator");
        }
        let comparison = policy.compare(samples)?;
        let tx = self.conn.unchecked_transaction()?;
        let stored_candidate_id = Self::resolve_harness_candidate_id(&tx, candidate_id)?;
        let stored_baseline_id = Self::resolve_harness_candidate_id(&tx, baseline_id)?;
        let active: String = tx
            .query_row(
                "SELECT candidate_id FROM active_harness_config WHERE slot = 'default'",
                [],
                |row| row.get(0),
            )
            .context("no active baseline configuration")?;
        if active != stored_baseline_id {
            anyhow::bail!("baseline is not the active harness configuration");
        }
        let now = chrono::Utc::now().to_rfc3339();
        if !comparison.passed {
            tx.execute("INSERT INTO harness_evaluations (candidate_id, baseline_id, evaluator, samples_json, policy_json, comparison_json, evidence_ref, legacy_unverifiable, created_at) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, 0, ?8)", rusqlite::params![stored_candidate_id, stored_baseline_id, evaluator, serde_json::to_string(samples)?, serde_json::to_string(&policy)?, serde_json::to_string(&comparison)?, evidence_ref, now])?;

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Capture the HealthEvidenceSnapshot fresh, immediately before promoting, for the exact candidate_id being promoted.
  2. Use a single EVALUATOR constant when both building and promoting so the strings cannot drift.
  3. Assert candidate_id/evaluator equality on the snapshot before calling promote_harness.

Example fix

// before
store.promote_harness(&candidate_id, &baseline_id, evaluator, evidence_ref, &health_evidence, ...)?;

// after
if health_evidence.candidate_id != candidate_id || health_evidence.evaluator != evaluator {
    anyhow::bail!("health evidence is for a different candidate/evaluator; recapture it");
}
store.promote_harness(&candidate_id, &baseline_id, evaluator, evidence_ref, &health_evidence, ...)?;
Defensive patterns

Strategy: validation

Validate before calling

if health_evidence.candidate_id != candidate_id || health_evidence.evaluator != evaluator {
    return Err(anyhow::anyhow!(
        "health evidence is for candidate {} / evaluator {}, not {candidate_id} / {evaluator}",
        health_evidence.candidate_id, health_evidence.evaluator
    ));
}
health_evidence.verify()?;
store.promote_harness(&candidate_id, &baseline_id, evaluator, evidence_ref, &health_evidence, ...)?;

Type guard

fn health_evidence_matches(he: &HealthEvidenceSnapshot, candidate_id: &str, evaluator: &str) -> bool {
    he.candidate_id == candidate_id && he.evaluator == evaluator
}

Try / catch

match store.promote_harness(&candidate_id, &baseline_id, evaluator, evidence_ref, &health_evidence, ...) {
    Ok(out) => { /* handled */ }
    Err(e) if e.to_string().contains("health evidence does not match") => {
        // recapture the snapshot for this candidate/evaluator and retry
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: promote_harness where health_evidence.candidate_id != candidate_id or health_evidence.evaluator != evaluator (e.g. "recorded-v1").

Common situations: Reusing a health snapshot from a prior candidate run; evaluator naming drift between capture and promotion; copy-paste of a snapshot across candidates.

Related errors


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