"""Crash recovery and state reconciliation integration tests.""" from __future__ import annotations import hashlib import json from pathlib import Path from src.runtime.cli.reconcile import reconcile_runtime from src.runtime.storage.sqlite_store import SQLiteStore def test_reconcile_resolves_crash_mismatch(tmp_path: Path): """Simulates a crash where a Markdown file and manifest were written, but SQLite status remained in 'received' state. Asserts: 1. Reconcile detects the completed artifact. 2. Reconcile calculates and verifies the SHA-256 hash. 3. Reconcile updates SQLite status to 'completed_text' with matching payload. """ db_path = tmp_path / "state.db" out_dir = tmp_path / "out" out_dir.mkdir() base_cfg = json.loads(Path("runtime_config.local.json").read_text(encoding="utf-8")) base_cfg["paths"]["sqlite_db"] = str(db_path) base_cfg["paths"]["output_dir"] = str(out_dir) cfg_file = tmp_path / "cfg.json" cfg_file.write_text(json.dumps(base_cfg, indent=2), encoding="utf-8") store = SQLiteStore(db_path) fp = "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" # Step 1: SQLite has received status store.claim_or_get_execution(fp, "https://example.com/test", "trafilatura", "1.0.0") # Step 2: Disk has completed markdown and manifest md_content = "---\ntitle: Reconciled Article\n---\n\nContent here." md_file = out_dir / f"{fp}.md" md_file.write_text(md_content, encoding="utf-8") md_hash = hashlib.sha256(md_content.encode("utf-8")).hexdigest() manifest_data = { "manifest_version": "1.0.0", "fingerprint": fp, "status": "completed_text", "artifacts": { "markdown_path": str(md_file), "markdown_sha256": md_hash, "manifest_path": str(out_dir / f"{fp}.result.json"), }, } manifest_file = out_dir / f"{fp}.result.json" manifest_file.write_text(json.dumps(manifest_data, indent=2), encoding="utf-8") # Step 3: Run reconciliation report = reconcile_runtime(cfg_file) assert report["divergent_states_recovered"] == 1 # Step 4: Verify DB updated to completed_text record = store.get_execution(fp) assert record is not None assert record["current_status"] == "completed_text"