docs(1b): første levende kjøring — måleprotokoll, ikke konklusjon

Foundry-miljøet opprettet og målt. Stigen fra fase 1a fulgt: token → preflight fra
utpakket pakke → gatet triviell probe (prosjektets FØRSTE levende modellkall, 1 passed,
5,02 s) → full run_project.

Trinn 4 døde med BudgetExceeded rounds limit=12 observed=13. Diagnosen er utledet av
KODE, ikke av flere betalte kjøringer: _fetch_parsed tikker en runde per forsøk og
retryer ved parse-feil, så tolv oppbrukte runder betyr at svarene i hovedsak ikke lot
seg parse til IR-formen. Den råe svarteksten finnes ikke i noen artefakt i dag — å
skaffe den er en søm, altså Iron-Law-arbeid, ikke en omkjøring med høyere tak.

Uttalt bieffekt: BudgetExceeded forlot kjøringen som traceback, ikke strukturert utfall.
På den hostede flaten ville det blitt HTTP 500 for en normal, forventet tilstand.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SeW1LhH5TtXxKZPe9JkqL1
This commit is contained in:
Kjell Tore Guttormsen 2026-08-14 10:57:06 +02:00
commit 5bd8e1caa1

View file

@ -0,0 +1,110 @@
# Fase 1b — den første levende kjøringen (14. august 2026)
Dette dokumentet er et **måleprotokoll**, ikke en konklusjon. Alt under er kjørt; ingenting er utledet.
Der noe ikke er bevist, står det.
## 0. Hva som ble opprettet
| Ressurs | Verdi |
|---|---|
| Ressursgruppe | `portfolio-optimiser-rg` (eastus) |
| Foundry-ressurs | `po-foundry-ktg``kind: AIServices`, `--allow-project-management` |
| Prosjekt | `po-project` |
| Deployment | `gpt-4-1-mini` (modell `gpt-4.1-mini`, versjon `2025-04-14`, GlobalStandard) |
| Prosjekt-endepunkt | `https://po-foundry-ktg.services.ai.azure.com/api/projects/po-project` |
| Rolle | `Foundry User` (`53ca6127-…`) på **prosjekt**-scope |
**`gpt-4o-mini` ble avvist av plattformen** med `ServiceModelDeprecating` — modellnavnet måtte måles
med `az cognitiveservices model list`, ikke hentes fra hukommelsen. Kommandoene er hentet fra
Microsoft Learn (`az cognitiveservices account create` / `account project create`), ikke formulert
fritt.
**Rotårsaken til at dette ikke fantes før** var prosedural, ikke teknisk: den påloggede identiteten
har vært **Owner på abonnementet** hele tiden, mens repoets egen state-fil hadde ført opprettelsen
opp som operatørens oppgave og samtidig sagt at operatøren aldri kjører kommandoer selv. Arbeidet
tilhørte ingen, og hver økt målte lydig på nytt at det ikke fantes.
## 1. Stigen — billigste trinn først
Disiplinen fra fase 1a: bevis så mye som mulig før det dyre trinnet, så en feil er attribuerbar.
| Trinn | Kommando | Utfall |
|---|---|---|
| 1 | `az account get-access-token --resource https://ai.azure.com` | exit 0 |
| 2 | `preflight --profile azure` (fra **utpakket overleveringspakke**) | `preflight OK (azure)` |
| 3 | `pytest tests/test_foundry_profile_live.py` (gatet triviell probe) | **1 passed, 5,02 s** |
| 4 | Full `run_project` mot levende modell | **RC=1 — `BudgetExceeded`** |
**Trinn 3 er prosjektets første levende modellkall noensinne.** Det beviser at auth, RBAC,
endepunkt-form og deployment-navn komponerer — og at en rød trinn 4 derfor *ikke* kan skyldes noen
av dem.
## 2. Trinn 4 — hva som faktisk skjedde
```
uv run python -m portfolio_optimiser.run BYGG-KONTOR-NORD \
--profile azure \
--docs-dir shared/examples/bygg-energi-mikro \
--bundle-dir shared/examples/bygg-energi-mikro \
--outbox-dir <tmp>/outbox --run-id live-001
```
stdout var **tom**. stderr bar to linjer som betyr noe:
```
GroupChatOrchestrator reached max_rounds=3; forcing completion.
portfolio_optimiser.budget.BudgetExceeded: budget exceeded: rounds limit=12 observed=13
```
Den første er forventet — maker/checker-debatten kjører til taket også i den offline demoen. Den
andre er funnet.
### Diagnosen, utledet av kode og ikke av flere betalte kjøringer
`generate._fetch_parsed` er en `while True` som kaller `meter.tick_round()` for **hvert** forsøk og
`continue`-er ved parse-feil. Rund-budsjettet i genereringsfasen er `max(max_rounds * 4, 4)` = **12**
(`run.py:546`). Hadde modellsvarene parset til IR-formen, ville tre validerings-forsøk kostet tre
runder. At alle tolv gikk med betyr at **de fleste svarene fra `gpt-4.1-mini` ikke lot seg parse**
taket ble brent på formatfeil, ikke på validator-avslag.
**Dette er et FUNN, ikke en diagnose som er ferdig.** Det som mangler for å lukke den, er den råe
svarteksten, og den finnes ikke i noen artefakt i dag (`--outbox-dir` skrev kun
`live-001-runconfig.json`). Å skaffe den krever en endring i koden, altså Iron-Law-arbeid — ikke en
rask omkjøring med høyere tak, som ville kostet penger og fortsatt ikke sagt hvorfor.
### En bieffekt som er verdt å uttale
`BudgetExceeded` forlot kjøringen som en **uhåndtert exception med traceback**, ikke som et
strukturert utfall. På den hostede flaten ville nøyaktig dette blitt `HTTP 500` — altså ville
ressurs-utmattelse (en normal, forventet tilstand) presentert seg for en ekstern kaller som en
serverfeil. Det er ikke rettet her; det er notert.
## 3. Hva som ER bevist, og hva som IKKE er det
**Bevist, målt:**
- Rammeverket når en levende Foundry-modell: auth, RBAC på prosjekt-scope, endepunkt-form,
deployment-oppslag og klientbygging virker.
- Kunnskapsbase-navigasjon, debatt-orkestrering og genererings-løkka kjører mot ekte modellsvar —
kjøringen døde *inne i* løkka, ikke før den.
- Preflight fra den **utpakkede overleveringspakka** er grønn mot et ekte prosjekt, både med vårt
eget endepunkt-variabelnavn og med plattformens injiserte.
**Ikke bevist:**
- At systemet produserer et **validert forslag** mot en levende modell. Det har det aldri gjort.
Kjøringen nådde aldri fram til validatoren med en parsebar kandidat.
- At `gpt-4.1-mini` er en egnet modell for proposer-rollen. Målingen peker mot at den ikke er det
uten endret prompting eller structured output — men én kjøring er én kjøring.
- Noe som helst om kostnad i drift. Denne kjøringen kostet noen få øre; det sier ingenting om en
reell portefølje.
## 4. Neste steg, i rekkefølge
1. **Fang den råe svarteksten** ved parse-feil (i dag forsvinner den i `except: continue`). Test
først — dette er en søm, ikke en logg-linje.
2. Vurder **structured output** mot Foundry for proposer-rollen, framfor å prompte fram JSON.
3. Vurder om `BudgetExceeded` skal bli et strukturert utfall i stedet for en traceback, særlig for
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).