portfolio-optimiser/docs/2026-09-02-f15-maf-pinnen.md
Kjell Tore Guttormsen ef2f1cbe61 fix(maf): en vakt som gikk inert i STILLHET, funnet ved aa loefte pinnen (F15, ORDRE 20260829T155150Z)
MAF core 1.9.0 -> 1.16.0, orchestrations 1.0.1 -> 1.1.1. De to kan ikke loeftes
hver for seg: orchestrations 1.1.1 krever selv core>=1.15.0.

Iron Law: vakt-testen kjoert ROED mot 1.9.0 (2 failed) FOER pinnen ble roert.
Gulvet bor i EN konstant og pyproject-asserten deriverer sin streng fra den.

NEVNER: 16 private/ugaranterte former, derivert fra repoets EGNE siteringer,
alle 16 sjekket mot begge versjoner, 2 endret seg. Kjent-positiv: MiddlewareFailure
flippet NO -> YES. KP-kandidaten _compaction.py ble FORKASTET (teller 0 i begge,
diskriminerer ingenting).

DEN FARLIGE ENDRINGEN er den ordren navnga - formen som fortsatt importerer, men
har flyttet semantikk i stillhet. En park skriver naa TO checkpoints og bare EN
baerer plan-review-typen, saa en feildeklarert _ALLOWED_CHECKPOINT_TYPES toemmer
ikke lenger listingen: den taper nOEyaktig den checkpointen som betyr noe,
get_latest returnerer den ANDRE, og _parks `latest is None`-vakt passerte mens
kjOEringen svarte rc=0 og skrev et spOErsmaal som aldri kan baere svaret. Vakten
sjekker naa EGENSKAPEN den alltid mente (request_id in pending_request_info_events
- et DEKLARERT felt) i stedet for symptomet som pleide aa innebaere den, og fjerner
dermed en privat avhengighet i stedet for aa legge til en.

ExperimentalWarning-paret P4 pkt. 2 betalte for aa BEHOLDE er borte fordi MAF
sluttet aa sende det: _feature_stage.py emitterer ved FOERSTE BRUK, ikke ved import.
Goldenens stderr regenerert som BESLUTNING (fire -> to linjer); site-packages-
maskeringen BEHOLDT (spannet er ubebodd, ikke pensjonert).

Load-bearing MAALT mot HELE suiten, gronn kontroll 1089/5, stdout BYTE-UENDRET
(ea8c534773acdbe41ae68f2c55724d69aaf8be4f): M1 revert av vakten -> 1 rod.
EN mutasjon ble IKKE rod og staar som aerlighets-grense, ikke som gate: spikens
checkpoint_ids[-1] er rekkefolge-avhengig (Path.glob), altsaa flaky.

Rapport: docs/2026-09-02-f15-maf-pinnen.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 19:35:49 +02:00

11 KiB
Raw Blame History

F15 — MAF-pinnen løftet 1.9.0 → 1.16.0

Ordre: 20260829T155150Z-30491335-from-.claude (operatørbeslutning 29.08: operatøren betaler for F15 nå; F3 og F16 TIER 2 er UTSATT og er ikke rørt her). Grunnlag: MAF-gjelden — omfang § 2. Hvert tall under kommer fra en kommando kjørt i denne økten.

0. Resultat

agent-framework-core 1.9.0 → 1.16.0
agent-framework-orchestrations 1.0.1 → 1.1.1 (krever selv core>=1.15.0 — de to gulvene kan ikke løftes hver for seg)
agent-framework-foundry / -openai 1.8.2 / 1.8.2, uendret (målt etter uv sync)
Ny transitiv msgspec 0.21.1
Testsuite 1089 passed / 5 skipped / 0 failed (før: 1087 passed + 2 failed = samme 1089 ikke-skippede; ingen test tapt eller lagt til)
uv run ruff check . All checks passed
uv run ruff format --check . 187 files already formatted
uv run mypy src Success, 34 source files
Golden demo-transcript.stdout BYTE-UENDRET, ea8c534773acdbe41ae68f2c55724d69aaf8be4f
Golden demo-transcript.stderr REGENERERT — fire linjer → to. Beslutning, ikke rydding; se § 3

1. Iron Law — vakten var rød først

tests/test_maf_version_guard.py er testen. Diffen som løfter gulvet til 1.16.0 lå uncommittet i treet fra en tidligere økt, og ble kjørt rød mot 1.9.0 før pinnen ble rørt:

2 failed, 2 passed  (test_installed_maf_version_is_supported, test_pyproject_pins_...)

Gulvet bor nå i én konstant (_MIN_VERSION), og pyproject-asserten deriverer sin forventede streng fra den — to literaler for ett faktum drifter (kø-(p)), og et driftet gulv er en vakt som slutter å vokte uten én lokal diff. Etter bumpen: 4 passed.

2. Nevner-disiplin — tre tall

16 distinkte private/ugaranterte MAF-former leaner po på. 16 sjekket (19 mekaniske sjekker). 2 endret seg.

Inventaret er derivert fra repoets egne siteringer, ikke oppfunnet: hver underscore-modul- referanse i src/ (grep -rnoE "_[a-z_]+\.py:[0-9-]+" src/) pluss hver MAF-form en søm faktisk overstyrer eller konstruerer. Instrumentet (probe.py) kjørte mot BEGGE versjoner; det er efemert og bor ikke i repoet.

Form 1.9.0 1.16.0
P1 BaseChatClient._inner_get_response kw-only (messages/stream/options) OK OK
P2 BaseChatClient._build_response_stream OK OK
P3 …_magentic:MagenticPlanReviewRequest (allowlist-streng) OK OK
P4 …_magentic:MagenticPlanReviewResponse (allowlist-streng) OK OK
P5 strengt stall-sjekk stall_count > max_stall_count OK OK
P6 reset-sjekk reset_count >= max_reset_count OK OK
P7 next_speaker not in _participant_registry.participants-fallback OK OK
P8 nøyaktig ÉN ctx.request_info i _magentic.py OK (1) OK (1)
P9 is_request_satisfied på ledgeren OK (8) OK (8)
P10 list_checkpoints svelger blokkert type til logger.warning OK OK (men se § 4)
P11 get_latest velger på timestamp · P11b allowed_checkpoint_types= OK OK
P12 runner matcher på graf-signatur OK OK
P13 …_base_group_chat_orchestrator + reached max_rounds-meldingen OK OK
P14 extend_instructions to-arg GA-signatur (_sessions.py) OK OK
P15 console-exportere gatet på flagget · P15b ENABLE_INSTRUMENTATION OK OK
P16 ExperimentalWarning-emisjonen goldenen pinner 2 linjer 0 linjer — ENDRET
Checkpoint-antallet per park (ikke i proben — fanget av suiten) 1 lesbar 2 — ENDRET

Kjent-positiv (L93): proben KAN oppdage en endret form. MiddlewareFailure (ny i 1.15.0) er en delta målt uavhengig i § 2 av omfangsdokumentet. Kontrollen flippet NO → YES over bumpen. Den andre kandidaten, _compaction.pys @experimental-markører, er forkastet som kjent-positiv: den teller 0 i BEGGE versjoner, altså diskriminerer den ingenting — målt, ikke antatt.

Ærlighets-grense, uttalt: proben sjekker FORMER. Den mest konsekvensrike endringen (§ 4) var usynlig for den og ble fanget av testsuiten. En form-probe er gulvet, ikke beviset — nevneren over skal leses som «16 former sjekket mekanisk», ikke «alt som kunne endre seg er sjekket».

3. Golden stderr — regenerert som beslutning

Målt: null ExperimentalWarning fyrer på import under 1.16.0, mens @experimental-dekoratørene fortsatt FINNES i treet (3 i _skills.py, 5 i _harness/_memory.py). Verifisert mot exit-status (import portfolio_optimiser → rc 0, IMPORT-OK) før det negative resultatet ble lest som et faktum.

Rotårsak, lest ut av kilden: _feature_stage.py:411 bruker _add_runtime_warning(...) — 1.16.0 emitterer advarselen ved første bruk, ikke ved dekorering/import. Demoen instansierer verken SkillResource eller MemoryStore, så de to linjene sluttet å bli sendt oppstrøms. De ble aldri dempet av oss.

Fasiten er derfor regenerert fra en faktisk kjøring gjennom den uendrede normalisereren: fire linjer → to (blanklinje + arbeidskopi:). stdout er byte-uendret, og test_normalisation_does_not_mask_a_new_warning er fortsatt grønn — P4 pkt. 2s garanti om at en NY advarsel når stderr står. Span 1 (site-packages-maskeringen) er beholdt: spannet er ubebodd, ikke pensjonert, og en advarsel som kommer tilbake skal fortsatt felle pinnen med stien maskert.

Påstandene om «fire linjer» er rettet der de er LEVENDE (tracing.py, test_tracing_loadbearing.py, test_explore_loadbearing.py, test_golden_transcript_loadbearing.py, CLAUDE.md ×3, og operatørens docs/plan/2026-08-12-demo-runbook.md). De daterte plan-/reviewdokumentene er historikk og er IKKE omskrevet.

4. Den farlige endringen — en vakt som gikk inert i stillhet

Ordren ba spesifikt om formen som «fortsatt IMPORTERER men har endret SEMANTIKK i stillhet». Det er denne, og den traff en load-bearing garanti:

Målt: under 1.16.0 skriver én park TO checkpoint-filer. Bare den ene bærer plan-review-typen. Med en feildeklarert _ALLOWED_CHECKPOINT_TYPES blir derfor listingen ikke lenger tom — den taper nøyaktig den checkpointen som betyr noe, get_latest returnerer den ANDRE, og explore._parks vakt (latest is None) passerte. Kjøringen svarte rc=0 og skrev et spørsmål som peker på en checkpoint som aldri kan bære svaret: nøyaktig den døde spørsmålsfila laget finnes for å nekte, nå stille.

Per-fil-måling (samme park, samme katalog):

fil FULL allowlist TOM allowlist
76ac52bf… (bærer forespørselen) ok BLOCKED
b3fe53b7… ok ok

Fiksen tester egenskapen den alltid mente, ikke symptomet som pleide å innebære den: vakten sjekker nå at checkpointen den navngir faktisk bærer DENNE forespørselen, mot det deklarerte feltet WorkflowCheckpoint.pending_request_info_events — ikke mot den private, emergente «blokkert ⇒ tom listing»-oppførselen. Det fjerner en privat avhengighet i stedet for å legge til en.

if latest is None or str(request.request_id) not in latest.pending_request_info_events:
    raise CheckpointUnreadable(...)

Load-bearing MÅLT mot HELE suiten, grønn kontroll 1089/5: M1 — reverter vakten til latest is None: 1 rød (test_a_park_with_no_readable_checkpoint_refuses_instead_of_writing_a_dead_question), restaurert og shasum -c OK.

Checkpoint-formen verifisert med FAKTISK KJØRING, ikke import: tests/test_async_plan_review_loadbearing.py (19 tester) driver park → spørsmålsfil → svarfil → resume i en fersk interpreter, og er grønn. Det er den kjøringen ordren ba om.

5. Spiken traff den samme fella — og gaten er ÆRLIG svakere enn M1

spikes/e_magentic.py gjenopptok fra checkpoint_ids[-1] — SISTE element i en glob-ordnet listing, nøyaktig det explore._parks egen docstring advarer mot. Med to checkpoints døde resumen på RuntimeError: No pending requests found in workflow context. Spiken velger nå den checkpointen som bærer forespørselen, som produksjonen.

MÅLT, og det motsier det jeg antok: mutasjonen som setter [-1] tilbake ble IKKE rød (1089 passed). Feilen er rekkefølge-avhengig (Path.glob) — den ble observert rød i den første fullkjøringen etter bumpen og grønn med samme effektive valg her. Spikens gamle form er altså flaky, ikke deterministisk gal, og fiksen står på den observerte feilen pluss fjerningen av et dokumentert anti-mønster — ikke på en gate. Sagt høyt fordi en mutasjon som ikke ble rød ikke er et bevis, og å presentere den som ett ville vært den vakuøse gaten dette repoet teller instanser av.

6. Fant IKKE, og bygde IKKE

  • Ingen F3. Ingen F16 TIER 2. Utsatt av operatøren; ikke rørt, ikke forberedt.
  • Ingen publisering, ingen push, ingen release.
  • README-ens hosting-begrunnelse mistet sitt premiss og er RETTET, ikke gjenåpnet: agent-framework-foundry-hosting krever core>=1.13.0, og treet låser nå 1.16.0 — så versjonsgrunnen til stdlib-serveren er borte. Om pakka skal adopteres er et ÅPENT spørsmål denne bumpen bevisst ikke gjenåpner; det som er målt og shippet er fortsatt stdlib-serveren.
  • Ordrens steg 0 om STATE-linjen er en no-op: git stash list er tom OG STATE.md:20 sier allerede at den er tom. Linje 36 er en sann historisk merknad om økt 73. Det var ingenting å rette, og det sies her i stedet for å produsere en kosmetisk endring.

7. Verifiseringslogg

# Påstand Kommando
1 Vakten rød på 1.9.0 før pinnen uv run pytest tests/test_maf_version_guard.py -q → 2 failed
2 Installerte versjoner etter bump importlib.metadata.version(...) → core 1.16.0, orch 1.1.1, foundry/openai 1.8.2
3 16 former / 19 sjekker, begge versjoner probe.py mot 1.9.0 (0 CHANGED) og 1.16.0 (1 CHANGED)
4 Kjent-positiv virker KP1 MiddlewareFailure NO → YES
5 Kjent-positiv-kandidat forkastet KP2 _compaction.py @experimental = 0 i begge
6 Advarslene borte, ikke import-feil python -c "import portfolio_optimiser" → rc 0 + warnings.catch_warnings → 0
7 Rotårsak _feature_stage.py:411 _add_runtime_warning
8 To checkpoints, én bærer forespørselen per-fil decode_checkpoint_value med FULL vs TOM allowlist
9 M1 rød, restaurert full suite → 1 failed; shasum -c OK
10 M2 ikke rød full suite → 1089 passed
11 Grønn kontroll + de tre portene pytest 1089/5 · ruff check · ruff format --check · mypy src
12 stdout byte-uendret shasumea8c534773acdbe41ae68f2c55724d69aaf8be4f
13 Demoens stdout fortsatt 61 linjer python -m portfolio_optimiser.simulation | wc -l → 61