Commit graph

2 commits

Author SHA1 Message Date
2e04c00d6e style(format): ruff format on the three files P7/P8 left drifting [skip-docs]
Pure formatting, no behaviour change. ruff 0.15.18 reported
"3 files would be reformatted, 195 files already formatted" on HEAD 455d611;
after this commit "198 files already formatted". Suite 1570 passed / 5 skipped
before and after, golden demo-transcript.stdout content sha1 unchanged
(ea8c534773acdbe41ae68f2c55724d69aaf8be4f).

Two of the three came from P7 (277bb95), one from P8 (455d611).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 06:23:35 +02:00
455d611660 feat(run,generate): a run says what its delivered input can ground, before it spends an attempt [skip-docs]
P7 is right and landed, but re-measuring it exposed a consequence no row stated: with the gate
live, 29 of 29 cost codes in 13 of 13 delivered proposals fall across the three free recordings
(PM's denominator; 14 of 14 in 8 proposals on the PARSEABLE one -- the five blobs that separate
the numbers are refused by pydantic's `claimed <= total` and never reach stage 0b). All 29 were
invented, so the gate is right; but a gate that always refuses is as useless as one that never
does.

The cause is that the PROMPT asks for something the input cannot supply. `_build_messages`
requires each affected_item to "restate a cost line as the project's price schedule already
carries it", while K2's delivered input carries 9 occurrences / 2 distinct code-shaped tokens --
`SHA-01`/`SHA-10`, both document numbers off a page footer -- and `derive_cost_baseline` refuses
the base outright. There is no cost line in it to restate.

`GroundingOffer(chars, identifiers, cost_lines)` reports it. The PAIR is the diagnosis: "50
identifiers, 0 cost lines" says what neither number says alone. A REPORT, never a gate -- it
blocks nothing, because a blocking requirement IS `--require-cost-baseline` (F4/D-3, opt-in,
untouched), and `_ground_against_input` is untouched.

The callsite is MEASURED, not chosen: `generate.py` composes the grounding per attempt, after
`await _fetch_parsed`, so a report there could only speak once an attempt had been paid for;
`run.py` binds both halves above the `--live-dry-run` cut and before the first `debate.run`, so
the FREE trip says it. `delivered` is bound ONCE and the same variable feeds the report and
`_evaluate`; the report composes THROUGH `_grounding_text`, the gate's own composer.

A pattern is admissible here and not in the gate, and that is the difference between a report and
a falsifier: an unknown form is a token left uncounted -- an under-count, never a false rejection.
The forms are transcribed from the measurement; bare numbers are excluded with the number
(46 394 / 2 117 in K2). `grounding_offer_notice` is the ONE renderer and is silent when the run
CAN anchor -- omission, never an empty row.

Load-bearing MEASURED (tests/test_grounding_offer_loadbearing.py, 12 arms), nine mutations all
red against the WHOLE suite + green control 1570/5 (from 1558/5, strict superset, 0 removed) and
the golden byte-unchanged (shasum -a 1 of the CONTENT = ea8c534773acdbe41ae68f2c55724d69aaf8be4f).

Measurement: docs/2026-09-09-p8-forankringstilbudet.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 17:50:02 +02:00