# Chart-review document selection

How a chart-review question decides which of a patient's documents to read. Written as a handoff:
someone with no prior context should be able to start here and end up able to change this code.

Everything was read at `origin/main` @ `53b9ee820` (2026-09-02). Line citations will drift; the
structure will not.

## Read in this order

| # | Document | What it answers |
|---|---|---|
| 1 | [`v3-selection-architecture.md`](./v3-selection-architecture.md) | What the feature is, end to end: entry points, the pipeline, the selection agent, every tool, the catalogue, every flag, the output contract. |
| 2 | [`v2-find-documents.md`](./v2-find-documents.md) | The incumbent `findRelevantDocumentsWithLLM` in full — the behavior any replacement is measured against. |
| 3 | [`v2-v3-comparison.md`](./v2-v3-comparison.md) | **Start here if you only read one.** Scoping, regressions, failure bias, doc gaps, and the rollout gate. |
| 4 | [`episode-and-chart-scoping.md`](./episode-and-chart-scoping.md) | Per-tool audit: is each path episode-scoped, chart-scoped, fail-open or fail-closed. |
| 5 | [`scale-and-failure-bias.md`](./scale-and-failure-bias.md) | Every cap and truncation; every failure path graded SAFE or DANGEROUS. |
| 6 | [`latency-plan.md`](./latency-plan.md) | What is already measured, and the ordered plan for cutting selection latency and cost. |

For *how to measure* a change, see [`packages/ai-agents/scripts/EVAL_RUNBOOK.md`](../../packages/ai-agents/scripts/EVAL_RUNBOOK.md).
For agent-code conventions, [`packages/ai-agents/README.md`](../../packages/ai-agents/README.md).

## The three-sentence version

Two selectors are live. A chart-review question runs through either the v2 `AgentQuestionRunner` or
the v3 `AuditQuestionPassFailRunner`, but **both call the same legacy `findRelevantDocumentsWithLLM`
by default** — the v3-native catalogue-navigating selector is gated behind `enableAgenticDocSelection`,
which defaults `false`. Turning that flag on is the rollout this documentation exists to de-risk.

## Where the code lives

| Concern | Path |
|---|---|
| v3 runner and selection step | `packages/ai-agents/src/runners/audit-question/` |
| v3 tools | `packages/ai-agents/src/tools/chart-review/` |
| Catalogue (shared, leaf package) | `packages/documents/src/` |
| v2 selector and pipeline | `packages/legacy/src/chart-review/run-v2/lib/` |
| Gate resolution from LaunchDarkly | `packages/jobs/src/audit-question-config/` |

`packages/documents` is shared by both stacks. A change to `renderListing` changes the prompt the
**live v2 selector** sees, not just v3's.

## In flight as of 2026-09-02

| Stream | State | Change |
|---|---|---|
| [#1670](https://github.com/CircleHealthAI/circlehealth/pull/1670) `episode-scoped-run-context` | open | Stops re-applying the episode filter over a reviewer's hand-picked charts; filters the hoisted set to its episode. **Both halves are no-ops on main** — see the comparison §1. |
| [#1666](https://github.com/CircleHealthAI/circlehealth/pull/1666) `catalogue-tag-legend` | open | Tags become `{label, value}` data, deduped, hoisted into a `# Tags` legend written once. **Cross-stack — changes v2's prompt too.** |

Already on main, and easy to mistake for in-flight work: the 20k-char flat-listing budget,
`WHOLE_CHART_NOTE` and the rewritten `proved_absent` classification landed in
[#1633](https://github.com/CircleHealthAI/circlehealth/pull/1633) (`eed3bdc17`). The local
`selection-flat-listing-when-small` branch is a stale leftover of that work and is now *behind* main;
it carries nothing that main lacks.

Closed on purpose, do not resurrect: #1665 (superseded by #1670), #1672.
