feat(1b): proposeren får en grammatikk — strict structured output [skip-docs]
Fase 1b, funn 1b. Den første levende kjøringen brant tolv runder på svar som
ikke lot seg parse til IR-formen; e371890 gjorde teksten synlig, dette fjerner
årsaken. generate_via_llm sender nå
options={"response_format": proposal_response_format()} på hvert
genererings-kall.
Formen er MÅLT, ikke valgt. ChatOptions.response_format tar
type[BaseModel] | Mapping, og begge profiler ærer den: LOCAL sender en Mapping
ordrett til Chat Completions, AZURE (FoundryChatClient -> RawFoundryChatClient
-> RawOpenAIChatClient) konverterer samme envelope til Responses-APIets
text.format. Klassen — det korteste svaret — er avvist på bevis: gitt en klasse
konverterer klienten med type_to_response_format_param, som emitterer
minimum/exclusiveMinimum/minItems/prefixItems og et assumptions-node hvis
additionalProperties er et skjema. Azures publiserte subset utelukker alle fire.
assumptions kan ikke bare droppes, og det er også en måling: validator
._monte_carlo faller tilbake på item.unit_cost for hver kode uten bånd, så uten
bånd er alle 512 samples identiske og P10 == P50 == P90. Den stokastiske
falsifisereren ville gått inert mens den fortsatt rapporterte persentiler.
Wire-en bærer derfor et array av navngitte entries som _parse_ir folder tilbake
til IR-ens map — additivt, aldri erstatning. Skjemaet deriveres fra
SavingsProposal; sanitiseren er fail-closed (StructuredOutputUnsupported).
Load-bearing målt mot hele suiten, seks mutasjoner alle røde, grønn kontroll
864/4: detach wiringen (1) · detach sanitiseren (3) · dropp assumptions fra
skjemaet (1) · fail-closed -> stille reparasjon (1) · detach normaliseringen
(3) · erstatning i stedet for tillegg (2, inkl. golden-transkriptet).
T3 ble skrevet vakuøs først og felt av sin egen mutasjon: den påsto å bli rød
når assumptions forsvant fra skjemaet, men den scriptede klienten ignorerer
skjemaet. Testen fikk en direkte assert på skjemaet.
Ærlighets-grense: ingen betalt kjøring gjort. Testene beviser konformitet med
det dokumenterte subsettet, ikke aksept fra det levende endepunktet.
859 -> 864 passed / 4 skipped. ruff + format + mypy rene.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013EQNU4tfAhsBvdefT1jUhk
This commit is contained in:
parent
d371475ec9
commit
642ce8ae9a
4 changed files with 612 additions and 3 deletions
38
CLAUDE.md
38
CLAUDE.md
|
|
@ -555,6 +555,44 @@ Python ≥3.10. MAF (`agent-framework-core` 1.9.0). Pakkehåndtering: `uv`. To b
|
|||
trunker til 100 tegn slik at sentinelen OVERLEVER (1 rød — verbatim-asserten alene, den skarpe
|
||||
diskriminatoren). Ærlighets-grense: `_charge_usage` kan raise FØR parse, og et svar tapt der er
|
||||
ikke en parse-feil og fanges ikke.
|
||||
- **Proposeren får en GRAMMATIKK, og skjemaet er DERIVERT + fail-closed (Fase 1b, funn 1b):**
|
||||
`generate_via_llm` sender `options={"response_format": proposal_response_format()}` på hvert
|
||||
genererings-kall. **Formen er MÅLT, ikke valgt:** `ChatOptions.response_format` tar
|
||||
`type[BaseModel] | Mapping`, og BEGGE profiler ærer den — LOCAL
|
||||
(`OpenAIChatCompletionClient`) sender en Mapping ordrett til Chat Completions, AZURE
|
||||
(`FoundryChatClient` → `RawFoundryChatClient` → `RawOpenAIChatClient`) konverterer SAMME
|
||||
envelope til Responses-APIets `text.format`. **Klassen er AVVIST på bevis:** gitt en klasse
|
||||
konverterer klienten med `type_to_response_format_param`, som (målt) emitterer `minimum` /
|
||||
`exclusiveMinimum` / `minItems` / `prefixItems` og et `assumptions`-node hvis
|
||||
`additionalProperties` er et SKJEMA — fire ting Azures publiserte subset utelukker
|
||||
(Learn: «Unsupported type-specific keywords» + `additionalProperties: false` i hvert objekt).
|
||||
Vår egen mapping er eneste måte å styre hva som når tråden. **Å stripe beskrankningene koster
|
||||
ingenting:** skjemaets jobb er FORM, validatorens jobb er VERDIER — `minItems`/`gt=0` gjenreises
|
||||
av pydantic i `_parse_ir` og av `validate_proposal`. **Skjemaet DERIVERES fra `SavingsProposal`**
|
||||
(`strict_json_schema`), aldri håndskrevet: en andre kopi av en form som alt bor i `ir.py` drifter
|
||||
stille, og modellen ville fortsatt blitt bestilt for den gamle. **`assumptions` KAN IKKE bare
|
||||
droppes, og det er en MÅLING:** feltet er det ene uttrykksløse (fri-form map av 2-tupler), men
|
||||
`validator._monte_carlo` faller tilbake på `item.unit_cost` for hver kode uten bånd — uten bånd
|
||||
i det hele tatt er alle 512 samples IDENTISKE og P10 == P50 == P90. Den stokastiske
|
||||
falsifisereren ville gått inert mens den fortsatt rapporterte persentiler: repoets kardinalklasse
|
||||
(en gate som bare kan bli grønn). Derfor bærer WIRE-en et array av navngitte entries og
|
||||
`_parse_ir` folder det tilbake til IR-ens map — **additivt, aldri erstatning** (map-formen
|
||||
parser uendret; alle scriptede svar i suiten og golden-transkriptet bruker den). Sanitiseren er
|
||||
**fail-closed** (`StructuredOutputUnsupported`) på `prefixItems`/`oneOf`/`allOf`/fri-form map
|
||||
uten deklarert override — validering, ALDRI reparasjon (speiler `write_concept_file`).
|
||||
Prompt-linja «Respond with ONLY a JSON object» + parse-retry + funn-1-fangsten står URØRT: en
|
||||
leverandør som ignorerer `response_format` må fortsatt få beskjed, og backstoppen er poenget.
|
||||
Load-bearing MÅLT (`tests/test_structured_output_loadbearing.py`), seks mutasjoner alle røde +
|
||||
grønn kontroll 864/4: detach wiringen (1 rød) · detach sanitiseren (3 røde) · dropp
|
||||
`assumptions` fra skjemaet (1 rød) · fail-closed → stille reparasjon (1 rød) · detach
|
||||
normaliseringen (3 røde) · erstatning i stedet for tillegg (2 røde — T5 PLUSS
|
||||
golden-transkriptet, et uavhengig vitne). **T3 ble skrevet VAKUØS først** (repoets 08-09-klasse,
|
||||
sjette gang): den påsto å bli rød når `assumptions` forsvant fra skjemaet, men den scriptede
|
||||
klienten ignorerer skjemaet — påstanden ble bevist usann av M3 og testen fikk en DIREKTE
|
||||
assert på skjemaet. **ÆRLIGHETS-GRENSE, UTTALT:** ingen betalt kjøring er gjort, så at det
|
||||
emitterte skjemaet ER akseptert av det levende endepunktet er IKKE verifisert — testen beviser
|
||||
konformitet med det DOKUMENTERTE subsettet, ikke aksept. Ollamas oppførsel på
|
||||
`response_format` er likeledes uverifisert.
|
||||
- **Overleverings-pakka ER `git archive HEAD`, aldri en kuratert kopi (Fase 5):**
|
||||
`scripts/make-handover-package.sh` bygger én zip en ekstern organisasjon deployer uten å klone
|
||||
repoet. **Tracked files only er hele eksponerings-kontrollen** — `STATE.md`, `*.local.md` og
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue