"""Extended write integration tests: cross-module write consistency for modules
not covered by test_write_integration.py and test_core_write_integration.py.

Covers:
- Standards write lifecycle (create, deactivate, seed_defaults) and context impact
- Benchmarks cross-table write pipeline (build_runs → quality_scores → review_issues)
- Context Engine request tracking (record_request, evaluate_relevance) in session pipeline
- Knowledge create_with_lineage (promotion from observations with FK updates)
- Patterns create_from_observations (promotion from observations with lineage)
- Standards deactivation affecting context retrieval (cross-module consistency)
- Benchmarks quality scoring against standards (cross-table foreign key writes)
"""

import json

import pytest

from greymatter_core.benchmarks import BenchmarkManager
from greymatter_core.context import ContextEngine
from greymatter_core.db import SQLiteDatabase
from greymatter_core.documents import DocumentStore
from greymatter_core.knowledge import KnowledgeStore
from greymatter_core.patterns import PatternManager
from greymatter_core.quality import QualityEngine
from greymatter_core.sessions import SessionManager
from greymatter_core.standards import StandardsManager
from greymatter_core.work_items import WorkItemManager


# ---------------------------------------------------------------------------
# Fixtures
# ---------------------------------------------------------------------------


@pytest.fixture
def db():
    """Shared in-memory database for extended write integration tests."""
    database = SQLiteDatabase(":memory:")
    yield database
    database.close()


@pytest.fixture
def knowledge(db):
    return KnowledgeStore(db)


@pytest.fixture
def patterns(db):
    return PatternManager(db)


@pytest.fixture
def sessions(db):
    return SessionManager(db)


@pytest.fixture
def work_items(db):
    return WorkItemManager(db)


@pytest.fixture
def standards(db):
    return StandardsManager(db)


@pytest.fixture
def doc_store(db):
    return DocumentStore(db)


@pytest.fixture
def quality(db):
    return QualityEngine(db)


@pytest.fixture
def context_engine(db, doc_store, standards, patterns):
    return ContextEngine(db, doc_store, standards, patterns)


@pytest.fixture
def benchmarks(db):
    return BenchmarkManager(db)


# ---------------------------------------------------------------------------
# 1. Standards Write Lifecycle Integration
# ---------------------------------------------------------------------------


class TestStandardsWriteLifecycleIntegration:
    """Verify standards write operations and their effect on context retrieval."""

    def test_create_persists_all_fields(self, db, standards):
        """create() stores all fields including optional ones in the DB."""
        standards.create(
            standard_id="qs-test-001",
            category="testing",
            rule="Always test write paths",
            severity="critical",
            example_good="def test_write_persists(): ...",
            example_bad="# no tests written",
            rationale="Untested writes hide data corruption",
        )
        row = db.execute_one(
            "SELECT * FROM quality_standards WHERE id = ?", ("qs-test-001",)
        )
        assert row is not None
        assert row["category"] == "testing"
        assert row["rule"] == "Always test write paths"
        assert row["severity"] == "critical"
        assert row["example_good"] == "def test_write_persists(): ..."
        assert row["example_bad"] == "# no tests written"
        assert row["rationale"] == "Untested writes hide data corruption"
        assert row["active"] == 1

    def test_deactivate_sets_active_flag(self, db, standards):
        """deactivate() sets active=0 without deleting the row."""
        standards.create(
            standard_id="qs-deactivate-test",
            category="testing",
            rule="Will be deactivated",
            severity="minor",
        )
        standards.deactivate("qs-deactivate-test")

        row = db.execute_one(
            "SELECT active FROM quality_standards WHERE id = ?",
            ("qs-deactivate-test",),
        )
        assert row["active"] == 0

        # Row still exists
        count = db.execute_one(
            "SELECT COUNT(*) as cnt FROM quality_standards WHERE id = ?",
            ("qs-deactivate-test",),
        )
        assert count["cnt"] == 1

    def test_seed_defaults_populates_all_standards(self, db, standards):
        """seed_defaults() inserts all DEFAULT_STANDARDS into the DB."""
        count = standards.seed_defaults()
        assert count >= 10

        row_count = db.execute_one(
            "SELECT COUNT(*) as cnt FROM quality_standards"
        )
        assert row_count["cnt"] == count

    def test_seed_defaults_idempotent_no_duplicates(self, db, standards):
        """Running seed_defaults() twice inserts no duplicates."""
        first_count = standards.seed_defaults()
        second_count = standards.seed_defaults()
        assert second_count == 0

        total = db.execute_one(
            "SELECT COUNT(*) as cnt FROM quality_standards"
        )
        assert total["cnt"] == first_count

    def test_deactivation_removes_from_active_queries(self, standards):
        """Deactivated standards no longer appear in get_active()."""
        standards.create(
            standard_id="qs-keep",
            category="testing",
            rule="Keep this one",
            severity="critical",
        )
        standards.create(
            standard_id="qs-remove",
            category="testing",
            rule="Remove this one",
            severity="critical",
        )
        assert len(standards.get_active()) == 2

        standards.deactivate("qs-remove")
        active = standards.get_active()
        assert len(active) == 1
        assert active[0]["id"] == "qs-keep"

    def test_deactivation_affects_context_payload(self, standards, context_engine):
        """Deactivating a standard removes it from context payload."""
        standards.create(
            standard_id="qs-ctx-1",
            category="security",
            rule="Security rule 1",
            severity="critical",
        )
        standards.create(
            standard_id="qs-ctx-2",
            category="security",
            rule="Security rule 2",
            severity="critical",
        )

        payload_before = json.loads(standards.get_context_payload())
        rules_before = {s["rule"] for s in payload_before}
        assert "Security rule 1" in rules_before
        assert "Security rule 2" in rules_before

        standards.deactivate("qs-ctx-2")

        payload_after = json.loads(standards.get_context_payload())
        rules_after = {s["rule"] for s in payload_after}
        assert "Security rule 1" in rules_after
        assert "Security rule 2" not in rules_after


# ---------------------------------------------------------------------------
# 2. Benchmarks Cross-Table Write Pipeline
# ---------------------------------------------------------------------------


class TestBenchmarksCrossTableWritePipeline:
    """Verify benchmark writes across build_runs, quality_scores, review_issues."""

    def test_full_benchmark_lifecycle(self, db, benchmarks, standards):
        """Full lifecycle: start → complete → score → issue → resolve."""
        # Seed a standard for scoring
        standards.create(
            standard_id="qs-bench-test",
            category="testing",
            rule="Test all write paths",
            severity="critical",
        )

        # Start run
        run = benchmarks.start_run(
            approach="greymatter", task_name="Write integration tests",
        )
        assert run["completed_at"] is None
        run_row = db.execute_one(
            "SELECT * FROM build_runs WHERE id = ?", (run["id"],)
        )
        assert run_row["approach"] == "greymatter"
        assert run_row["task_name"] == "Write integration tests"

        # Complete run
        completed = benchmarks.complete_run(
            run["id"], lines=200, tests=15, passing=15, first_pass=True,
        )
        assert completed["completed_at"] is not None
        assert completed["lines_written"] == 200
        assert completed["test_count"] == 15
        assert completed["tests_passing"] == 15
        assert completed["first_pass_success"] == 1

        # Score against standard
        benchmarks.score_run(
            run["id"], "qs-bench-test", passed=True,
            found_by="code_review", detail="All writes tested",
        )
        scores = db.execute(
            "SELECT * FROM quality_scores WHERE build_run_id = ?", (run["id"],)
        )
        assert len(scores) == 1
        assert scores[0]["standard_id"] == "qs-bench-test"
        assert scores[0]["passed"] == 1
        assert scores[0]["detail"] == "All writes tested"

        # Record issue
        issue_id = benchmarks.record_issue(
            run["id"], severity="minor", category="naming",
            description="Variable 'x' not descriptive",
            found_by="code_review",
        )
        issue_row = db.execute_one(
            "SELECT * FROM review_issues WHERE id = ?", (issue_id,)
        )
        assert issue_row["build_run_id"] == run["id"]
        assert issue_row["severity"] == "minor"
        assert issue_row["fixed_at"] is None

        # Resolve issue
        benchmarks.resolve_issue(issue_id, fix_minutes=3)
        resolved = db.execute_one(
            "SELECT * FROM review_issues WHERE id = ?", (issue_id,)
        )
        assert resolved["fixed_at"] is not None
        assert resolved["time_to_fix_minutes"] == 3

    def test_multiple_scores_per_run(self, db, benchmarks, standards):
        """Multiple quality scores accumulate correctly for one run."""
        standards.create(
            standard_id="qs-multi-1",
            category="testing",
            rule="Rule 1",
            severity="critical",
        )
        standards.create(
            standard_id="qs-multi-2",
            category="security",
            rule="Rule 2",
            severity="critical",
        )

        run = benchmarks.start_run(approach="subagent", task_name="Multi-score test")
        benchmarks.score_run(run["id"], "qs-multi-1", passed=True, found_by="review")
        benchmarks.score_run(run["id"], "qs-multi-2", passed=False, found_by="review")

        scores = benchmarks.get_scores(run["id"])
        assert len(scores) == 2
        passed_count = sum(1 for s in scores if s["passed"])
        failed_count = sum(1 for s in scores if not s["passed"])
        assert passed_count == 1
        assert failed_count == 1

    def test_multiple_issues_per_run(self, db, benchmarks):
        """Multiple issues accumulate and resolve independently."""
        run = benchmarks.start_run(approach="raw_claude", task_name="Issue test")
        id1 = benchmarks.record_issue(
            run["id"], "critical", "security", "SQL injection", "review",
        )
        benchmarks.record_issue(
            run["id"], "minor", "naming", "Bad variable name", "review",
        )

        issues = benchmarks.get_issues(run["id"])
        assert len(issues) == 2

        # Resolve only the first
        benchmarks.resolve_issue(id1, fix_minutes=10)

        issues = benchmarks.get_issues(run["id"])
        resolved = [i for i in issues if i["fixed_at"] is not None]
        unresolved = [i for i in issues if i["fixed_at"] is None]
        assert len(resolved) == 1
        assert len(unresolved) == 1
        assert resolved[0]["id"] == id1

    def test_invalid_approach_raises(self, benchmarks):
        """start_run() rejects invalid approach values."""
        with pytest.raises(ValueError, match="Invalid approach"):
            benchmarks.start_run(approach="invalid", task_name="Bad")

    def test_invalid_severity_raises(self, benchmarks):
        """record_issue() rejects invalid severity values."""
        run = benchmarks.start_run(approach="greymatter", task_name="Test")
        with pytest.raises(ValueError, match="Invalid severity"):
            benchmarks.record_issue(
                run["id"], "extreme", "testing", "Bad severity", "review",
            )

    def test_benchmark_with_session_tracking(self, db, benchmarks, sessions):
        """Benchmark run can reference a session for traceability."""
        session = sessions.start(project="greymatter")
        run = benchmarks.start_run(
            approach="greymatter",
            task_name="Session-tracked build",
            session_id=session["id"],
        )

        row = db.execute_one(
            "SELECT session_id FROM build_runs WHERE id = ?", (run["id"],)
        )
        assert row["session_id"] == session["id"]

        # Both records exist independently
        s_row = db.execute_one(
            "SELECT * FROM sessions WHERE id = ?", (session["id"],)
        )
        assert s_row is not None

    def test_defect_density_calculation(self, benchmarks):
        """defect_density() computes correct ratios across approaches."""
        # GreyMatter: 200 lines, 1 issue → 5.0 defects/KLOC
        r1 = benchmarks.start_run(approach="greymatter", task_name="GM Build")
        benchmarks.complete_run(r1["id"], lines=200, tests=10, passing=10, first_pass=True)
        benchmarks.record_issue(r1["id"], "minor", "naming", "Issue 1", "review")

        # Subagent: 100 lines, 2 issues → 20.0 defects/KLOC
        r2 = benchmarks.start_run(approach="subagent", task_name="Sub Build")
        benchmarks.complete_run(r2["id"], lines=100, tests=5, passing=5, first_pass=True)
        benchmarks.record_issue(r2["id"], "critical", "security", "Issue 1", "review")
        benchmarks.record_issue(r2["id"], "minor", "naming", "Issue 2", "review")

        density = benchmarks.defect_density()
        gm = next(d for d in density if d["approach"] == "greymatter")
        sub = next(d for d in density if d["approach"] == "subagent")
        assert gm["defects_per_kloc"] == pytest.approx(5.0)
        assert sub["defects_per_kloc"] == pytest.approx(20.0)


# ---------------------------------------------------------------------------
# 3. Context Engine Request Tracking Integration
# ---------------------------------------------------------------------------


class TestContextRequestTrackingIntegration:
    """Verify context request recording and relevance scoring in session context."""

    def test_record_request_persists_to_db(self, db, context_engine, sessions):
        """record_request() creates a row in context_requests with correct fields."""
        session = sessions.start(project="greymatter")
        context_engine.record_request(
            session_id=session["id"],
            query="load architecture context",
            doc_ids=["doc-001", "doc-002"],
            tokens=1500,
        )

        row = db.execute_one(
            "SELECT * FROM context_requests WHERE session_id = ?",
            (session["id"],),
        )
        assert row is not None
        assert row["query"] == "load architecture context"
        assert json.loads(row["documents_served"]) == ["doc-001", "doc-002"]
        assert row["tokens_served"] == 1500
        assert row["relevance_score"] is None  # not yet evaluated

    def test_evaluate_relevance_updates_score(self, db, context_engine, sessions):
        """evaluate_relevance() sets the relevance_score on existing request."""
        session = sessions.start(project="greymatter")
        context_engine.record_request(
            session_id=session["id"],
            query="search for auth patterns",
            doc_ids=["doc-auth-1"],
            tokens=800,
        )

        # Get the request ID (autoincrement)
        row = db.execute_one(
            "SELECT id FROM context_requests WHERE session_id = ?",
            (session["id"],),
        )
        request_id = row["id"]

        context_engine.evaluate_relevance(request_id, score=0.85)

        updated = db.execute_one(
            "SELECT relevance_score FROM context_requests WHERE id = ?",
            (request_id,),
        )
        assert updated["relevance_score"] == pytest.approx(0.85)

    def test_multiple_requests_per_session(self, db, context_engine, sessions):
        """Multiple context requests accumulate for one session."""
        session = sessions.start(project="greymatter")

        context_engine.record_request(
            session_id=session["id"],
            query="initial context load",
            doc_ids=["doc-1"],
            tokens=1000,
        )
        context_engine.record_request(
            session_id=session["id"],
            query="follow-up search",
            doc_ids=["doc-2", "doc-3"],
            tokens=500,
        )

        rows = db.execute(
            "SELECT * FROM context_requests WHERE session_id = ? ORDER BY id",
            (session["id"],),
        )
        assert len(rows) == 2
        assert rows[0]["query"] == "initial context load"
        assert rows[1]["query"] == "follow-up search"

    def test_context_build_with_documents_and_standards(
        self, standards, doc_store, context_engine, sessions,
    ):
        """Full context build: standards + documents → verify all components present."""
        standards.seed_defaults()
        doc_store.create(
            doc_type="design", title="API Design",
            content="RESTful API design patterns for GreyMatter",
            project="greymatter",
        )

        session = sessions.start(project="greymatter")
        ctx = context_engine.build_session_context(
            project="greymatter", max_tokens=50000,
        )

        # Standards loaded
        parsed_standards = json.loads(ctx["quality_standards"])
        assert len(parsed_standards) >= 10

        # Documents included
        assert len(ctx["recent_context"]) >= 1
        doc_titles = [d["title"] for d in ctx["recent_context"]]
        assert "API Design" in doc_titles

        # Track the request
        doc_ids = [d["id"] for d in ctx["recent_context"]]
        context_engine.record_request(
            session_id=session["id"],
            query="session context build",
            doc_ids=doc_ids,
            tokens=len(ctx["quality_standards"]) // 4,
        )

        sessions.end(session["id"], summary="Context was useful")

        # Verify end-to-end: session ended and request recorded
        ended = sessions.get(session["id"])
        assert ended["ended_at"] is not None


# ---------------------------------------------------------------------------
# 4. Knowledge create_with_lineage Integration
# ---------------------------------------------------------------------------


class TestKnowledgeLineageWriteIntegration:
    """Verify knowledge creation with lineage tracking from observations."""

    def test_create_with_lineage_no_tracker(self, db, knowledge):
        """create_with_lineage() without LineageTracker still creates the entry."""
        # KnowledgeStore._lineage is None by default
        entry = knowledge.create_with_lineage(
            entry_type="expertise",
            title="Promoted knowledge",
            content="Knowledge derived from observations",
            domain="testing",
            source_observation_ids=["obs-001", "obs-002"],
            session_id="sess-test",
        )
        assert entry is not None
        assert entry["title"] == "Promoted knowledge"

        row = db.execute_one(
            "SELECT * FROM knowledge_entries WHERE id = ?", (entry["id"],)
        )
        assert row is not None
        assert row["entry_type"] == "expertise"
        assert row["domain"] == "testing"

    def test_create_with_lineage_persists_entry_fields(self, db, knowledge):
        """create_with_lineage() passes all fields through to create()."""
        entry = knowledge.create_with_lineage(
            entry_type="gotcha",
            title="Lineage gotcha",
            content="Found during observation review",
            domain="database",
            scope="domain-specific",
            valence="negative",
            tags="sqlite,gotcha",
            session_id="sess-001",
        )

        row = db.execute_one(
            "SELECT * FROM knowledge_entries WHERE id = ?", (entry["id"],)
        )
        assert row["entry_type"] == "gotcha"
        assert row["domain"] == "database"
        assert row["scope"] == "domain-specific"
        assert row["tags"] == "sqlite,gotcha"

    def test_create_with_lineage_in_session_pipeline(
        self, db, knowledge, sessions, work_items,
    ):
        """create_with_lineage() works correctly in a full session pipeline."""
        session = sessions.start(project="greymatter")
        work = work_items.create(
            title="Promote observations to knowledge",
            project="greymatter",
        )
        sessions.update_state(
            session["id"], "active", active_work_item_id=work["id"],
        )

        entry = knowledge.create_with_lineage(
            entry_type="expertise",
            title="Promoted during active session",
            content="Observation consolidation result",
            domain="orchestration",
            session_id=session["id"],
        )

        work_items.complete(work["id"])
        sessions.end(session["id"], summary="Promoted observations")

        # Verify all entities are consistent
        k_row = db.execute_one(
            "SELECT * FROM knowledge_entries WHERE id = ?", (entry["id"],)
        )
        assert k_row is not None

        w_row = db.execute_one(
            "SELECT status FROM work_items WHERE id = ?", (work["id"],)
        )
        assert w_row["status"] == "completed"

        s_row = db.execute_one(
            "SELECT ended_at FROM sessions WHERE id = ?", (session["id"],)
        )
        assert s_row["ended_at"] is not None


# ---------------------------------------------------------------------------
# 5. Patterns create_from_observations Integration
# ---------------------------------------------------------------------------


class TestPatternFromObservationsWriteIntegration:
    """Verify pattern creation from observations write path."""

    def test_create_from_observations_no_tracker(self, db, patterns):
        """create_from_observations() without LineageTracker creates the pattern."""
        pat = patterns.create_from_observations(
            type="process",
            domain="testing",
            title="TDD pattern from observations",
            observation="Multiple observations showed TDD reduces bugs",
            source_observation_ids=["obs-a", "obs-b"],
            session_id="sess-test",
        )
        assert pat is not None
        assert pat["title"] == "TDD pattern from observations"
        assert pat["confidence"] == "low"

        row = db.execute_one(
            "SELECT * FROM patterns WHERE id = ?", (pat["id"],)
        )
        assert row is not None
        assert row["type"] == "process"
        assert row["domain"] == "testing"

    def test_create_from_observations_then_add_evidence(
        self, db, patterns, sessions,
    ):
        """Pattern created from observations can accumulate evidence normally."""
        pat = patterns.create_from_observations(
            type="preference",
            domain="coding",
            title="Always use type hints",
            observation="Type hints improve code quality",
        )
        assert pat["confidence"] == "low"

        # Add evidence to escalate confidence
        for _ in range(3):
            s = sessions.start(project="greymatter")
            patterns.add_evidence(pat["id"], session_id=s["id"])
            sessions.end(s["id"])

        row = db.execute_one(
            "SELECT * FROM patterns WHERE id = ?", (pat["id"],)
        )
        assert row["confidence"] == "medium"
        assert row["confirmations"] == 3
        assert row["applications"] == 3

    def test_create_from_observations_cross_module_with_knowledge(
        self, db, knowledge, patterns, sessions,
    ):
        """Pattern from observations + knowledge creation stay consistent."""
        # Create observation-like knowledge entries
        obs1 = knowledge.create(
            entry_type="observation",
            title="Agents retry on 429",
            content="Seen in 5 sessions",
            domain="api",
        )
        obs2 = knowledge.create(
            entry_type="observation",
            title="Retries need backoff",
            content="Without backoff, retries storm",
            domain="api",
        )

        # Promote to pattern
        pat = patterns.create_from_observations(
            type="process",
            domain="api",
            title="Exponential backoff",
            observation="Use exponential backoff for 429 responses",
            source_observation_ids=[obs1["id"], obs2["id"]],
        )

        # Promote to knowledge
        promoted = knowledge.create_with_lineage(
            entry_type="expertise",
            title="Backoff best practice",
            content="Always use exponential backoff with jitter",
            domain="api",
            source_pattern_ids=[pat["id"]],
        )

        # All three entities exist independently
        assert knowledge.get(obs1["id"]) is not None
        assert knowledge.get(obs2["id"]) is not None
        assert patterns.get(pat["id"]) is not None
        assert knowledge.get(promoted["id"]) is not None


# ---------------------------------------------------------------------------
# 6. Cross-Module Standards + Benchmarks + Context Pipeline
# ---------------------------------------------------------------------------


class TestCrossModuleWritePipeline:
    """Verify cross-module write consistency across standards, benchmarks, context."""

    def test_standards_seed_score_deactivate_pipeline(
        self, db, standards, benchmarks,
    ):
        """Full pipeline: seed standards → score build → deactivate → verify."""
        # Seed
        count = standards.seed_defaults()
        assert count >= 10

        # Start and score a build run
        run = benchmarks.start_run(
            approach="greymatter", task_name="Pipeline test",
        )
        benchmarks.complete_run(
            run["id"], lines=150, tests=10, passing=10, first_pass=True,
        )

        # Score against a seeded standard
        active = standards.get_active(severity_filter=["critical"])
        assert len(active) >= 1
        first_standard = active[0]
        benchmarks.score_run(
            run["id"], first_standard["id"], passed=True, found_by="auto",
        )

        # Verify score references a real standard
        scores = benchmarks.get_scores(run["id"])
        assert len(scores) == 1
        assert scores[0]["standard_id"] == first_standard["id"]

        # Deactivate the standard
        standards.deactivate(first_standard["id"])

        # Standard still referenced in score (FK integrity)
        score_row = db.execute_one(
            "SELECT * FROM quality_scores WHERE standard_id = ?",
            (first_standard["id"],),
        )
        assert score_row is not None

    def test_session_context_benchmark_full_workflow(
        self, db, standards, benchmarks, sessions, doc_store,
        context_engine, knowledge, work_items,
    ):
        """End-to-end: session → context build → work → benchmark → knowledge."""
        standards.seed_defaults()

        # Start session and build context
        session = sessions.start(project="greymatter")
        doc_store.create(
            doc_type="design", title="Arch Doc",
            content="Architecture overview", project="greymatter",
        )
        ctx = context_engine.build_session_context(project="greymatter")
        assert ctx["quality_standards"]

        # Do work
        work = work_items.create(
            title="Implement feature", project="greymatter",
        )
        work_items.update_status(work["id"], "in_progress")

        # Track benchmark
        run = benchmarks.start_run(
            approach="greymatter",
            task_name="Feature implementation",
            session_id=session["id"],
        )
        benchmarks.complete_run(
            run["id"], lines=100, tests=8, passing=8, first_pass=True,
        )

        # Capture knowledge from the work
        entry = knowledge.create(
            entry_type="expertise",
            title="Feature insight",
            content="Learned during implementation",
            domain="orchestration",
        )

        # Complete everything
        work_items.complete(work["id"])
        sessions.end(session["id"], summary="Feature complete")

        # Verify all entities are consistent
        s = sessions.get(session["id"])
        assert s["ended_at"] is not None

        w = work_items.get(work["id"])
        assert w["status"] == "completed"

        r = benchmarks.get_run(run["id"])
        assert r["completed_at"] is not None
        assert r["session_id"] == session["id"]

        k = knowledge.get(entry["id"])
        assert k is not None


# ---------------------------------------------------------------------------
# 7. Write Error Handling for Extended Modules
# ---------------------------------------------------------------------------


class TestExtendedWriteErrorHandling:
    """Verify error handling for write operations in extended modules."""

    def test_evaluate_relevance_nonexistent_request(self, db, context_engine):
        """evaluate_relevance() on nonexistent request ID is a no-op."""
        # Should not raise — UPDATE matches 0 rows
        context_engine.evaluate_relevance(request_id=99999, score=0.5)

        # Verify nothing was inserted
        rows = db.execute("SELECT * FROM context_requests")
        assert len(rows) == 0

    def test_benchmark_complete_nonexistent_run(self, db, benchmarks):
        """complete_run() on nonexistent run is a no-op."""
        # Should not raise — UPDATE matches 0 rows
        result = benchmarks.complete_run(
            "br-nonexistent", lines=100, tests=5, passing=5, first_pass=True,
        )
        assert result is None

    def test_benchmark_resolve_nonexistent_issue(self, db, benchmarks):
        """resolve_issue() on nonexistent issue is a no-op."""
        # Should not raise — UPDATE matches 0 rows
        benchmarks.resolve_issue(issue_id=99999, fix_minutes=5)

    def test_standards_deactivate_nonexistent(self, db, standards):
        """deactivate() on nonexistent standard is a no-op."""
        # Should not raise — UPDATE matches 0 rows
        standards.deactivate("qs-nonexistent")

        count = db.execute_one(
            "SELECT COUNT(*) as cnt FROM quality_standards"
        )
        assert count["cnt"] == 0


# ---------------------------------------------------------------------------
# 8. Write Idempotency for Extended Modules
# ---------------------------------------------------------------------------


class TestExtendedWriteIdempotency:
    """Verify idempotent behavior for extended module write operations."""

    def test_seed_defaults_three_times(self, standards):
        """seed_defaults() is safe to call multiple times."""
        c1 = standards.seed_defaults()
        c2 = standards.seed_defaults()
        c3 = standards.seed_defaults()
        assert c1 >= 10
        assert c2 == 0
        assert c3 == 0

    def test_double_deactivate_is_safe(self, standards):
        """Deactivating an already-deactivated standard is a no-op."""
        standards.create(
            standard_id="qs-double-deactivate",
            category="testing",
            rule="Test rule",
            severity="minor",
        )
        standards.deactivate("qs-double-deactivate")
        standards.deactivate("qs-double-deactivate")

        row = standards.get("qs-double-deactivate")
        assert row["active"] == 0

    def test_double_resolve_issue_is_safe(self, benchmarks):
        """Resolving an already-resolved issue updates the fix time."""
        run = benchmarks.start_run(approach="greymatter", task_name="Test")
        issue_id = benchmarks.record_issue(
            run["id"], "minor", "naming", "Bad name", "review",
        )
        benchmarks.resolve_issue(issue_id, fix_minutes=5)
        benchmarks.resolve_issue(issue_id, fix_minutes=10)

        issues = benchmarks.get_issues(run["id"])
        assert issues[0]["time_to_fix_minutes"] == 10
