I'll review the diff systematically.

### expert_build/summarize.py:cmd_summarize (entry writing refactor)
VERDICT: CONCERN
CORRECTNESS: QUESTIONABLE
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: COVERED
INTEGRATION: WIRED
REASONING: The refactor from subprocess `entry` CLI to direct file writing is a good simplification. However, there's a file collision risk: `topic = source_path.stem`, so two source files with the same stem (e.g., `docs/foo.md` and `lib/foo.py`) would silently overwrite each other at `entries/YYYY/MM/DD/foo.md`. The old subprocess code had the same issue, but the new code makes it easier to fix (e.g., incorporating parent directory into the path). Additionally, `date.today()` is called inside the loop — if processing runs across midnight, entries split across two date directories. Neither is a regression, but the collision case is worth a test or guard.

---

### expert_build/summarize.py:cmd_summarize (source: frontmatter parsing)
VERDICT: PASS
CORRECTNESS: VALID
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: COVERED
INTEGRATION: WIRED
REASONING: The `source:` fallback parsing is correct. The `elif` ensures `source_url:` lines are handled first, and `if not source_url` prevents overwriting if `source_url:` appeared on a prior line. If `source:` appears before `source_url:` in frontmatter, `source_url:` still wins because it overwrites on its own `if` branch. Tests cover the URL-from-source propagation path (`test_entry_has_source_url_from_fetch_frontmatter`).

---

### expert_build/propose.py:cmd_propose_beliefs (source: fallback)
VERDICT: CONCERN
CORRECTNESS: QUESTIONABLE
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: UNTESTED
INTEGRATION: PARTIAL
REASONING: The parsing logic mirrors `summarize.py` and is structurally correct. However, the `source:` field in entries written by `summarize.py` is always a **local file path** (e.g., `/tmp/sources/doc.md`), not a URL. When this fallback fires (no `source_url:` present), it sets `source_url` to a local path, which then appears in the header as `SOURCE_URL: /tmp/sources/doc.md`. This is semantically misleading — a local path labeled as a URL. No tests cover this change in `propose.py`.

---

### expert_build/summarize.py (provenance frontmatter output)
VERDICT: PASS
CORRECTNESS: VALID
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: COVERED
INTEGRATION: WIRED
REASONING: The output frontmatter cleanly separates concerns: `source:` is always the local input path, `source_url:` carries the original URL if one existed, `source_id:` propagates when present. The `"---\n" + "\n".join(fm_lines) + "\n---\n\n"` construction is correct and produces valid YAML frontmatter. Tests verify all three fields and the directory structure.

---

### tests/test_summarize.py (test updates and new tests)
VERDICT: PASS
CORRECTNESS: VALID
SPEC_COMPLIANCE: N/A
ISSUE_COMPLIANCE: N/A
BELIEF_COMPLIANCE: N/A
TEST_COVERAGE: COVERED
INTEGRATION: WIRED
REASONING: Tests are significantly improved — they now verify actual file output rather than asserting that subprocess mocks were called. The `_find_entry` helper is clean. New provenance tests cover: source path in frontmatter, URL propagation from `source:` to `source_url:`, `source_id` propagation, LLM summary in body, and directory structure. The `test_strips_frontmatter_before_summarizing` was properly split to cover both `source:` and `source_url:` stripping. The `test_discovers_both_md_and_py` test avoids the collision issue by using distinct stems (`alpha`, `beta`).

---

## Summary

Two concerns worth addressing:

1. **`propose.py` has no test coverage** for the new `source:` fallback, and the fallback will label local file paths as `SOURCE_URL` when no real URL exists. Consider either (a) adding a test, or (b) only falling back to `source:` when the value looks like a URL.

2. **File collision on same-stem sources** — not a regression from the old code, but now trivially fixable since you control the write path. A guard or test would be cheap insurance.

### SELF_REVIEW
LIMITATIONS: Could not see the full `cmd_summarize` or `cmd_propose_beliefs` functions — only the diff hunks. Could not verify how `source_path` is constructed or whether there are other callers of the entry-writing logic. No visibility into how `SOURCE_URL` headers are consumed downstream from `propose.py`.

---

### FEATURE_REQUESTS
- Include full function bodies for modified functions so reviewers can verify loop context, variable initialization, and early returns
- Show downstream consumers of modified output formats (e.g., what reads the `SOURCE_URL` header from propose)

---
