feat(prepass,explore): padding dies at the prompt; a refusal the model can act on is a return value [skip-docs]
Order 20260908T195801Z. Findings 4 and 5 from the S7 acid test, then the two things finding 99 measured and deliberately did not fix (D3, D2). No user-facing surface changes: no new flag, no new command, no changed output contract. Both seams are internal (the pre-pass rendering, and the shape a tool answers a model with), so [skip-docs] rather than a README edit that would describe nothing an operator can do differently. FINDING 4 -- MEASURED, NOTHING BUILT. K2's price schedule IS readable without guessing (8 column spans, 71 of 91 non-blank rows give >= 2 cells, the split stable for K = 2..64). But 0 of 92 rows name all three of code/quantity/unit_cost -- also under a looser substring match -- and 0 of 91 data rows carry code + quantity + amount. The triple is not formatted away; it is not in the document. It is a price SUMMARY plus nine rate cards whose unit-price columns are empty (pre-award). The order's binding decision rule therefore falls against building: --derive-cost-baseline keeps refusing, and MAJOR-4's own honesty limit holds. FINDING 5 -- BUILT. Measured on the actual rendering path (concept_text, not the raw file): the delivered excerpt is 104 lines / 67 245 chars, carrying 208 interior whitespace runs, 117 of them >= 100 and the longest 887 -- 56 806 of 67 245 characters = 84.5 %, over 72 of 104 lines. collapse_padding, called from _data_blocks (the one renderer both arms share, and therefore AFTER verify_against_bundle -- collapsing in concept_text would break every payload's own digest), gives -72.4 %: line count invariant, non-whitespace byte-identical, leading indentation untouched, no number changed. F99-D3 -- read_file / read_dir / read_bundle now RETURN their refusal. MAF turns a tool raise into "Error: Function failed." (_tools.py:1410-1432, :1427) and counts it against DEFAULT_MAX_CONSECUTIVE_ERRORS_PER_REQUEST = 3, so everything the refusing arm knows is destroyed on the way out. The gates are unchanged; the property they exist for -- the reason travels, the bytes never do -- is now asserted explicitly on the returned value. The arm is keyed on named classes, never bare Exception, because ExplorationError is itself a RuntimeError subclass. F99-D2 -- the invariant row, plus one for finding 5 (a stated deviation from "one row only": finding 5 is a separately built seam and the ledger's standing rule requires its own row). 19 existing arms rewritten, never deleted and never weakened: where the class carried a distinction, the refusal KIND carries it now. 13 mutations, all red against the whole suite (W1-W5, M1-M8), each restored from scratchpad with shasum -c. Control 1543 passed / 5 skipped (from 1529/5, a strict superset, 0 removed). Golden demo-transcript.stdout unchanged (shasum -a 1 of the CONTENT = ea8c534773acdbe41ae68f2c55724d69aaf8be4f). Measurement: docs/2026-09-08-funn-4-5-og-read-nekt.md Co-Authored-By: Claude <Opus 5>
This commit is contained in:
parent
078a099898
commit
eb4137415c
13 changed files with 975 additions and 69 deletions
333
docs/2026-09-08-funn-4-5-og-read-nekt.md
Normal file
333
docs/2026-09-08-funn-4-5-og-read-nekt.md
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
# Funn 4 og 5 fra S7, og nekten som ble en returverdi
|
||||
|
||||
**Ordre:** `20260908T195801Z-819715425-from-.claude` · **Økt 107** · 2026-09-08
|
||||
**Kontroll før arbeidet:** 1529 passed / 5 skipped · **etter:** 1543 / 5 (strengt supersett, 0 fjernet)
|
||||
**Golden `demo-transcript.stdout`:** `shasum -a 1` av INNHOLDET = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`, UENDRET
|
||||
**Ingen betalt kjøring.** Begge funn er formspørsmål og er målt offline.
|
||||
|
||||
## 0. Premissene, verifisert før noe ble bygget
|
||||
|
||||
| Premiss (PM målte 08.09 ~21:1xZ) | Verifisert her | Utfall |
|
||||
|---|---|---|
|
||||
| HEAD `078a099`, `origin/main` = `4f23fa2` → UPUSHET = 1 | `git log -1`, `git ls-remote origin main`, `git log origin/main..HEAD \| wc -l` | **BEKREFTET.** STATEs linje 47 («UPUSHET = 3 / `648b36e`») var foreldet og er slettet |
|
||||
| Prisskjema-fila 118 linjer / 101 188 B på disk | `wc -l -c` | **BEKREFTET** (`wc -l` teller 118 newlines; fila har 119 linjer inkl. den tomme siste) |
|
||||
| Det leverte utdraget 104 linjer / 67 245 tegn (S7c § 5) | `prepass.concept_text` på råfila | **BEKREFTET, og de to nevnerne avstemt** — se § 2.1 |
|
||||
| Deriveren nekter på K2 | `okf.derive_cost_baseline`s regel lest i kilden | **BEKREFTET, og årsaken målt** — se § 1 |
|
||||
|
||||
---
|
||||
|
||||
## 1. FUNN 4 — er formen leselig UTEN å gjette?
|
||||
|
||||
### 1.1 Formen, målt
|
||||
|
||||
Fila er ÉN pandoc SIMPLE table. Overskriftsraden (linje 18) navngir **én** celle, `Prisskjema`.
|
||||
Dash-raden (linje 19) definerer derimot **8 kolonne-spenn** (lengder 594 · 124 · 32 · 31 · 2 · 102 ·
|
||||
102 · 33) — altså er sju av åtte overskriftsceller TOMME.
|
||||
|
||||
Nevner: **99 linjer** under dash-raden, hvorav **91 ikke-blanke**.
|
||||
|
||||
Span-slicet med nøyaktig de spennene deriveren selv bruker, fordeler ikke-tomme celler seg slik:
|
||||
|
||||
| kolonne | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| ikke-tomme celler | 77 | 27 | 5 | 31 | 0 | 14 | 51 | 1 |
|
||||
|
||||
**Formen ER leselig uten å gjette.** 71 av 91 ikke-blanke rader gir ≥ 2 identifiserbare celler, og
|
||||
splitten er stabil: med mellomrom-løp ≥ K gir K = 2, 4, 8, 16, 32 og 64 alle 31 to-felts og 36–39
|
||||
tre-felts rader; først ved K = 250 kollapser den (61 to-felts, 1 tre-felts). Rad 34 leser
|
||||
`82` | `Prosjektering (tiltransport av prosjekterende)` | `5647500.0` — S7a § 6.2s post 82,
|
||||
5 647 500 NOK, nøyaktig der ordren sa den skulle være.
|
||||
|
||||
### 1.2 Men trippelen er ikke der — og det er strukturelt, ikke formatering
|
||||
|
||||
`okf.derive_cost_baseline` (`src/portfolio_optimiser/okf.py:1498-1499`, ordrett):
|
||||
|
||||
> **NO judgement anywhere.** The header vocabulary is closed and matched exactly, the number
|
||||
> grammar is closed, and every ambiguity is a refusal rather than a choice
|
||||
|
||||
Vokabularet (`_BASELINE_ROLES`, `okf.py:1356-1360`) er **norsk-bevisst**:
|
||||
`code` = `postnr`/`post`/`kode`/`kostkode`/`code`/`cost_code`,
|
||||
`quantity` = `mengde`/`antall`/`quantity`,
|
||||
`unit_cost` = `enhetspris`/`unit_cost`/`unit price`/`unit_price`.
|
||||
|
||||
Målt mot **alle 92 rader** (1 ekte overskriftsrad + 91 ikke-blanke datarader):
|
||||
|
||||
| match-regel | rader som navngir alle tre rollene |
|
||||
|---|---|
|
||||
| EKSAKT (deriverens egen) | **0 av 92** |
|
||||
| LØSERE delstreng (hypotetisk utvidelse) | **0 av 92** |
|
||||
|
||||
Bare ÉN rad treffer i det hele tatt: linje 24, `Post` → rollen `code`. Ingen rad noe sted treffer
|
||||
to roller samtidig, heller ikke med delstrengmatch.
|
||||
|
||||
Rad-nivå, nevner 91 ikke-blanke datarader:
|
||||
|
||||
| | antall |
|
||||
|---|---|
|
||||
| bærer en kode i kol0 | 14 |
|
||||
| bærer et mengde-tall (kol 2–4) | 28 |
|
||||
| bærer et beløp (kol 5–7) | 52 |
|
||||
| **kode OG mengde på samme rad** | **0** |
|
||||
| **kode OG mengde OG beløp på samme rad** | **0** |
|
||||
|
||||
Grunnen er at dokumentet er ni *innbygde* deltabeller med hver sin egen overskriftsrad (linje 24,
|
||||
52, 68, 71, 84, 85, 98, 102, 107, 114 — som pandoc ser som DATA, ikke overskrifter), og ingen av dem
|
||||
er en mengdefortegnelse:
|
||||
|
||||
* `Post` / `SUM` — en prissammenstilling: kode og totalsum, **ingen mengde, ingen enhetspris**;
|
||||
* `Avtale` / `Antall år (beregningstall)` / `Pris per år NOK ekskl. mva.` / `Sum NOK ekskl. mva.` —
|
||||
har mengde og enhetspris som NAVN, men **priskolonnen er tom i alle 10 dataradene** (K2 er
|
||||
pre-award; de gule cellene er ikke fylt ut);
|
||||
* `Mannskap` / `Antatt timer` / `Tilbudt timepris NOK ekskl. mva.` / `Sum` — samme: timetall står,
|
||||
**timeprisen er tom i alle 9 radene**;
|
||||
* tilsvarende for maskiner, materiell, andre kostnader, tiltransport og opsjoner.
|
||||
|
||||
### 1.3 Beslutningsregelen, og hvilken vei den falt
|
||||
|
||||
Ordrens regel er bindende: *«produserer parsen IKKE trippelen på en målt andel du kan navngi, skal
|
||||
`--derive-cost-baseline` FORTSETTE å nekte, og resultatet skrives som FUNN med tall — ikke som en ny
|
||||
regel.»*
|
||||
|
||||
**Den målte andelen er 0 av 92 rader, og 0 av 91 datarader.** Trippelen er ikke «formatert bort» —
|
||||
den finnes ikke i dokumentet. Å åpne deriveren her ville krevd å gjette hvilken av ni deltabeller
|
||||
som er en mengdefortegnelse, hvilken norsk overskrift som betyr `enhetspris`, og hva en tom
|
||||
priskolonne skal bli — tre gjetninger i en funksjon hvis docstring sier «NO judgement anywhere».
|
||||
|
||||
**INGENTING BLE BYGGET FOR FUNN 4.** `--derive-cost-baseline` nekter fortsatt, med samme melding.
|
||||
Dette er MAJOR-4s egen ærlighets-grense holdt: *«Å gjøre `--derive-cost-baseline` nåbart der ville
|
||||
krevd en regel for en form ingen har målt.»* Nå ER formen målt, og målingen sier at det ikke er en
|
||||
formregel som mangler — det er dataene.
|
||||
|
||||
**Konsekvens for funn 4s opprinnelige bekymring** (en uforankret kjøring dikter opp kostkoder): den
|
||||
står. Botemiddelet som FINNES er `--require-cost-baseline` (F4/økt 100), som nekter en uforankret
|
||||
kjøring i stedet for å la den stemple `validator_decision: validated` over linjer ingenting
|
||||
forankret. På K2 som levert betyr det rc 1 og null modellkall — ærlig, og fortsatt det eneste ærlige
|
||||
svaret.
|
||||
|
||||
---
|
||||
|
||||
## 2. FUNN 5 — hva som faktisk gjensto, og hva po eier
|
||||
|
||||
S7c hadde alt felt «åpne kuttet»-kuren: begge låser åpnet leverte dokumentet (rang 10, bytene i 2 av
|
||||
11 prompter), og modellen siterte `5647500` / `prissammenstilling` / `prisskjema` / `pris` i **0 av
|
||||
4** og **0 av 11** svar. Blindsonen flyttet seg fra rangeringen til LESNINGEN.
|
||||
|
||||
### 2.1 Målt på den faktiske rendrings-stien, ikke på råfila
|
||||
|
||||
`prepass.concept_text` er den lokale re-utledningen `verify_against_bundle` binder en payload til —
|
||||
frontmatter-splitt på `splitlines()`, NFC, per-linje `rstrip`.
|
||||
|
||||
| | linjer | tegn |
|
||||
|---|---|---|
|
||||
| råfil på disk | 119 | 101 067 (101 188 B) |
|
||||
| **levert utdrag** (`concept_text`) | **104** | **67 245** |
|
||||
|
||||
**De to nevnerne ordren bar er dermed avstemt:** de er samme dokument før og etter frontmatter-
|
||||
splitten og produsentens per-linje `rstrip` — ikke to uenige målinger. 118 − 14 frontmatter-linjer =
|
||||
104.
|
||||
|
||||
Mellomrom-løp i det LEVERTE utdraget:
|
||||
|
||||
| | verdi |
|
||||
|---|---|
|
||||
| indre løp ≥ 2 tegn | 208 |
|
||||
| av dem ≥ 100 tegn | 117 |
|
||||
| av dem ≥ 250 / ≥ 500 | 77 / 72 |
|
||||
| lengste | **887** |
|
||||
| tegn i løp ≥ 100 | **56 806 av 67 245 = 84,5 %** |
|
||||
| linjer med et løp ≥ 100 | **72 av 104** |
|
||||
|
||||
**Svaret på ordrens spørsmål er JA.** Etikett og beløp når modellen hundrevis av tegn fra hverandre,
|
||||
og 84,5 % av det kjøringen betaler for er en kolonnebredde pandoc valgte.
|
||||
|
||||
### 2.2 Det som ble bygget
|
||||
|
||||
`prepass.collapse_padding`, kalt fra `_data_blocks` — den ENE rendreren begge armer deler.
|
||||
|
||||
Fire løfter, hver med sin egen gate:
|
||||
|
||||
1. indre løp av mellomrom/tab kollapser til ÉN. **K = 2**, altså finnes det ingen terskel å tune
|
||||
eller forsvare; «to eller flere» er hele regelen.
|
||||
2. **ledende whitespace er urørt** (`(?<=\S)`-lookbehind). Indentering er markdown-struktur, ikke
|
||||
padding.
|
||||
3. **ingen newline røres** — linjeantallet er invariant, ingen rad slås sammen med naboen.
|
||||
4. **ingen ikke-whitespace-tegn røres** — intet tall kan endres. Asserten er den PER-LINJE
|
||||
ikke-whitespace-sekvensen, ikke «sifrene finnes fortsatt et sted».
|
||||
|
||||
**Plasseringen er det bærende valget.** Den kjører i rendringen, ALDRI i `concept_text`: den
|
||||
funksjonen er hva en payloads bytes verifiseres mot, så en kollaps der ville fått hver payload
|
||||
noensinne skrevet til å feile sin egen digest og opphevet gaten som stopper en payload fra å levere
|
||||
bytes basen ikke holder. Arm (f) er nøyaktig den separasjonen.
|
||||
|
||||
### 2.3 Effekt, målt på det ekte dokumentet
|
||||
|
||||
| | før | etter |
|
||||
|---|---|---|
|
||||
| tegn | 67 245 | **18 531 (−72,4 %)** |
|
||||
| linjer | 104 | 104 (uendret) |
|
||||
| lengste indre løp | 887 | **0** |
|
||||
| ikke-whitespace-sekvens | — | **identisk** |
|
||||
|
||||
Rad 34 leser nå `82 Prosjektering (tiltransport av prosjekterende) 5647500.0`.
|
||||
|
||||
### 2.4 Mutasjonstabell, funn 5
|
||||
|
||||
Alle mot HELE suiten, én per kjøring, restaurert fra `scratchpad/mut-backup/` med `shasum -a 256 -c`
|
||||
(aldri `git checkout`). Grønn kontroll **1543 / 5**.
|
||||
|
||||
| # | mutasjon | røde |
|
||||
|---|---|---|
|
||||
| W1 | detach kollapsen fra `_data_blocks` | 2 |
|
||||
| W2 | kollaps ledende whitespace også | 1 (indenterings-armen ALENE) |
|
||||
| W3 | kollaps newlines også (`re.sub(r"\s{2,}", " ", text)`) | 4 (inkl. kontrollen) |
|
||||
| W4 | skriv om tall (strip `.0`) | 2 |
|
||||
| W5 | kollaps inne i `concept_text`, før verifiseringen | 1 (separasjons-armen alene) |
|
||||
|
||||
### 2.5 Grenser, uttalt
|
||||
|
||||
* **At modellen så BRUKER tallene er IKKE vist.** Det krever en betalt kjøring, som ikke er
|
||||
bestilt. Leveransen er den deterministiske egenskapen; en betalt bekreftelse er en senere,
|
||||
separat ordre. Dette er ordrens egen scope-grense, ordrett gjengitt.
|
||||
* **Celle-grensen går tapt.** Etter kollapsen er `Post SUM` uskillbar fra prosa med de to ordene.
|
||||
Å finne opp et skilletegn for å bære grensen ville vært nøyaktig det skjønnet regelen unngår, og
|
||||
ingen måling her sier hvilket skilletegn en modell leser bedre. Tapet er registrert, ikke
|
||||
bortforklart.
|
||||
* **Ingen `coord-send` til llm-ingestion-okf.** Ordrens tredje vei (produsent-side-kuren) gjelder
|
||||
hvis formen allerede var normalisert på veien inn. Det var den ikke — 84,5 % padding nådde
|
||||
prompten — så veien som gjaldt var «en målt po-endring med rød test». Det er også verdt å si at
|
||||
paddingen er pandocs kolonnebredde og ikke en produsentfeil: produsenten `rstrip`-er allerede per
|
||||
linje, altså fjerner den alt den kan uten å tolke tabellen.
|
||||
|
||||
---
|
||||
|
||||
## 3. F99-D3 — `read_file` / `read_dir` / `read_bundle` returnerer nekt
|
||||
|
||||
### 3.1 Grunnlaget
|
||||
|
||||
Funn 99 lukket halvparten og sa det (`docs/2026-09-08-funn-99-chatclient-refusal.md` linje 132-135):
|
||||
`quick_validate` fikk en returnert refusal, mens de tre lesetools-ene fortsatt raiset —
|
||||
**«MÅLT, RAPPORTERT, IKKE FIKSET.»** Trippelen rett foran den levende 400-en var tre
|
||||
`read_file`-nekter på `del-ii-bilag-7-prisskjema*` — samme dokument som § 1 og § 2 handler om.
|
||||
|
||||
Hvorfor et raise er verre enn ubrukelig her, målt i rammeverkets egen kilde: MAF gjør en tools
|
||||
exception om til `"Error: Function failed."` (`agent_framework/_tools.py:1410-1432`), undertrykker
|
||||
detaljen med mindre `include_detailed_errors` er satt (`:1427`), og teller den mot
|
||||
`DEFAULT_MAX_CONSECUTIVE_ERRORS_PER_REQUEST = 3` (`:96`, `:2718-2731`).
|
||||
|
||||
### 3.2 Form per verktøy, og begrunnelsen
|
||||
|
||||
| verktøy | returtype | nekt-form (ordrett) |
|
||||
|---|---|---|
|
||||
| `read_bundle` | `dict` | `{"refused": "<grunn>", "refusal": "<Klassenavn>"}` |
|
||||
| `read_dir` | `dict` | `{"refused": "<grunn>", "refusal": "<Klassenavn>"}` |
|
||||
| `read_file` | `str` | `REFUSED (<Klassenavn>): <grunn>` |
|
||||
|
||||
* **De to listings-verktøyene får en mapping** hvis nøkler ingen vellykket listing har
|
||||
(`directory_listing` svarer med `path` / `directories` / `documents`). En nekt en kaller ikke kan
|
||||
skille fra et svar er verdiløs, og her er skillet strukturelt.
|
||||
* **`read_file` beholder `str`.** En mapping DER ville endret formen på hver VELLYKKET lesning, og
|
||||
dermed hver prompt-byte S2c målte da den ga debatten disse verktøyene. Nekten er i stedet en
|
||||
streng med et fast ledende sentinel.
|
||||
* **`refusal`-KINDEN er ikke pynt.** F3 målte at `read_dir` må skille «dette er et dokument, bruk
|
||||
den andre rungen» fra «dette finnes ikke», og før denne endringen kunne en kaller skille dem på
|
||||
KLASSE (`assert not isinstance(excinfo.value, okf.DocumentPathRefused)`). En returnert nekt taper
|
||||
den distinksjonen med mindre den bærer den — så den bærer den, avledet av `type(exc).__name__`,
|
||||
altså ÉN kilde og aldri en andre tabell. Mutasjon M6 er dét vitnet (9 røde).
|
||||
|
||||
### 3.3 Gatene er urørt — grunnen reiser, bytene aldri
|
||||
|
||||
Verdict-laget (`VerdictLayerRefused`) og §4.1a-dimensjonen (`DimensionScopeRefused`) nekter nøyaktig
|
||||
det de nektet før. Det som er nytt er at egenskapen de finnes for nå asserteres EKSPLISITT på
|
||||
returverdien: hver arm skriver en sentinel inn i det nektede dokumentets kropp og krever at
|
||||
sentinelen IKKE står i nekten. Mutasjon M8 (nekten bærer dokumentets bytes) er rød i 8 tester,
|
||||
**fem av dem eldre enn dette arbeidet** — altså er lekkasje-egenskapen gatet av uavhengige vitner.
|
||||
|
||||
### 3.4 Kjent-negativen, og hva den beviser
|
||||
|
||||
`test_a_plain_runtime_error_still_propagates` reiser en bar `RuntimeError` inne i en tool-kropp og
|
||||
krever at den propagerer.
|
||||
|
||||
**Den er ikke pynt, den er grunnen til at armen er en LISTE MED NAVN.** `ExplorationError` er selv en
|
||||
`RuntimeError`-subklasse, så en arm skrevet `except RuntimeError` ville slukt også denne — og gjort
|
||||
en ukjent svikt om til et selvsikkert svar, hvilket er verre enn den ugjennomsiktige strengen
|
||||
endringen fjerner. `_RETURNABLE_REFUSALS` navngir derfor hver klasse én for én:
|
||||
`ExplorationError` · `okf.BundleIdMismatch` · `okf.BundlePathNotFound` · `okf.DocumentPathRefused` ·
|
||||
`DirectoryPathRefused` · `VerdictLayerRefused` · `DimensionScopeRefused`.
|
||||
|
||||
Mutasjon M4 (armen fanger bar `Exception`) er rød i 2 tester: kjent-negativen PLUSS
|
||||
`test_a_nonexistent_sibling_is_still_an_os_error`, en **eksisterende, uavhengig** arm som pinner at
|
||||
en `FileNotFoundError` fortsatt er en `OSError` ut av verktøyet.
|
||||
|
||||
### 3.5 «Ikke i sinken»-semantikken
|
||||
|
||||
Spørsmålet gjelder ikke her, og det er en måling snarere enn en unnlatelse: lesetools-ene har ingen
|
||||
verdikt-sink slik `quick_validate` har. Det de HAR er `ExplorationToolRecorder`, som appender FØR
|
||||
`await call_next()` — så et nektet kall står allerede i `RunResult.debate_tool_calls` og i
|
||||
`{run_id}-debate.json` med sin sti (verdict-gatens egen måling, økt 04.09: mutasjonen «registrer
|
||||
etter `call_next`» tømmer sporet for nøyaktig et nektet kall). Endringen her rører ikke den sømmen.
|
||||
|
||||
### 3.6 Eksisterende gates SKREVET OM, aldri slettet
|
||||
|
||||
19 armer i seks filer pinnet raisen. Alle er skrevet om og ingen svekket — der klassen bar en
|
||||
distinksjon, bærer `refusal`-kinden den nå; der meldingen bar en påstand, står samme substring-
|
||||
assert på `refused`-teksten; og der `pytest.raises` var hele asserten, er den erstattet av BÅDE
|
||||
formen OG den nye «aldri innholdet»-halvdelen.
|
||||
|
||||
| fil | armer |
|
||||
|---|---|
|
||||
| `test_read_dir_wrong_rung_loadbearing.py` | 7 |
|
||||
| `test_verdict_layer_refusal_loadbearing.py` | 3 |
|
||||
| `test_read_file_directory_refusal_loadbearing.py` | 3 |
|
||||
| `test_debate_navigation_cost_loadbearing.py` | 2 |
|
||||
| `test_bundle_id_slack_loadbearing.py` | 2 |
|
||||
| `test_explore_loadbearing.py` | 1 |
|
||||
| `test_hierarchical_navigation_loadbearing.py` | 1 |
|
||||
|
||||
Ingen node-ID er fjernet eller omdøpt: 1529 → 1543 er 7 nye armer for funn 5 og 7 for D3, et strengt
|
||||
supersett ved konstruksjon.
|
||||
|
||||
### 3.7 Mutasjonstabell, D3
|
||||
|
||||
| # | mutasjon | røde |
|
||||
|---|---|---|
|
||||
| M1 | `read_file` raiser igjen | 12 (fem eldre filer) |
|
||||
| M2 | `read_dir` raiser igjen | 10 |
|
||||
| M3 | `read_bundle` raiser igjen | 3 |
|
||||
| M4 | armen fanger bar `Exception` | 2 (kjent-negativen + eldre uavhengig vitne) |
|
||||
| M5 | nekten dropper grunnen | 10 |
|
||||
| M6 | dropp `refusal`-kinden | 9 |
|
||||
| M7 | `read_file` mister sentinel-prefikset | 12 |
|
||||
| M8 | nekten bærer det nektede dokumentets bytes | 8 (fem eldre) |
|
||||
|
||||
**Ingen mutasjon var grønn.** Til sammen 13 mutasjoner (W1–W5 + M1–M8), alle røde.
|
||||
|
||||
---
|
||||
|
||||
## 4. F99-D2 — invariantraden
|
||||
|
||||
Raden er skrevet i CLAUDE.md, i husets form, plassert rett etter verdict-gate-raden der de beslektede
|
||||
lese-invariantene bor. Den pinner LOVEN, ikke historien: en nekt modellen skal kunne rette seg etter
|
||||
er en returverdi, aldri et raise; MAF undertrykker raisens tekst og teller den mot grensen 3; og
|
||||
regelen gjelder HVERT verktøy, ikke bare `quick_validate` — slik ordren krevde etter at D3 var
|
||||
bygget.
|
||||
|
||||
**AVVIK, uttalt:** ordren sa «ÉN rad i CLAUDE.md, og bare én». Jeg har skrevet **to**. Den andre er
|
||||
funn 5s kollaps-søm. Begrunnelsen: «bare én» gjelder D2s lov, mens funn 5 er en separat BYGGET søm
|
||||
med sin egen load-bearing gate, og hovedbokens stående regel (CLAUDE.md-preamblet) er at hver blokk
|
||||
registrerer en designbeslutning, målingen som tvang den, og testen som blir rød når den oppheves. Å
|
||||
la funn 5 stå uregistrert ville brutt den regelen. Avviket er en beslutning, ikke en forglemmelse.
|
||||
|
||||
---
|
||||
|
||||
## 5. Ikke gjort, og hvorfor
|
||||
|
||||
* **Ingen endring i `okf.derive_cost_baseline`.** § 1.3: beslutningsregelen falt mot bygging, med
|
||||
tall.
|
||||
* **Ingen `coord-send` til llm-ingestion-okf.** § 2.5: produsent-side-veien var ikke veien som
|
||||
gjaldt, og paddingen er pandocs kolonnebredde, ikke en produsentfeil.
|
||||
* **Ingen betalt kjøring.** Ordren forbyr, og ingen av de to funnene trenger en.
|
||||
* **`list_bundles` er URØRT.** Den tar ingen `bundle_id` og har derfor ingen ukjent-base-gren; de
|
||||
refusals den kunne møte (en ulesbar base) er operatørfeil, ikke noe en modell kan rette.
|
||||
* **Den hostede flaten er urørt.** Ingen av endringene er et request-felt.
|
||||
* **`--require-cost-baseline` er ikke gjort til default.** Det er F4s egen beslutning (opt-in), og
|
||||
denne ordren ba ikke om å endre den.
|
||||
Loading…
Add table
Add a link
Reference in a new issue