portfolio-optimiser-claude/docs/2026-08-18-funn-koeer-og-gater.md
Kjell Tore Guttormsen 607f017537 test(okf): the one unquoting rule was pinned at its edge, not in its three clauses
D7 mirroring candidate (a)/(i) `unquote_scalar`, measured. The sibling grew that
function after a duplicated conversion had drifted; our counterpart
`okf._strip_matching_quotes` is genuinely ONE rule -- one definition, one call
site, and `unquote` appears in 0 of 76 .py files under src+tests (positive
control: the same query finds `parse_frontmatter`). So the drift shape is absent.

But the rule was covered only at its edge. Detaching it outright is red; each of
its three clauses was green-but-dead against the whole 950-test suite -- weakening
the length guard, dropping the matching requirement, and widening the quote set
with a symmetric delimiter all left the suite green. Same class as the
_STRUCTURE_MARKERS hole: named and edge-covered is not covered.

tests/test_okf_unquote_loadbearing.py closes the three clauses (950 -> 955). Each
clause test is green before and red after exactly its own mutation, with the
population control green in both, clause 3 pinned on its line via --red-at.

A measuring trap, measured: the first clause-3 mutation added '[' to the quote
set and the suite stayed green -- which reads as "not covered" but is a NO-OP,
since '[' can never satisfy the matching clause. Flow-form values are protected
by the matching clause, not the quote set. The harness cannot distinguish a
behaviour-preserving mutation from an undetected seam; both surface as "stayed
GREEN". A mutation must be shown to change behaviour before its green is read as
a hole.

No flow decoding is added here -- that is the sibling's B4 work, and these tests
pin today's boundary so it cannot land silently on this side.

Co-Authored-By: Claude <claude-opus-5>
2026-08-31 23:31:17 +02:00

142 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 1722 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:
- S2.7
- 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.
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.