{"record":{"id":"37dfa159514df3bb","repo":"affaan-m/ECC","slug":"health-evidence-does-not-match-candidate-and-evalu","errorCode":null,"errorMessage":"health evidence does not match candidate and evaluator","messagePattern":"health evidence does not match candidate and evaluator","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"ecc2/src/session/store.rs","lineNumber":5476,"sourceCode":"        policy: PromotionPolicy,\n        evidence_ref: &str,\n        health_evidence: &HealthEvidenceSnapshot,\n        health_check: F,\n    ) -> Result<HarnessPromotionOutcome>\n    where\n        F: FnOnce(&str) -> Result<bool>,\n    {\n        if candidate_id.len() != 64\n            || baseline_id.len() != 64\n            || evaluator != \"recorded-v1\"\n            || evidence_ref.trim().is_empty()\n            || evidence_ref.len() > 4096\n        {\n            anyhow::bail!(\"valid candidate ids, recorded-v1 evaluator, and bounded evidence reference are required\");\n        }\n        health_evidence.verify()?;\n        if health_evidence.candidate_id != candidate_id || health_evidence.evaluator != evaluator {\n            anyhow::bail!(\"health evidence does not match candidate and evaluator\");\n        }\n        let comparison = policy.compare(samples)?;\n        let tx = self.conn.unchecked_transaction()?;\n        let stored_candidate_id = Self::resolve_harness_candidate_id(&tx, candidate_id)?;\n        let stored_baseline_id = Self::resolve_harness_candidate_id(&tx, baseline_id)?;\n        let active: String = tx\n            .query_row(\n                \"SELECT candidate_id FROM active_harness_config WHERE slot = 'default'\",\n                [],\n                |row| row.get(0),\n            )\n            .context(\"no active baseline configuration\")?;\n        if active != stored_baseline_id {\n            anyhow::bail!(\"baseline is not the active harness configuration\");\n        }\n        let now = chrono::Utc::now().to_rfc3339();\n        if !comparison.passed {\n            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])?;","sourceCodeStart":5458,"sourceCodeEnd":5494,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/ecc2/src/session/store.rs#L5458-L5494","documentation":"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.","triggerScenarios":"promote_harness where health_evidence.candidate_id != candidate_id or health_evidence.evaluator != evaluator (e.g. \"recorded-v1\").","commonSituations":"Reusing a health snapshot from a prior candidate run; evaluator naming drift between capture and promotion; copy-paste of a snapshot across candidates.","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."],"exampleFix":"// before\nstore.promote_harness(&candidate_id, &baseline_id, evaluator, evidence_ref, &health_evidence, ...)?;\n\n// after\nif health_evidence.candidate_id != candidate_id || health_evidence.evaluator != evaluator {\n    anyhow::bail!(\"health evidence is for a different candidate/evaluator; recapture it\");\n}\nstore.promote_harness(&candidate_id, &baseline_id, evaluator, evidence_ref, &health_evidence, ...)?;","handlingStrategy":"validation","validationCode":"if health_evidence.candidate_id != candidate_id || health_evidence.evaluator != evaluator {\n    return Err(anyhow::anyhow!(\n        \"health evidence is for candidate {} / evaluator {}, not {candidate_id} / {evaluator}\",\n        health_evidence.candidate_id, health_evidence.evaluator\n    ));\n}\nhealth_evidence.verify()?;\nstore.promote_harness(&candidate_id, &baseline_id, evaluator, evidence_ref, &health_evidence, ...)?;","typeGuard":"fn health_evidence_matches(he: &HealthEvidenceSnapshot, candidate_id: &str, evaluator: &str) -> bool {\n    he.candidate_id == candidate_id && he.evaluator == evaluator\n}","tryCatchPattern":"match store.promote_harness(&candidate_id, &baseline_id, evaluator, evidence_ref, &health_evidence, ...) {\n    Ok(out) => { /* handled */ }\n    Err(e) if e.to_string().contains(\"health evidence does not match\") => {\n        // recapture the snapshot for this candidate/evaluator and retry\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["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."],"tags":["rust","harness","health-evidence","validation"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}