test(spikes): S0-S6 maalt for Magentic-utforskningssloeyfa (ORDRE 20260823T162224Z) [skip-docs]

Maaling foer bygging. Alle aatte antakelsene i planens § F flyttet fra «umaalt» til
et maalt utfall; ingenting bygget, ingenting i src/.

S0 (versjon): 1.0.1 loeser paa core 1.9.0. Diffen mot 1.0.0 er upstream #4371 -
`StandardMagenticManager.__init__` mistet sin persistente `AgentSession`, og hvert
manager-kall mynter naa en engangs-sesjon. **E2 OG E4 er dermed BORTE (4/4 -> 0/5).**
E1 (single-use) og E7 (orphan `_agent_thread`, :1369) staar. Ordrens «felles hvis»
(E7 staar -> revert) hviler paa at 1.0.1 ikke kjoeper noe; den kjoepte noe stoerre
enn det som ble haapet, saa laasen staar paa 1.0.1 I PAAVENTE AV OPERATOEREN.

S1 (B7): E1-E4 + E7 i repoets form. Versjons-sensitiviteten testes mot en STRUKTURELL
sonde (holder manageren en persistent sesjon?), aldri en versjonsstreng - den sier
AARSAKEN og overlever en versjon planen ikke har sett.
S2 (budsjett): A1+A2 GROENNE. `BudgetMiddleware` fyrer paa manager-stien
(`meter.tokens == 8`), og `BudgetExceeded` forlater `workflow.run` som repoets EGEN
type med `kind`/`limit`/`observed` intakt - ikke pakket i en ExceptionGroup.
S3 (plan review): rundturen virker; en revise koster 2 manager-kall, 0 ledger-kall,
0 runder, og SPOER PAA NYTT -> `max_plan_revisions` maa inn i kontrakten.
S3b: doer 3 staar. To rundturer per menneskesvar; `from_strings` gjenopptar IKKE
manageren, kun `approve` gjoer det. Pris: `AgentApprovalExecutor` er ikke re-eksportert.
S4 (resume i NY prosess): GROENN. Pris: `FileCheckpointStorage` nekter aa deserialisere
plan-review-typene uten `allowed_checkpoint_types` - uten det feiler resume som et
FRAVAER (tom listing), ikke som en feil.
S5: median `validate_proposal` 13,6 ms - fritt kallbart i loekka.
S6 (scratch-venv, ingenting lagt til pyproject): 2 `workflow.run`-spans, men
`enable_console_exporters` skriver til STDOUT og ville oedelagt golden-transkriptet;
`ConsoleSpanExporter(out=sys.stderr)` gir spanene paa stderr OG byte-identisk stdout.

Klienten er repoets `ScriptedChatClient` og budsjett-typene er PRODUKSJONENS - en bar
`BaseChatClient` no-op-er middleware, og `spikes/_harness.py`s egen kopi er nettopp
grunnen til at koe-(y) fantes.

Load-bearing MAALT mot HELE suiten, groenn kontroll 920/5: konstant persistent-sesjon
(2 roede) · aldri fest middleware paa manageren (3 roede, detach-armen groenn) · detach
markoer-registreringen (1 roed) · flipp `_route`-rekkefoelgen (4 roede) · resume uten
`checkpoint_id` (1 roed) · builder uten `with_checkpointing` (1 roed) · tom
`_ALLOWED_CHECKPOINT_TYPES` (1 roed). Og EN falsifisert: resume uten
`checkpoint_storage=` gir 0 roede - planens E-tabell navngir feil detach-punkt, og
det er skrevet inn i § F i stedet for aa staa som en gate som ikke kan bli roed.

Planens V1-sti ble portabel i 2eb4622 (pakke-gaten var roed paa HEAD siden 2e33905).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UTEa7uw2JMxgijx8k8XgxG
This commit is contained in:
Kjell Tore Guttormsen 2026-08-23 19:36:00 +02:00
commit 9f0843ab6d
5 changed files with 997 additions and 13 deletions

View file

@ -443,21 +443,60 @@ grønn, ellers synkron-først og U12 etter planen, sammen med core-bumpen.
## F. Nøkkelantakelser, risiko og åpne beslutninger
**Alle åtte radene er MÅLT i økt 54** (ordre `20260823T162224Z`, spikes S0S6). Måleapparatet er
`spikes/e_magentic.py` + `tests/spikes/test_e_magentic.py` (16 tester), kjørt mot orchestrations
**1.0.1** på core 1.9.0; hele suiten 920 passed / 5 skipped, golden-transkriptet uendret
(`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`).
| # | Antakelse | Test | Status |
|---|---|---|---|
| A1 | Agent-nivå `ChatMiddleware` fyrer på managerens kall | S2 | **umålt — RISIKO** (planens budsjettgaranti hviler her) |
| A2 | `BudgetExceeded` reist inni en Magentic-deltaker propagerer ut av `workflow.run` | S2 | målt for GroupChat (live-kjøringen 14.08), umålt for Magentic |
| A3 | `request_info`-rundtur på 1.0.0 | E6 | **MÅLT grønn** |
| A4 | Resume med pending plan review i NY prosess | S4 | umålt — kode-lest (`_runner_context.py:414-426`) |
| A5 | `AgentApprovalExecutor` som deltaker gir svar midt i kjøringen | S3b | umålt |
| A6 | Persona-manuset kan drive en Magentic-manager (ledger-JSON) offline | E1E6 brukte en `FakeClient` med gyldig ledger-JSON | **MÅLT mulig**; portering til `ScriptedChatClient` er S1/S3 |
| A7 | Utforskning som opt-in holder demo-transkriptet byte-uendret | `shasum` i E-tabellen | bygges slik; verifiseres per økt |
| A8 | 1.0.1 er API-identisk med 1.0.0 | S0 | umålt |
| A1 | Agent-nivå `ChatMiddleware` fyrer på managerens kall | S2 | **MÅLT GRØNN.** `BudgetMiddleware` på manager-agenten krediterer meteret (`meter.tokens == 8` etter ett kall) og stopper kjøringen. Detach-kontroll: uten middleware fullfører SAMME 1-token-budsjett. Planens budsjettgaranti står. |
| A2 | `BudgetExceeded` reist inni en Magentic-deltaker propagerer ut av `workflow.run` | S2 | **MÅLT GRØNN, og som repoets EGEN type** — ikke pakket i en `ExceptionGroup`: `isinstance(exc, BudgetExceeded)`, `kind="tokens"`, `limit=1`, `observed=8`. Trippelen kø-(y) leser er intakt, så 429-kanalen kan brukes uendret. |
| A3 | `request_info`-rundtur | S3 | **MÅLT GRØNN på 1.0.1.** Review stopper kjøringen uten output (manageren har da kun kalt `facts`+`plan`); `revise` koster nøyaktig 2 manager-kall (`facts_update`, `plan_update`), **null ledger-kall og null runder**, og **spør på nytt**; `approve` kjører løkka til sluttsvar. Bekrefter at `max_plan_revisions` MÅ inn i kontrakten — ellers er en alltid-reviderende ekspert et ubundet forbruk. |
| A4 | Resume med pending plan review i NY prosess | S4 | **MÅLT GRØNN.** Foreldreprosessen stopper på review og etterlater checkpoints; en subprosess (`spikes/e_magentic_resume.py`) som aldri så kjøringen svarer fra checkpointen alene og driver workflowen til sluttsvar. **Pris, ikke forutsett:** `FileCheckpointStorage` NEKTER å deserialisere `MagenticPlanReviewRequest`/`…Response` uten at begge navngis i `allowed_checkpoint_types` — uten det er checkpoint-fila uleselig og listingen TOM, altså en resume som feiler som et FRAVÆR. Begge prosesser må deklarere dem. |
| A5 | `AgentApprovalExecutor` som deltaker gir svar midt i kjøringen | S3b | **MÅLT GRØNN — dør 3 i C.6 står.** Ekspertens ord når både liaisonen og en senere manager-prompt. **To rundturer per menneskesvar:** `from_strings([svar])` mater svaret tilbake INN i liaisonen og gjenopptar IKKE manageren (målt: null manager-kall mellom de to forespørslene); først `approve()` sender liaisonens output videre. **Kostnad:** `AgentApprovalExecutor` er IKKE re-eksportert fra `agent_framework.orchestrations` (svartypen ER det) — døra koster i dag en privat-API-import. |
| A6 | Persona-manuset kan drive en Magentic-manager (ledger-JSON) offline | S1/S3 | **MÅLT GRØNN med repoets `ScriptedChatClient`** (ikke lenger en ad-hoc `FakeClient`). Ett forbehold funnet: selectoren får den SAMMENSLÅTTE prompten, så ett av fem manager-kall bærer to markører — rutingen må teste senere-stadium-markøren først. Og en `next_speaker` som ikke matcher en deltaker gir **stille sluttsvar uten at noen ble spurt** (`_magentic.py:1128-1131`), målt da liaison-spiken først het `worker`. |
| A7 | Utforskning som opt-in holder demo-transkriptet byte-uendret | `shasum` | **MÅLT uendret** gjennom hele økten (`ea8c534…`). |
| A8 | 1.0.1 er API-identisk med 1.0.0 | S0 | **MÅLT: API-identisk, ATFERD ikke.** Diffen er upstream-regresjonsfiksen #4371: `StandardMagenticManager.__init__` mistet `self._session = agent.create_session()`, og hvert manager-kall mynter nå en engangs-sesjon. **Konsekvens: E2 OG E4 er BORTE** (4/4 → **0/5** begge). E1 (single-use `RuntimeError`, null kall) og E7 (`MagenticResetSignal` skriver til orphan-attributtet `_agent_thread`, `:1369`, sesjonsidentitet uendret) står. Manager-sesjonen fjernet også fra checkpoint-state, konsistent med at manageren nå er tilstandsløs per kall. |
**Målt korreksjon til E-tabellen (U12/S4):** kriteriet «detach `checkpoint_storage` → rød» er
FEIL — å fjerne `checkpoint_storage=` fra `run()` lar HELE suiten stå grønn (920 passed), fordi
`.with_checkpointing(...)` på builderen allerede ga workflowen lageret. De to bærende punktene er
`checkpoint_id=` (fjernes → rød) og builderens `.with_checkpointing(...)` (fjernes → rød).
**Load-bearing MÅLT** (mot HELE suiten, grønn kontroll 920/5): `manager_keeps_persistent_session`
konstant `True` (2 røde — E2+E4 alene) · aldri fest `BudgetMiddleware` på manageren (3 røde, mens
detach-armen forblir grønn) · detach markør-registreringen (1 rød — S3b-positiven alene, kontrollen
grønn) · flipp `_route`-rekkefølgen så `pre-survey` testes først (4 røde) · resume uten
`checkpoint_id=` (1 rød) · builder uten `.with_checkpointing()` (1 rød) · tom
`_ALLOWED_CHECKPOINT_TYPES` (1 rød) · og den falsifiserte: resume uten `checkpoint_storage=` (**0
røde** — funnet over).
**S5 — `quick_validate`-latens: median 13,6 ms** over 20 kall på `bygg-energi-baseline-mikro`
(forankret baseline + assumption-bånd, så stage 0 + CBC + 512-sample Monte Carlo er alle med).
Langt under 2 s-terskelen: verktøyet kan kalles fritt i løkka, og kontrakten trenger ingen
egen latens-post. Båndet er med med vilje — uten det faller `_monte_carlo` tilbake på
`item.unit_cost`, alle draw blir identiske, og tallet ville underrapportert den ekte kostnaden.
**S6 — OTEL er gratis, men IKKE via `enable_console_exporters`.** I et scratch-venv pinnet til
samme stack (core 1.9.0 / orch 1.0.1 / `opentelemetry-sdk` 1.44.0; **ingenting lagt til
`pyproject.toml`**) gir `configure_otel_providers(enable_console_exporters=True)` **2
`workflow.run`-spans** — pluss `workflow.build`, `executor.process`, `edge_group.process`,
`message.send`, `invoke_agent`, `chat synthetic` — men de skrives til **stdout**, som ville
ødelagt golden-transkriptet. Med `exporters=[ConsoleSpanExporter(out=sys.stderr)]` kommer de 2
`workflow.run`-spanene på **stderr** og demoens stdout er **byte-identisk med fasiten** (samme
shasum). U14 er altså én økts arbeid — forutsatt at exporteren konstrueres eksplisitt mot stderr,
aldri via flagget.
**Beslutninger som trenger operatøren (speiles i avslutningsblokken):**
1. Versjon: bli på 1.0.x (anbefalt) vs. core-bump til 1.15 nå.
1. **Versjon — premisset har flyttet seg.** Ordrens «felles hvis» sa: står E7 i 1.0.1, revert til
1.0.0. E7 STÅR — men 1.0.1 viste seg å fikse noe større enn det som ble håpet: E2/E4, altså
«en plausibel fasit produsert av null arbeid». Låsen står derfor på **1.0.1** i påvente av
operatøren. Alternativene: bli på 1.0.1 (anbefalt) · revert til 1.0.0 etter ordrens bokstav ·
core-bump til 1.15 nå (egen økt).
2. U14 som deklarert avhengighet (`opentelemetry-sdk` + exporter) i wheel/handover — ja/nei.
3. HITL-leveranse: synkron-først (anbefalt, uansett S4) vs. asynkron som krav i samme plan.
3. HITL-leveranse: synkron-først (anbefalt) vs. asynkron i samme plan — **S4 grønn, så asynkron
er nå teknisk mulig**; valget er ren rekkefølge, ikke lenger risiko.
4. Commons-amendment «Step 0 — Explore» — sende forslag nå (anbefalt: ja, via coord, uten å vente).
---