docs(major2): steg 9 fullfoert - M38..M40 roede, K2-omkjoeringen maalt, last_ruling-paastanden rettet

M38 (attempts_remaining fra max_attempts alene) 2 roede - T3a og T5, som BEGGE
navngir M38 i sin docstring; M39 (drop --checkpoint-dir-nekten) 1; M40
(honoured=True ved revise-tid) 2. Sum: 41 kjoeringer, 40 roede, 1 groenn (M29).

K2-omkjoeringen (kriterium 8), instrumentet validert mot en kjent positiv foerst
(3 954 tegn / 1 495 tok, S7a-3s tall reprodusert eksakt): utforskningen 12
prompter / 18 355 tokens UENDRET til tokenet, debatt-promptene uendret i antall
OG stoerrelse, genererings-promptene 2 -> 4. Totalt 17 -> 19 prompter,
19 274 -> 19 776 tokens (+2,6 %). Utfallet flytter seg 200 000 -> 150 000 NOK og
dom-noekkelen be8535e2 -> f23ecff8; ekspertens ord staar ordrett i 2 av 6
proposer-prompter (0 av 4 i kontrollen).

generate.py: kommentaren paasto at `assert last is not None` ville fyrt uten
baereren. M29 maalte at den ikke KAN - D1(a) returnerer inne i loekka naar
remaining == 0, og paa siste forsoek er max_attempts - i - 1 alltid 0, saa halen
er naabar kun etter en validator-avvisning, som setter `last` ogsaa. Baereren er
uvitnet (budget_stop-presedensen), og det staar naa i kilden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-05 20:39:52 +02:00
commit 74ea1dcf02
2 changed files with 132 additions and 27 deletions

View file

@ -1,14 +1,11 @@
# 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`)
> `c391fb5` · `fedf989` · `bfc634d` · `ee7da3b`); mutasjonene M1M40 og K2-omkjøringen er
> målt mot nøyaktig det treet (`shasum -c` grønn før og etter hver mutasjon)
> **Grønn kontroll:** 1363 / 5 under mutasjonsmålingen, 1364 / 5 etter README-armen i steg 10
---
@ -66,7 +63,7 @@ invariantraden).
---
## 2. Mutasjonstabellen — M1M37 målt, M38M40 gjenstår
## 2. Mutasjonstabellen — M1M40, ÉN liste
**Grønn kontroll:** `uv run pytest -q`**1363 passed / 5 skipped**.
Node-ID-settet er et **strengt supersett** av pre-MAJOR-2-baselinen: 1319 → 1368, **0 fjernet**,
@ -75,9 +72,14 @@ Golden `tests/golden/demo-transcript.stdout` **BYTE-UENDRET**, `shasum -a 1` av
`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
`scratchpad/major2/pristine/` og verifisert med `shasum -c` — aldri `git checkout`. Alle 41
kjøringer rapporterte `restore=OK`.
**Nevneren, med enhet:** M1M40 er **40 mutasjons-ID-er**, men M26 er sjekket i TO lengder
(M26a/M26b, planens funn-1-skjerping), så måleprotokollen er **41 KJØRINGER**. Av dem er **40
røde og 1 grønn** (M29). Begge tellemåtene er sanne; dokumentet teller i KJØRINGER hele veien,
og `coord-send`-rapporten gjør det samme.
| 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 … | — |
@ -118,18 +120,23 @@ kjøringer rapporterte `restore=OK`.
| 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** | — |
| M38 | `attempts_remaining` regnet fra `max_attempts` alene | 2 | T3a, T5 | — |
| M39 | drop `--checkpoint-dir`-nekten | 1 | park-armen alene | — |
| M40 | `honoured=True` satt ved revise-tid i stedet for etter hentingen | 2 | T3b, T9 | — |
**Sum så langt: 38 kjøringer, 37 røde, 1 grønn (M29).**
**Sum: 41 kjøringer (40 mutasjons-ID-er), 40 røde, 1 grønn (M29).**
### To signaturer verdt å lese
### Tre 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.
* **M38 er rød i TO armer, og begge NAVNGIR den.** T3a («no exception, exactly two calls»
under `max_rounds=2`/`max_attempts=10`) og T5 (terminalen viser `attempts_remaining == 0` under
`max_rounds=1`/`max_attempts=3`) er de to sidene av den samme ledger-bevisste `min(...)`: den
ene måler at løkka STOPPER der boka slutter, den andre at TALLET operatøren leser sier det
samme. Det ble VERIFISERT i docstringene, ikke antatt ut fra at armene lå i samme fil.
* **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
@ -137,22 +144,108 @@ kjøringer rapporterte `restore=OK`.
---
## 3. K2-omkjøringen — IKKE KJØRT
## 3. K2-omkjøringen — kriterium 8
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.
Samme base, samme syntetiske prisfikstur og samme instrument som S7b § 3 og S2c § 3:
`scratchpad/s7b-syretest/K2-priset-SYNTETISK` (630 konseptfiler, erklært id `k2-trinn1-20260903`
mot monteringsnavnet — S7a-3-slakken fyrer, og kjøringen sier det). K2-basen er **utracket og
finnes kun på denne maskinen**, så kriteriet er verifiserbart her og rapporteres; det asserteres
aldri av suiten.
K2-basen er **utracket og finnes kun på denne maskinen**, så kriteriet er verifiserbart her og
rapporteres — det asserteres aldri av suiten.
**Instrumentet er validert mot en KJENT POSITIV FØR bruk:** rotnivå-listingen på LEVERT K2 måles
til **3 954 tegn / 1 495 o200k-tokens over 629 konsepter**, som reproduserer S7a-3s publiserte tall
eksakt. Uten den kontrollen ville et lavt ETTER-tall like gjerne betydd at sonden var i stykker
(MAJOR-3s falske null).
---
### 3.1 De to kjøringene
## 4. Ærlighets-grenser (så langt)
Manuset (`scratchpad/major2/scripted-replies-major2.json`) gir proposeren FIRE steg — to
tilnærminger × to forsøk, der annethvert oppgir **150 000** i stedet for **200 000**. Manus-
posisjonen er delt over kjøringen, ikke per tilnærming (målt), så kontrollen og den reviderte
kjøringen leser den samme lista fra hver sin ende.
```bash
# KONTROLL — samme flagg, samme manus, bare et annet SVAR
printf 'approve\napprove\n' | uv run portfolio-optimiser K2 \
--docs-dir scratchpad/s7b-syretest/K2-priset-SYNTETISK \
--bundle-dir scratchpad/s7b-syretest/K2-priset-SYNTETISK \
--derive-cost-baseline \
--explore "Finn kostnadsbesparelser i Stange skole-anbudet" \
--explore-config scratchpad/s7b-syretest/explore-config.json \
--scripted-replies scratchpad/major2/scripted-replies-major2.json \
--outbox-dir scratchpad/major2/outbox-control --run-id major2-control \
--proposal-review
# REVIDERT — to revise, to approve
printf 'revise Bruk 150 000, ikke 200 000\napprove\nrevise Bruk 150 000, ikke 200 000\napprove\n' | ...
```
**Kontrollen er approve-only, ikke «uten flagget».** Det isolerer SVARET: begge kjøringene har
døra, samme manus og samme budsjett, så alt som skiller dem er hva mennesket sa.
### 3.2 Utfallet flytter seg
| | KONTROLL (approve ×2) | REVIDERT (revise/approve ×2) |
|---|---|---|
| review-spørsmål | 2 over 2 kandidater | **4 over 2 kandidater** |
| `hypothesis-1` | VALIDERT 200 000 NOK | **VALIDERT 150 000 NOK** |
| `own-proposal` | VALIDERT 150 000 NOK | VALIDERT 150 000 NOK |
| kjøringens utfall | best **200 000** NOK | best **150 000** NOK |
| dom-nøkkel | `be8535e204cdc4c6` | **`f23ecff85f4188b5`** |
| `attempts remaining` vist | 2 | 2, så **1** på forsøk to |
Begge kjøringene ender rc 0 med `ValidatedProposal`. Validatorens dom er ikke overstyrt av noen —
det er en ANNEN kandidat som ble dømt, fordi mennesket kjøpte ett forsøk til.
### 3.3 Prisen: én ekstra genererings-prompt per tilnærming
| fase | prompter (kontroll) | tokens | prompter (revidert) | tokens |
|---|---|---|---|---|
| 1 — utforskning (navigatør 5, manager 6, hypotesiser 1) | 12 | 18 355 | 12 | **18 355** |
| 2a — debatt (proposer 2, checker 1) | 3 | 513 | 3 | **513** |
| 2b — generering | 2 | 406 | **4** | 908 |
| **sum** | **17** | **19 274** | **19** | **19 776** |
**Utforskningen er uendret til tokenet**, og debatt-promptene er uendret både i antall og i
størrelse (proposer 314, checker 199 i begge). Hele forskjellen er de **to ekstra
genererings-promptene** — én per tilnærming, nøyaktig dét en `revise` kjøper. **+502 tokens, +2,6 %**
for en kjøring der et menneske faktisk endret utfallet.
Klassifiseringen debatt/generering er MÅLT, ikke antatt: genererings-prompten bærer
`Project: {id} - {name}` (`generate._build_messages`), debatt-turen bærer basepekeren.
### 3.4 Ordene når fram — ORDRETT
`Bruk 150 000, ikke 200 000` står i **2 av 6** proposer-prompter i den reviderte kjøringen og i
**0 av 4** i kontrollen — altså nøyaktig i de to andre-forsøks-promptene, og ingen andre steder.
`scratchpad/major2/outbox-revise/major2-revise-proposal-reviews.json`:
```json
{"approach_id": "hypothesis-1", "attempt": 0, "decision": "revise",
"feedback": "Bruk 150 000, ikke 200 000", "honoured": true,
"p50": 319311.8986090132, "verdict_key": "be8535e204cdc4c6"}
{"approach_id": "hypothesis-1", "attempt": 1, "decision": "approve", "feedback": "",
"honoured": true, "p50": 319311.8986090132, "verdict_key": "f23ecff85f4188b5"}
```
Posten er nøklet per `(approach_id, attempt)` og bærer `verdict_key` for den kandidaten mennesket
faktisk SÅ — attempt 0 navngir 200 000-kandidaten, attempt 1 den kjøringen endte på. Kontrollens
artefakt har to rader, begge `approve` med tom feedback: **fila skrives uansett, fordi en reviewer
ble gitt** (D4).
**Ærlighets-grense på nettopp dette manuset:** den skriptede proposeren LESER ikke feedbacken — den
returnerer steg 2 uansett. Det som er målt her er derfor (a) at ordene når prompten ordrett, (b) at
et forsøk til faktisk ble kjøpt og hentet (`honoured: true`), og (c) at kjøringen bærer validatorens
dom på DET forsøket. At en levende modell ville korrigert seg etter ordene er ikke vist, og kan
ikke vises av et manus.
## 4. Ærlighets-grenser
* **`last_ruling`-bæreren er uvitnet** — se § 1. Planens «Critical risk #1» er falsifisert.
Kommentaren i `generate.py` som påsto at asserten ville fyrt er RETTET i samme commit som dette
dokumentet; commit-teksten for `bbf4d3b` bærer fortsatt den gamle påstanden, og historikken
skrives ikke om.
* **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
@ -173,3 +266,9 @@ rapporteres — det asserteres aldri av suiten.
* **`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).
* **K2-prisene er SYNTETISKE**, og manuset er skriptet: null modellkall, banneret sier det på hver
kjøring. Det som er vist er at maskineriet kommer HELT fram med et menneske i løkka, ikke hva et
tilbud koster. Multiplikatorene i § 3.3 gjelder dette manuset.
* **README-armen har intet M-nummer** — M-lista lukket ved M40. Den ble drevet rød to ganger
(manglende blokk, og blokk uten `--checkpoint-dir` navngitt), og kontrollen på at uttrekkeren
ikke stille finner ingenting er `--plan-review`-blokka.