feat(1b): skjemaet ER akseptert av det levende endepunktet - malt, ikke resonnert [skip-docs]

Fase 1b siste trinn: forste bundne levende kjoring over HELE run_project-stien
mot Foundry (gpt-4-1-mini). Okt 37s uttalte aerlighets-grense er lukket ved
maling: ingen -parse-failures.json i outboksen, altsa parset hvert eneste
genererings-svar. assumptions-normaliseringen virket ende-til-ende.

Utfall: rejected pa P90 (claimed 34500 > feasible 11488), checker approve.
Kjoringen KONKLUDERTE - per pre-registreringen det bestatte utfallet. De to
falsifisererne skilte lag for forste gang mot en levende modell.

FUNN storre enn den gronne testen: modellen fant opp kostkoden
EL-LIGHTING-OP-HR (null treff i kunnskapsbasen). Avvisningen var riktig men
skjedde pa 30%-cap-en, ikke stage 0 - bundelen shipper ingen cost-baseline.json,
sa S4.0-forankringen var inaktiv. Ko-fort, ikke rettet her.

Gate-designet er ovis beslutning, tatt for koding:
- TREDJE distinkt opt-in PORTFOLIO_LIVE_FULL_RUN (truthiness, 4b-invarianten).
  Begge eksisterende live-tester gater pa SAMME to Foundry-variabler, sa
  gjenbruk ville latt den billige proben fyre den dyre kjoringen - stigen i
  maleprotokollen ville kollapset til ett trinn. MALT: den dyre SKIPPET med
  begge Foundry-variablene satt.
- Asserten i EN kopi (conftest.assert_full_run_contract, ko-(p)), smal med
  vilje: fravaer av parse-failures-artefaktet + at validatoren avgjorde. En
  rejected BESTAR - pastanden er schema-aksept, ikke modell-dommekraft.
- Iron Law uten a betale to ganger: diskrimineringen bevist OFFLINE av
  test_live_full_run_contract.py. To mutasjoner, hver sin signatur: detach
  artefakt-sjekken (T1 rod ALENE) - raise ubetinget (T2 rod ALENE).

STATE-premiss korrigert: "test_foundry_profile_live dekker KUN klient-nivaet"
var upresist - test_portfolio_live.py dekket allerede fan-outen, men dens
len(runs)==1 kan ikke skille validert fra avvist og bar derfor ikke pastanden.

869 passed / 5 skipped (fra 867/4), ruff+format+mypy rene.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GF7va4cpRiuf79kTzAi3vW
This commit is contained in:
Kjell Tore Guttormsen 2026-08-14 20:02:26 +02:00
commit 2d1264088e
5 changed files with 408 additions and 0 deletions

View file

@ -108,3 +108,107 @@ serverfeil. Det er ikke rettet her; det er notert.
den hostede flaten.
4. Først når 1 og 2 er på plass: en ny bundet kjøring, og en gatet test som dekker **hele
`run_project`-stien** (den eksisterende gatede testen dekker kun klient-nivået).
**Rettelse til punkt 4, målt 14.08 (økt 40):** parentesen er upresis. `tests/test_portfolio_live.py`
fantes allerede og dekker `run_portfolio`-utfoldingen — altså hele `run_project`-stien — med samme
env-gate. Men den asserterer `len(result.runs) == 1`, og fordi `runs` og `failures` *partisjonerer*,
kan den kun skille «kjøringen fullførte» fra «kjøringen raiste». Den kan **ikke** skille et validert
forslag fra et avvist, og heller ikke en kjøring der svarene parset fra en der de ikke gjorde det.
Den bærer derfor ikke påstanden 1b skal felle. Punkt 4 står, men grunnen er en annen enn skrevet.
## 5. Pre-registrerte utfall (skrevet FØR kjøringen)
Denne kjøringen har ett formål: å felle den ene gjenstående ærlighets-grensen fra økt 37 — **at det
emitterte `response_format`-skjemaet ER akseptert av det LEVENDE endepunktet er uverifisert**;
testene beviser konformitet med Azures *dokumenterte* subset, ikke aksept.
**Instrumentet** er `conftest.assert_full_run_contract`, og diskriminatoren er et artefakt repoet
allerede eier: `{run_id}-parse-failures.json` skrives hvis og bare hvis et svar ikke lot seg parse
(økt 35). Artefaktets **fravær** ved siden av et `RunResult` beviser at hvert genererings-svar kom
tilbake i den bestilte formen. Kontraktens evne til å skille er bevist **offline og gratis**
(`tests/test_live_full_run_contract.py`, to mutasjoner med hver sin signatur: detach artefakt-sjekken
→ T1 rød alene; raise ubetinget → T2 rød alene). Det betalte kallet er *målingen*, ikke beviset på at
måleinstrumentet virker.
**Hva hvert utfall betyr — avgjort på forhånd:**
| Utfall | Betydning |
|---|---|
| Ingen parse-failure-artefakt + validatoren avgjorde (`validated` **eller** `rejected`) | **Ærlighets-grensen er felt.** Skjemaet ble akseptert av det levende endepunktet. En P90-avvisning er et *bestått* utfall — kjøringen KONKLUDERTE. |
| Parse-failure-artefaktet finnes | Skjemaet ble **ikke** honorert. Et FUNN, ikke et bevis — og denne gangen finnes den råe teksten (økt 35), så neste steg kan begrunnes i stedet for gjettes. |
| `BudgetExceeded` | Fortsatt ubevist, men artefaktet forklarer hvorfor. Samme form som 1a-kjøringen. |
**Taket heves IKKE.** `max_rounds`/`max_tokens` står på defaultene den første levende kjøringen døde
på: fyrer ledgeren igjen, er dét informasjon, og å heve taket ville brukt mer penger på en sti som
kanskje fortsatt er brukket.
**Gate-variabelen er en TREDJE, distinkt opt-in** (`PORTFOLIO_LIVE_FULL_RUN`, lest på *truthiness*).
Begge de eksisterende live-testene gater på nøyaktig `PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT` +
`PORTFOLIO_FOUNDRY_DEPLOYMENT`; å gjenbruke det paret ville betydd at en operatør som eksporterer de
to for å kjøre den **billige** ett-ords-proben også fyrer den dyre fullkjøringen — altså at stigen i
§1 kollapser til ett trinn. `PORTFOLIO_MODEL_MAP` er med i skip-betingelsen av en annen grunn:
uten den feiler kjøringen av en *konfigurasjons*-årsak som ser ut som en modell-feil.
## 6. Den bundne fullkjøringen — målt 14.08 kl. 19:54
Stigen på nytt, samme disiplin som §1. Alt under er kjørt.
| Trinn | Kommando | Utfall |
|---|---|---|
| 1a | `az account get-access-token --resource https://ai.azure.com` (uten rør) | exit 0, `expiresOn 21:07:40` |
| 1b | `az ad signed-in-user show` (ekte Graph-kall, ikke lokal cache) | exit 0 — gmail-kontoen, ikke jobbkontoen |
| 2 | `preflight --profile azure` | `preflight OK (azure)` |
| 3 | `pytest tests/test_foundry_profile_live.py` | **1 passed, 5,48 s** |
| 3b | samme kall, med `test_full_run_live.py` samlet | **SKIPPED** — det tredje flagget holder stigen |
| 4 | `pytest tests/test_full_run_live.py` (`PORTFOLIO_LIVE_FULL_RUN=1`) | **1 passed, 22,87 s** |
Trinn 3b er verdt å uttale: den dyre testen hoppet over **selv med begge Foundry-variablene satt**.
Det er den empiriske bekreftelsen på at det tredje opt-in-flagget gjør jobben sitt design lover.
### Ærlighets-grensen ER felt
Outboksen inneholder `-proposal.json`, `-outcome.json`, `-runconfig.json` — og **ingen
`-parse-failures.json`**. Hvert eneste genererings-svar fra `gpt-4.1-mini` kom tilbake som et
parsebart objekt i den bestilte formen. Økt 37s uttalte grense — *«at det emitterte skjemaet ER
akseptert av det LEVENDE endepunktet er IKKE verifisert»* — er dermed **lukket ved måling**, ikke
ved resonnement. Kontrasten til den første levende kjøringen er hele funnet: der brant tolv runder
på formatfeil og etterlot null tegn; her feilet ingen.
`assumptions` kom tilbake som forventet (`{"EL-LIGHTING-OP-HR": [10.0, 13.0]}`), altså virker økt 37s
additive wire-form → IR-map-normalisering ende-til-ende mot et levende endepunkt. Det var
beslutningen som holdt den stokastiske falsifisereren fra å gå inert, og den er nå prøvd i felt.
### Utfallet: `rejected` — og det er et bestått utfall
```
outcome_type: rejected
reason: claimed saving 34500 exceeds P90 feasible 11488
checker_verdict: approve
validator_decision: rejected
token_usage: 15 306
```
Kjøringen KONKLUDERTE. Per §5s pre-registrering er dette det positive utfallet: validatoren ble nådd
med en parsebar kandidat og avgjorde. **Og de to falsifisererne skilte lag for første gang mot en
levende modell** — checkeren godkjente *resonnementet*, validatoren avviste *tallene*. Nøyaktig den
uavhengigheten `checker_verdict` holdes atskilt fra `provenance.validator_decision` for.
### FUNN som er viktigere enn den grønne testen: modellen fant opp en kostkode
Forslaget bar `code: "EL-LIGHTING-OP-HR"` (3 000 × 11,5). **Den koden finnes ikke noe sted i
kunnskapsbasen** (`grep` over hele bundelen: null treff). Kunnskapsbasen instruerer eksplisitt
mappingen `ENERGI-TOTAL-EL`, 300 000 kWh × 1,00 NOK — modellen konstruerte i stedet sin egen
kostlinje med en egen enhet.
Avvisningen var derfor **riktig, men skjedde på feil gate**: 30 %-cap-en fanget den på *magnitude*
(34 500 > P90 11 488), ikke stage 0 på *eksistens*. Grunnen er en kjent og uttalt egenskap, ikke en
defekt: S4.0-forankringen aktiveres på bundle-stien KUN når bundelen shipper `cost-baseline.json`,
og `bygg-energi-mikro` gjør ikke det (målt) — «en pre-amendment-bundle er legitimt uforankret».
Dette er akkurat den hallusinasjons-klassen S4.0 ble bygget for, observert i felt for første gang.
At den uforankrede gaten fanget den likevel er betryggende; at den fanget den på den dyre gaten
i stedet for den billige er en kø-post, ikke noe som endres her.
**Fortsatt ikke bevist:** at systemet produserer et *validert* forslag mot en levende modell. Denne
kjøringen avviste — korrekt, og med en begrunnelse som kan leses. Én kjøring er én kjøring, og
`gpt-4.1-mini`s egnethet for proposer-rollen er ikke avgjort av den.