feat(prepass): the excerpt's new fields reach the prompt, po stops dropping them twice

P2 measured that the producer's payload now carries title/req_number/sources/source_* on
every excerpt (14 members, was 9), but PrepassExcerpt ignored them (extra="ignore") and
_data_blocks rendered only concept_id/adjudication/trust_tier -- so (b') was a po verdict,
never a model verdict. title/req_number/sources are now named fields; source_* locators are
read via model_extra and a prefix scan (measured: the producer treats source_* as an
open-ended family, not a fixed allowlist), so a future producer's new source_foo key reaches
the prompt without a code change here. A P1-form payload renders byte-identical to before.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-08 16:42:17 +02:00
commit 2453246d4b
5 changed files with 406 additions and 3 deletions

View file

@ -501,7 +501,10 @@ when the seam is detached, so the loop cannot silently degrade into theater.
```
The cut is printed and written to `{run_id}-prepass.json`. **This buys a declared cut, not a
cheaper run** — the delivered text costs more than a pointer does. And note the limit it inherits:
cheaper run** — the delivered text costs more than a pointer does. When the payload's producer
declares a `title`, `req_number` or `sources` address for an excerpt, that reaches the prompt
alongside the text, so a proposal can cite the requirement a person would — not only the internal
identifier the base assigns it. And note the limit it inherits:
an *empty* delivery is evidence the base does not answer the question, but a *full* one is not
evidence that it does. The excerpts are the closest matches, which is not the same as an answer;
the run says so to the agents in as many words.