You are a senior code reviewer. Review the following code changes.

## Specification

No specification provided. Focus on correctness, tests, and integration.





## Code Changes

```diff
diff --git a/expert_build/prompts.py b/expert_build/prompts.py
index 8144a2d..53ff11f 100644
--- a/expert_build/prompts.py
+++ b/expert_build/prompts.py
@@ -73,6 +73,8 @@
 - Include commands, paths, config values when relevant
 - Do NOT include opinions or subjective assessments
 - Aim for 3-8 beliefs per entry (not every sentence is a belief)
+- Set "accept" to true if the claim is well-supported by the source material, \
+false if it is vague, speculative, or poorly supported
 
 ---
 
@@ -83,7 +85,7 @@
 ---
 
 Respond with ONLY this JSON array (no other text):
-[{{"id": "<kebab-case-id>", "claim": "<one-line factual claim>", "source": "<path to entry file>", "source_url": "<url from SOURCE_URL in header, or empty string>"}}]
+[{{"id": "<kebab-case-id>", "claim": "<one-line factual claim>", "accept": true, "source": "<path to entry file>", "source_url": "<url from SOURCE_URL in header, or empty string>"}}]
 """
 
 EXAM_ANSWER = """\
diff --git a/expert_build/propose.py b/expert_build/propose.py
index b7cd699..59b716e 100644
--- a/expert_build/propose.py
+++ b/expert_build/propose.py
@@ -440,7 +440,8 @@ async def run_batches():
                 claim = b.get("claim", "")
                 source = b.get("source", "")
                 source_url = b.get("source_url", "")
-                f.write(f"### [ACCEPT/REJECT] {bid}\n")
+                verdict = "[ACCEPT]" if b.get("accept", True) else "[REJECT]"
+                f.write(f"### {verdict} {bid}\n")
                 f.write(f"{claim}\n")
                 f.write(f"- Source: {source}\n")
                 f.write(f"- Source URL: {source_url or 'none'}\n\n")
diff --git a/tests/test_propose.py b/tests/test_propose.py
index e96eced..42fe6ec 100644
--- a/tests/test_propose.py
+++ b/tests/test_propose.py
@@ -37,10 +37,10 @@ def make_args(input_dir, output="proposed-beliefs.md", batch_size=2, model="test
     )
 
 
-def _json_beliefs(*beliefs):
+def _json_beliefs(*beliefs, accept=True):
     """Helper to build a JSON response from (id, claim) tuples."""
     return json.dumps([
-        {"id": b[0], "claim": b[1], "source": "entry.md", "source_url": ""}
+        {"id": b[0], "claim": b[1], "accept": accept, "source": "entry.md", "source_url": ""}
         for b in beliefs
     ])
 
@@ -315,3 +315,45 @@ def invoke_side_effect(prompt, model=None, timeout=None):
     assert "belief-1" in content
     assert "belief-2" in content
     assert "belief-3" in content
+
+
+def test_accept_verdict_from_llm(entries_dir, work_dir):
+    """LLM's accept=true produces [ACCEPT] in output."""
+    (entries_dir / "entry0.md").write_text("# Entry\nContent")
+
+    output = work_dir / "proposed-beliefs.md"
+    args = make_args(entries_dir, output=str(output), batch_size=5)
+
+    def invoke_side_effect(prompt, model=None, timeout=None):
+        return _json_beliefs(("good-belief", "A solid claim."), accept=True)
+
+    with patch("expert_build.propose.check_model_available", return_value=True), \
+         patch("expert_build.propose.invoke", new_callable=AsyncMock, side_effect=invoke_side_effect), \
+         patch("expert_build.propose._load_existing_beliefs", return_value=[]), \
+         patch("expert_build.propose._has_embeddings", return_value=False):
+        cmd_propose_beliefs(args)
+
+    content = output.read_text()
+    assert "### [ACCEPT] good-belief" in content
+    assert "### [REJECT]" not in content
+
+
+def test_reject_verdict_from_llm(entries_dir, work_dir):
+    """LLM's accept=false produces [REJECT] in output."""
+    (entries_dir / "entry0.md").write_text("# Entry\nContent")
+
+    output = work_dir / "proposed-beliefs.md"
+    args = make_args(entries_dir, output=str(output), batch_size=5)
+
+    def invoke_side_effect(prompt, model=None, timeout=None):
+        return _json_beliefs(("weak-belief", "A vague claim."), accept=False)
+
+    with patch("expert_build.propose.check_model_available", return_value=True), \
+         patch("expert_build.propose.invoke", new_callable=AsyncMock, side_effect=invoke_side_effect), \
+         patch("expert_build.propose._load_existing_beliefs", return_value=[]), \
+         patch("expert_build.propose._has_embeddings", return_value=False):
+        cmd_propose_beliefs(args)
+
+    content = output.read_text()
+    assert "### [REJECT] weak-belief" in content
+    assert "### [ACCEPT]" not in content

```

## Observation Results

You previously requested observations. Here are the results:

```json
{
  "run_batches_body": {
    "function": "run_batches",
    "file": "expert_build/propose.py",
    "start_line": 423,
    "end_line": 425,
    "source": "    async def run_batches():\n        tasks = [_process_batch(i, bt, semaphore) for i, bt in enumerate(batches)]\n        return await asyncio.gather(*tasks)"
  },
  "json_beliefs_callers": {
    "symbol": "_json_beliefs",
    "usages": [
      {
        "file": "tests/test_propose.py",
        "line": 40,
        "text": "def _json_beliefs(*beliefs, accept=True):"
      },
      {
        "file": "tests/test_propose.py",
        "line": 62,
        "text": "return _json_beliefs((f\"belief-from-batch-{call_count}\", \"A belief.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 86,
        "text": "return _json_beliefs((f\"belief-{call_count}\", \"A belief.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 108,
        "text": "return _json_beliefs("
      },
      {
        "file": "tests/test_propose.py",
        "line": 138,
        "text": "return _json_beliefs((f\"belief-{call_count}\", \"A belief.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 169,
        "text": "return _json_beliefs((\"retried-belief\", \"A belief from retry.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 190,
        "text": "return '```json\\n' + _json_beliefs((\"fenced-belief\", \"A belief.\")) + '\\n```'"
      },
      {
        "file": "tests/test_propose.py",
        "line": 214,
        "text": "return _json_beliefs((\"test-belief\", \"A belief.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 237,
        "text": "return _json_beliefs((\"test-belief\", \"A belief.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 260,
        "text": "return _json_beliefs((\"test-belief\", \"A belief.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 280,
        "text": "return _json_beliefs((\"new-belief\", \"Fresh.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 305,
        "text": "return _json_beliefs((f\"belief-{call_count}\", f\"A belief from batch {call_count}.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 328,
        "text": "return _json_beliefs((\"good-belief\", \"A solid claim.\"), accept=True)"
      },
      {
        "file": "tests/test_propose.py",
        "line": 349,
        "text": "return _json_beliefs((\"weak-belief\", \"A vague claim.\"), accept=False)"
      }
    ],
    "production_usages": [],
    "test_usages": [
      {
        "file": "tests/test_propose.py",
        "line": 40,
        "text": "def _json_beliefs(*beliefs, accept=True):"
      },
      {
        "file": "tests/test_propose.py",
        "line": 62,
        "text": "return _json_beliefs((f\"belief-from-batch-{call_count}\", \"A belief.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 86,
        "text": "return _json_beliefs((f\"belief-{call_count}\", \"A belief.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 108,
        "text": "return _json_beliefs("
      },
      {
        "file": "tests/test_propose.py",
        "line": 138,
        "text": "return _json_beliefs((f\"belief-{call_count}\", \"A belief.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 169,
        "text": "return _json_beliefs((\"retried-belief\", \"A belief from retry.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 190,
        "text": "return '```json\\n' + _json_beliefs((\"fenced-belief\", \"A belief.\")) + '\\n```'"
      },
      {
        "file": "tests/test_propose.py",
        "line": 214,
        "text": "return _json_beliefs((\"test-belief\", \"A belief.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 237,
        "text": "return _json_beliefs((\"test-belief\", \"A belief.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 260,
        "text": "return _json_beliefs((\"test-belief\", \"A belief.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 280,
        "text": "return _json_beliefs((\"new-belief\", \"Fresh.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 305,
        "text": "return _json_beliefs((f\"belief-{call_count}\", f\"A belief from batch {call_count}.\"))"
      },
      {
        "file": "tests/test_propose.py",
        "line": 328,
        "text": "return _json_beliefs((\"good-belief\", \"A solid claim.\"), accept=True)"
      },
      {
        "file": "tests/test_propose.py",
        "line": 349,
        "text": "return _json_beliefs((\"weak-belief\", \"A vague claim.\"), accept=False)"
      }
    ],
    "production_count": 0,
    "test_count": 14,
    "total_count": 14
  },
  "accept_field_usages": {
    "symbol": "accept",
    "usages": [
      {
        "file": "tests/test_propose.py",
        "line": 40,
        "text": "def _json_beliefs(*beliefs, accept=True):"
      },
      {
        "file": "tests/test_propose.py",
        "line": 43,
        "text": "{\"id\": b[0], \"claim\": b[1], \"accept\": accept, \"source\": \"entry.md\", \"source_url\": \"\"}"
      },
      {
        "file": "tests/test_propose.py",
        "line": 320,
        "text": "def test_accept_verdict_from_llm(entries_dir, work_dir):"
      },
      {
        "file": "tests/test_propose.py",
        "line": 321,
        "text": "\"\"\"LLM's accept=true produces [ACCEPT] in output.\"\"\""
      },
      {
        "file": "tests/test_propose.py",
        "line": 328,
        "text": "return _json_beliefs((\"good-belief\", \"A solid claim.\"), accept=True)"
      },
      {
        "file": "tests/test_propose.py",
        "line": 342,
        "text": "\"\"\"LLM's accept=false produces [REJECT] in output.\"\"\""
      },
      {
        "file": "tests/test_propose.py",
        "line": 349,
        "text": "return _json_beliefs((\"weak-belief\", \"A vague claim.\"), accept=False)"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 22,
        "text": "from expert_build.propose import auto_accept_proposals"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 43,
        "text": "no_auto_accept=False,"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 66,
        "text": "# --- auto_accept_proposals ---"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 77,
        "text": "auto_accept_proposals(str(f))"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 82,
        "text": "def test_preserves_already_accepted(self, tmp_path):"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 87,
        "text": "\"### [ACCEPT/REJECT] needs-accept\\n\""
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 90,
        "text": "auto_accept_proposals(str(f))"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 99,
        "text": "auto_accept_proposals(str(f))"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 147,
        "text": "def test_stops_on_no_auto_accept(self, work_dir, capsys):"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 148,
        "text": "args = make_pipeline_args(no_auto_accept=True)"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 153,
        "text": "assert \"--no-auto-accept\" in captured.err"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 155,
        "text": "def test_auto_accepts_and_imports(self, work_dir):"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 161,
        "text": "patch(\"expert_build.propose.cmd_accept_beliefs\") as mock_accept:"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 165,
        "text": "assert mock_accept.called"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 310,
        "text": "def test_no_auto_accept_stops_early(self, work_dir, capsys):"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 311,
        "text": "args = make_pipeline_args(no_auto_accept=True, url=None, pdf=None)"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 408,
        "text": "def test_no_auto_accept_sets_paused(self, work_dir):"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 409,
        "text": "args = make_pipeline_args(no_auto_accept=True, url=None, pdf=None)"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/httpcore/_async/interfaces.py",
        "line": 99,
        "text": "Return `True` if the connection is currently able to accept an"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/httpcore/_async/http2.py",
        "line": 451,
        "text": "# 2. Mark the connection as errored, so that we don't accept any other"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/httpcore/_async/http2.py",
        "line": 480,
        "text": "# 2. Mark the connection as errored, so that we don't accept any other"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/httpcore/_sync/interfaces.py",
        "line": 99,
        "text": "Return `True` if the connection is currently able to accept an"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/httpcore/_sync/http2.py",
        "line": 451,
        "text": "# 2. Mark the connection as errored, so that we don't accept any other"
      }
    ],
    "production_usages": [
      {
        "file": ".venv/lib/python3.14/site-packages/httpcore/_async/interfaces.py",
        "line": 99,
        "text": "Return `True` if the connection is currently able to accept an"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/httpcore/_async/http2.py",
        "line": 451,
        "text": "# 2. Mark the connection as errored, so that we don't accept any other"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/httpcore/_async/http2.py",
        "line": 480,
        "text": "# 2. Mark the connection as errored, so that we don't accept any other"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/httpcore/_sync/interfaces.py",
        "line": 99,
        "text": "Return `True` if the connection is currently able to accept an"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/httpcore/_sync/http2.py",
        "line": 451,
        "text": "# 2. Mark the connection as errored, so that we don't accept any other"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/httpcore/_sync/http2.py",
        "line": 480,
        "text": "# 2. Mark the connection as errored, so that we don't accept any other"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/h11/_receivebuffer.py",
        "line": 9,
        "text": "# - find next \\r\\n or \\r\\n\\r\\n (\\n or \\n\\n are also acceptable),"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/h11/_writers.py",
        "line": 56,
        "text": "# (either by import or copy/paste). We already accept them as status codes"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/_typing.py",
        "line": 8,
        "text": "# * In 3.10, x|y is an accepted shorthand for Union[x,y]."
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/_typing.py",
        "line": 47,
        "text": "\"\"\"A protocol object which can accept either Python's built-in"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/__init__.py",
        "line": 261,
        "text": "constructor accepts certain keyword arguments used in"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/element.py",
        "line": 612,
        "text": "# last_child can't be None because we passed accept_self=True"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/element.py",
        "line": 665,
        "text": "self, is_initialized: bool = True, accept_self: bool = True"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/element.py",
        "line": 672,
        "text": "this method returns None is if `accept_self` is False and the"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/element.py",
        "line": 679,
        "text": ":param accept_self: Is ``self`` an acceptable answer to the"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/element.py",
        "line": 688,
        "text": "if not accept_self and last_child is self:"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/element.py",
        "line": 2176,
        "text": "is_initialized=False, accept_self=True"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/element.py",
        "line": 2179,
        "text": "# accept_self=True into _last_descendant. Worst case,"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/element.py",
        "line": 3098,
        "text": "# accept_self is True. Worst case, last_descendant will end up"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/element.py",
        "line": 3100,
        "text": "last_descendant = cast(PageElement, self._last_descendant(accept_self=True))"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/builder/_htmlparser.py",
        "line": 369,
        "text": "acceptable to the parser."
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/builder/_htmlparser.py",
        "line": 423,
        "text": "\"Could not convert input to Unicode, and html.parser will not accept bytestrings.\""
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/builder/__init__.py",
        "line": 325,
        "text": "acceptable to the parser."
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/builder/__init__.py",
        "line": 623,
        "text": "\"form\": {\"accept-charset\"},"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/builder/_html5lib.py",
        "line": 427,
        "text": "# Now we can define the type this method accepts as a dictionary"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/builder/_html5lib.py",
        "line": 550,
        "text": "is_initialized=False, accept_self=True"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/builder/_html5lib.py",
        "line": 553,
        "text": "# Since we passed accept_self=True into _last_descendant,"
      },
      {
        "file": ".venv/lib/python3.14/site-packages/bs4/builder/_lxml.py",
        "line": 221,
        "text": "acceptable to the parser."
      },
      {
        "file": ".venv/lib/python3.14/site-packages/anyio/abc/_streams.py",
        "line": 199,
        "text": "\"\"\"An interface for objects that let you accept incoming connections.\"\"\""
      },
      {
        "file": ".venv/lib/python3.14/site-packages/anyio/abc/_streams.py",
        "line": 208,
        "text": ":param handler: a callable that will be used to handle each accepted connection"
      }
    ],
    "test_usages": [
      {
        "file": "tests/test_propose.py",
        "line": 40,
        "text": "def _json_beliefs(*beliefs, accept=True):"
      },
      {
        "file": "tests/test_propose.py",
        "line": 43,
        "text": "{\"id\": b[0], \"claim\": b[1], \"accept\": accept, \"source\": \"entry.md\", \"source_url\": \"\"}"
      },
      {
        "file": "tests/test_propose.py",
        "line": 320,
        "text": "def test_accept_verdict_from_llm(entries_dir, work_dir):"
      },
      {
        "file": "tests/test_propose.py",
        "line": 321,
        "text": "\"\"\"LLM's accept=true produces [ACCEPT] in output.\"\"\""
      },
      {
        "file": "tests/test_propose.py",
        "line": 328,
        "text": "return _json_beliefs((\"good-belief\", \"A solid claim.\"), accept=True)"
      },
      {
        "file": "tests/test_propose.py",
        "line": 342,
        "text": "\"\"\"LLM's accept=false produces [REJECT] in output.\"\"\""
      },
      {
        "file": "tests/test_propose.py",
        "line": 349,
        "text": "return _json_beliefs((\"weak-belief\", \"A vague claim.\"), accept=False)"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 22,
        "text": "from expert_build.propose import auto_accept_proposals"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 43,
        "text": "no_auto_accept=False,"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 66,
        "text": "# --- auto_accept_proposals ---"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 77,
        "text": "auto_accept_proposals(str(f))"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 82,
        "text": "def test_preserves_already_accepted(self, tmp_path):"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 87,
        "text": "\"### [ACCEPT/REJECT] needs-accept\\n\""
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 90,
        "text": "auto_accept_proposals(str(f))"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 99,
        "text": "auto_accept_proposals(str(f))"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 147,
        "text": "def test_stops_on_no_auto_accept(self, work_dir, capsys):"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 148,
        "text": "args = make_pipeline_args(no_auto_accept=True)"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 153,
        "text": "assert \"--no-auto-accept\" in captured.err"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 155,
        "text": "def test_auto_accepts_and_imports(self, work_dir):"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 161,
        "text": "patch(\"expert_build.propose.cmd_accept_beliefs\") as mock_accept:"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 165,
        "text": "assert mock_accept.called"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 310,
        "text": "def test_no_auto_accept_stops_early(self, work_dir, capsys):"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 311,
        "text": "args = make_pipeline_args(no_auto_accept=True, url=None, pdf=None)"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 408,
        "text": "def test_no_auto_accept_sets_paused(self, work_dir):"
      },
      {
        "file": "tests/test_pipeline.py",
        "line": 409,
        "text": "args = make_pipeline_args(no_auto_accept=True, url=None, pdf=None)"
      }
    ],
    "production_count": 117,
    "test_count": 25,
    "total_count": 142
  },
  "propose_beliefs_prompt_body": {
    "error": "No function found at 'PROPOSE_BELIEFS'",
    "file": "expert_build/prompts.py"
  },
  "propose_test_coverage": {
    "source_file": "expert_build/propose.py",
    "test_files": [
      {
        "path": "tests/test_pipelinepy",
        "exists": false
      },
      {
        "path": "tests/test_propose.py",
        "exists": true,
        "line_count": 359
      },
      {
        "path": "tests/test_proposepy",
        "exists": false
      }
    ],
    "test_count": 3
  }
}
```

Use these results to inform your review. Do not request the same observations again.


## Instructions

For each significant change (new file, modified function, etc.), provide a structured verdict.

Use this exact format for each change:

### <file_path or file_path:function_name>
VERDICT: PASS | CONCERN | BLOCK
CORRECTNESS: VALID | QUESTIONABLE | BROKEN
SPEC_COMPLIANCE: MEETS | PARTIAL | VIOLATES | N/A
ISSUE_COMPLIANCE: ADDRESSES | PARTIAL | UNRELATED | N/A
BELIEF_COMPLIANCE: CONSISTENT | VIOLATES | N/A
TEST_COVERAGE: COVERED | PARTIAL | UNTESTED
INTEGRATION: WIRED | PARTIAL | MISSING
REASONING: <brief explanation of your assessment>
---

## Review Criteria

1. **CORRECTNESS**: Does the code do what it claims? Is the logic sound?
   - VALID: Logic is correct, no bugs apparent
   - QUESTIONABLE: Logic may have edge cases or unclear behavior
   - BROKEN: Clear bugs or incorrect behavior

2. **SPEC_COMPLIANCE**: Does it meet MUST requirements from the spec?
   - MEETS: All relevant spec requirements satisfied
   - PARTIAL: Some requirements met, others missing or incomplete
   - VIOLATES: Contradicts spec requirements
   - N/A: No spec provided or not applicable

3. **ISSUE_COMPLIANCE** (only when an issue is provided): Do the changes address the problem or feature described in the issue?
   - ADDRESSES: Changes directly solve the issue's stated problem or implement the requested feature
   - PARTIAL: Changes partially address the issue but leave some aspects unresolved
   - UNRELATED: Changes do not appear related to the issue
   - N/A: No issue provided

4. **TEST_COVERAGE**: Are there tests for the new/changed code?
   - COVERED: Tests exist and cover the changes
   - PARTIAL: Some tests exist but coverage is incomplete
   - UNTESTED: No tests for the changes

5. **INTEGRATION**: Are callers updated? Is the feature usable end-to-end?
   - WIRED: Feature is fully integrated and usable
   - PARTIAL: Interface exists but callers not updated, or integration incomplete
   - MISSING: No integration with existing code

6. **BELIEF_COMPLIANCE** (only when beliefs are provided): Do the changes respect known architectural invariants, contracts, and rules?
   - CONSISTENT: Changes align with or reinforce known beliefs
   - VIOLATES: Changes contradict a specific belief — cite the belief ID
   - N/A: No beliefs provided or no relevant beliefs apply

## Verdict Guidelines

- **BLOCK**: Security issues, broken functionality, spec violations, or missing critical integration
- **CONCERN**: Missing tests, partial integration, questionable patterns, or unclear logic
- **PASS**: Correct, tested, well-integrated code

## Important

- Full function bodies for modified functions may be available in the observations section — use them to verify the complete logic, not just the diff hunks
- Related test files (prefixed with ``related_test:``) may be included in observations — check whether existing test assertions still match modified return types, signatures, or behavior. Flag any test that would break due to the changes
- If duplicate test coverage is detected (multiple test files covering the same source), note it in your review
- Focus on actual issues, not style preferences
- If a method signature is added but callers aren't updated, that's PARTIAL integration
- Be specific in reasoning - reference line numbers or function names
- When in doubt, use CONCERN rather than PASS

## Self-Review

After completing your review, add a brief self-assessment:

### SELF_REVIEW
LIMITATIONS: <what context were you missing that affected review quality?>
---

Examples of limitations:
- "Could not see full class to verify no other methods access the modified field"
- "Test file not included in diff - cannot verify coverage claims"
- "Spec file referenced but not provided"


## Feature Requests

If this review tool could be improved to help you do a better job, suggest features:

### FEATURE_REQUESTS
- <suggestion 1>
- <suggestion 2>
---

Examples:
- "Include full file context for modified functions, not just diff hunks"
- "Show callers of modified methods to verify integration"
- "Include test file alongside implementation changes"

Only include this section if you have specific suggestions. Skip if none.
