docs(verdict-gate): maaleavsnittet og invariantraden - fem mutasjoner, fire tall verifisert

S2c § 6s fjerde aerlighets-grense er lukket, og BEGGE stedene den sto skrevet er
rettet: en invariantrad som fortsatt sier "MAALT, RAPPORTERT, IKKE FIKSET" om noe
som er fikset er en ledger som lyver, og S2c-raden i CLAUDE.md sa nettopp det.

docs/2026-09-04-s2c-debatt-k2.md § 8: premisset (2 883 tegn, prompt 1 og 3), hvor
regelen bor og hvorfor akkurat der, at den gatede doera er uroert, at en nektet
lesning er registrert, mutasjonstabellen og de fire verifiserte tallene.

CLAUDE.md: ny invariantrad; S2c-raden retter sin egen paastand.

Verifisert med kommandoer, ikke fra hukommelsen:
  suite            1314 passed / 5 skipped (fra 1306/5, +8, strengt supersett)
  golden           ea8c534773acdbe41ae68f2c55724d69aaf8be4f (INNHOLD, ikke blob)
  syretest doer    850 000 av 3 852 500, 3 av 5, stage 4 + stage 5
  syretest loekke  verdict key=be8535e204cdc4c6, 2 av 2
  mutasjoner       M1 4 roede - M2 1 - M3 1 - M4 3 - M5 4, alle mot HELE suiten

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-04 20:41:32 +02:00
commit bcf3337d8a
2 changed files with 146 additions and 11 deletions

View file

@ -1793,11 +1793,52 @@ Python ≥3.10. MAF (`agent-framework-core` 1.16.0, `-orchestrations` 1.1.1 —
dette manuset; et proposer-manus konsumeres PÅ NYTT av `generate_via_llm`s ferske klient, så et
manus som åpner med et verktøykall brenner genererings-forsøk (uttalt i loaderens docstring, ikke
reparert — å gjette hvilke steg som var «ment for» hvilket kallsted er reparasjon); den hostede
flaten er urørt; og **`read_file` er fortsatt sti-adresserbar til `type: verdict`-laget** — ingen
listing navngir det, men en gjettet sti når en dom utenom den gatede ExpeL-folden. Egenskapen er
ARVET fra S7a-3 og er nå nåbar fra debatten også: MÅLT, RAPPORTERT, IKKE FIKSET (én regel ett
sted, som også endrer utforskningen — egen beslutning). Måling:
`docs/2026-09-04-s2c-debatt-k2.md`.
flaten er urørt; og **`read_file` var sti-adresserbar til `type: verdict`-laget — LUKKET samme dag**
(raden under). Grensen sto her som MÅLT, RAPPORTERT, IKKE FIKSET, med begrunnelsen at å lukke
den er én regel ett sted som også endrer utforskningen, altså en egen beslutning; beslutningen
ble tatt. Måling: `docs/2026-09-04-s2c-debatt-k2.md`.
- **En dom nås gjennom ÉN dør, og `read_file` er ikke den — nekten leser DOKUMENTET, ikke gangen
(verdict-gaten, 04.09, ordre `20260904T172353Z`):** ingen listing navngir `type: verdict`-laget
(`Bundle.context_files` dropper det på hvert nivå, så verken `read_bundle`, `read_dir` eller
`bundle_context` nevner en dom), men en GJETTET sti nådde en — MÅLT: alle 2 883 tegn av
fixturens frø-dom, og i en debattkjøring nådde kroppen prompt 1 og 3. Egenskapen var ARVET fra
S7a-3 og ble nåbar fra debatten da S2c ga den navigatørens fire verktøy. Regelen bor i
`read_file` inne i `navigator_tools`, altså i ÉN kopi for BEGGE kallere — ikke i renderingen
(S2c målte selv at et filter som skjuler et dokument mens denne sprossen serverer bytene er «et
filter i navnet alene») og ikke i prompt-tekst (råd til en utrodd velger er ikke en gate).
**Predikatet er nøklet på det RESOLVERTE DOKUMENTETS frontmatter** (`okf.declares_verdict_type`),
aldri på navigasjonen: `Bundle.verdicts` svarer på «hvilke dommer nådde gangen» — riktig spørsmål
for ExpeL-frøene, feil her, fordi en dom ingen `index.md` lenker er fraværende fra gangen og
ville seilt rett gjennom (M2 → 1 rød, den armen ALENE). `_VERDICT_TYPE` er nå ÉN kopi av hva et
verdict ER (kø-(p)); tre flater svarer på det. **Gaten står FØR dimensjonssjekken**, fordi laget
nektes ubetinget og `dimension=None` er utforskningens EGEN kall — en gate etter den grenen ville
vært fraværende fra nøyaktig den kalleren den ble skrevet for (M5 → 4 røde).
`VerdictLayerRefused` er en `ValueError` (`DimensionScopeRefused`-presedensen: kalleren er en
modell som velger en sti, så nekten hører på CLI-ens nekt-tuppel og hostings 400-arm, aldri
krasj-kanalen). **Den GATEDE døra er urørt, og det er dét som skiller en gate fra en vegg:** en
egen arm kjører hele `run_project` og asserterer at `realiseringsgrad=0.82` fortsatt når
hypotese-prompten gjennom Steg-1-folden. **En nektet lesning er REGISTRERT, aldri stille**
recorderen appender FØR `await call_next()`, så kallet står i `RunResult.debate_tool_calls` og i
`{run_id}-debate.json` med sin sti; det er en EGEN gate og ikke en passasjer på nekten, MÅLT:
mutasjonen «registrer etter `call_next`» tømmer sporet for nøyaktig et nektet kall (`trace = ()`),
fordi invokasjonen aldri returnerer (M3 → 1 rød, den armen ALENE). Sideegenskap MÅLT: en nekt fra
et verktøy fanges av MAF og returneres som feilresultat til modellen — kjøringen fortsetter, og
`finally`-artefaktet skrives som før. Load-bearing MÅLT
(`tests/test_verdict_layer_refusal_loadbearing.py`, 8 armer), **fem mutasjoner alle røde mot HELE
suiten** + grønn kontroll **1314/5** (fra 1306/5; +8, ingen eksisterende testfil rørt, altså et
strengt supersett ved konstruksjon) og golden `demo-transcript.stdout` BYTE-UENDRET
(`shasum -a 1` av INNHOLDET = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): M1 detach gaten (4) ·
M2 gate på gangen (1) · M3 registrer etter `call_next` (1) · M4 gate på komplementet av
`context_files` (3 — hvorav TO eldre, UAVHENGIGE vitner: katalog-gatens «hele indeksen er ett
kall unna» og utforskningens byte-identitets-arm, altså er stigens toppsprosse gatet av tester
eldre enn dette arbeidet) · M5 gaten bak dimensjonsgrenen (4). Syretesten er UENDRET i utfall:
850 000 NOK validert av 3 852 500, 3 av 5, de to falne på stage 4 og stage 5, og hele løkka gir
fortsatt dom-nøkkel `be8535e204cdc4c6`. **Ærlighets-grenser, uttalt:** ingen LEVENDE modell har
prøvd den gjettede stien (structured-output-grensens klasse); gaten sitter på `read_file`, ikke
på filsystemet — en kaller som selv åpner en fil i basen utenom verktøyene er upåvirket; og
nekten er nøklet på den ENE erklærte typen ExpeL-folden eier, aldri på et bredere
«ikke i `context_files`»-komplement, som M4 viser ville rammet `index.md` — navigasjon, ikke en
dom. Måling: `docs/2026-09-04-s2c-debatt-k2.md` § 8.
- **STATE.md er local-only** (gitignored). Voyage session-state er efemert; STATE.md er kanonisk kontinuitet.
- Prosess: Voyage-plugin (`/trekbrief → /trekplan → /trekexecute → /trekreview`) per større fase.

View file

@ -202,12 +202,10 @@ MCP-kontrollen og den skriptede døra. Sømmen er altså vitnet fra flere uavhen
åpner med et verktøykall svarer derfor også genererings-kallet med et `function_call`, som ikke
parser. Det er uttalt i `_load_scripted_replies`' docstring og ikke reparert: å gjette hvilke
steg som var «ment for» hvilket kallsted er reparasjon, og denne loaderen validerer.
* **`read_file` er fortsatt sti-adresserbar til `type: verdict`-laget.** Ingen listing navngir det
(`context_files` dropper det ved konstruksjon), men en modell som gjetter en sti kan lese en
dom utenom den gatede ExpeL-folden. Egenskapen er ARVET fra utforskningen (S7a-3) og er derfor
ikke ny her, men den er nå nåbar fra debatten også. **MÅLT, RAPPORTERT, IKKE FIKSET** — å lukke
den er én regel ett sted (`read_file` nekter det ingen listing ville vist), og den endrer
utforskningens oppførsel også, altså en egen beslutning.
* **~~`read_file` er fortsatt sti-adresserbar til `type: verdict`-laget.~~ LUKKET 04.09** —
se § 8 under. Grensen sto her som MÅLT, RAPPORTERT, IKKE FIKSET, med begrunnelsen at å lukke den
er én regel ett sted som også endrer utforskningen, altså en egen beslutning. Den beslutningen
ble tatt samme dag (ordre `20260904T172353Z-6293121787`).
* **`--scripted-replies` tar nå steg-lister for debattens roller.** Nekten som forsvant hadde en
begrunnelse som nå er målbart usann (proposer og checker ER agenter med verktøy). Arm
`test_a_step_list_is_refused_for_a_debate_role` er SKREVET OM til sin positive, ikke slettet —
@ -231,3 +229,99 @@ uv run --with tiktoken==0.12.0 python scratchpad/s7b-syretest/profile_phases.py
# mutasjon nr. N mot hele suiten
uv run python scratchpad/s2c-debatt/mut.py M1
```
---
## 8. Tillegg 04.09 — verdict-laget nektes i `read_file`
Ordre `20260904T172353Z-6293121787`. § 6s fjerde ærlighets-grense er lukket: `read_file` nekter nå
ethvert dokument som erklærer `type: verdict`, **uansett hvordan stien ble funnet**.
### 8.1 Premisset, målt før noe ble skrevet
`read_file(bygg-energi-mikro, verdict-led-fro.md)` returnerte alle **2 883 tegn** av frø-dommen. I
en debatt-kjøring der proposer-manuset ber om den ved sti nådde kroppen **prompt 1 og 3**. Ingen
listing navngir fila — `Bundle.context_files` dropper laget på hvert nivå — så hullet var
utelukkende den gjettede stien.
### 8.2 Hvor regelen bor, og hvorfor akkurat der
I `read_file` inne i `explore.navigator_tools`, altså i **én kopi for begge kallere**:
utforskningen (`--explore`) og, siden S2c, debatten. Ikke i renderingen (§ 6s eget funn: et filter
som skjuler et dokument mens denne sprossen serverer bytene er «et filter i navnet alene») og ikke
i prompt-tekst (råd til en utrodd velger er ikke en gate).
To detaljer er bærende, og begge har sin egen mutasjon:
* **Predikatet leser DOKUMENTET, ikke gangen.** `okf.declares_verdict_type(sti)` leser den
resolverte filas frontmatter. `Bundle.verdicts` svarer på «hvilke dommer nådde navigasjonen» —
riktig spørsmål for ExpeL-frøene, feil spørsmål her: en dom ingen `index.md` lenker er fraværende
fra gangen og ville seilt rett gjennom en navigasjons-nøklet sjekk. `_VERDICT_TYPE` er nå ÉN
kopi av hva et verdict ER (kø-(p)); tre flater svarer på det.
* **Gaten står FØR dimensjonssjekken.** Laget nektes ubetinget, og `dimension=None` er
utforskningens egen kall — en gate plassert etter den grenen ville vært fraværende fra nøyaktig
den kalleren den ble skrevet for.
### 8.3 Den gatede døra er urørt
En nekt som også lukket ExpeL-folden ville sett identisk ut på hver nekt-arm og fjernet løkkas hele
læringsvei. Arm (3) kjører derfor hele `run_project` mot den ekte fixturen og asserterer at
`realiseringsgrad=0.82` fortsatt når hypotese-prompten. Dette er en gate, ikke en vegg.
### 8.4 En nektet lesning er REGISTRERT, aldri stille
`ExplorationToolRecorder` registrerer FØR `await call_next()`, så et nektet kall står i
`RunResult.debate_tool_calls` og i `{run_id}-debate.json` med sin sti. Det er en **egen** gate og
ikke en passasjer på nekten: mutasjonen «registrer etter `call_next`» tømmer sporet for nøyaktig et
nektet kall (målt: `trace = ()`), fordi invokasjonen aldri returnerer. En operatør som leser
artefaktet etter en betalt kjøring kan altså skille en kjøring som prøvde den ugatede døra fra en
som aldri gjorde det.
Målt sideegenskap: en nekt fra et verktøy fanges av MAF og returneres som feilresultat til
modellen — kjøringen fortsetter, og `finally`-artefaktet skrives som før.
### 8.5 Mutasjonsmålingen
Grønn kontroll **1314 passed / 5 skipped** (fra 1306/5; +8 = de åtte nye armene, ingen eksisterende
testfil rørt, altså et strengt supersett ved konstruksjon). Fem mutasjoner, alle røde mot HELE
suiten:
| # | mutasjon | røde | signatur |
|---|---|---|---|
| M1 | detach gaten | **4** | armene 1, 2, 4, 5 — ordrens test 1 og 2 blant dem |
| M2 | gate på gangen (`Bundle.verdicts`) i stedet for dokumentet | **1** | arm 5 ALENE — den ulenkede dommen |
| M3 | registrer etter `call_next` | **1** | arm 4 ALENE — spor-halvdelen er sin egen gate |
| M4 | gate på komplementet av `context_files` (rammer `index.md`) | **3** | arm 6 + TO eldre, uavhengige vitner |
| M5 | gaten flyttet bak dimensjonsgrenen | **4** | armene 1, 2, 4, 5 — fraværende for `dimension=None` |
M4s to uavhengige vitner er `test_catalogue_cost_loadbearing::test_the_full_index_is_still_one_call_away`
og `test_explore_loadbearing::test_an_exploration_leaves_the_knowledge_base_byte_identical` — stigens
toppsprosse er altså gatet av tester eldre enn dette arbeidet.
### 8.6 Uendret utfall, verifisert med kommandoer
* Golden `demo-transcript.stdout` BYTEUENDRET, `shasum -a 1` av **INNHOLDET** =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f` (ikke git-blob-id-en — S7a-3 pkt. 4).
* Syretesten, deterministisk dør: `850 000 NOK validert av 3 852 500`, 3 av 5 validert, de to
falne på stage 4 (P90 612 000) og stage 5 (`energy_efficiency`-cap 112 500). Identisk.
* Syretesten, hele løkka: `K2: ValidatedProposal (… verdict key=be8535e204cdc4c6)`, 2 av 2
tilnærminger validert. Identisk ned til dom-nøkkelen.
* `ruff check src tests` og `mypy src` rene.
### 8.7 Ærlighets-grenser for dette tillegget
* **Ingen levende modell har prøvd den gjettede stien.** Bevist er hva rammeverket nekter, ikke at
en modell ville forsøkt — structured-output-grensens klasse, som resten av dette dokumentet.
* **Gaten er på `read_file`, ikke på filsystemet.** En kaller som selv åpner en fil i basen utenom
verktøyene er upåvirket; regelen gjelder sømmen der bytene forlater verktøyet til en agent.
* **Andre lag enn `verdict` er urørt.** Nekten er nøklet på den ene erklærte typen ExpeL-folden
eier, ikke på et bredere «ikke i `context_files`»-komplement — som M4 viser ville rammet
`index.md`, som er navigasjon og ikke en dom.
### 8.8 Kommandoer
```bash
uv run pytest -q # 1314 passed / 5 skipped
shasum -a 1 tests/golden/demo-transcript.stdout # ea8c534773acdbe41ae68f2c55724d69aaf8be4f
bash scratchpad/mutate.sh M1 scratchpad/m1.py # mutasjon N mot HELE suiten
```