Now I have the full picture. Here's my review:

---

## Code Review: Restore LLM accept/reject recommendation in propose-beliefs

### expert_build/prompts.py
VERDICT: PASS
CORRECTNESS: VALID
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: COVERED (indirectly via propose tests)
INTEGRATION: WIRED
REASONING: The prompt change correctly adds the `accept` boolean field to the LLM instruction and the expected JSON schema. The guidance ("well-supported" vs "vague, speculative, or poorly supported") is clear enough for LLM compliance. The field defaults to `true` in the consumer (`b.get("accept", True)`), which is a safe fallback if the LLM omits it.
---

### expert_build/propose.py:run_batches (lines 443-447)
VERDICT: PASS
CORRECTNESS: VALID
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: COVERED
INTEGRATION: PARTIAL
REASONING: The verdict logic `"[ACCEPT]" if b.get("accept", True) else "[REJECT]"` is correct and the default-to-True is a sensible fallback. However, there is a downstream integration concern — see next item.
---

### expert_build/propose.py:auto_accept_proposals (unchanged, but affected)
VERDICT: CONCERN
CORRECTNESS: QUESTIONABLE
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: PARTIAL
INTEGRATION: PARTIAL
REASONING: `auto_accept_proposals` (line 254-259) only matches the regex `\[ACCEPT/REJECT\]`. With this change, new proposals are written as `[ACCEPT]` or `[REJECT]` directly — so `auto_accept_proposals` becomes a no-op on newly generated files. In the pipeline flow, this means `[REJECT]` beliefs will not be converted to `[ACCEPT]` by auto-accept, which may be intentional (the LLM already decided), but the function's docstring ("Rewrite all [ACCEPT/REJECT] markers to [ACCEPT]") and the header text at line 367 ("Edit each entry: change `[ACCEPT/REJECT]` to `[ACCEPT]` or `[REJECT]`") are now stale. The header still describes a manual workflow that no longer applies to new output.

Additionally, `cmd_accept_beliefs` (line 471-477) only parses `[ACCEPT]` entries — it ignores `[REJECT]`. This means `[REJECT]` beliefs are silently dropped during acceptance, which is probably the desired behavior, but it's worth confirming this is intentional since previously the user made the accept/reject decision manually.
---

### expert_build/propose.py line 367 (header text)
VERDICT: CONCERN
CORRECTNESS: QUESTIONABLE
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: UNTESTED
INTEGRATION: PARTIAL
REASONING: The file header still says "Edit each entry: change `[ACCEPT/REJECT]` to `[ACCEPT]` or `[REJECT]`." This instruction no longer matches the generated output format — entries are now pre-stamped as `[ACCEPT]` or `[REJECT]` by the LLM. The header should be updated to reflect the new workflow (e.g., "Review each entry and change `[REJECT]` to `[ACCEPT]` to keep, or vice versa").
---

### tests/test_propose.py:_json_beliefs
VERDICT: PASS
CORRECTNESS: VALID
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: COVERED
INTEGRATION: WIRED
REASONING: The helper correctly adds keyword-only `accept` parameter with default `True`, preserving backward compatibility with all 12 existing callers (none pass `accept`, so they all get `True` — matching the old implicit behavior).
---

### tests/test_propose.py:test_accept_verdict_from_llm
VERDICT: PASS
CORRECTNESS: VALID
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: COVERED
INTEGRATION: WIRED
REASONING: Good positive test. Verifies that `accept=True` in the LLM response produces `[ACCEPT]` in output. Also asserts no `[REJECT]` markers are present, ruling out false positives.
---

### tests/test_propose.py:test_reject_verdict_from_llm
VERDICT: PASS
CORRECTNESS: VALID
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: COVERED
INTEGRATION: WIRED
REASONING: Good negative test. Verifies that `accept=False` produces `[REJECT]`. The symmetry with the accept test is clean.
---

### tests/test_pipeline.py (unchanged, but affected)
VERDICT: CONCERN
CORRECTNESS: QUESTIONABLE
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: PARTIAL
INTEGRATION: PARTIAL
REASONING: `test_preserves_already_accepted` (line 82) still constructs test data with `[ACCEPT/REJECT]` markers (line 87). These tests still pass because `auto_accept_proposals` hasn't changed, but they no longer test the real-world flow: newly proposed beliefs will have `[ACCEPT]` or `[REJECT]`, not `[ACCEPT/REJECT]`. There should be a test verifying that `auto_accept_proposals` (or whatever replaces it) handles the new format correctly — or the function should be updated to also convert `[REJECT]` to `[ACCEPT]` if that's the intended pipeline behavior.
---

## Summary

The core change is correct and well-tested: the LLM now produces an `accept` boolean, and it's rendered as `[ACCEPT]`/`[REJECT]` in the output. The concern is with downstream integration:

1. **`auto_accept_proposals`** is now effectively dead code for new proposals — it only matches `[ACCEPT/REJECT]`, which is no longer generated. If the pipeline relies on this for auto-acceptance, `[REJECT]` beliefs will remain rejected even in auto-accept mode.
2. **The file header** (line 367) still describes the old manual workflow.
3. **Pipeline tests** test the old format exclusively.

These may be intentional design choices (the LLM's judgment replaces blanket auto-accept), but if so, `auto_accept_proposals` should be updated or removed, and the header text should be refreshed.

---

### SELF_REVIEW
LIMITATIONS: I did not see the full pipeline command (`cmd_pipeline`) to verify how `auto_accept_proposals` is called in the end-to-end flow — it's possible the pipeline already handles the new format differently. I also could not run the test suite to confirm all existing tests still pass with the `_json_beliefs` signature change.
---

### FEATURE_REQUESTS
- Include downstream callers of modified functions (e.g., show where `auto_accept_proposals` is called in the pipeline) to verify end-to-end integration
- Flag unchanged functions whose behavior is affected by format changes in the diff (stale consumers)
---
