[mutation-ok] rationale: no mutation is pinned in code. `src/` is byte-identical to HEAD (git diff HEAD -- src/ is empty; `if False` occurs 0 times under src/). The three matches the guard found are PROSE in the docs note and the test file's docstring, quoting the detach mutation that was run and restored. Every harness run in this session verified its restore by sha256 from disk. S2.7 is the D7 mirroring queue's topmost unmeasured candidate. The MAF sibling tightened its validator in two halves -- (a) a structural block on `claimed > nominal_feasible`, (b) an IR invariant `low <= unit_cost <= high`. Both halves are GATED here on D-A pkt. 1 + a commons pull, and the defect they answer is confirmed on our side as C-F2. So neither is built. The question this answers is the one that is answerable offline: is today's boundary -- "the ONE numeric gate is p90" -- load-bearing? One rule, structurally: a claim is numerically bounded in exactly two places in src, each with its own spec role (ir.py:50 §7.1, validator.py:68 §3 Step 4). The sibling's drift shape does not exist here. But the coverage splits cleanly across the rule. Measured with scripts/mutation_harness.py, denominator tests/ (all 955), each run sha256-restored: everything the gate COMPUTES is red, because the golden fixture freezes it -- policy cap, band branch, band endpoint order, MC seed, p90 cut point, nominal_feasible. Everything the gate DECIDES WITH is green-but-dead -- bound to p10, bound to nominal_feasible, and loosening the comparison each left all 955 green. The golden freezes what the validator produces, so it cannot help with the one thing it does not observe: which bound the gate reads. Swapping p90 for nominal_feasible IS the gated S2.7 half (a), and it would have landed with the suite green, before D-A was decided. Closed by tests/test_validator_gate_loadbearing.py (8 tests, 955 -> 963). Each clause is green before and red after exactly its own mutation, with the golden figures green in BOTH runs -- which shows mechanically that the mutation moved the decision, not the arithmetic. The two IR tests are pinned with --red-at against the invariant's own message, since they die in a helper. The AST population control was proved against a BEHAVIOUR-PRESERVING mutation (the gate widened to a logically equivalent conjunction) with all three behavioural controls green: a new gate site is invisible to any behavioural test, which is why it is there. Two things the measurement gave in addition. Under the containment mutation the golden test stayed green, confirming mechanically that half (b) is golden-compatible when D-A lands. And the IR carries no ORDER on band endpoints either -- strictly more than C-F2 names: (1.40, 0.70) is accepted, and while random.uniform still draws from [0.70, 1.40], it walks the seeded stream backwards, which is a different p90 (120456.91 against 121057.09). Honest limit: pinning that a claim above nominal_feasible validates today is not an endorsement of it. C-F2 calls that a MAJOR spec-level defect and the fix is gated, not declined. These tests make the gated work arrive as a visible red test and a decision, never as a silent swap. No src change, no spec text touched, the fasit untouched. Dated under the D7 frame: work AFTER 2026-08-09, not independent convergence. Co-Authored-By: Claude <claude-opus-5>
207 lines
13 KiB
Markdown
207 lines
13 KiB
Markdown
# Målte funn, køer og gater (flyttet ut av STATE.md 2026-08-18)
|
||
|
||
> Bakgrunn: `STATE.md` er current state-of-play og har et tak på ~120 linjer. Den 18.08 lå
|
||
> fila på 149. Operatørbeslutningen samme dag var å flytte tre punkter hit og la STATE
|
||
> beholde ÉN peker per punkt på formen `fil § Overskrift` — et grep-bart paragraf-anker,
|
||
> aldri et linjenummer. **Ingenting er slettet:** state er flyttet, ikke fjernet.
|
||
>
|
||
> Alt under er MÅLERESULTATER med en dato, ikke fakta om verden. Datoen står ved hver
|
||
> påstand, og en påstand herfra er et premiss som skal verifiseres på nytt før den handles
|
||
> på — særlig tall som råtner (versjoner, testantall, oppstrøms-tilstand).
|
||
|
||
## Negative funn
|
||
|
||
Steder som ER undersøkt for en manglende søm, og hvor svaret var «ingen søm å feste». De er
|
||
ferdig avklart i økt 17–22 og skal **ikke re-måles** — enumerert her nettopp for at ingen
|
||
senere økt skal bruke tid på dem igjen:
|
||
|
||
- `test_preflight` (9 tilfeller)
|
||
- `test_zero_model_calls`
|
||
- `notify` :224
|
||
- `ir` :69
|
||
- `validator` :56
|
||
- `step1_expel` :99
|
||
- cli_paritet-parene
|
||
- `method_spec` + `ingest_spec` (6 tilfeller — merk: **ikke lenger dekkende**, se under)
|
||
- alle 8 fra økt 22
|
||
|
||
**Korreksjon 2026-08-18 (økt 32):** `ingest_spec`-oppføringen gjaldt den §12-ankrede vakten.
|
||
Økt 32 målte et hull den enumereringen ikke fanget — enhver seksjon §1–§11 kunne tømmes uten
|
||
at én test i suiten ble rød (10 av 11 seksjoner; §7 var eneste overlapp, via O2-ratchet-en).
|
||
Hullet er lukket med `_STRUCTURE_MARKERS` i `tests/test_ingest_spec_loadbearing.py` (commit
|
||
`40b4631`). Lærdommen er generell: **et negativt funn har et scope, og scopet er den
|
||
spørringen som ble kjørt** — ikke fila den ble kjørt mot.
|
||
|
||
## D7-speilingskøen
|
||
|
||
Åtte kandidater for speiling mellom D7-søsknene. **Ingen er besluttet** — de står som
|
||
kandidater, ikke som planlagt arbeid. **Tre er målt, 5 står igjen:**
|
||
|
||
- ~~S2.7~~ — **MÅLT 2026-09-07, se under**
|
||
- S3.2
|
||
- S4.0 (`126807a`)
|
||
- (p) `to_ore` — TO kallsteder
|
||
- ~~(a)/(i) `unquote_scalar`~~ — **MÅLT 2026-08-31, se under**
|
||
- `mandate.py`
|
||
- A5 — TO halvdeler
|
||
- ~~B4 `ToolCallRecorder`~~ — **BESVART 2026-08-25, se under**
|
||
|
||
**B4 spurte OSS:** gir Claude-SDK-siden serveridentiteten gratis? MAF får verktøynavn UTEN
|
||
server-prefiks. Åpent hos søskenet: MAF S3.4 (F10).
|
||
|
||
### B4 — svaret er NEI (målt 2026-08-25, offline, mot `claude-agent-sdk` 0.2.139)
|
||
|
||
`create_sdk_mcp_server` emitterer det **bare** verktøynavnet. Serveridentiteten finnes — på
|
||
`McpSdkServerConfig["name"]` og `Server.name` — men den er **disjunkt fra hvert navn
|
||
verktøylista bærer**. Strengen `mcp__` forekommer i **0 av 24** Python-filer i pakken
|
||
(positiv kontroll: `create_sdk_mcp_server` blir funnet av samme spørring, så spørringen KAN
|
||
finne). Konstruksjonssiden namespacer altså ingenting: en `ToolCallRecorder` hengt der ser
|
||
`record_call`, ikke `mcp__tool_call_recorder__record_call`, og må få servernavnet fortalt.
|
||
Det er **samme pris som søskenet betaler**.
|
||
|
||
**Ærlig grense — hva målingen IKKE sier.** Den navnerommede formen `mcp__<server>__<tool>`
|
||
eksisterer: den bygges inne i CLI-en som følger med SDK-en (`_bundled/claude`, 178 literale
|
||
`mcp__`-forekomster, konstruksjonen på formen `` `mcp__${…}__${…}` ``). Det er **lest av
|
||
artefaktet, ikke observert i en kjøring hos oss** — å se den emittert krever en live
|
||
`query()`, som både D6-kostnadsregelen og suitens offline-invariant forbyr. Funnet er derfor
|
||
scopet til den sømmen vi faktisk kan bygge på: den in-process konstruksjonssiden. Prefikset
|
||
finnes på et lag vi bevisst ikke kjører, og et lag vi ikke kjører er ikke en søm vi kan feste
|
||
en recorder i.
|
||
|
||
**Pinnet av** `tests/test_sdk_tool_namespace_loadbearing.py` (4 tester). Value-beviset er
|
||
kjørt, ikke påstått: SDK-en ble mutert til å namespace ved konstruksjon (`"name":
|
||
f"mcp__{name}__{tool_def.name}"`) — **grønn før, 3 av 4 røde etter**, og den ene som forble
|
||
grønn er nettopp populasjons-kontrollen, som den skal. SDK-fila ble restaurert byte-identisk
|
||
(sha256 verifisert begge veier).
|
||
|
||
**Datering (D7-rammen):** dette er arbeid ETTER 2026-08-09 og skal **ikke** leses som
|
||
uavhengig konvergens selv om svaret er identisk med søskenets.
|
||
|
||
### (a)/(i) `unquote_scalar` — svaret er JA, den var ÉN regel, men pinnet bare i kanten (målt 2026-08-31)
|
||
|
||
Kandidaten står i køen fordi søskenet vokste en navngitt `unquote_scalar` etter at en
|
||
**duplisert konvertering hadde driftet** — to steder som fjernet anførselstegn fra en
|
||
frontmatter-skalar, etter to regler. Speilings-spørsmålet er derfor ikke «har vi funksjonen»,
|
||
men det søskenets defekt faktisk stiller: **er den ÉN regel hos oss, og er selve regelen
|
||
load-bearing?**
|
||
|
||
**Populasjonen først.** `unquote_scalar` finnes ikke hos oss: **0 treff av 76 undersøkte
|
||
`.py`-filer** i `src`+`tests` (positiv kontroll: samme spørring finner `parse_frontmatter` i
|
||
`okf.py`), og `unquote` finnes ikke i repoet utenfor `.venv`. Vår motpart er
|
||
`okf._strip_matching_quotes` — **én definisjon, ett kallsted** (`_parse_frontmatter_and_body`).
|
||
Søskenets drift-form finnes altså ikke her.
|
||
|
||
**Men regelen var dekket bare i kanten.** Med `scripts/mutation_harness.py`, nevner `tests/`
|
||
(hele suiten, 950 tester), hver kjøring sha256-restaurert:
|
||
|
||
- Å detache regelen helt (`return value[1:-1]` → `return value`) er **RØD** —
|
||
`test_okf.py::TestFrontmatter::test_unknown_fields_preserved_and_quotes_stripped` fanger den.
|
||
- Hver av de tre **klausulene** var **grønn-men-død**: å svekke lengdevakten (`>= 2` → `>= 1`),
|
||
å droppe matching-kravet (`value[0] == value[-1] and`), og å utvide quote-settet med en
|
||
symmetrisk delimiter (backtick) lot hele suiten stå grønn.
|
||
|
||
Samme klasse som `_STRUCTURE_MARKERS`-hullet i økt 32: sømmen var NAVNGITT og kant-dekket, som
|
||
ikke er det samme som dekket. **Pinnet av** `tests/test_okf_unquote_loadbearing.py` (5 tester,
|
||
950 → 955). Value-beviset er kjørt, ikke påstått: hver klausul-test er grønn før og rød etter
|
||
nøyaktig sin egen mutasjon, med populasjons-kontrollen grønn i begge (mutasjonen landet ikke
|
||
for bredt), og ledd 3 pinnet på linje via `--red-at`.
|
||
|
||
**EN MÅLETRAP, MÅLT — ny lærdom om harnesset.** Første forsøk på klausul 3 utvidet settet med
|
||
`'['`. Suiten forble grønn, hvilket leses som «klausulen er ikke dekket» — men mutasjonen er en
|
||
**no-op**: `'['` kan aldri tilfredsstille matching-kravet, siden `[` ikke er `]`. Flow-form-
|
||
verdier er altså beskyttet av **matching-klausulen, ikke av quote-settet**, og en grønn kjøring
|
||
under den mutasjonen var aldri bevis om quote-settet i det hele tatt. **Harnesset kan ikke
|
||
skille en oppførsels-bevarende mutasjon fra en udekket søm — begge kommer ut som «stayed
|
||
GREEN».** En mutasjon må vises å endre oppførsel før dens grønne leses som et hull. Dette er
|
||
Verifiseringsloven ansikt 4 anvendt på selve måleapparatet: et negativt resultat fra en
|
||
spørring som ikke KAN finne, er ikke null — det er ikke målt.
|
||
|
||
**Ærlig grense — hva dette IKKE sier.** Å pinne at flow-verdier passerer **urørt** er ikke
|
||
flow-DEKODING, og fila legger ingen til: `tags: [a, b]` forblir strengen `"[a, b]"`. Den
|
||
linje-orienterte parseren har ingen nesting-modell ved design (§1 ærlighets-regelen). Den
|
||
additive flow-dekoderen er søskenets B4-arbeid i `portfolio-optimiser` og er bevisst **ikke**
|
||
bygget her; testene pinner dagens grense slik at det arbeidet ikke kan lande stille på denne
|
||
siden.
|
||
|
||
**Datering (D7-rammen):** arbeid ETTER 2026-08-09 — skal **ikke** leses som uavhengig konvergens.
|
||
|
||
|
||
### S2.7 — gaten er ÉN regel, og den var pinnet i ARITMETIKKEN, ikke i BESLUTNINGEN (målt 2026-09-07)
|
||
|
||
Kandidaten står i køen fordi søskenet strammet validatoren i to halvdeler: (a) en strukturell
|
||
blokk på `claimed > nominal_feasible`, og (b) en IR-invariant `low ≤ unit_cost ≤ high`. **Begge
|
||
halvdeler er GATET her** på D-A pkt. 1 + commons-pull (paritetsplanens rad 12), og defekten de
|
||
svarer på er bekreftet på vår side som C-F2 (`docs/review-2026-07.md`). Speilings-spørsmålet som
|
||
KAN besvares offline i dag er derfor et annet: **er dagens grense — «den ENE numeriske gaten er
|
||
p90» — load-bearing?**
|
||
|
||
**Populasjonen først.** En claim er numerisk avgrenset i nøyaktig TO steder i `src/`, med hver
|
||
sin spec-rolle: skjema-invarianten (claim ≤ items-total, §7.1, `ir.py:50`) og validator-gaten
|
||
(claim ≤ p90, §3 Steg 4, `validator.py:68`). `_FEASIBLE_FRACTION` forekommer kun i `validator.py`,
|
||
og det finnes ingen annen Monte Carlo eller `quantiles`-beregning i pakken (positiv kontroll:
|
||
samme spørring finner `validate_proposal` i `loop.py:284`). Søskenets drift-form — to gater som
|
||
har glidd fra hverandre — finnes altså ikke her.
|
||
|
||
**Men dekningen deler seg rent på tvers av regelen.** Med `scripts/mutation_harness.py`, nevner
|
||
`tests/` (hele suiten, 955 tester), hver kjøring sha256-restaurert:
|
||
|
||
- Å detache gaten helt (`if … > p90:` → `if False:`) er **RØD** — `test_validator.py` fanger den.
|
||
- Alt gaten **REGNER UT** er RØDT, og goldenen er grunnen: policy-taket (`0.30` → `0.31`),
|
||
band-grenen (ignorér bands), band-endepunktenes rekkefølge, MC-seeden, p90-kuttpunkt-indeksen
|
||
og `nominal_feasible`-formelen reddet alle suiten.
|
||
- Alt gaten **BESLUTTER MED** er **grønn-men-dødt**: å bytte grensen til `p10`, å bytte den til
|
||
`nominal_feasible`, og å løsne `>` til `>=` lot alle 955 testene stå grønne.
|
||
|
||
Det skillet ER funnet, og det er skarpere enn «sømmen er tynn»: goldenen fryser hvert tall
|
||
validatoren PRODUSERER, og kan derfor ikke hjelpe med det ene den ikke observerer — hvilken
|
||
grense gaten LESER. Konsekvensen er konkret: **å bytte `p90` mot `nominal_feasible` ER den gatede
|
||
S2.7-halvdel (a), og den ville landet med suiten grønn**, før D-A er besluttet.
|
||
|
||
**Pinnet av** `tests/test_validator_gate_loadbearing.py` (8 tester, 955 → 963). Value-beviset er
|
||
kjørt, ikke påstått: hver klausul-test er grønn før og rød etter nøyaktig sin egen mutasjon, med
|
||
golden-tallene grønne i BEGGE kjøringer — som mekanisk viser at mutasjonen flyttet BESLUTNINGEN,
|
||
ikke aritmetikken. De to IR-testene er pinnet med `--red-at` mot invariantens egen feilmelding,
|
||
fordi de dør i en hjelpefunksjon og ikke i testkroppen.
|
||
|
||
**Mutasjonene ble vist å endre oppførsel FØR deres grønne ble lest som hull** (fellen fra økt 39).
|
||
Alle tre grensetilfellene er nåbare og ble kjørt: en claim nøyaktig PÅ p90 finnes (degenerert
|
||
band, `0.30 × 1000 == 300.0`), og med goldenens eget band valideres en claim på 100 000 mens
|
||
`nominal_feasible` er 90 000 — C-F2s første moteksempel, reprodusert live på p90 = 121 057.09,
|
||
sammen med det andre (claim 55 000 mot nominal 30 000, p90 = 65 058.49). Begge tallene er
|
||
identiske med review-ens, som bekrefter at defekten er spec-båren.
|
||
|
||
**To ting målingen ga i tillegg.** (1) Populasjonskontrollen (AST) ble bevist mot en
|
||
**oppførselsbevarende** mutasjon — `> p90` utvidet til `> p10 and > p90`, som er logisk identisk
|
||
når `p10 ≤ p90` — og alle tre oppførselskontrollene forble grønne. En ny gate-plassering er
|
||
usynlig for enhver oppførselstest; det er nettopp derfor AST-kontrollen står der. (2) Under
|
||
containment-mutasjonen forble golden-testen **grønn**, hvilket mekanisk bekrefter review-ens
|
||
påstand om at S2.7 halvdel (b) er golden-kompatibel når D-A lander.
|
||
|
||
**Nytt utover C-F2:** IR-en har heller ingen ORDNING på band-endepunktene. `(1.40, 0.70)`
|
||
aksepteres; `random.uniform(1.40, 0.70)` trekker fortsatt fra [0.70, 1.40], så området korrumperes
|
||
ikke — men den seedede strømmen vandres baklengs, hvilket er en ANNEN p90 (målt: 120 456.91 mot
|
||
121 057.09). Et band hvis betydning avhenger av argument-rekkefølgen er ennå ikke et band.
|
||
|
||
**Ærlig grense — hva dette IKKE sier.** Å pinne at en claim over `nominal_feasible` validerer i
|
||
dag er ingen godkjenning av oppførselen; C-F2 kaller den en MAJOR spec-nivå-defekt, og fiksen er
|
||
GATET, ikke avvist. Testene pinner grensen slik at det gatede arbeidet MÅ ankomme som en synlig
|
||
rød test og en beslutning, aldri som et stille bytte. Ingen `src/`-endring er gjort, ingen
|
||
spec-tekst rørt, og fasiten er ikke berørt.
|
||
|
||
**Datering (D7-rammen):** arbeid ETTER 2026-08-09 — skal **ikke** leses som uavhengig konvergens.
|
||
|
||
|
||
Rammen rundt køen: å lese søskenets kode er tillatt (`3bdf7f0`), men kopiering skal kun skje
|
||
der det tjener løsningen, aldri som snarvei. **Uavhengighets-beviset er DATERT** t.o.m.
|
||
2026-08-09; arbeid etter den datoen kan ikke leses som uavhengig konvergens.
|
||
|
||
## D-A-gater og fasit-berøring
|
||
|
||
- **D-A#5 mangler story-etikett oppstrøms** — avklar med MAF før teksten låses. En ny
|
||
hovedbok-kontrakt MÅ inn i §12s kryssjekktabell i SAMME amendment; ellers blir tabellen
|
||
ufullstendig i det øyeblikket kontrakten finnes.
|
||
- **D-A#2 rører fasiten.** commons er meldt at vår §12-vakt keyer på ordrett `| `generated` |`
|
||
⇒ et amendment som ERSTATTER raden gjør oss RØDE. Det er **by design**: en fasit-endring
|
||
skal koste en synlig rød test, ikke gli gjennom.
|
||
- **Gates:** D-F/D-G → K13 · D-B → K14/K15 · D-E · okf-toolkit-§8 · delbarhet av ledger-/
|
||
outbox-format. R-9 er valgfri.
|