{"record":{"id":"0b4fbeafb3ec8a8d","repo":"affaan-m/ECC","slug":"baseline-is-not-the-active-harness-configuration","errorCode":null,"errorMessage":"baseline is not the active harness configuration","messagePattern":"baseline is not the active harness configuration","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"ecc2/src/session/store.rs","lineNumber":5490,"sourceCode":"            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])?;\n            let evaluation_id = tx.last_insert_rowid();\n            tx.execute(\"INSERT INTO harness_eval_audit (event_type, candidate_id, prior_candidate_id, evaluation_id, evidence_ref, legacy_unverifiable, created_at) VALUES ('promotion_rejected', ?1, ?2, ?3, ?4, 0, ?5)\", rusqlite::params![stored_candidate_id, stored_baseline_id, evaluation_id, evidence_ref, now])?;\n            tx.commit()?;\n            return Ok(HarnessPromotionOutcome {\n                evaluation_id: Some(evaluation_id),\n                promoted: false,\n                rolled_back: false,\n                failures: comparison.failures,\n            });\n        }\n        let changed = tx.execute(\"UPDATE active_harness_config SET candidate_id = ?1, updated_at = ?2 WHERE slot = 'default' AND candidate_id = ?3\", rusqlite::params![stored_candidate_id, now, stored_baseline_id])?;\n        if changed != 1 {\n            anyhow::bail!(\"atomic promotion compare-and-swap failed\");\n        }","sourceCodeStart":5472,"sourceCodeEnd":5508,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/ecc2/src/session/store.rs#L5472-L5508","documentation":"promote_harness requires that the baseline_id argument equals the currently active candidate in slot 'default'. Promotion is always relative to the live baseline: you cannot promote against a stale or hypothetical baseline.","triggerScenarios":"baseline_id (after resolve_harness_candidate_id) != the active_harness_config 'default' candidate_id. The active row is read with .context(\"no active baseline configuration\") just before the comparison.","commonSituations":"Stale baseline captured before a prior promotion completed; a concurrent promotion already changed the active config; passing candidate_id as baseline_id by argument-order mistake.","solutions":["Re-read the active candidate id immediately before promoting and pass it as baseline_id.","Serialize all promotions behind a single-writer / mutex so the baseline cannot change mid-call.","Use resolve_harness_candidate_id to canonicalize both ids before comparing, so aliases do not cause false mismatches."],"exampleFix":"// before\nstore.promote_harness(&candidate_id, &stale_baseline_id, ...)?;\n\n// after\nlet live_baseline = store.active_harness_id()?.ok_or_else(|| anyhow::anyhow!(\"no active harness\"))?;\nstore.promote_harness(&candidate_id, &live_baseline, ...)?;","handlingStrategy":"validation","validationCode":"let live_baseline = store.active_harness_id()? // or the store's active getter\n    .ok_or_else(|| anyhow::anyhow!(\"no active harness to promote against\"))?;\nif live_baseline != baseline_id {\n    // re-read happened; adopt the live baseline or abort\n    return Err(anyhow::anyhow!(\"baseline {baseline_id} is stale; live active is {live_baseline}\"));\n}\nstore.promote_harness(&candidate_id, &live_baseline, ...)?;","typeGuard":"fn baseline_is_active(active: &str, baseline_id: &str) -> bool {\n    active == baseline_id\n}","tryCatchPattern":"match store.promote_harness(&candidate_id, &baseline_id, ...) {\n    Ok(out) => { /* handled */ }\n    Err(e) if e.to_string().contains(\"baseline is not the active\") => {\n        // re-read active config and retry with the fresh baseline\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Read the active baseline in the same critical section as the promotion call.","Serialize promotions behind a single writer so the baseline cannot change mid-call.","Resolve aliases to canonical ids before comparing baseline to active."],"tags":["rust","sqlite","harness","concurrency","state"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}