feat(1b): et tak som fyrer er ikke en krasj — BudgetExceeded får sin egen kanal [skip-docs]
Prosjektets første levende kjøring døde på `rounds limit=12 observed=13`, og den
hostede flaten svarte `500 {error_type, error}` — nøyaktig det samme den sier når
modell-endepunktet faller. Nå: 429 med trippelen som STRUKTUR.
Beslutningen er S3.4-invarianten anvendt på transporten: `budget_stop` ble holdt
utenfor `stop_reason` fordi de to stoppene betyr motsatte ting, og å svare
ressurs-utmattelse på krasj-kanalen gjør «det gikk ikke» uleselig på samme måte.
IKKE 200, og det er dét som skiller den fra `Rejection`: en `Rejection` er en
kjøring som KONKLUDERTE og hører i payloaden, mens et uttømt budsjett produserte
ingen proposal — en 2xx ville latt en automatisk kaller bokføre «analysert» for en
kjøring som analyserte ingenting. 429 fordi betingelsen oppstår av en TILDELING
(`max_rounds`/`max_tokens` er whitelistede request-felt), aldri av en serverfeil.
`kind`/`limit`/`observed` legges ut som felt, aldri `str(exc)` (kø-(y));
`error_type` holdes ute — den nøkkelen tilhører feilkanalen. `budget_exhausted` er
ikke foldet inn i `outcome_type` og kunne ikke vært det: `outbox.outcome_payload`
er den ene kopien av den forgreningen og tar `ValidatedProposal | Rejection`.
Ærlighets-grense: ingen `Retry-After` — å vente endrer ingenting.
Iron Law: begge nye tester RØDE før armen fantes. Fem mutasjoner mot HELE suiten,
alle røde med hver sin signatur, grønn kontroll 867/4: detach armen (2 røde) ·
flat streng i stedet for struktur (1 rød — struktur-testen alene) · ekko `limit`
som `observed` (1 rød) · utvid armen til `Exception` (6 røde) · stemple
`error_type` på budsjett-kroppen (1 rød).
500-armens vitne ble BYTTET, ikke slettet: den eksisterende testen brukte
`BudgetExceeded` som sin 500-prøve, så en ny arm alene ville etterlatt
krasj-kanalen uten vitne. Den bærer nå en ekte ikke-budsjett-`RuntimeError`, og er
dét som holder den nye armen smal.
Kjørt, ikke bare testet: `python main.py` startet, `/readiness` 200, ukjent felt →
400 med navnet, 404, SIGTERM → exit 0.
865 → 867 passed / 4 skipped; ruff + format + mypy rene. DEPLOY.md §6 dokumenterer
429 for mottakeren.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1bsX79aDS7fJ5udWGWAEN
This commit is contained in:
parent
605c02aa62
commit
986fc19350
4 changed files with 143 additions and 9 deletions
31
CLAUDE.md
31
CLAUDE.md
|
|
@ -188,7 +188,8 @@ Python ≥3.10. MAF (`agent-framework-core` 1.9.0). Pakkehåndtering: `uv`. To b
|
|||
ukjente felt NEKTES ved navn (400), aldri stille droppet (valg-doc §0-fella anvendt på vår egen
|
||||
flate); `profile` defaulter til `azure` KUN her (containeren har ingen lokal endpoint;
|
||||
`run_project`s egen default forblir LOCAL). Feilmapping ærlig: `ValueError` (pydantic-kontrakter
|
||||
subklasser den) → 400, alt annet → 500 `{error_type, error}` (speiler `RunFailure`), og en
|
||||
subklasser den) → 400, `BudgetExceeded` → 429 (EGEN rad under, 14.08), alt annet → 500
|
||||
`{error_type, error}` (speiler `RunFailure`), og en
|
||||
`Rejection` er en VELLYKKET kjøring → 200 — det negative utfallet tilhører payloaden, aldri
|
||||
transporten. `outbox.outcome_payload` er den ENE kopien av validated/rejected-forgreningen
|
||||
(delt av fil-skriveren og HTTP-responsen — to kopier drifter, kø-(p)-regelen). **Container-innpakningen
|
||||
|
|
@ -216,6 +217,34 @@ Python ≥3.10. MAF (`agent-framework-core` 1.9.0). Pakkehåndtering: `uv`. To b
|
|||
(`tests/test_hosting_loadbearing.py`), de tre gjenværende mutasjonene alle røde på riktig test og
|
||||
på INGEN annen: send `project_id` to ganger · whitelist et felt `run_project` ikke tar · fjern
|
||||
`bundle_dir` fra whitelisten.
|
||||
- **Et tak som fyrer er IKKE en krasj — `BudgetExceeded` får sin EGEN kanal (429), og trippelen
|
||||
bæres som STRUKTUR (1b-køen, 14.08):** prosjektets første levende kjøring døde på
|
||||
`rounds limit=12 observed=13`, og den hostede flaten svarte `500 {error_type, error}` — altså
|
||||
nøyaktig det samme den sier når modell-endepunktet faller. **Beslutningen er S3.4-invarianten
|
||||
anvendt på transporten:** `budget_stop` ble holdt UTENFOR `stop_reason` fordi de to stoppene
|
||||
betyr motsatte ting, og å svare ressurs-utmattelse på krasj-kanalen gjør «det gikk ikke»
|
||||
uleselig på nøyaktig samme måte. **IKKE 200, og det er dét som skiller den fra `Rejection`:**
|
||||
en `Rejection` er en kjøring som KONKLUDERTE (og hører derfor i payloaden), mens et uttømt
|
||||
budsjett produserte ingen `proposal` i det hele tatt — en 2xx ville latt en automatisk kaller
|
||||
bokføre «analysert» for en kjøring som analyserte ingenting. **429 fordi betingelsen oppstår av
|
||||
en TILDELING** (`max_rounds`/`max_tokens` er whitelistede request-felt, og å heve dem er
|
||||
kallerens egen botemiddel), aldri av en serverfeil — derfor 4xx, ikke 5xx.
|
||||
`kind`/`limit`/`observed` legges ut som felt, ALDRI `str(exc)` (kø-(y): de beskriver ÉN ledger,
|
||||
og «hvilket tak bandt, og hvor langt forbi» er hele det operative spørsmålet); `error_type`
|
||||
holdes UTE — den nøkkelen tilhører feilkanalen, og en kaller som switcher på dens
|
||||
tilstedeværelse skal ikke finne den her. `budget_exhausted` er IKKE foldet inn i `outcome_type`,
|
||||
og kunne ikke vært det: `outbox.outcome_payload` er den ENE kopien av den forgreningen og tar
|
||||
`ValidatedProposal | Rejection`, som en uttømt kjøring ikke har noen av. **Ærlighets-grense,
|
||||
uttalt:** ingen `Retry-After` — å vente endrer ingenting, botemiddelet er et større tak eller å
|
||||
akseptere stoppet, og en header som lover tid ville vært en løgn. Load-bearing MÅLT
|
||||
(`tests/test_hosting_loadbearing.py`), fem mutasjoner alle røde mot HELE suiten, hver med sin
|
||||
egen signatur + grønn kontroll 867/4: detach armen (2 røde) · flat streng i stedet for struktur
|
||||
(1 rød — struktur-testen ALENE, altså rir den ikke på status-asserten) · ekko `limit` som
|
||||
`observed` (1 rød) · utvid armen til `Exception` (6 røde, inkl. 400-armen) · stemple
|
||||
`error_type` på budsjett-kroppen (1 rød). **500-armens vitne ble byttet, ikke slettet:** den
|
||||
eksisterende testen brukte `BudgetExceeded` som sin 500-prøve, så å bare legge til en ny arm
|
||||
ville etterlatt krasj-kanalen uten vitne — den bærer nå en ekte ikke-budsjett-`RuntimeError`,
|
||||
og er dét som holder den nye armen SMAL.
|
||||
- **Påstander flaten gjør om SEG SELV gates som rå tekst, linjeforankret (Fase 3, A5):** to påstander
|
||||
bodde i prosa der ingen test kunne se dem, og begge drev. (1) `env.template` sa at credential
|
||||
resolves via `DefaultAzureCredential` — den har ALDRI gjort det; gaten leser de klassene
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue