portfolio-optimiser/docs/2026-09-04-major2-proposal-review-k2.md
Kjell Tore Guttormsen 38cbc2c8ac wip(major2): step 9 partial - M1..M37 measured [skip-docs]
Ordre 20260904T173146Z-8102814273-from-portfolio-optimiser, steg 9 PAABEGYNT.
Oektskifte ved soemmen paa operatoerens forespoersel (kontekst 50 pct).

Groenn kontroll: 1363 passed / 5 skipped. Node-ID-settet er et STRENGT SUPERSETT av
pre-MAJOR-2-baselinen (1319 -> 1368, 0 fjernet, 49 lagt til). ruff check / ruff format
--check / mypy rene. Golden demo-transcript.stdout BYTE-UENDRET, shasum -a 1 av INNHOLDET
= ea8c534773acdbe41ae68f2c55724d69aaf8be4f.

38 mutasjonskjoeringer utfoert (M1-M37, M26 delt i a/b), alle mot HELE suiten, maks to per
Bash-kall, restaurert fra scratchpad + shasum -c, aldri git checkout. Alle 38 rapporterte
restore=OK. 37 roede, 1 GROENN.

M29 FORBLE GROENN, og det felte et premiss i planen. Mutasjonen reverterer last_ruling-
baereren til `assert last is not None`, og hele suiten staar groenn: D1(a) gjoer at en revise
med attempts_remaining == 0 RETURNERER inne i loekka, og paa siste forsoek er remaining alltid
0 - saa loekka kan bare falle gjennom til halen etter en validator-AVVISNING, som setter `last`
ogsaa. Baereren er dermed UVITNET (budget_stop-presedensen), og planens "Critical risk #1" er
falsifisert. Kommentaren i generate.py som paastaar at asserten ville fyrt maa rettes i neste
oekt - den er en paastand flaten gjoer om seg selv (Fase-3-klassen).

To signaturer verdt aa lese: M13 og M23 er roede i tester ELDRE enn dette arbeidet (A5-ens
eksakte fire-navns-listing, parse-fangstens kontroll, Fase-4es to partisjons-asserts), og
M26a/M26b har ULIKE signaturer fordi sentinelen paa 31 tegn overlever 40-trunkeringen.

GJENSTAAR: M38, M39, M40; K2-omkjoeringen (kriterium 8, manuset er forberedt i
scratchpad/major2/scripted-replies-major2.json); hele steg 10.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 10:09:15 +02:00

11 KiB
Raw Blame History

MAJOR-2 — en dør for menneskelig tilbakemelding på forslaget som ligger på bordet

Status: DELVIS — steg 9 er påbegynt, ikke fullført. M1M37 er målt; M38, M39 og M40 gjenstår, og K2-omkjøringen (§ 3) er ikke kjørt. Steg 10 (invariantraden + README) er ikke skrevet. Dokumentet er committet i denne tilstanden fordi økten skiftes ved sømmen; neste økt fortsetter fra M38.

Måledato: 2026-09-05 (stien bærer ordredatoen, headeren måledatoen — S7b/S2c-formen) Ordre: 20260904T173146Z-8102814273-from-portfolio-optimiser Kode målt ved: ee7da3b (steg 18: ce4c15e · d4c8691 · bbf4d3b · 59f3fce · c391fb5 · fedf989 · bfc634d · ee7da3b)


0. Hva døra er

Spørsmål Før Etter
Kan et menneske svare på forslaget mens det ligger på bordet? nei ja — --proposal-review
Hvor mange menneske-sømmer finnes inne i løkka? 1 (plan_reviewer, som fyrer FØR enhver hypotese finnes) 2
Hva skjer med svaret? revise kjøper ETT forsøk til under det EKSISTERENDE taket; ordene når neste prompt ORDRETT
Hvem avgjør utfallet? validatoren validatoren — dens SISTE dom (D6)
Mynter en approve en dom? nei; F2 står
En kjøring uten reviewer byte-identisk: samme prompter, samme utboks-filer, golden uendret

Målt før arbeidet startet (docs/2026-09-02-misjonsreview-v2.md § 3, re-målt mot HEAD): grep -n "prior_" generate.py finner nøyaktig ÉN søm — prior_rejection, maskinens egen falsifisering matet tilbake inne i samme kjøring. Et menneskes dom lander i NESTE kjøring (Steg-7-innboksen). «Improved proposals given feedback» var altså, for en person, en to-kjørings løkke med dager imellom.


1. Løkkas exit-kontrakt — og et premiss målingen felte

FØR (generate.py ved bcf3337):

        if isinstance(result, ValidatedProposal):
            return GenerationResult(outcome=result, refinements=tuple(fed_back))
        last = result
    assert last is not None  # max_attempts >= 1, so at least one validation ran
    return GenerationResult(outcome=last, refinements=tuple(fed_back))

last settes KUN av en validator-avvisning. Planen (§ Risks, «Critical» #1) sa at «validert → revise» på hvert forsøk derfor ville nå slutten av løkka med last is None og dø på asserten.

ETTER: en eksplisitt bærer last_ruling: ValidatedProposal | Rejection | None, satt etter HVER validate_proposal; D6 leses rett av den.

⚠️ PLANENS PREMISS ER FALSIFISERT AV MÅLINGEN — M29 forble GRØNN (0 røde av 1363). Mutasjonen reverterer bæreren til assert last is not None, og HELE suiten står grønn. Grunnen er strukturell og ble først synlig da mutasjonen ble kjørt: D1(a) gjør at en revise med attempts_remaining == 0 returnerer den validerte dommen inne i løkka, og på siste forsøk er remaining = max_attempts - i - 1 alltid 0. Løkka kan derfor bare falle GJENNOM til halen etter en validator-avvisning, som setter last også. last_ruling og last er dermed identiske i det ene punktet halen leser dem.

Konsekvens, uttalt heller enn skjult: bæreren er UVITNET (budget_stop-presedensen). Den står fordi den gjør D6 eksplisitt og fjerner en assert som hviler på en ikke-lokal invariant — ikke fordi en test holder den. Kommentaren i generate.py som påsto at asserten ville fyrt er en påstand flaten gjør om seg selv (Fase-3-klassen) og må rettes i neste økt, sammen med commit-teksten for bbf4d3b som bærer samme påstand (historikken skrives ikke om; rettelsen står her og i invariantraden).


2. Mutasjonstabellen — M1M37 målt, M38M40 gjenstår

Grønn kontroll: uv run pytest -q1363 passed / 5 skipped. Node-ID-settet er et strengt supersett av pre-MAJOR-2-baselinen: 1319 → 1368, 0 fjernet, 49 lagt til. ruff check src tests, ruff format --check src tests og mypy src rene. Golden tests/golden/demo-transcript.stdout BYTE-UENDRET, shasum -a 1 av INNHOLDET = ea8c534773acdbe41ae68f2c55724d69aaf8be4f (ikke git-blob-id-en).

Protokoll per mutasjon: hele suiten, maks to mutasjoner per Bash-kall, restaurert fra scratchpad/major2/pristine/ og verifisert med shasum -c — aldri git checkout. Alle 38 kjøringer rapporterte restore=OK.

M hva mutasjonen gjør røde første navngitte armer uavhengige vitner
M1 detach reviewer-kallet (returner på validert som før) 16 T1, T2, T3a …
M2 ignorer beslutningen (alltid approve) 13 T1, T2, T3a …
M3 drop prior_feedback-injeksjonen (print-and-discard) 6 ordrett-armen, komposisjons-armen, T1 …
M4 tøm feedback etter ett forsøk (ikke-klebrig) 1 T6 alene
M5 akkumuler avvisninger i prompten 1 T6 alene
M6 vis også en AVVIST kandidat til revieweren 4 T4, T6, T10 …
M7 la en revise slippe å tikke rundeboka 1 T3a alene
M8 la revisjoner løkke UTENFOR max_attempts 36 A5, mandat, portefølje … ja — 18 testfiler, alle eldre enn dette arbeidet
M9 honoured konstant True (og ingen forfremmelse) 6 T2, T3a, T3b, T7 …
M10 approach_id alltid None 3 T5, T8, T5-run
M11 skriv artefaktet etter returen, ikke fra finally 2 T9, T16
M12 skriv artefaktet kun når lista er ikke-tom 2 T10, T16
M13 skriv artefaktet også uten reviewer 3 T11 jatest_a5_per_approach_artifacts, test_parse_failure_capture
M14 la en approve mynte en Verdict 1 T12 alene
M15 les EOF som approve 2 T16-unit, T16-CLI
M16 fang ikke ProposalReviewInputError ved navn 1 T16-CLI alene
M17 enhver ikke-revise-linje er approve 1 T15 alene
M18 drop single_only-raden 1 T17 alene
M19 drop report_forbidden-raden 1 T18 alene
M20 bibliotekssømmen wiret, argparse-flagget borte 9 T13, T16, T17 …
M21 strømmene bundet ved konstruksjon 1 T20 alene
M22 slett den hostede navngitte nekten 1 T21 alene
M23 videresend det hostede feltet i stedet for å nekte 4 T21, partisjons-armen ja — Fase-4e-armene i test_explore_callsites + test_hosting
M24 fersk reviewer per base i dispatcheren 1 T22 alene
M25 render kandidaten som repr 2 T14, T13
M26a trunker feedback til 20 tegn 5 T1, T3b, T8 …
M26b trunker feedback til 40 tegn (sentinelen OVERLEVER) 3 T1, T8, T13
M27 fall tilbake til siste validerte forslag (D6-alternativ b) 1 T13-loop alene
M28 drop verdict_key fra posten 2 payload-armen, run-payload-armen
M29 reverter exit-kontrakten til assert last is not None 0 — (se § 1)
M30 drop --live-dry-run-nekten 1 dry-run-armen alene
M31 drop --proposals-from-mandate-nekten 1 pfm-armen alene
M32 notice-rendereren skriver linja uten reviewer 2 notice-armen, CLI-kontrollen
M33 notice-rendereren returnerer None på null 3 notice-armen, null-armen, CLI-null-armen
M34 feedback løftet ut av per-approach-kallet (krysser tilnærminger) 5 T1, T7, T5-run …
M35 bygg posten fra en RETURNERT liste i stedet for kaller-eid sink 1 T9 alene
M36 dispatcheren slutter å tråde revieweren 1 T22 alene
M37 detach CLI-utskriften mens rendereren fortsatt returnerer linja 2 T13, CLI-null-armen
M38 attempts_remaining regnet fra max_attempts alene IKKE MÅLT
M39 drop --checkpoint-dir-nekten IKKE MÅLT
M40 honoured=True satt ved revise-tid i stedet for etter hentingen IKKE MÅLT

Sum så langt: 38 kjøringer, 37 røde, 1 grønn (M29).

To signaturer verdt å lese

  • M13 og M23 er røde i tester som er ELDRE enn dette arbeidet. «Skriv artefaktet iff en reviewer ble gitt» (D4) holdes av A5-ens eksakte fire-navns-listing og av parse-fangstens kontroll; den hostede partisjonen holdes av Fase-4es to asserts. Sømmene er altså gatet av uavhengige vitner, ikke bare av sine egne armer.
  • M26a og M26b har ULIKE signaturer, og det var ikke gitt. Ved 40 tegn overlever PROPOSAL-REVIEW-SENTINEL-9c41ae (31 tegn) i de armene hvis feedback er kortere enn taket, så T3b og T9 blir grønne igjen mens T1, T8 og T13 — de med lengre feedback — forblir røde. Planens to-lengde-skjerping virker altså etter hensikten her.

3. K2-omkjøringen — IKKE KJØRT

Kriterium 8 (S7b DEL-B-kommandoen over scratchpad/s7b-syretest/K2-priset-SYNTETISK pluss --proposal-review med et pipet revise/approve-manus, mot en approve-only-kontroll) gjenstår. Manuset er forberedt: scratchpad/major2/scripted-replies-major2.json bærer et FIRE-stegs proposer-manus (to tilnærminger × to forsøk), der annethvert steg oppgir 150 000 i stedet for 200 000, slik at «svaret ble BRUKT» er utfallet og ikke bare at en post finnes.

K2-basen er utracket og finnes kun på denne maskinen, så kriteriet er verifiserbart her og rapporteres — det asserteres aldri av suiten.


4. Ærlighets-grenser (så langt)

  • last_ruling-bæreren er uvitnet — se § 1. Planens «Critical risk #1» er falsifisert.
  • Steg 5 under-rapporterer på en revidert kjøring: en revise bruker ett av de SAMME max_attempts-forsøkene en validator-avvisning ville brukt, så en kjøring kan bruke opp forsøkene på ekspert-revisjoner og aldri nå en andre validator-falsifisering. refinements under-rapporterer da ved konstruksjon. Uttalt, ikke reparert.
  • coverage-radene navngir ikke en revise som årsak. Hver revise tikker den DELTE rundeboka, så en eksperts egne revisjoner kan la halen av en kommisjon stå not_evaluated. Detaljen forblir «budget exhausted before this approach was evaluated» — sann, og coverage er et non-goal. Terminalen viser attempts remaining FØR hvert svar, og review-posten er der årsaken kan leses.
  • Checker-gaten (6b) og dimensjons-gaten (6c) overstyrer ETTER at genereringen har returnert. En approve registrert ordrett i artefaktet kan derfor sitte på en kjøring hvis utfall er en checker-kildet Rejection. Posten sier hva mennesket SÅ og SVARTE, aldri hva kjøringen konkluderte; at de to er uenige er tilsiktet, og å blande dem er nøyaktig det to-falsifiserer-raden forbyr.
  • Feedback-teksten er UBEGRENSET, som plan-review-feedback — belastet max_tokens, som er bunden. At den når en proposer som holder navigatør-verktøyene er uttalt, ikke voktet.
  • F4s traceback-asymmetri er urørt: PlanReviewInputError forlater fortsatt CLI-en som en traceback, mens ProposalReviewInputError fanges ved navn. Uttalt, ikke fikset her.
  • run_portfolio tar ingen reviewer, og fraværet er assertert.
  • Ingen levende modell har svart på en review. Alt her er skriptede stand-ins (structured-output-grensens klasse).