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
- Capture the HealthEvidenceSnapshot fresh, immediately before promoting, for the exact candidate_id being promoted.
- Use a single EVALUATOR constant when both building and promoting so the strings cannot drift.
- 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
- Capture health evidence in the same call that promotes, passing the same candidate_id and evaluator constant.
- Build a HealthEvidenceSnapshot constructor that takes the candidate_id + evaluator so they cannot drift.
- Never reuse a snapshot across candidates.
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
- valid candidate id and bounded activation evidence reference
- valid candidate ids, recorded-v1 evaluator, and bounded evid
- health check result does not match persisted assertion
- harness health evidence exceeds integrity verification bound
- At least one guided harness must be selected
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/37dfa159514df3bb.
Report an issue: GitHub.