# `orchestrator.codereview.reviewer`
<!-- generated by `orchestrator understand`; the PKG is source of truth, edits here are advisory -->

[← Episteme](../README.md) · [Architecture](../architecture.md)

**Source:** [`src/orchestrator/codereview/reviewer.py`](../../src/orchestrator/codereview/reviewer.py)

4 types · 8 functions · python

## Changing this safely

**Tested by** (2): `tests.codereview.test_grounding`, `tests.codereview.test_reviewer`

**Most depended-upon here** — a change to these reaches the most code (call graph, ≤4 hops):

- [`LLMReviewer`](../../src/orchestrator/codereview/reviewer.py#L80) — reaches **4** symbols
- [`ReviewService`](../../src/orchestrator/codereview/reviewer.py#L252) — reaches **4** symbols
- [`_format_comment`](../../src/orchestrator/codereview/reviewer.py#L224) — reaches **4** symbols
- [`_format_summary`](../../src/orchestrator/codereview/reviewer.py#L228) — reaches **4** symbols
- [`_valid_anchors`](../../src/orchestrator/codereview/reviewer.py#L185) — reaches **4** symbols
- [`_verdict`](../../src/orchestrator/codereview/reviewer.py#L215) — reaches **4** symbols
- [`_coerce_severity`](../../src/orchestrator/codereview/reviewer.py#L178) — reaches **3** symbols · **no test path visible**
- [`build_review_submission`](../../src/orchestrator/codereview/reviewer.py#L197) — reaches **3** symbols

_3 of the symbols other code depends on here have no test path the graph can see — worth a second look before changing them. Absence of a path is not proof of absence of a test: calls through an attribute chain (`obj.method()`) are skipped rather than guessed at, so indirect coverage is invisible._

## Types

### `ImpactFindingSource`

[`src/orchestrator/codereview/reviewer.py:74`](../../src/orchestrator/codereview/reviewer.py#L74)

- **Extends** (1): `typing.Protocol`

### `LLMReviewer`

[`src/orchestrator/codereview/reviewer.py:80`](../../src/orchestrator/codereview/reviewer.py#L80)

- **Called by** (2 production · 9 test): [`_build_review_service`](../../src/orchestrator/codereview/webhook.py#L177), [`_main`](../../scripts/live_review.py#L32), [`_service`](../../tests/codereview/test_reviewer.py#L196), [`test_llm_reviewer_degrades_on_garbage`](../../tests/codereview/test_reviewer.py#L95), [`test_llm_reviewer_parses_findings`](../../tests/codereview/test_reviewer.py#L58), [`test_llm_reviewer_skips_malformed_findings`](../../tests/codereview/test_reviewer.py#L102), [`test_llm_reviewer_tolerates_code_fence`](../../tests/codereview/test_reviewer.py#L86), [`test_review_service_carries_grounding_verifier`](../../tests/codereview/test_grounding.py#L153), [`test_review_service_posts_pkg_impact_comment`](../../tests/codereview/test_grounding.py#L115), [`test_reviewer_injects_grounding_into_prompt`](../../tests/codereview/test_grounding.py#L75), [`test_reviewer_without_grounder_has_no_impact_section`](../../tests/codereview/test_grounding.py#L82)
- **Fields**: `_grounder`, `_llm`, `_model`

### `ReviewGrounder`

[`src/orchestrator/codereview/reviewer.py:68`](../../src/orchestrator/codereview/reviewer.py#L68)

- **Extends** (1): `typing.Protocol`

### `ReviewService`

[`src/orchestrator/codereview/reviewer.py:252`](../../src/orchestrator/codereview/reviewer.py#L252)

- **Called by** (2 production · 3 test): [`_build_review_service`](../../src/orchestrator/codereview/webhook.py#L177), [`_main`](../../scripts/live_review.py#L32), [`_service`](../../tests/codereview/test_reviewer.py#L196), [`test_review_service_carries_grounding_verifier`](../../tests/codereview/test_grounding.py#L153), [`test_review_service_posts_pkg_impact_comment`](../../tests/codereview/test_grounding.py#L115)
- **Fields**: `_audit`, `_github`, `_impact_source`, `_reviewer`, `_verifiers`

## Functions

### `_coerce_severity`

[`src/orchestrator/codereview/reviewer.py:178`](../../src/orchestrator/codereview/reviewer.py#L178)

- **Called by** (1): [`_finding_from_llm`](../../src/orchestrator/codereview/reviewer.py#L150)
- **Calls** (1): [`Severity`](../../src/orchestrator/codereview/verifiers.py#L34)

### `_finding_from_llm`

[`src/orchestrator/codereview/reviewer.py:150`](../../src/orchestrator/codereview/reviewer.py#L150)

- **Called by** (1): [`_parse`](../../src/orchestrator/codereview/reviewer.py#L114)
- **Calls** (2): [`Finding`](../../src/orchestrator/codereview/verifiers.py#L45), [`_coerce_severity`](../../src/orchestrator/codereview/reviewer.py#L178)

### `_format_comment`

[`src/orchestrator/codereview/reviewer.py:224`](../../src/orchestrator/codereview/reviewer.py#L224)

- **Called by** (1): [`build_review_submission`](../../src/orchestrator/codereview/reviewer.py#L197)

### `_format_summary`

[`src/orchestrator/codereview/reviewer.py:228`](../../src/orchestrator/codereview/reviewer.py#L228)

- **Called by** (1): [`build_review_submission`](../../src/orchestrator/codereview/reviewer.py#L197)

### `_loads_json_object`

[`src/orchestrator/codereview/reviewer.py:130`](../../src/orchestrator/codereview/reviewer.py#L130)

- **Called by** (1): [`_parse`](../../src/orchestrator/codereview/reviewer.py#L114)
- **Calls** (1): `loads`

### `_valid_anchors`

[`src/orchestrator/codereview/reviewer.py:185`](../../src/orchestrator/codereview/reviewer.py#L185)

- **Called by** (1): [`build_review_submission`](../../src/orchestrator/codereview/reviewer.py#L197)
- **Calls** (1): [`iter_added_lines`](../../src/orchestrator/codereview/diff_utils.py#L26)

### `_verdict`

[`src/orchestrator/codereview/reviewer.py:215`](../../src/orchestrator/codereview/reviewer.py#L215)

- **Called by** (1): [`build_review_submission`](../../src/orchestrator/codereview/reviewer.py#L197)
- **Calls** (1): [`worst_severity`](../../src/orchestrator/codereview/verifiers.py#L293)

### `build_review_submission`

[`src/orchestrator/codereview/reviewer.py:197`](../../src/orchestrator/codereview/reviewer.py#L197)

- **Called by** (1 production · 3 test): [`_compute`](../../src/orchestrator/codereview/reviewer.py#L270), [`test_submission_anchors_inline_vs_floating_and_blocks`](../../tests/codereview/test_reviewer.py#L121), [`test_submission_clean_diff_comments_not_approves`](../../tests/codereview/test_reviewer.py#L145), [`test_submission_warnings_only_does_not_block`](../../tests/codereview/test_reviewer.py#L138)
- **Calls** (6): [`ReviewComment`](../../src/orchestrator/codereview/github_client.py#L94), [`ReviewSubmission`](../../src/orchestrator/codereview/github_client.py#L104), [`_format_comment`](../../src/orchestrator/codereview/reviewer.py#L224), [`_format_summary`](../../src/orchestrator/codereview/reviewer.py#L228), [`_valid_anchors`](../../src/orchestrator/codereview/reviewer.py#L185), [`_verdict`](../../src/orchestrator/codereview/reviewer.py#L215)

## Imports

`__future__.annotations`, `collections.abc.Awaitable`, `collections.abc.Callable`, `json`, `logging`, [`orchestrator.codereview.diff_utils`](../../src/orchestrator/codereview/diff_utils.py#L1), [`orchestrator.codereview.github_client`](../../src/orchestrator/codereview/github_client.py#L1), [`orchestrator.codereview.verifiers`](../../src/orchestrator/codereview/verifiers.py#L1), [`orchestrator.core.llm`](../../src/orchestrator/core/llm/__init__.py#L1), `typing.Any`, `typing.Protocol`

## Imported by

[`orchestrator.codereview.webhook`](../../src/orchestrator/codereview/webhook.py#L1), [`scripts.live_review`](../../scripts/live_review.py#L1), [`tests.codereview.test_grounding`](../../tests/codereview/test_grounding.py#L1), [`tests.codereview.test_reviewer`](../../tests/codereview/test_reviewer.py#L1)
