portfolio-optimiser/docs/invarianter.md
Kjell Tore Guttormsen 7dcce64f6a
docs(invarianter): the toolbox's four first doors, and the binding that measures an execution [skip-docs]
One row for the whole delivery: why `portfolio-optimiser-toolbox` is the third console script (it
is the one thing the other two cannot be used for), what each subcommand is bound to, why every
handler is a thin adapter and every dispatch an explicit branch, and how the probes assert on what
the door wrote rather than on the function it calls.

Plus the third repair of B-gate's binding with its measurements: the judge's seven forms at 0 of 1,
the naming rule turned into a discriminator, named-prose reasons, row 3 at 15 of 15 over 514 files,
and the runbook heading that is no longer a section. The row states its own limit (the gate reads
that the probe drives the door; it does not re-run the probe with the door broken) and records that
N7 stays open in the gate and closed in the suite.

The mutation run is in the row because two of its findings could not have come from reading: the
dead-code pruning survived two mutants until the arms that reach it were written, and three
mutants are named as non-measurements (two renamed a label, one was equivalent).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 09:07:56 +02:00

3493 lines
330 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.

# Invariant-hovedboken — portfolio-optimiser
> **Note for visitors — what this file is.** This is the repository's **invariant ledger**: each
> block records a design decision, the measurement that forced it, and the test that turns red when
> the decision is undone. It was the body of [`CLAUDE.md`](../CLAUDE.md) until 2026-09-18, when it
> had grown past the size Claude Code injects whole (150 000 characters — a rule past the cut
> reaches nobody), and was moved here **verbatim**, in its original order. Written in Norwegian
> because that is the maintainer's working language.
>
> **You need none of it to use the framework** — start with the [README](../README.md). It is
> published anyway, because the reasoning behind a decision is worth more than the decision, and
> because a rule kept out of sight is a rule that drifts without anyone noticing.
## Slik leses og skrives boken
- Hver rad er én beslutning: hva som ble valgt, målingen som tvang fram valget, og testen
(`tests/test_*_loadbearing.py`) som blir rød når beslutningen oppheves. Radene står i den
rekkefølgen de ble skrevet; nyere rader nederst.
- **Nye rader skrives HER, aldri i `CLAUDE.md`.** `CLAUDE.md` beholder kun de korte, umålte
grunnreglene og pekeren hit. Finn en rad med `grep -n '^- \*\*<stikkord>' docs/invarianter.md`.
- Radene er uendret fra `CLAUDE.md` ved flyttingen — en rad som siterer «denne fila» eller
«raden under» mener denne boken. **Ett unntak, uttalt:** funn 99-raden siterte MAFs
`DEFAULT_MAX_CONSECUTIVE_ERRORS_PER_REQUEST` med verdien inne i kodespennet — formen `test_doc_constant_sync_loadbearing`
leser som en sitering av en konstant i VÅR pakke (fail-closed på ukjent navn); verdien står nå i prosa
rett etter spennet, og linjereferansen er urørt.
## Radene
- **Framework-nøytral kontekst-søm:** OKF-bundle-navigasjon (`okf.py`) og den delte
`shared/`-kjernen er ren stdlib — null `agent_framework`/`mcp`-import, så samme bundles
konsumeres uendret av begge stacker (D7-portabel). Håndhevet av
`tests/test_okf.py::test_okf_is_maf_free`; importér aldri MAF inn i kontekst-laget.
- **OKF-navigert bundle-kontekst (ikke stuffing):** på bundle-stien bygges agent-lese-konteksten
ved å NAVIGERE bundelen (`okf.bundle_context`: index + frontmatter + cross-links, progressiv
disclosure) — aldri keyword-chunk-stuffing (målbilde §2/§4). `type: verdict`-laget ekskluderes
fra denne konteksten: tidligere dommer når hypotese-prompten KUN via den gatede ExpeL-folden.
Load-bearing: `test_bundle_context_excludes_verdict_layer` + empty-store-kontrollen i
`test_step1_expel_loadbearing.py` (realiseringssignalet lekker aldri inn via kontekst).
- **Navigasjons-kontrakten er hierarkisk, og escape — ikke dybde — er forbudt** (`method-spec`
§3 Steg 1): `navigate_bundle` følger cross-links REKURSIVT, dybde-først i først-sett-rekkefølge;
ledende `/` betyr **bundle-rot** (aldri filsystem-absolutt), alt annet er relativt til den
LENKENDE filas katalog; dedup skjer på **resolvert** sti (så `./a.md` == `a.md`, og sykler
termineres). `safe_resolve` er den ENESTE inn-/ut-av-bundle-testen (fail-closed) — den erstattet
den pensjonerte «separator = utenfor bundelen»-heuristikken, som forvekslet dybde med escape.
Manglende `index.md` er feil KUN i bundle-rota (navigasjon følger lenker, aldri katalog-enumerering).
Rendering er FLAT uansett dybde; nestede `index.md` er navigasjon, ikke innhold. Gaten er
commons-eide nav-goldens (`shared/examples/nav-golden-*/expected-read-context.md`, byte-nivå
fasit): `test_nav_golden_hierarchy_*` (positiv) + `test_nav_golden_escape_*` (negativ — en gate
som bare kan bli grønn beviser ingenting).
**Et hopp er TOLERERT, men ikke lenger TAUST (21.08):** `_walk` registrerer hver lenke den ikke
fulgte på `Bundle.skipped` — hvilken fil lenken sto i, lenketeksten ORDRETT (operatøren redigerer
den teksten, ikke den resolverte stien), og hvilken av de TO grunnene som gjaldt: `outside-bundle`
(escape — ofte bevisst, en lenke til nabobasen) eller `missing` (inne i basen, ingen lesbar fil —
nesten alltid en skrivefeil). Den tredje grenen, `canonical in seen`, er DEDUP og registreres
ALDRI — den er korrekt navigasjon og dét som terminerer sykler; en implementasjon som logget hvert
`continue` ville rapportert en frisk base som halvlest. Toleransen er URØRT (§4 krever at det ikke
kastes) — dette er synlighet, ikke en ny nekt. **Feltet DEFAULTER til tom tuppel, og det er
MOTSATT av `cost_baseline_anchored`s «påkrevd uten default»:** en tom trace er et ærlig POSITIVT
utsagn («hver lenke ble fulgt», `external_calls`-presedensen), mens en manglende bool måtte påstå
noe om en hendelse og begge påstandene ville iblant vært usanne. Sporet forlater kjøringen på
`RunResult.skipped_links` (RUN-nivå — navigasjonen skjer ÉN gang per kjøring, før noe forslag
finnes) og `DryRunReport.skipped_links`, aldri på `ProvenanceStamp`, som beskriver gaten som dømte
ÉN kandidat. `run.skipped_links_notice` er ENESTE renderer, tar den alt oppløste tuppelen og
returnerer `None` når ingenting ble hoppet over (omisjon, aldri tom rad — `announce`-regelen);
reason-TOKENET printes rått, så det finnes ingen andre display-vokabular å drifte fra feltet.
Ingenting av dette når `bundle_context` (som bygges av `index_summary` + `context_files` alene) —
dét er hva som holder nav-goldenene byte-uendret, og `Bundle(` har fortsatt ÉN konstruksjons-sted
(`okf.py`, i `navigate_bundle`). Load-bearing MÅLT
(`tests/test_navigation_visibility_loadbearing.py`), åtte mutasjoner alle røde mot HELE suiten +
grønn kontroll 897/5: detach `missing`-registreringen (6 røde) · detach `outside-bundle` (2 røde) ·
kollaps de to grunnene til én (2 røde) · registrer dedup-grenen (1 rød) · renderer returnerer alltid
linja (3 røde — inkl. kontrollene, altså er omisjonen selv gatet) · detach dry-run-printen (1 rød) ·
detach full-run-printen (1 rød) · konstant tom trace ut av `run_project` (4 røde).
- **Kuraterte skrivere kan ikke forfalske ingest-stempelet** (`ingest-spec` §3): `write_concept_file`
er repoets ene authoring-primitiv som materialiserer en konseptfil fra CALLER-oppgitt frontmatter,
og avviser derfor det KOMPLETTE eierskaps-stempelet (`generated: true` + `ingest_manifest`) med
`IngestStampError` — mens hver halvdel alene er lovlig (kuratert innhold kan bære ett
provenance-felt). Validering, ALDRI reparasjon: ingenting skrives. Uten dette kunne en kuratert fil
bli stille slettet av en senere re-materialisering, som fjerner nøyaktig det som bærer stempelet.
**`generated`-verdien er FAIL-CLOSED på YAML-1.1-sannhetsformer, ikke bare literalen `"true"`**
(funn 21.08, økt 52): `_YAML_TRUE_LITERALS` (`{"true", "yes", "on"}`, case-insensitivt) er
ENESTE vokabular, målt mot PyYAML sin `safe_load`-resolver — bare `1`/bare `y`/`n` er BEVISST
UTELATT (resolves til int/streng, aldri bool, så en YAML-leser ville uansett ikke lest dem som
stempelet). Uten dette var sjekken inert kun i kraft av at pinnet `llm-ingestion-okf v0.3.2`
skriver strengen `"true"` — en fremtidig `uv sync` mot en skrivemåte som `yes`/`on` ville latt
vakten slutte å vokte uten én lokal diff. Load-bearing MÅLT
(`tests/test_ingest_stamp_fail_closed_loadbearing.py`), fire mutasjoner alle røde mot HELE
suiten: revert til literalen `"true"` (2 røde — de nye sannhetsformene alene) · over-widen til å
inkludere `1`/`y` (1 rød) · `and``or` (4 røde, halv-stempel-lovligheten brutt) · detach gaten
helt (4 røde).
- **`IngestError` må overleve anyio-task-gruppene (kø-(x), 2026-08-03):** `stdio_client` og
`ClientSession` er hver sin task group, og anyio pakker ALT som forlater en av dem i en
`BaseExceptionGroup`. Derfor nådde `stdio_call_tool`s egne feil (`mcp_tool_error`,
`mcp_non_text_content`) kalleren som en exception group — aldri som `IngestError`, som er typen
hele Door A fanger og switcher på via `code`. `_unwrap_ingest_error` pakker ut og re-raiser den
eide feilen; alt annet re-raises URØRT (innsnevring, aldri blanket re-raise). Duck-typet på
`.exceptions`, fordi `except*`/`ExceptionGroup` er 3.11+ og repoet er `>=3.10`. **Ingen
canned-tool-test kunne fanget dette** — de går aldri inn i en task group; defekten dukket opp
første gang koden faktisk ble kjørt. En MCP-server på ingest-stien må eksponere en
**null-argument-tool** (URL-en bærer begge koordinatene, tool kalles med `{}`), så
`datasource.build_mcp_server` kan IKKE serve den — `retrieve_cost_docs(query)` har et påkrevd
argument og returnerer et error-result. De to er separate sømmer med vilje. Load-bearing MÅLT
(`tests/test_ingest_golden_mcp.py`), fem mutasjoner alle røde: detach unwrappingen · detach
`initialize()` · gjør feilkoden generisk · detach `isError`-grenen · endre ett byte av bodyen.
- **MCP-timeouten må komponeres MED anyios eget cancel scope, ikke `asyncio.wait_for` utenfra
(kø-(z), 2026-08-03):** STATE-premisset ("en utypet `TimeoutError` re-raises urørt") var FEIL —
målt mot en EKTE hengende server ga `asyncio.wait_for(run(), timeout=...)` aldri en
`TimeoutError` i det hele tatt; den kansellerer `run()` UTENFRA strukturen anyio selv eier
(`stdio_client`/`ClientSession`), og de to kansellerings-mekanismene komponerer ikke — målt
utfall var en `anyio.BrokenResourceError` inni en `BaseExceptionGroup` (en bakgrunns-reader-task
mistet skrive-enden midt i nedrigging). Fiksen er `anyio.fail_after(timeout_seconds)` NESTET
INNI begge task-gruppene, der anyio rigger ned sin egen struktur rent og raiser en ren
`TimeoutError`. **Innsnevringen dekker IKKE bare typen:** builtin `TimeoutError` er også
`socket.timeout` (≥3.10) og `asyncio.TimeoutError` (≥3.11), så et ubetinget `except TimeoutError`
ville mislabelt en HVILKEN SOM HELST `TimeoutError` som `mcp_timeout` — reviewet FØR commit
(advisor) fant nøyaktig dette. Retteslen er `anyio.CancelScope.cancelled_caught`: kun scopet som
faktisk traff SIN EGEN deadline tjener `mcp_timeout`-koden, ellers re-raises urørt (speiler
`_unwrap_ingest_error`s eierskaps-regel). **Ingen levende utløser finnes i dag** for en
"fremmed" `TimeoutError` på denne stien — MÅLT: MCPs eget per-request read-timeout
(`ClientSession.send_request`) konverterer sin `anyio.fail_after` til `McpError` FØR den når oss,
og en tool som raiser `TimeoutError` server-side blir et ordinært `isError`-resultat (samme
som enhver annen tool-exception) — begge verifisert empirisk, ikke antatt. Diskriminatoren er
likevel pinned med en syntetisk test (raiser fra `StdioServerParameters`-konstruksjon, inni
fail_after-scopet men FØR noen task group), fordi defektklassen ellers ikke har en nåbar sti å
bevise den mot. Load-bearing MÅLT (`tests/test_ingest_golden_mcp.py`) mot HELE 625-suiten, fire
mutasjoner alle røde: detach hele oversettelsen · revert til `asyncio.wait_for` · relabel koden ·
detach `cancelled_caught`-gaten (behold kun scope-presence). `anyio` promotert fra transitiv
(via `mcp`) til deklarert direkte dep (`pyproject.toml`) — modulen importerer den nå direkte.
- **Door A-innholdsgaten kan IKKE bo i `materialize` — den bor rundt den (P2/S1.b, 2026-08-09):**
`materialize` er en REN delegasjon til det pinnede `llm_ingestion_okf` v0.3.2s
`materialize_bundle`, som stager i minnet og utfører sin EGEN disk-fase; **det finnes ingen
callback mellom de to**, så en gate plassert «i skrivepunktet» kunne bare kjørt ETTER at bytene
hadde landet — en opprydding, ikke en gate (planens premiss, felt ved måling FØR bygging).
`materialize_gated` er derfor: **kopier bundelen → materialiser inn i kopien → skann det som ble
generert → publiser eller forkast.** **Kopien er BÆRENDE:** bibliotekets §3 eierskaps-skann,
kollisjons-gaten mot kuratert innhold og §6 index-merge leser alle den EKSISTERENDE bundelen —
staging i en tom katalog mister alle tre og publiserer en bundle uten kuraterte naboer og deres
index-lenker (datatap forkledd som sikkerhetsfiks; MÅLT av kun ÉN test, 809 andre merket
ingenting). `materialize` forblir UGATET med vilje — fire golden-suiter pinner bytene, og en
kaller som vil ha gaten ber om den ved navn. **Utfall per BUNDLE, diagnostikk per DOKUMENT:**
delvis publisering ville etterlatt bundle + index som svarer til INTET manifest, men
`import_bundle` itererer forbi første avvisning så hvert funn rapporteres. **Trust følger ORIGIN,
aldri channel** (`Origin.EXTERNAL`/`Channel.AUTOMATIC` = UNTRUSTED) — ikke et av guardens to
`Policy`-preset: `PRESET_USER_UPLOAD` bærer `quarantine_default=True` som Door A ikke har.
**Den laveste dispositionen er `warn`, ikke `allow`** (`warn < quarantine_review < fail_secure`;
`allow` finnes ikke) — en gate skrevet mot `== allow` ville avvist hvert dokument noensinne.
**Funnene til `log.md` (OKF §7), ALDRI konsept-frontmatter** — der ville de brutt fire goldener.
Guarden shipper ingen `py.typed`: mypy-override ALENE gjør sømmen type-BLIND, så `_stamp_line` +
koersering stopper `Any` ved grensen. Load-bearing MÅLT
(`tests/test_ingest_content_gate_loadbearing.py`), fem mutasjoner alle røde + grønn kontroll:
detach gaten · la den fyre ETTER publisering · `Origin.INTERNAL` · tom staging-katalog ·
rapporter kun første avvisning. **Målingen felte en VAKUØS test først:** en hard injeksjon
scorer `fail_secure` under BEGGE tierene, så `Origin.INTERNAL`-mutasjonen lot alle tre
avvisningstestene stå grønne — beslutningen så dekket ut uten å være testet. Båndet der tieren
faktisk avgjør er høy-entropi-innhold (`quarantine_review` vs `warn`), og testen ble skrevet mot
nøyaktig det.
- **`shared/` leses som PAKKEDE DATA, med arbeidstreet som overstyring (Fase 4a):** wheelen bærer
en byte-identisk speiling av hele `shared/`-treet under `portfolio_optimiser/_shared/`
(hatchling force-include i `pyproject.toml`), og `shared_root()` løser ved KALL-tid i fast
rekkefølge: `PORTFOLIO_SHARED_ROOT` → arbeidstreets `shared/` når det finnes → pakket kopi.
**Arbeidstreet er autoritativt i en checkout** — det er dét som holder pull-only-subtree-
kontrakten og de byte-eksakte goldenene urørt (målt: goldens shasum-identiske før/etter, og
`shared/` selv urørt). Den pakkede kopien er dét som gjør wheel og container mulig uten klone
(målt før: 1.0.0-wheelen bar 58 filer, null under `shared/`; etter: 122, hvorav 64 under
`_shared/`, og sdist→wheel-kjeden bærer treet). Speilingen er ALDRI en redigert derivat —
byte-identitet er egenskapen som lar commons-goldenene fortsatt gate den pakkede kopien.
Load-bearing MÅLT (`tests/test_shared_packaged_data_loadbearing.py`, ekte `uv build` i
fixturen — pakkekonfigen er selv en søm), tre mutasjoner alle røde mot hele suiten: detach
fallbacken (1 rød) · detach force-include (3 røde) · snu rekkefølgen (1 rød — ordnings-testen
var grønn før fiksen; dens kontroll på at pakket kopi FINNES er det som gjør flippen målbar).
- **AZURE-profilen leser MILJØET sitt ved kall-tid, ikke operatørens laptop (Fase 4b):** endepunktet
løses som første IKKE-TOMME av `_ENDPOINT_ENVS` — vårt eget `PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT`
FØRST, deretter Foundrys injiserte `FOUNDRY_PROJECT_ENDPOINT`. **Vårt vinner** (det er dét enhver
doc, recipe og test setter, så en eksport av det er en bevisst handling; en plattformverdi som
stille overstyrte den ville vært uforklarlig utenfra), og fallbacken er dét som lar samme image
kjøre hostet uten ekstra wiring. **Presedensen gjelder VERDIER, ikke deklarasjoner** — et
eksportert-men-tomt eget navn faller igjennom i stedet for å skygge et ekte injisert inn i en
fail-fast. Feilmeldingen navngir BEGGE: operatøren i en container og operatøren på en laptop
leter etter hver sin variabel. Credential velges av samme miljø: `AzureCliCredential` lokalt
(konstruksjon henter INGEN token — `az login` er operatørens manuelle steg),
`ManagedIdentityCredential` når `FOUNDRY_HOSTING_ENVIRONMENT` er satt, fordi containeren ikke har
noen Azure CLI og plattformen mynter den en egen Entra-identitet ved deploy. **Ikke
`DefaultAzureCredential`:** Learns egen MAF-veiledning sier «prefer a specific credential such as
`ManagedIdentityCredential` to avoid unintended credential probing» — probing ville vandret en
kjede som ikke KAN lykkes der, og gjort en konfigfeil om til en treg en. Markøren leses på
**truthiness, ikke presence**: en eksportert tom verdi er et shell-uhell, ikke et hosting-signal.
Klienten eksponerer INGEN credential-attributt (målt), så testene observerer via en
`FoundryChatClient`-recorder — med én UPATCHET arm, ellers ville de kun bevist at vi sender
*noe* som heter `credential`. Load-bearing MÅLT
(`tests/test_hosted_backend_loadbearing.py`), fire mutasjoner alle røde mot hele suiten + grønn
kontroll: detach credential-valget · presence i stedet for truthiness · detach fallbacken · snu
presedensen. **Fail-fast-testen ble skrevet VAKUØS først** (repoets 08-09-klasse):
`PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT` INNEHOLDER `FOUNDRY_PROJECT_ENDPOINT`, så asserten på det
injiserte navnet var oppfylt av vårt eget; den fjerner nå vårt navn før den sjekker.
- **Hostet inngang er en WRAPPER rundt `run_project` på ÉN asyncio-løkke (Fase 4d):** `main.py`
`hosting.py` serverer hosting-kontrakten (port 8088/`PORT` på truthiness, `GET /readiness`,
`POST /invocations`, SIGTERM → exit 0) med stdlib asyncio — ALDRI `as_agent()` (validator,
baseline-forankring, checker-gate og ledger ligger UTENFOR grafen, spike §5) og ALDRI tråder
(NG1-guarden: `http.server`s trådvariant ville lagt samtidige kjøringer på OS-tråder der
S3.3-resonnementet ikke holder; samtidige invocations interleaver som koroutiner — samme modell
som `run_portfolio`s bølger, og `/readiness` svarer mens en kjøring venter på modell-I/O, målt).
**Formen er MÅLT, ikke valgt:** hosting-pakkas `InvocationsHostServer` finnes kun i bygg som
krever core>=1.13.0 (treet låser 1.9.0; eneste 1.9-kompatible bygg er en forlatt alfa med defekt
metadata — importerer `mcp` udeklarert), og et gjenbrukt bygget workflow er SINGLE-USE på 1.9.0
(målt kall-serie [2, 0, 0] — rundetaket persisterer i objektet, så gjenbruk gir TOMME kjøringer;
ferskt objekt per kall er ren kontroll). Payloaden whitelistes på `run_project`s signatur —
ukjente felt NEKTES ved navn (400), aldri stille droppet (valg-doc §0-fella anvendt på vår egen
flate); `profile` defaulter til `azure` KUN her (containeren har ingen lokal endpoint;
`run_project`s egen default forblir LOCAL). Feilmapping ærlig: `ValueError` (pydantic-kontrakter
subklasser den) → 400, `BudgetExceeded` → 429 (EGEN rad under, 14.08), alt annet → 500
`{error_type, error}` (speiler `RunFailure`), og en
`Rejection` er en VELLYKKET kjøring → 200 — det negative utfallet tilhører payloaden, aldri
transporten. `outbox.outcome_payload` er den ENE kopien av validated/rejected-forgreningen
(delt av fil-skriveren og HTTP-responsen — to kopier drifter, kø-(p)-regelen). **Container-innpakningen
(`Dockerfile`/`azure.yaml`) ER FJERNET 14.08** — se python-only-invarianten under; resten av
denne raden står, for `main.py` startes nå direkte (`python main.py`). Load-bearing MÅLT (`tests/test_hosting_loadbearing.py`), seks mutasjoner alle
røde mot hele suiten på riktig test: detach felt-mappingen · dropp ukjente felt stille · flipp
400/500 · detach azure-defaulten · detach SIGTERM-handleren · detach main.py-shimen (de to
siste fanges KUN av subprosess-testen — P4-presedensen). Chunked request-bodies støttes ikke, og under CPU-bundne strekk (CBC-solven)
står readiness — uttalt, ikke skjult.
- **Whitelisten må komponere med den EKTE `run_project`, og artefaktene gates som RÅ TEKST
(Fase 4e):** alle 4d-testene ga `invoke` en stand-in som sluker `**kwargs`, så whitelisten kunne
navngi et felt `run_project` ikke tar — eller sende samme argument to ganger — uten at én test
merket det, mens en levende container svarte 500. **Sømmen er `run._default_factory`, ikke
payloaden:** `client_factory` NEKTES av whitelisten med vilje (en kaller av en hostet agent skal
aldri velge serverens modellklient), så å patche factory-defaulten er eneste injeksjonspunkt
flaten etterlater (samme argument `test_run_cli_loadbearing` gjør for `main()`). Testen sender
HVERT whitelistet felt og asserterer dekningen mot `_ALLOWED_FIELDS`, så et felt lagt til senere
ikke kan gli forbi uøvet. Profilen er **LOCAL, ikke den hostede defaulten**: AZURE-armen slår opp
et Foundry-deployment-navn i modell-mappet FØR noen klient bygges (`run.py` stempler provenance
med det), så den kan ikke fullføre offline — **containeren trenger altså `PORTFOLIO_MODEL_MAP`
eller et utfylt `data/model_map.json`, ikke bare et endepunkt** (målt her, ikke antatt).
**Artefakt-halvdelen av denne raden er PENSJONERT 14.08** sammen med `Dockerfile`/`azure.yaml`
(rå-tekst-gaten pinnet `--platform linux/amd64` + ÉN kopi av startkommandoen; to av radens fem
mutasjoner traff nettopp den). Whitelist-halvdelen står URØRT. Load-bearing MÅLT
(`tests/test_hosting_loadbearing.py`), de tre gjenværende mutasjonene alle røde på riktig test og
på INGEN annen: send `project_id` to ganger · whitelist et felt `run_project` ikke tar · fjern
`bundle_dir` fra whitelisten.
- **Et tak som fyrer er IKKE en krasj — `BudgetExceeded` får sin EGEN kanal (429), og trippelen
bæres som STRUKTUR (1b-køen, 14.08):** prosjektets første levende kjøring døde på
`rounds limit=12 observed=13`, og den hostede flaten svarte `500 {error_type, error}` — altså
nøyaktig det samme den sier når modell-endepunktet faller. **Beslutningen er S3.4-invarianten
anvendt på transporten:** `budget_stop` ble holdt UTENFOR `stop_reason` fordi de to stoppene
betyr motsatte ting, og å svare ressurs-utmattelse på krasj-kanalen gjør «det gikk ikke»
uleselig på nøyaktig samme måte. **IKKE 200, og det er dét som skiller den fra `Rejection`:**
en `Rejection` er en kjøring som KONKLUDERTE (og hører derfor i payloaden), mens et uttømt
budsjett produserte ingen `proposal` i det hele tatt — en 2xx ville latt en automatisk kaller
bokføre «analysert» for en kjøring som analyserte ingenting. **429 fordi betingelsen oppstår av
en TILDELING** (`max_rounds`/`max_tokens` er whitelistede request-felt, og å heve dem er
kallerens egen botemiddel), aldri av en serverfeil — derfor 4xx, ikke 5xx.
`kind`/`limit`/`observed` legges ut som felt, ALDRI `str(exc)` (kø-(y): de beskriver ÉN ledger,
og «hvilket tak bandt, og hvor langt forbi» er hele det operative spørsmålet); `error_type`
holdes UTE — den nøkkelen tilhører feilkanalen, og en kaller som switcher på dens
tilstedeværelse skal ikke finne den her. `budget_exhausted` er IKKE foldet inn i `outcome_type`,
og kunne ikke vært det: `outbox.outcome_payload` er den ENE kopien av den forgreningen og tar
`ValidatedProposal | Rejection`, som en uttømt kjøring ikke har noen av. **Ærlighets-grense,
uttalt:** ingen `Retry-After` — å vente endrer ingenting, botemiddelet er et større tak eller å
akseptere stoppet, og en header som lover tid ville vært en løgn. Load-bearing MÅLT
(`tests/test_hosting_loadbearing.py`), fem mutasjoner alle røde mot HELE suiten, hver med sin
egen signatur + grønn kontroll 867/4: detach armen (2 røde) · flat streng i stedet for struktur
(1 rød — struktur-testen ALENE, altså rir den ikke på status-asserten) · ekko `limit` som
`observed` (1 rød) · utvid armen til `Exception` (6 røde, inkl. 400-armen) · stemple
`error_type` på budsjett-kroppen (1 rød). **500-armens vitne ble byttet, ikke slettet:** den
eksisterende testen brukte `BudgetExceeded` som sin 500-prøve, så å bare legge til en ny arm
ville etterlatt krasj-kanalen uten vitne — den bærer nå en ekte ikke-budsjett-`RuntimeError`,
og er dét som holder den nye armen SMAL.
- **Påstander flaten gjør om SEG SELV gates som rå tekst, linjeforankret (Fase 3, A5):** to påstander
bodde i prosa der ingen test kunne se dem, og begge drev. (1) `env.template` sa at credential
resolves via `DefaultAzureCredential` — den har ALDRI gjort det; gaten leser de klassene
`backends.py` faktisk konstruerer **fra selve tilordningslinja**, ikke fra modulen, fordi
kommentarene NAVNGIR `DefaultAzureCredential` fire ganger for å begrunne hvorfor den ikke brukes —
en fil-bred substring-gate ville vært rød på nøyaktig den prosaen den beskytter (repoets
08-09-klasse, fjerde gang). (2) README-ens wheel-filnavn bærer versjonen bygget stempler på fila,
så en versjonsbump ville stille etterlatt en publisert install-kommando som peker på en fil som
ikke finnes. **Hver positiv assert er paret med en KONTROLL** på at det søkes etter noe som finnes
— en ekstraktor som stille finner null lager en gate som bare kan bli grønn. Load-bearing MÅLT
(`tests/test_public_surface_claims_loadbearing.py`) mot HELE suiten, begge røde på riktig test og
på INGEN annen: gjeninnfør credential-påstanden (2 røde, 844 grønne) · la wheel-filnavnet drifte
(1 rød, 845 grønne). Bumpen selv var den tredje målingen — `pyproject` 1.0.0 → 1.1.0 gjorde
README-gaten rød alene, FØR README ble rettet. **`repo-standard`-gaten kan IKKE verifisere denne
fasen:** den var OK/20 sjekker før arbeidet startet, og `RELEASE-STALE` er strukturelt blind for
repo med null utgivelser (org-ops hovedbok #18). Bevisene er Forgejo-APIet, filinnholdet og
ren-klon-kjøringen.
- **GOVERNANCE er en LENKE, aldri en kopi (org-ops D11):** én kanonisk `GOVERNANCE.md` bor i
`repo-standard` og hvert repo lenker den fra README. Å skrive vår egen ville gjort oss til kopi
nr. 12 av en fil D11-bølgen holder på å rydde vekk. Bus-faktor 1 står uttalt i den kanoniske
teksten, ikke i vår.
- **To falsifiserere, samme kandidat (Steg 3/4, målbilde §2/§6):** den deterministiske validatoren
gater *tallene* (blokkerende), checkeren gater *resonnementet*. Checkeren avslutter turen med en
`VERDICT: APPROVE` / `VERDICT: REJECT — <grunn>`-linje; et eksplisitt avslag blokkerer et ellers
validert forslag (`run_project` overflater begge debatt-deltakere via `output_from=agents` og
overstyrer utfallet til en checker-kilde-`Rejection`). Gaten er opt-in-reject (fail-open ved
manglende markør), og `provenance.validator_decision` forblir ærlig — den speiler KUN validatoren,
aldri checkeren (de to falsifisererne blandes aldri). Load-bearing:
`tests/test_checker_gate_loadbearing.py` blir rød ved BEGGE detach-punkt (revert `output_from`,
eller fjern override). Checkeren «må faktisk gate, ELLER vi slutter å kalle det maker-checker».
- **Informert forbedring, bundet (Steg 5, målbilde §5/§7):** `generate_via_llm`s ytre
`max_attempts`-løkke er ikke lenger blind — validatorens *forrige* `Rejection.reason` mates inn i
neste forsøks prompt (`_build_messages(prior_rejection=...)`), så proposeren korrigerer i stedet
for å gjenta. Kun den mest-nylige falsifiseringen (`last`, ikke akkumulert), kun grunnen (aldri
forrige proposal-JSON), under EKSISTERENDE tak (`meter.tick_round` + `max_attempts` — ingen ny
løkke; «forbedre til god nok» uten tak er forbudt). Eneste *per-forsøk*-falsifiserer her er
validatoren; å seede generering med checker-*kritikken* er run-nivå og separat scoped (IKKE bygget
her) — så koden påstår ikke mer enn den gjør. Load-bearing:
`tests/test_step5_refine_loadbearing.py` blir rød når reason-injeksjonen detaches (utfallet
flipper aldri + reason-verbatim-asserten faller); kontrollen beviser at løkka forblir bundet.
- **Falsifiserings-historikken FORLATER generate-løkka som typet returverdi (Steg 5, del 2):**
`generate_via_llm` returnerer `GenerationResult(outcome, refinements)` — ikke lenger bare
`ValidatedProposal | Rejection`. Før dette forbrukte løkka hver `Rejection` internt (`last`) og
DROPPET den, så Steg 5 var det ene av åtte steg uten observerbart utfall. **Returverdi, ikke
out-parameter/callback:** en returnert verdi kan ikke bli stille tapt av en kaller som glemmer å
sende en samler, og mypy tvinger hvert kallsted til å ta stilling. **`refinements` bærer KUN
avvisninger som faktisk ble matet tilbake** i et senere forsøks prompt — ved uttømt budsjett ER
den siste avvisningen `outcome`, den informerte ingenting, og å telle den med ville vært
dobbeltføring (en «samle alt»-implementasjon består den positive testen og faller på kontrollen).
Taket er URØRT: `max_attempts` + `meter.tick_round` står, og `last` driver fortsatt prompten alene
(prompt-veksten er uendret). `run.py` akkumulerer på tvers av `_evaluate`-kallene, så
`_evaluate_mandate` er urørt; `RunResult.refinements` er defaultet (`coverage`-presedensen), og
med mandat er den KONKATENERT på tvers av tiltak, ikke nøklet per tiltak (uttalt ærlighets-grense).
`scripted_factory` tar nå `str | reply_selector` per rolle, så simuleringens proposer korrigerer
seg innholds-nøklet uten en andre scriptet kropp. Load-bearing MÅLT
(`tests/test_step5_history_loadbearing.py`), fire mutasjoner: detach returneringen · samle-alt ·
detach run-wiringen · reverter simuleringens proposer til konstant svar.
- **Lang/async fil-løkke (Steg 7, målbilde §3/§7):** `run_project(verdict_dir=...)` er den lange
tilbakemeldings-tidsskalaen — en ekspert/persona dropper en verdict-fil (vanlig JSON, RAW-laget
per §10 R2) i en inbox-mappe ETTER en kjøring, og en separat, senere kjøring `load_verdicts_from_dir`
`store.add` **merger** den inn FØR Steg-1-folden (ingen endring i folden), så dommen når neste
hypotese. **Rolledeling (§3, ufravikelig):** systemet LESER mappa; eksperten/personaen SKRIVER den
`run_project` persisterer ALDRI sin egen fangede dom tilbake (det er outbox/Steg 8). Merge, aldri
erstatt (`run_portfolio`-tråding intakt); tolerant last (manglende mappe / fremmede / halvskrevne
filer hoppes over, ikke raises — RAW-lag, kontrast `okf.load_ir_projection`s fail-fast); `id` leses
verbatim, re-mintes aldri. `write_verdict` er den offentlige authoring-primitiven (persona/test +
framtidig Steg 8), men wires IKKE inn i `run_project`. Load-bearing:
`tests/test_step7_async_loop_loadbearing.py` — en dom droppet etter Run A MÅ nå Run B's prompt
(Run B bruker FERSK store → overføringen er fil-løkka, ikke in-memory-carryover); tom-inbox-kontroll
beviser kausalitet. Markør = realiseringsverdi som finnes ingen steder i bundelen (ikke frøets 0.82).
- **Gated wiki-promotering (Steg 8, målbilde §3/§6/§7):** når en ekspert/persona GODKJENNER et
utfall, løfter `verdicts.promote_verdict` det fra RAW output-laget inn i kontekst-laget (OKF-bundelen)
som en `type: verdict`-konseptfil, navigerbar av neste kjørings `seed_store_from_bundle`. **Gaten er
fail-closed:** en ikke-godkjent dom (`decision ∉ {approved, approved_with_adjustment}`) raiser
`PromotionRefused` og skriver/linker INGENTING — kun menneske/persona-godkjent kunnskap når wikien,
aldri rå agent-output (selv-forurensning). Provenance-stemplet (hvem/eksperiment/når; `timestamp` er
påkrevd keyword, ingen wall-clock-default → deterministisk). **OKF-skriveren bor i `okf.py` og er ren
stdlib** (D7-portabel, MAF-fri — håndhevet av `test_okf_is_maf_free`); navigasjon følger KUN
index-cross-links, så `promote_verdict` linker filen i `index.md` via en NØYTRAL label (ellers lekker
signalet inn i `index_summary``bundle_context` utenom gaten). **R4 = valgfri+gated:** `promote_verdict`
er en offentlig opt-in-primitiv, wires IKKE inn i `run_project` (speiler `write_verdict` — systemet
leser; gaten/personaen promoterer). Ærlighets-grenser: promotert fil er MINIMAL (læringssignal kun som
`description`/body-prosa, reproduserer ikke seedens strukturerte `realization_rate` o.l.); id =
læringsnøkkel, så to godkjenninger om samme kandidat deler filnavn (last-write-wins, som `write_verdict`)
— wikien vokser én kuratert fil per distinkt kandidat, ikke per dom-hendelse. Load-bearing-trio
(`tests/test_step8_promotion_loadbearing.py`): gaten avviser ikke-godkjent dom (RØD uten gate); godkjent
dom er navigerbar (RØD når `link_in_index` detaches); promotert signal holdes ute av `bundle_context`
(RØD når en beskrivende index-label lekker det inn). Index-RMW er ikke-atomisk (enprosess-MVP).
- **En dom nøkles på SIN kandidat, ikke bundelens ene IR-projeksjon (S3.2):** `seed_store_from_bundle`
leser hver `type: verdict`-fils EGNE strukturelle felt fra frontmatter (`affected_codes` /
`measure_type` / `claimed_saving_nok`); mangler de, faller nøklingen tilbake til
`bundle_candidate_features` — så hver pre-S3.2-seed står uendret (fallbacken er BÆRENDE: fjernes
den, brekker step1-suiten ved collection). Uten dette kollapset en bundle med dommer om flere
kandidater dem på ÉN nøkkel, og en dom om kandidat B scoret perfekt strukturell match mot
kandidat As query. **ALLE TRE felt eller ingen:** en delvis erklæring raiser
`VerdictFrontmatterError` i stedet for å slås sammen med bundle-kandidaten — sammenslåingen ville
myntet en nøkkel som tilhører INGEN av kandidatene. Validering, ALDRI reparasjon (speiler
`write_concept_file`); den tolerante hopp-over-regelen hører til RAW-innboks-laget.
`claimed_saving_nok` parses med `json.loads` — SAMME literal-regel IR-projeksjonen gikk gjennom —
og skrives tilbake som `str()` av råverdien, fordi `_mint_id` hasher den (`30000``30000.0`; en
normaliserende skriver ville splittet én kandidats signal på to id-er). `promote_verdict` skriver
de tre feltene, så en promotert dom ikke utgir seg for målbundelens kandidat; nøkkelen er
signal-fri, så Steg-8s no-leak-egenskap står. **Semantikken er bestemt HER** — commons' seeding-regel
(`method-spec` §3 Steg 1) hadde ikke kommet; D7-speiling forblir ÅPEN. Load-bearing MÅLT
(`tests/test_step32_multicandidate_loadbearing.py` + `test_step8_promotion_loadbearing.py`), fem
mutasjoner alle røde: detach per-dom-nøklingen · detach feltene `promote_verdict` skriver · gjør en
delvis/uparsebar nøkkel tolerant · normaliser magnituden ved skriving · fjern fallbacken (kontroll).
- **Den deterministiske gaten er FORANKRET i prosjektets faktiske kostbaseline (S4.0, F3/F8):** før
S4.0 resonnerte HVER stage kun om tall forslaget selv oppga, så en internt konsistent hallusinasjon
klarerte hele gaten. `validate_proposal(..., baseline=...)` avstemmer nå hvert `affected_item` mot
`CostBaseline` (`ir.py`) i en **stage 0 — FØR løseren** (billigst, og den eneste som skiller en
oppdiktet linje fra en ekte; å bruke en CBC-solve på tall som ikke tilhører prosjektet er arbeid på
et krav som uansett ikke kan valideres). To uavhengige avvisninger: ukjent kostkode, og ekte kode
med `quantity`/`unit_cost` utenfor `tolerance` (default 5 %, **konfig**) relativt til BASELINE-verdien.
Validering, ALDRI reparasjon — forslaget avvises, aldri stilltiende korrigert til baselinen.
**Argumentet er VALGFRITT** (`None` = pre-S4.0-oppførsel), men begge run-stier SETTER det: road-stien
fra `project.cost_items` (alltid — estimatet ER prosjektet), bundle-stien KUN når bundelen shipper
`cost-baseline.json` (`load_optional_cost_baseline`) — en pre-amendment-bundle er legitimt
uforankret, og det er dét som holder commons-goldenene byte-identiske. **Toleransen stopper ved
fravær:** en baseline som FINNES men er malformed raiser på BEGGE loaderne (å lese korrupt som
«ingen baseline» ville gitt en uforankret gate i forkledning — samme resonnement som `read_spend`).
**F8:** metode-cap-en slås opp i `METHOD_CAPS`-registeret (måletype→brøk, injiserbart), ikke mot
`energy_efficiency`-literalen — en andre metode er nå data, ikke en redigering av validatoren.
Format- og toleranse-semantikken er bestemt LOKALT (commons-amendmentet D-A pkt. 2 kom aldri, som i
S3.2); **D7-speiling ÅPEN.** Load-bearing MÅLT (`tests/test_s40_cost_baseline_loadbearing.py`), seks
mutasjoner alle røde: detach avstemmings-stagen · detach magnitude-toleransen · detach road-wiringen ·
detach bundle-wiringen · ignorer det injiserte cap-registeret · gjør den valgfrie loaderen tolerant.
**En UFORANKRET kjøring sier det nå — og BEGGE utsagn stammer fra kjøringens ENE oppslag, aldri
en andre lesing av bundelen (21.08):** `ProvenanceStamp.cost_baseline_anchored` er PÅKREVD uten
default (begge defaults lyver: `True` lar en glemsom konstruktør påstå en ankring som ikke skjedde,
`False` underrapporterer en ekte — en binær kjensgjerning om en falsifiserer har ingen ærlig
default), og `DryRunReport` bærer det samme fordi en dry-run stopper før noe stempel finnes.
`run.cost_baseline_notice(anchored)` er ENESTE renderer, tar den alt oppløste BOOLEANEN, og
returnerer `None` når kjøringen ER forankret — omisjon, aldri en tom rad (`announce`-regelen).
**IKKE foldet inn i `mandate.announce`, og det er en MÅLING:** den fyrer kun med `--mandate`, så
nettopp de bare bundle-dry-runsene defekten ble målt på ville fortsatt sagt ingenting — og den
renderes FØR `run_project`, altså før noen har oppløst baselinen. Utboksen trengte ingen endring
(`write_proposal` dumper hele stempelet). Ankeringen forblir VALGFRI: dette er synlighet, ikke en
ny nekt, og golden-transkriptet er byte-uendret fordi demoen kjører en base som HAR fila.
Portefølje-armen er DEFENSIV og uttalt (ingen referanse-prosjekt setter `bundle_dir`, så den er
unåbar i dag — `budget_stop`-presedensen; testen driver en crafted `PortfolioResult`). Load-bearing
MÅLT (`tests/test_baseline_visibility_loadbearing.py`), seks mutasjoner alle røde mot HELE suiten +
grønn kontroll 885/5: konstant stamp-wiring (3 røde) · konstant dry-run-wiring (1 rød) · detach
dry-run-printen (1 rød) · renderer returnerer alltid linja (2 røde — inkl. den forankrede
kontrollen, altså er omisjonen selv gatet) · detach full-run-printen (1 rød) · detach
portefølje-printen (1 rød). Det PÅKREVDE feltet tvang fem eksisterende test-konstruktører til å ta
stilling — det er egenskapen, ikke friksjonen.
- **Globalt token-tak håndheves FØR kall, aldri bare etterpå (S3.4, F10):** `PortfolioBudget` +
`PortfolioMeter` er ÉN ledger over hele porteføljepasset (og — seedet av `read_spend` — på tvers
av pass), mens per-run `Budget`/`TokenMeter` er uendret. Taket har tre tenner, med hver sin jobb:
(1) **oppstartsnekt** — en rest som ikke kan finansiere én kjøring raiser `BudgetRefused` FØR noe
lastes (et pass som har råd til null prosjekter er en caller-feil, ikke et resultat);
(2) **wave-assembly** — et prosjekt som ikke kan finansieres blir ALDRI STARTET, og passet stopper
strukturert (`budget_stop` + `stopped_early`, fullførte runs bevart). Aldri-startet er poenget:
et ufinansiert prosjekt som bare avbrytes har allerede kostet kall. Fordi hele bølgen sjekkes mot
SAMME før-bølge-rest, **reserverer** admission hver members krav — ellers overforplikter en bølge
av k taket med inntil k kjøringer; (3) **pre-call-guard** i `BudgetMiddleware` — et kall resten
ikke kan betale for NEKTES i stedet for å gjøres (post-charge-sjekken består: ekte usage kjennes
først etterpå, så guarden stopper NESTE kall, aldri det som er i lufta). `budget_stop` er et EGET
felt, aldri `stop_reason`: et mål-stopp er suksess, dette er ressurs-utmattelse — å slå dem sammen
ville gjort «vi stoppet» uleselig. `record`/`check` er SPLITTET i `PortfolioMeter` fordi tokens
leverandøren allerede har fakturert må nå ledgeren selv når samme charge bryter run-taket.
Spend-fila er vår EGEN regnskapstilstand: `read_spend` raiser på korrupt innhold (kontrast det
tolerante RAW-inbox-laget — å lese korrupt som null ville gitt tilbake et allerede brukt budsjett),
og `write_spend` tar et PÅKREVD `stamp` uten wall-clock-default (byte-determinisme, speiler
`promote_verdict`). `portfolio_meter` og `meter_factory` er gjensidig utelukkende — en
factory-meter er ubundet, så begge sammen ville gitt et pass som SER capped ut uten å være det.
Load-bearing MÅLT (`tests/test_portfolio_budget_loadbearing.py` + `tests/test_budget.py`), seks
mutasjoner alle røde: detach wave-sjekken · detach pre-call-guarden · detach bølge-reservasjonen ·
sjekk run-taket før global kreditering · detach oppstartsnekten · gjør `read_spend` tolerant.
- **`BudgetExceeded`s tre felt beskriver ÉN og samme ledger (kø-(y)):** `kind`/`limit`/`observed`
er ett strukturert stopp-event, og `observed` var det udefenderte tredje feltet — MÅLT: fire av
fem raise-steder (`TokenMeter.charge`, `tick_round`, og BEGGE armene i `exhausted()`) kunne
rapportere hvilken som helst verdi uten at 621 tester merket det; bare `PortfolioMeter.check`
var dekket. **Fellen som skjulte det:** `spikes/_harness.py:41` har sin EGEN kopi av
`BudgetExceeded`/`TokenMeter`, så `spikes/test_harness.py`s `observed`-assert dekker IKKE den
shippede modulen — produksjonens `tick_round` hadde null direkte test. `exhausted()` er det
ENESTE stedet som VELGER ledger (S3.4-guarden), så en refusal som sier `portfolio_tokens` mens
den rapporterer runets eget forbruk ville villedet enhver leser. **Testene bygges med
`observed != limit`**: ved nøyaktig-uttømt sammenfaller de to, og en test skrevet der kan ikke
skille dem — den ville passert på en implementasjon som ekkoet taket tilbake som forbruket.
Ingen defekt funnet i verdiene selv (kontrast (x)/(p)): trippelen var koherent alle fem steder,
gapet var rent dekning. Load-bearing MÅLT (`tests/test_budget.py`), ni mutasjoner alle røde:
fem `observed`-mutasjoner (inkl. kontrollen) + fire ekko-mutasjoner.
- **Pengetall kvantiseres i ÉN orden, fra ÉN kilde (kø-(p)):** `ledger.to_ore` er rammeverkets ENE
NOK→øre-konvertering (Decimal, ROUND_HALF_UP), og den brukes **per pengebeløp — deretter summeres
HELTALL**. `run.py` importerer den; aldri en egen kopi (to kopier av en penge-konvertering drifter,
og en driftet kopi setter de to sidene av en mål-sammenligning på hver sin skala — S4.0s
`REPLIES`-presedens). Før dette summerte `run.py`s mål-baseline `Project.total_cost`-FLOATS og
kvantiserte totalen ÉN gang, mens `SavingsLedger` summerte per-kandidat-heltall — og de to ordenene
møttes i nøyaktig ETT punkt: `_goal_limit_if_reached`, der et prosent-mål avgjør om et
porteføljepass stopper tidlig. **Målt divergens:** tre linjer à `60000.005` NOK er `18000003` øre
kvantisert først, men `18000001` summert først (float-drift til `180000.01499999998`) — nok til å
vippe et mål. **Kvantiser-først valgt fordi hver `CostItem` ER et beløp** (S4.0 gjorde per-linje
`quantity`/`unit_cost` til validatorens grunnsannhet), og fordi heltallsaddisjon er assosiativ →
rekkefølge-uavhengig under D-D-bølgemodellen, som float-folden ikke er. **To kallsteder, ikke ett:**
portefølje- og per-prosjekt-baselinen er separate, og en fiks på bare den ene OVERLEVDE hele suiten
(målt). Load-bearing MÅLT (`tests/test_money_quantization_loadbearing.py`), fem mutasjoner alle
røde: detach portefølje-baselinen · detach per-prosjekt-baselinen · gjeninnfør en privat kopi i
`run.py` · endre avrundingsmodus · la `realize` gå utenom `to_ore`. **Ærlighets-grense:**
`sum_claimed_saving_nok` (`run.py:_aggregate`) er BEVISST urørt — et float-NOK-rapportfelt som
aldri kvantiseres og aldri sammenlignes mot ledgeren, altså utenfor ordens-defekten.
- **En BETALT test får sin EGEN opt-in, og instrumentet bevises GRATIS (Fase 1b, siste trinn):**
`tests/test_full_run_live.py` kjører hele `run_project`-stien mot et ekte Foundry-deployment, og
gates på **fire** ting — de to Foundry-variablene, `PORTFOLIO_MODEL_MAP`, og et TREDJE, distinkt
`PORTFOLIO_LIVE_FULL_RUN` lest på **truthiness** (4b-invarianten). **Den tredje variabelen er
load-bearing, ikke pynt:** `test_foundry_profile_live.py` (klient-probe) og `test_portfolio_live.py`
(fan-out) gatet på nøyaktig SAMME to variabler, så å gjenbruke det paret ville betydd at en
operatør som eksporterer dem for den BILLIGE ett-ords-proben også fyrer den dyre fullkjøringen —
altså at måleprotokollens stige («bevis så mye som mulig før det dyre trinnet, så en feil er
attribuerbar») kollapser til ett trinn. **MÅLT:** med begge Foundry-variablene satt SKIPPET den
dyre, og den billige var grønn. **Regelen gjelder HVER betalt arm, ellers er den ingen regel:**
`test_portfolio_live.py` passerer ingen `client_factory` og er derfor selv en betalt kjøring — den
fyrte på to-variabel-paret fra et bart `uv run pytest`, og ble gatet på den TREDJE variabelen i
samme slengen. Å la den stå ville gjort denne raden halvt usann den dagen den ble skrevet; en
invariant som beskriver én av to armer er en påstand flaten gjør om seg selv uten dekning, som er
nøyaktig Fase 3-klassen. Den billige klient-proben beholder to-variabel-gaten med vilje — den ER
det billige trinnet. `PORTFOLIO_MODEL_MAP` er med av en annen grunn — attribusjon: uten
den feiler kjøringen av en KONFIGURASJONS-årsak som ser ut som en modell-feil.
**Asserten bor i ÉN kopi** (`conftest.assert_full_run_contract`, kø-(p)) og er smal med vilje:
fraværet av `{run_id}-parse-failures.json` (økt 35-invarianten «filens tilstedeværelse er
signalet») + at `validator_decision` avgjorde. **En `rejected` BESTÅR** — påstanden som felles er
at det strukturerte skjemaet ER akseptert av det levende endepunktet, ikke at modellen resonnerer
godt; å kreve `validated` ville vært en modell-dømmekraft-påstand ingen enkelt kjøring kan bære.
**Iron Law uten å betale to ganger:** et betalt kall kan ikke kjøres rødt-så-grønt, så
diskrimineringen bevises OFFLINE av `tests/test_live_full_run_contract.py` — to armer over samme
helper (én parse-feil → kontrakten MÅ feile; alle parser → MÅ passere). Load-bearing MÅLT, to
mutasjoner med hver sin distinkte signatur: detach artefakt-sjekken (T1 rød ALENE — kontrakten
degraderer da til `test_portfolio_live.py`s `len(runs)==1`-klasse) · raise ubetinget (T2 rød
ALENE — den motsatte vakuiteten, en live-test som bare kan bli rød). **Det betalte kallet er
MÅLINGEN, aldri beviset på at måleinstrumentet virker.**
- **Offline simulering = primært metode-bevis (kostnadsdrevet, erstatter §11.8):** operatøren kjører
IKKE MAF mot ekte modell (verken Azure/Foundry eller Ollama — API for begge repoene er for kostbart
privat). `portfolio_optimiser.simulation` driver `run_project` med en SKRIPTET syntetisk chat-klient
(`ScriptedChatClient``OpenAIChatCompletionClient` — IKKE bare `BaseChatClient`, ellers no-op-er
`BudgetMiddleware`) over to kjøringer adskilt av en promotering, og viser at læringssløyfa lukkes:
Run A's godkjente persona-dom (markør fraværende fra bundelen) → `promote_verdict` → re-seed → Run B's
hypotese-prompt bærer markøren (tom-wiki-kontroll på Run A beviser kausalitet). **Ærlighet (§1,
ufravikelig):** beviser plumbing + deterministisk ryggrad + at dataflyten lukkes — IKKE at en levende
LLM ville produsert forslaget/dommen (skriptede stand-ins). Den genuine modell-atferd-sammenligningen
lever på Claude-SDK-siden (minimal API-kjøring). Skriptet klient = MAF-side stillas, IKKE delt
(`shared/` forblir framework-nøytralt). Kjøres `uv run python -m portfolio_optimiser.simulation`.
Load-bearing: `tests/test_simulation_loadbearing.py` blir RØD når promoteringen detaches.
- **Demoen KJØRER begge tidsskalaer, og de bæres av HVER SIN markør (P1/S1.a):** Steg 7-linja sa
«lang fil-løkke», men `simulate_learning_loop` kalte `run_project` UTEN `verdict_dir` — dommen kom
som funksjonsargument (`verdict_input`, den KORTE i-kjøring-fangsten). Nå skriver en ekspert en
faktisk fil (`write_verdict`) i en innboks MELLOM kjøringene, og Run B får `verdict_dir=`.
**Hvorfor en ANDRE markør og ikke persona-dommen gjennom innboksen:** Steg 7 (innboks) og Steg 8
(promotering) er to ULIKE mekanismer som begge ender i Run B's hypotese-prompt — med én delt
markør kunne hver av dem båret den alene, og `test_simulation_loadbearing.py`s promoterings-assert
ville stått GRØNN med promoteringen detached, altså blitt vakuøs. `simulate_learning_loop` raiser
derfor `ValueError` når `inbox_marker == marker`. Innboksen ligger VED SIDEN AV bundle-kopien,
aldri inni: en dom-fil inne i bundelen når neste kjøring som navigerbar kontekst, som er en annen
mekanisme i denne sin forkledning. Sentinel-`id` (aldri myntet) — `_mint_id` hasher kandidat-
featurene, så en myntet id kolliderer med den promoterte dommens, og `VerdictStore.add` er
first-write-wins per id. Load-bearing MÅLT (`tests/test_step7_demo_inbox_loadbearing.py`), tre
mutasjoner røde + grønn kontroll: detach `verdict_dir=` · la Run B lese en TOM mappe · sett
innboks-markøren til en verdi som FINNES i bundelen.
- **Det skriptede manuset nøkles på PROSJEKT-ID-en, og det er MÅLT:** `scripted_proposer(candidates)`
bygger simuleringens proposer fra et `ScriptedCandidate`-register, så et nytt prosjekt er en
data-oppføring (demo-uke-plan §4 risiko 2) — ikke et andre håndskrevet manus. **Hvorfor ikke
kostkode/tiltaksnavn:** to prompt-former når selectoren — debatt-prompten bærer hele
bundle-konteksten, mens genererings-prompten (`generate._build_messages`) bærer
`Project: {id} - {name}` pluss *debatt-outputen* som kontekst, altså selectorens EGET tidligere
svar. Kostkode og tiltaksnavn står derfor i genererings-prompten kun fordi manuset selv la dem
der; å nøkle på dem ville nøklet manuset på sin egen output. Prosjekt-ID-en er den ene
identifikatoren BEGGE former bærer og som RAMMEVERKET stempler. **Validering, ALDRI reparasjon:**
null treff — eller mer enn ett — raiser `ScriptedCandidateError`; et default-svar ville besvart et
uregistrert prosjekt med et ANNET prosjekts tall, som på skjermen er umulig å skille fra en riktig
kjøring, og en tvetydig blob er et DATA-problem som skal falle på generalprøven, ikke avgjøres av
register-rekkefølgen. `flip_key` MÅ være fraværende fra bundelen (ellers bærer forsøk 1s prompt
den allerede). `simulate_learning_loop` tar `project_id` ved siden av `bundle_dir`. Load-bearing
MÅLT (`tests/test_content_keyed_script_loadbearing.py`), fem mutasjoner alle røde + grønn
kontroll: detach nøklingen · én global flip-key · fallback ved ukjent prosjekt · første-treff ved
tvetydighet · detach `project_id`-argumentet. **Flip-key-testen ble skrevet om under målingen**
første form asserterte på FØRSTE register-oppføring, der «den matchede kandidatens nøkkel» og
«`candidates[0]`s nøkkel» sammenfaller; den kunne ikke skille de to implementasjonene.
- **Demoen kjører FORANKRET, og baselinen DERIVERES fra manuset (P4 pkt. 0):** før dette regnet
validatoren i demoen kun på tall forslaget selv oppga — S4.0-forankringen aktiveres bare når
kunnskapsbasen shipper `cost-baseline.json`, og ingen bundle under `shared/` har den. Reserven kan
aldri få fila DER (pull-only subtree + kriterium 8 krever goldenene byte-uendret), men det er en
*plasserings*-begrensning: `materialize_anchored_bundle` KOPIERER bundelen og legger fila til
utenfor `shared/`, og kjørestien (`run.py``load_optional_cost_baseline`) er da NØYAKTIG samme
søm en levert bundle ville brukt. **Retningen på avledningen er bærende:** reservens tall er
syntetiske, så manus-registeret er eneste grunnsannhet — `baseline_from_scripted_candidate`
avleder i KODE, aldri en andre håndskrevet kopi av de samme tallene (to kilder drifter, og drift
er nøyaktig det 10 %-prøven modellerer). På GO-dagen snus retningen (plan P3 b: registeret skrives
FRA levert fil). Begge skriptede svar må oppgi SAMME kostlinjer (`ValueError` ellers): var de
ulike, ville hypotese #1 blitt avvist av stage 0 istedenfor av P90 — samme REJECTED-linje på
skjermen, annen mekanisme. **Forankringen er usynlig i alt annet stdout** (målt: eneste diff mot
uforankret er KUNNSKAPSBASE-blokka), derfor printes den erklærte baselinen, og derfor er
`provenance` et PÅKREVD argument til `_baseline_lines` — kallstedet som velger bundelen er det
eneste som vet hvor tallene kom fra. Load-bearing MÅLT
(`tests/test_anchored_reserve_loadbearing.py`), fem mutasjoner røde + grønn kontroll: detach
main-wiringen · detach fil-skrivingen · la filnavnet drifte · detach to-svars-enigheten · returner
et literal i stedet for det avledede. **Målingen felte TESTEN først** (samme klasse som 08-06):
«ingen kostbaseline erklært» INNEHOLDER «kostbaseline erklært», og `ENERGI-TOTAL-EL` står allerede
i Steg 2-linja — begge assertene overlevde detach-mutasjonen. De to grenene deler nå ingen ordlyd.
- **Demoens stderr: rund-taket dempes, `ExperimentalWarning`-paret PINNES (P4 pkt. 2):** målt 08-09
var stderr seks linjer. `quiet_expected_round_cap_notice()` dropper KUN
«reached max_rounds=…; forcing completion» — en hendelse demoen selv provoserer (maker/checker
kjører til taket) — via et filter på den EMITTERENDE loggeren (`ROUND_CAP_LOGGER`, lest ut av MAFs
kilde). Logger-filtre gjelder kun loggeren posten ble logget GJENNOM; en forfars filtre konsulteres
aldri. Filteret installeres i `main()`, ALDRI ved import — en bibliotek-modul skal ikke
omkonfigurere loggingen til en konsument. **De to `ExperimentalWarning`-linjene dempes IKKE:** de
fyrer mens `portfolio_optimiser/__init__.py` importerer `run``agent_framework`, altså alltid FØR
`simulation` sin egen importblokk, under BEGGE kjøreformer — så å dempe dem ville krevd et
warnings-filter inne i bibliotekpakken, dvs. at rammeverket bestemmer hva MAF får si til enhver
konsument. En wrapper bak konsoll-kommandoen ble avvist av en andre grunn: da ville de to
kjøreformene skrevet ULIK stderr, og en byte-fasit ville pinnet kommandoen i stedet for programmet.
**Dempingen er smal ved konstruksjon** — nøklet på meldingen, ikke loggeren — nettopp så pkt. 3-pinnen
fortsatt kan felles av en NY advarsel. Load-bearing MÅLT
(`tests/test_demo_stderr_quiet_loadbearing.py`), fem mutasjoner røde + grønn kontroll: detach
`main()`-kallet (subprosess-testen er ENESTE som fanger det — de tre filter-testene installerer
filteret selv) · la filteret droppe alt · installer ved import · pluss de to entry-point-mutasjonene.
- **Demo-transkriptet er sjekket inn som fasit, og masken er SPANN-avgrenset (P4 pkt. 3):**
kriterium 6 er selv-identitet — to kjøringer av en REGREDERT demo er like enige som to kjøringer av
en riktig, så fasiten må forlate prosessen. `tests/golden/demo-transcript.stdout` er stdout ORDRETT
(målt byte-identisk over kjøringer OG i fersk klon), og er derfor også demoens abortsti: feiler
live-kjøringen, ER fila transkriptet. `…​.stderr` er normalisert på nøyaktig to MÅLTE miljø-spann —
`site-packages`-prefikset og temp-katalogen bak `(arbeidskopi: …)`, der `po-sim-`-prefikset holdes
SYNLIG fordi det er en egenskap ved programmet (`mkdtemp(prefix=…)`), ikke ved miljøet; pinnet
stderr er TO linjer (var fire til og med core 1.9.0 — se F15-raden). **Masken må ikke kunne vokse:** P4 pkt. 2 betalte for at en NY advarsel
fortsatt når stderr, og en normalisering som maskerte hele linjer ville opphevet det i ett trekk —
derfor er `test_normalisation_does_not_mask_a_new_warning` kontrollen som forbyr det (MÅLT: en
droppende normaliserer med fasiten regenerert under seg holder BEGGE likhets-testene grønne og
felles kun av kontrollen). `PYTHONIOENCODING` pinnes, ellers måler sammenligningen operatørens
locale i stedet for programmet. **Regenerering er en beslutning, aldri rydding** — fasiten kan ikke
bevise sin egen kjøring, den pinner outputen P3-kriteriene ble målt mot.
**Hashen radene under fører er `shasum -a 1` av INNHOLDET, aldri git-blob-id-en (S7a-3 pkt. 4).**
De to er ulike av konstruksjon — git hasher over `blob <len>\0` + innhold — så
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f` er sha1 av fila, mens `git hash-object` på samme fil
gir `55bdea3ad20616480d81b9e7544604b248a541c9` (stderr-goldenen: `ede3e2f…` innhold /
`12893ec…` blob). MÅLT etter at en økt søkte uttømmende etter `ea8c534…` som git-objekt, ikke fant
det, og leste fraværet som at ni invariant-rader siterte en fantomverdi — Verifiseringsloven
ansikt 4 mot ens eget instrument: et negativt resultat fra feil spørring er ikke et faktum.
Radene var RIKTIGE hele veien; det som manglet var etiketten, og den står nå i hver av dem.
- **Frø-setningen AVLEDES fra kjøringen (P4 pkt. 4):** demoen sier høyt hvor Kjøring B's tidligere
dommer kommer fra, og splitten (`_verdict_origin_line`) regnes ut — linja rett over printer allerede
antallet, så en håndskrevet «én av tre» ville vært den andre kopien som drifter (samme regel som
pkt. 0-baselinen), og ville blitt sagt uendret etter at en framtidig bundle shipper en ANDRE frøsatt
dom. Klassifisereren er de to markørene demoen alt sporer; den hviler på at den frøsatte dommen
bærer INGEN av dem, som MÅLES på levert bundle. **Planens forhåndsskrevne ordlyd var FEIL mot
levert innhold** («én av de TO») — målt henter Kjøring B TRE: én fulgte med kunnskapsbasen, to er
demoens egne (én per tidsskala). Load-bearing MÅLT
(`tests/test_p4_honesty_sentences_loadbearing.py` + golden-transkriptet), fem mutasjoner alle røde
+ grønn kontroll: ett byte i en stdout-linje · detach dempingen · over-normaliser stderr · literal
splitt (fanget av INGENTING i 800 tester bortsett fra skille-testen) · detach frø-setningens print.
- **Delt ekspert-persona som Agent Skill (§8, framework-nøytral):** ekspert-reviewer-personaen bor i
`shared/skills/expert-reviewer/` (`SKILL.md` + `references/example-verdict.json`) og er den ENE
delte artefakten begge stacker instansierer reviewer-en fra. `shared/` forblir REN DATA — MAF-siden
leser den via `portfolio_optimiser.persona.load_persona_example` (call-time, fail-fast), Claude-SDK-
søskenet med sin egen loader mot samme JSON. Dette AV-STUBBER simuleringen: persona-dommen (decision
+ rationale + sporet markør) hentes nå fra artefaktet ved call-time, ikke en inline-literal — så
personaen er genuint konsumert og kan ikke råtne stille. **Decision er binær** (`approved`/`rejected`
`FeedbackContract` run-stien tar; `approved_with_adjustment` avvises der, bor kun i bundle-seedens
frontmatter + promoterings-gaten); realiseringskorreksjonen lever i rationale-prosaen, ikke et tredje
enum. SKILL.md-prosaen nevner ALDRI en konkret framework (maf-guarden er import-formet). Load-bearing-
trio (`tests/test_persona_skill_loadbearing.py`): struktur+framework-nøytralitet (RØD på framework-
import), eksempelet er gyldig pipeline-input inkl. `FeedbackContract` (RØD på skjema-/kontrakt-drift,
på en throwaway-kopi — aldri den git-tracked fixturen), og sim-ens markør følger artefakt-fila (RØD i
det øyeblikk personaen re-inlines).
- **Den råe svarteksten fanges i en KALLER-EID SINK, ikke i en returverdi (Fase 1b, funn 1):**
`generate._fetch_parsed` kastet hvert uparsebart modellsvar i `except: continue`, så prosjektets
første levende kjøring brant tolv runder på formatfeil og etterlot **null tegn** av det modellen
faktisk sa — enhver videre betalt kjøring ville vært gjetning. **HVOR teksten overflates er avgjort
av en MÅLING, ikke av symmetri med Steg 5:** `meter.tick_round()` raiser `BudgetExceeded` INNE i
`_fetch_parsed`, og uten mandat fanger ingen den (`run.py`s ene `except BudgetExceeded` er
mandat-armen) — så på nøyaktig den stien fangsten finnes for, RETURNERER `generate_via_llm`
ingenting. Et felt på `GenerationResult` (Steg 5-formen) er derfor blindt for den, og et
outbox-artefakt skrevet ETTER kjøringen likeså. Sinken speiler i stedet `meter`: en kaller-eid
akkumulator løkka muterer, hvis innhold kalleren holder uansett hvordan løkka endte. Steg 5s
«returverdi, ikke out-parameter» gjelder en verdi som NÅR kalleren; her gjør den ikke det, og å
kopiere regelen blindt ville gjenoppbygd defekten ett lag opp. Artefaktet
`{run_id}-parse-failures.json` skrives fra en **`finally`**, ikke `except BudgetExceeded` — enhver
exception ut av genereringen ødelegger samme bevis, og en liste over exception-typer er en liste
som blir foreldet. **Teksten er VERBATIM** (en forkortelse gjør beviset om til en parafrase), og
fila skrives KUN når noe faktisk feilet, så dens tilstedeværelse ER signalet. Byte-determinisme
påstås IKKE for dette ene artefaktet — innholdet er en levende modells prosa. Load-bearing MÅLT
(`tests/test_parse_failure_capture_loadbearing.py`), seks mutasjoner alle røde mot HELE suiten +
grønn kontroll 859/4: detach fangsten (3 røde) · flytt skrivingen ut av `finally` (1 rød, KUN
budsjett-testen) · detach run-wiringen (2 røde, generate-testen grønn) · skriv artefaktet alltid
(kontrollen + den eksisterende `a5`-inerthetstesten) · trunker teksten til 40 tegn (3 røde) ·
trunker til 100 tegn slik at sentinelen OVERLEVER (1 rød — verbatim-asserten alene, den skarpe
diskriminatoren). Ærlighets-grense: `_charge_usage` kan raise FØR parse, og et svar tapt der er
ikke en parse-feil og fanges ikke.
- **Proposeren får en GRAMMATIKK, og skjemaet er DERIVERT + fail-closed (Fase 1b, funn 1b):**
`generate_via_llm` sender `options={"response_format": proposal_response_format()}` på hvert
genererings-kall. **Formen er MÅLT, ikke valgt:** `ChatOptions.response_format` tar
`type[BaseModel] | Mapping`, og BEGGE profiler ærer den — LOCAL
(`OpenAIChatCompletionClient`) sender en Mapping ordrett til Chat Completions, AZURE
(`FoundryChatClient``RawFoundryChatClient``RawOpenAIChatClient`) konverterer SAMME
envelope til Responses-APIets `text.format`. **Klassen er AVVIST på bevis:** gitt en klasse
konverterer klienten med `type_to_response_format_param`, som (målt) emitterer `minimum` /
`exclusiveMinimum` / `minItems` / `prefixItems` og et `assumptions`-node hvis
`additionalProperties` er et SKJEMA — fire ting Azures publiserte subset utelukker
(Learn: «Unsupported type-specific keywords» + `additionalProperties: false` i hvert objekt).
Vår egen mapping er eneste måte å styre hva som når tråden. **Å stripe beskrankningene koster
ingenting:** skjemaets jobb er FORM, validatorens jobb er VERDIER — `minItems`/`gt=0` gjenreises
av pydantic i `_parse_ir` og av `validate_proposal`. **Skjemaet DERIVERES fra `SavingsProposal`**
(`strict_json_schema`), aldri håndskrevet: en andre kopi av en form som alt bor i `ir.py` drifter
stille, og modellen ville fortsatt blitt bestilt for den gamle. **`assumptions` KAN IKKE bare
droppes, og det er en MÅLING:** feltet er det ene uttrykksløse (fri-form map av 2-tupler), men
`validator._monte_carlo` faller tilbake på `item.unit_cost` for hver kode uten bånd — uten bånd
i det hele tatt er alle 512 samples IDENTISKE og P10 == P50 == P90. Den stokastiske
falsifisereren ville gått inert mens den fortsatt rapporterte persentiler: repoets kardinalklasse
(en gate som bare kan bli grønn). Derfor bærer WIRE-en et array av navngitte entries og
`_parse_ir` folder det tilbake til IR-ens map — **additivt, aldri erstatning** (map-formen
parser uendret; alle scriptede svar i suiten og golden-transkriptet bruker den). Sanitiseren er
**fail-closed** (`StructuredOutputUnsupported`) på `prefixItems`/`oneOf`/`allOf`/fri-form map
uten deklarert override — validering, ALDRI reparasjon (speiler `write_concept_file`).
Prompt-linja «Respond with ONLY a JSON object» + parse-retry + funn-1-fangsten står URØRT: en
leverandør som ignorerer `response_format` må fortsatt få beskjed, og backstoppen er poenget.
Load-bearing MÅLT (`tests/test_structured_output_loadbearing.py`), seks mutasjoner alle røde +
grønn kontroll 864/4: detach wiringen (1 rød) · detach sanitiseren (3 røde) · dropp
`assumptions` fra skjemaet (1 rød) · fail-closed → stille reparasjon (1 rød) · detach
normaliseringen (3 røde) · erstatning i stedet for tillegg (2 røde — T5 PLUSS
golden-transkriptet, et uavhengig vitne). **T3 ble skrevet VAKUØS først** (repoets 08-09-klasse,
sjette gang): den påsto å bli rød når `assumptions` forsvant fra skjemaet, men den scriptede
klienten ignorerer skjemaet — påstanden ble bevist usann av M3 og testen fikk en DIREKTE
assert på skjemaet. **ÆRLIGHETS-GRENSE, UTTALT:** ingen betalt kjøring er gjort, så at det
emitterte skjemaet ER akseptert av det levende endepunktet er IKKE verifisert — testen beviser
konformitet med det DOKUMENTERTE subsettet, ikke aksept. Ollamas oppførsel på
`response_format` er likeledes uverifisert.
- **Overleverings-pakka ER `git archive HEAD`, aldri en kuratert kopi (Fase 5):**
`scripts/make-handover-package.sh` bygger én zip en ekstern organisasjon deployer uten å klone
repoet. **Tracked files only er hele eksponerings-kontrollen**`STATE.md`, `*.local.md` og
`.env` er gitignorert, så de KAN ikke komme inn; et filter vedlikeholdt i skriptet ville vært den
andre kopien av den regelen, og den andre kopien er den som drifter (kø-(p)). Mottakeren får altså
HEAD selv. Versjonen LESES fra `pyproject.toml` — et hardkodet tall her ville råtnet ved neste bump
nøyaktig som README-ens wheel-filnavn gjorde (Fase 3). `DEPLOY.md` ligger i treet og blir dermed
med i arkivet av seg selv; den bærer mottakerens tre første spørsmål — hvem gjør hva
(plattform-operatør / bestiller / fagperson), prosessen ende-til-ende, og **hvorfor det ikke
finnes et chat-grensesnitt** (flaten er `POST /invocations`, og `as_agent()` er bevisst vraket
fordi validator, baseline-forankring, checker-gate og ledger ligger UTENFOR grafen — et chat-lag
ville rutet forespørsler rundt nøyaktig det som gjør svaret etterprøvbart). Den navngir også det
4e målte deploy-kravet som ingen rad hadde skrevet ned: pakket `model_map.json` bærer
`REPLACE-WITH-*`, så uten `PORTFOLIO_MODEL_MAP` starter tjenesten, svarer på `/readiness` og
feiler HVER invocation. Gaten er `tests/test_handover_package_loadbearing.py`, og
DEPLOY.md-asserten er LINJEFORANKRET: `PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT` INNEHOLDER
`FOUNDRY_PROJECT_ENDPOINT`, så en delstreng-assert på det injiserte navnet ville vært oppfylt av
vårt eget (repoets 08-09-klasse, femte gang).
- **Overleveringen er KUN kjørbar Python, og fraværet er FJERNING — ikke filtrering (14.08,
operatørdirektiv etter ekstern test):** `Dockerfile` og `azure.yaml` er slettet fra TREET.
**Sømmen er valgt av den eksisterende invarianten, ikke av smak:** pakka ER `git archive HEAD`, så
å ekskludere filene fra arkivet ville krevd en kurerings-mekanisme (skript-filter eller
`export-ignore`) — den andre kopien av «hva mottakeren får», fri til å drifte fra HEAD, altså
nøyaktig kø-(p)-regelen raden over finnes for. Å beholde dem som «opt-in» ville ikke oppfylt
direktivet i det hele tatt. Fjerning holder arkivet ukurert OG gjør fraværet til en egenskap ved
HEAD, som er det eneste en gate kan måle. **De to gatene som pinnet flaten er håndtert BEVISST,
aldri stille svekket:** 4e-rå-tekst-gaten (`--platform linux/amd64` + ÉN kopi av startkommandoen)
er SLETTET med et notat der den sto — en gate som pinner en fjernet flate kan bare bli grønn — og
handover-gatens `_REQUIRED_MEMBERS` er ikke bare fratatt de to navnene, men erstattet av en
POSITIV fraværs-assert; å kun slutte å KREVE dem ville gitt en gate som ikke kan skille «fjernet»
fra «shippes fortsatt». Matchingen skjer på arkiv-MEDLEMSNAVN, ikke på prosa (dokumentene må
kunne forklare at ingen image shippes — repoets 08-09-klasse, sjette gang), og dokument-gaten
forbyr kommando-FRAGMENTER (`docker build`, `azd deploy`), ikke ordet. **Startkommandoen har nå
ÉN kopi igjen — DEPLOY.md-ens `python main.py`** — og den navngir inngangen subprosess-testen
faktisk kjører. **Ærlighets-grense, uttalt:** azd/hosted-agent-stien finnes ikke lenger i pakka;
hvordan prosessen driftes er mottakerens valg. `git archive HEAD` leser HEAD, ikke arbeidstreet,
så gaten er ekte men forsinket med én commit (funn 35). Load-bearing MÅLT
(`tests/test_handover_package_loadbearing.py`).
- **Sporing er OPT-IN, og «av» betyr at MAF ALDRI kalles (U14, økt 55):** `PORTFOLIO_OTEL` leses på
**truthiness** (4b-regelen) og er ENESTE bryter; uten den kalles `configure_otel_providers` ikke i
det hele tatt — spans LAGES fortsatt (`ENABLE_INSTRUMENTATION` defaulter `True`,
`observability.py:697`) og kastes, så ingenting KAN forlate prosessen. Et kall med tom
exporter-liste ville derimot installert providere og lest hver `OTEL_EXPORTER_OTLP_*` i det
omkringliggende miljøet — «av» må være fravær av kall, ikke kall uten innhold. **To regler er
MÅLT, ikke valgt** (`observability.py:849` bygger exporter-lista i fast rekkefølge: (1) env-avledede
OTLP-exportere UBETINGET, (2) de innsendte, (3) `ConsoleSpanExporter()` — default-sink **stdout**
når `enable_console_exporters` er sann fra argument ELLER `ENABLE_CONSOLE_EXPORTERS`): (a)
`enable_console_exporters=False` sendes EKSPLISITT i BEGGE moduser, ellers gir en operatør med den
variabelen eksportert et span-dump på stdout — nøyaktig det S6 målte som ødeleggende for
golden-transkriptet; (b) `console` NEKTER når en OTLP-endepunkt-variabel finnes, fordi steg (1)
ville lagt til en nettverks-exporter ordet «console» lover ikke er der. **Validering, ALDRI
reparasjon** — vi fjerner ikke operatørens miljøvariabel bak ryggen på dem
(`write_concept_file`-regelen); nekten NAVNGIR variabelen. `otlp` uten deklarert endepunkt nektes
også: providere med ingenting å eksportere til er en kjøring som SER sporet ut og ikke er det. En
ukjent verdi nektes ved navn, aldri stille fallback til av. **`tracing_notice` er ENESTE renderer**,
tar den alt oppløste `TracingSetup` og returnerer `None` når sporing er av — omisjon, aldri tom rad
(`announce`-regelen), og her bærende utover stil: demoens pinnede stderr er TO linjer (FIRE før F15). **Tre
kallsteder, ikke ett** (`run.main`, `simulation.main`, `hosting.main`): demoen er et skriptet bevis,
ikke produktet, og en søm bare demoen når ville latt de to inngangene en virksomhet faktisk kjører
være usporbare. **OTLP-exporter-PAKKENE er BEVISST ikke deklarert** (egress + grpc/protobuf-vekt i
et publisert wheel; MAF raiser selv en `ImportError` som navngir pakka) — uttalt ærlighets-grense.
**`PLAN_CREATED`/`REPLANNED`/`PROGRESS_LEDGER_UPDATED`-eventene planen navngir er IKKE bygget:**
de hører til utforskningssløyfa (U4) som ikke finnes ennå, og en emitter skrevet før kallstedet er
en form gjettet i stedet for målt. Load-bearing MÅLT
(`tests/test_tracing_loadbearing.py`), ni mutasjoner alle røde mot HELE suiten + grønn kontroll
943/5: exporteren tar sin stdout-default (4 røde) · `enable_console_exporters` overlatt til miljøet
(3 røde — inkludert den ATFERDSMESSIGE, som kjører demoen med variabelen eksportert; uten den ville
raden bare vært en keyword-assert) · detach console-nekten (4 røde) · detach otlp-endepunkt-nekten
(1 rød) · ukjent modus faller stille til av (2 røde) · «av» kaller MAF likevel + renderer returnerer
alltid en linje (9 røde, hvorav TRE i tester som fantes fra før — `test_golden_transcript` sin
da fire-linjers (nå to-linjers) stderr og `test_portfolio_cli_offline`s stille-pass — altså er omisjonen gatet av
uavhengige vitner) · detach demo-wiringen + detach CLI-wiringen (5 røde) · detach hosting-wiringen
(1 rød, KUN subprosess-testen — P4-presedensen).
- **Utforskningssløyfa er en MANDAT-FORMER, og de tre garantinivåene er strukturelle (U4+U13
synkron, økt 56):** `explore.py` legger en Magentic-manager OVER den normative sløyfa — `prompt +
kunnskapsbaser → Mandate → run_project(mandate=…)` UENDRET, Steg 3s maker-checker urørt (commons-eid
og normativ). Manageren velger VEI; det som forlater friheten er `mandate.Mandate`, aldri et forslag.
**Nivå 1** = `quick_validate`-verktøyet (SAMME `validate_proposal`, SAMME baseline, men rådgivende —
når ALDRI provenance); **nivå 2** = pipelinen som stempler; **nivå 3** = skriverettigheter, som kun
pipelinen har. `explore()` skriver INGENTING. **Mandatet bygges fra hypotesiserens MERKEDE turer**
(`HYPOTHESIS: {"label","rationale"}`), aldri fra sluttsvaret — sluttsvaret er RÅTT per design, og en
parser på det ville gjort det til et forslag. Markøren er dét som gjør fail-closed mulig: en umerket
tur er ikke en påstand (ingen stillhet å lukke), mens en MERKET-men-uleselig linje raiser
(`write_concept_file`-regelen). **Frø-approaches bevares ALLTID og FØRST** — også når sløyfa fant
ingenting og også ved stopp (§ C.6 dør 1 er en bevaringsregel, ikke en belønning for å bli ferdig).
**Tre kanaler, aldri én:** tokens OG runder raiser `BudgetExceeded` (rundene som
`kind="exploration_rounds"`, oversatt av VÅRT lag fordi orkestreringen MÅLT ikke raiser ved sitt eget
rundetak — den returnerer en kanonisk assistent-melding som ved transporten er uskillbar fra suksess),
mens alt semantisk er en VERDI i `stop` (S3.4-splitten: utmattelse og utfall er ikke samme sak).
Diskriminatoren mellom «nådde taket» og «ble kappet av taket» er SISTE ledgers
`is_request_satisfied` — samme felt orkestratoren selv forgrener på (`:1106`) — aldri
termineringsmeldingen, som er en inline f-string (`:1253`) uten konstant å pinne mot og som en modells
eget sluttsvar kan inneholde. **`speaker_known` sjekkes FØRST og slår alt annet:** en `next_speaker`
uten treff gir stille sluttsvar med NULL deltakerarbeid (`:1128-1131`), altså et plausibelt svar
ingen jobbet for (E2-klassen) — sløyfas egne funn holdes da tilbake, frøene ikke.
**Kontrakten nekter tre ting ved konstruksjon:** hvert av seks felt er PÅKREVD uten default (MAF
defaulter `max_round_count`/`max_reset_count` til ubegrenset, så et utelatt felt faller ikke tilbake
til noe forsiktig, men til dét `method-spec` §8 forbyr); `max_reset_count=0` nektes — **MÅLT**, ikke
resonnert: `reset_count >= max_reset_count` mot en teller som starter på 0 gjør at kjøringen
terminerer FØR første runde med kun `facts`+`plan`, null ledger-events og «maximum reset count», altså
en utforskning som utforsket ingenting, forkledd som en stall som aldri skjedde (`max_stall_count=0`
er derimot LOVLIG — strengt `>` gjør 0 til «reset ved første stallede runde»); og
`max_plan_revisions>0` med `enable_plan_review=False` nektes (en cap på en hendelse som ikke kan skje).
`max_plan_revisions` finnes fordi A3 MÅLTE at en `revise` koster 2 manager-kall, **null** ledger-kall
og **null** runder og så spør PÅ NYTT — under rundetaket alene er en alltid-reviderende ekspert
ubundet forbruk under vakter som alle ser tilfredse ut. Ved cap: typet stopp, ALDRI en påtvunget
approve (repair av et menneskes beslutning er den verste sorten). **U14s tre utsatte events er
landet** (`plan_created`/`replanned`/`progress_ledger_updated` som span-events på ÉN
`exploration`-span) — emisjon er UBETINGET og «av» betyr at OTel kaster dem, samme form MAFs egen
instrumentering alt har; en flagget emitter ville vært en andre oppløsning av regelen `tracing.py`
eier. Uttalt ærlighets-grense: eventene registreres når event-strømmen foldes, så REKKEFØLGEN er
tro og tidsstemplene er ikke øyeblikkene manageren handlet.
**Load-bearing MÅLT** (`tests/test_explore_loadbearing.py`, 32 tester), tolv mutasjoner alle røde mot
HELE suiten + grønn kontroll 975/5: detach rundetak-oversettelsen (1 rød) · test rundetaket FØR
tilfredsstillelse (1 rød — den motsatte feilen, som gjør en fullført utforskning til en budsjettfeil) ·
detach ukjent-taler-sjekken (1) · `BudgetMiddleware` av manageren, deltakerne beholder den (1) ·
detach revisjons-capen (1) · dropp frø-bevaringen (3) · la en ukjent-taler-kjøring levere funnene
videre (1) · detach alle tre span-events (1) · tillat `max_reset_count=0` (1) · gjør en merket-men-
uleselig hypotese tolerant (1) · la `read_bundle` skrive i basen den leser (1) · send spans til OTels
default-sink (2). **TO av dem FALSIFISERTE testen først, og begge er repoets vakuøs-gate-klasse:**
(i) skrivefrihets-testen drev kun `explore()`, men en `ScriptedChatClient` returnerer TEKST og
emitterer aldri et verktøykall — så ingen scriptet kjøring når en verktøykropp, og hele lesesømmen
(eneste sted en skriving realistisk kan komme fra) lå utenfor gaten; testen kaller nå hvert verktøy
DIREKTE. (ii) stdout-testen brukte `capsys`, men `ConsoleSpanExporter`s `out`-default bindes når
`opentelemetry.sdk.trace.export` FØRST importeres — under pytest er det stdout ved COLLECTION, som
`capsys` aldri ser; spans lå faktisk på stdout mens asserten var grønn. Dét er ikke en test-quirk å
omgå, det er nøyaktig faktumet U14 finnes for, og arven er P4-presedensen: **subprosessen er
målingen**. Begge armene kjøres nå i et barn (av: null trace-data noe sted; `PORTFOLIO_OTEL=console`:
spanet + `progress_ledger_updated`**stderr** og stdout tomt), med `EXPLORATION-OK` på stderr som
kontroll — uten den ville «stdout var tomt» vært like sant om et barn som krasjet ved import.
**Ærlighets-grenser, uttalt:** multi-base-dispatch (`Approach.bundle_id`, § C.7) venter til
`run_project` tar mer enn én `bundle_dir` — å shippe feltet før konsumenten er en form gjettet i
stedet for målt; `quick_validate`-dommene hypotesiseren så bor ikke i `ExplorationResult`, de er nivå
1 og hører hjemme i `{run_id}-exploration.json` som CLI-wiringen skriver; utforskningsrollene løses
via `resolve_model`s `default`-fallback til en operatør mapper dem eksplisitt; at en LEVENDE modell
kaller verktøyene er ikke bevist offline (samme klasse som structured-output-grensen).
- **Utforskningens KALLSTEDER: sporet er kaller-eid, og whitelisten ble en TREDELING (økt 57):**
`--explore "<prompt>" --explore-config FILE` i `run.py`, `explore_prompt` + `explore_contract`
den hostede flaten, og `simulate_exploration` som et TREDJE sim-scenario — alle opt-in, alle over
den uendrede sløyfa. **`ExplorationTrace` er en KALLER-EID akkumulator (funn-1-sinken, ett lag
opp), og formen er tvunget av en måling, ikke valgt:** `explore()` raiser `BudgetExceeded`
rundetaket og tokentaket fyrer fra middleware midt i løpet — på BEGGE stier konstrueres aldri et
`ExplorationResult`, mens § C.2 krever at artefaktet er lesbart «uansett hvilken vakt som fyrte».
Steg-5-regelen («returverdi, ALDRI en out-parameter») styrer en verdi som NÅR kalleren; her gjør
den ikke det, og å kopiere regelen blindt ville gjenoppbygd defekten den ble skrevet mot.
`ExplorationResult.ledger_log`/`.plan_reviews` BYGGES FRA akkumulatoren (`tuple(trace.ledger)`),
aldri ved siden av — to beholdere om ett faktum er kø-(p). `{run_id}-exploration.json` skrives fra
en **`finally`** (`write_parse_failures`-presedensen) via `explore.trace_payload``outbox`s
plain-mapping-skriver (RAW-laget forblir MAF-fritt); **`completed` er et EGET påkrevd felt**, fordi
en `stop: null` som betyr BÅDE «avsluttet normalt» og «vi fikk aldri vite» er stillheten
`cost_baseline_anchored` ble påkrevd for å lukke. **Åtte CLI-nekter, alle ved navn**, hvorav to
bærer en beslutning: (i) `--explore` + `--mandate` er TO KILDER TIL ETT MANDAT og NEKTES, aldri
slås sammen — `explore()` tar objective fra prompten og hardkoder `allow_own_proposals=True`, så
komposisjon ville stille overskrevet tre felt operatøren skrev selv; nekten NAVNGIR
biblioteksdøra (`seed_approaches`), fordi § C.6 dør 1 er et ekte behov flaten ikke betjener.
(ii) `enable_plan_review=true` nektes på BEGGE flater FØR `explore()` kalles, og det er en
TYPE-måling: `ExplorationError` er en `RuntimeError` og ligger utenfor `main()`s
`(ValueError, FileNotFoundError, ValidationError)`-tuppel og utenfor hostings 400-arm, så å
overlate den til sløyfa ville gitt traceback på CLI-en og 500 — krasj-kanalen — på HTTP.
(`TracingConfigError` er derimot en `ValueError`; 400-armen dekket den alt.) Etter nektene er hver
konfig-formet `ExplorationError` UNÅBAR fra begge inngangene ved konstruksjon; det som fortsatt kan
slippe ut (uleselig merket hypotese, uttømt budsjett) er RUN-en som feiler, ikke kalleren som tar
feil. **Hostings whitelist er nå `_REQUIRED` / `_OPTIONAL` / `_CONSUMED`:** utforskningsfeltene er
IKKE `run_project`-parametre, så Fase 4e-beviset fikk en NEGATIV halvdel — hvert videresendt felt
MÅ finnes i `inspect.signature(run_project)`, hvert konsumert felt MÅ ikke; uten den ville et felt
som glir fra konsumert til videresendt vært nøyaktig driften 4e finnes for. **Demo-scenarioet er
nåbart ved NAVN og bare der** (`main()` kaller det ikke, og at golden-transkriptet er byte-uendret
etter at det ble lagt til ER målingen av det), med en **vakuitets-vakt**: en label kunnskapsbasen
ALLEREDE oppgir refuseres, fordi den ville nådd hypotese-prompten som ordinær kontekst enten
utforskningen kjørte eller ei — `simulate_learning_loop`s to-markør-vakt i demo-form. Manager-
manuset nøkles på PROMPT-STADIET, ikke prosjekt-ID-en, og det er ikke et unntak fra
`scripted_proposer`-regelen: manageren får FEM ulike spørsmål og prosjekt-ID-en er konstant over
alle fem. **`--outbox-dir` uten `--run-id` NEKTES i utforskningsblokka, og det er en HOIST — ikke
en andre kopi av regelen:** `run_project` eier outbox-kontrakten og nekter på sin FØRSTE setning,
tidlig nok for enhver sti som fantes før U4, men utforskningen kjører FORAN det kallet — uten
hoisten brukes hele utforskningsbudsjettet på modellkall før nekten, og artefakt-skrivingen hoppes
over, så ikke engang regnskapet over hva som ble brukt overlever. Funnet i review FØR commit;
testen asserterer at INGEN modellkall skjedde, ikke bare at rc er 1 — ved exit-koden ser en nekt
etter forbruket identisk ut. **Scenarioet har BEVISST intet `label_in_bundle`-felt:** vakten
raiser før et resultat finnes, så feltet kunne kun vært `False`, og en assert på det ville vært
grønn mot enhver implementasjon — vakten ER kontrollen, og en alltid-sann gjentakelse av den ville
bare gjort den ekte lettere å avfeie. Load-bearing MÅLT
(`tests/test_explore_callsites_loadbearing.py`, 24 tester), sytten mutasjoner alle røde mot HELE
suiten, hver mot kontrollen som gjaldt da (990/5 for CLI-en + sporet, 996/5 for hosting, 998/5 for
sim-scenarioet, 999/5 for de to siste): detach sink-appenden (1) · andre liste
for rundene (4) · detach `--mandate`-nekten (1) · detach `--explore-config`-nekten (1) · skriv
artefaktet kun ved fullført kjøring (1) · detach CLI-ens `mandate=` (1) · slipp
`enable_plan_review` gjennom, CLI (1) · detach `--bundle-dir`-kravet, CLI (1) · detach
`--live-dry-run`-nekten (1) · fjern `--explore` fra portefølje-partisjonen (1) · videresend de
konsumerte feltene (2) · detach hostings `mandate=` (1) · detach `enable_plan_review`-nekten,
hosting (1) · detach `bundle_dir`-kravet, hosting (1) · detach sim-scenarioets `mandate=` (1) ·
detach vakuitets-vakten (1) · detach outbox/run-id-hoisten (1). **ÉN MUTASJON FALSIFISERTE TESTEN FØRST (repoets vakuøs-gate-klasse,
syvende gang):** portefølje-testen asserterte kun at meldingen nevnte `--explore`, og sto GRØNN
uten partisjonen — kjøringen falt da gjennom til «`--explore` requires `--bundle-dir`», som nevner
`--explore` også. To nekter som deler en delstreng er «assert aldri på ordlyd to grener deler»,
fanget av sin egen mutasjon; testen navngir nå `--portfolio`. **Ærlighets-grenser, uttalt:**
multi-base (`Approach.bundle_id`, § C.7) er FORTSATT ikke bygget — `run_project` tar én
`bundle_dir`; utforskningens egne modellkall er UANNONSERTE (annonseringens kontrakt er at en
KOMMISJON erklæres før arbeidet den bestiller, og før `explore()` returnerer finnes ingen —
`exploration_notice` dekker gapet i det sløyfa er ferdig); `BudgetExceeded` ut av `--explore`
tracebacker som den gjør for debatten i dag; og **den HOSTEDE flaten gir ingen innsyn i hva som
formet mandatet** — det er ingen outbox der og intet utforskningsfelt i `_response_payload`, så
ledgeren og de rådgivende dommene når kun CLI-ens artefakt. En bevisst scope-grense, men uttalt,
fordi flatens hele argument er at svaret er etterprøvbart.
- **Multi-base er en PARTISJON, aldri en videre `run_project`-signatur (U4+U13 del 3, § C.7, økt 58):**
planens § C.7 og økt 56s egen ærlighets-grense leste som om leveransen var «`run_project` tar mer
enn én `bundle_dir`». **Den kan ikke det, og nekten er STRUKTURELL:** på bundle-stien avleder
`run_project` FIRE enkeltverdier fra DEN basen — prosjektet (`_project_from_bundle`, som
fail-faster når basens egen `validator-input.json` ikke navngir det forespurte prosjektet),
validatorens stage-0-baseline (S4.0s hele poeng er at gaten er forankret i DETTE prosjektets
kostlinjer), agentenes lesekontekst og ExpeL-nøkkelen — og returnerer ETT stemplet `RunResult`.
En andre katalog på den signaturen ville tvunget et stille velg-en for alle fire, som er den
gjettede-form-klassen repoet nekter. **Planens egen setning sier det samme lest nært:**
«pipelinen kjøres per bundle som i dag (`run_portfolio`-formen)» = N kall, ikke ETT kall med N.
Premisset ble felt FØR bygging; ordren ba selv om nettopp den sjekken. **Konsekvensen er at INGEN
eksisterende kaller endrer signatur** — CLI, hosting og simulation sender fortsatt én base hver,
og kan fortsatt gjøre det. Tre sømmer: (1) `mandate.Approach.bundle_id`, default `""`, så hvert
mandat skrevet før i dag er fortsatt gyldig OG dispatchbart uendret; (2) `mandate.route_by_bundle`
— ren partisjon i `bundle_ids`-rekkefølge (aldri i approach-rekkefølge: spend-ordenen er en
egenskap ved hvordan kjøringen ble konfigurert, ikke ved hvordan en modell tilfeldigvis sekvenserte
hypotesene), **fail-fast på et mandat som ikke kan utføres som skrevet** (`load_mandate`-regelen —
en kjøring skal aldri gå videre på en stille degradert bestilling); (3)
`run.run_mandate_across_bundles` — dispatchen. **Den tar INGEN `project_id`-parameter, og det er
designet:** hver bases prosjekt leses fra DEN basens egen IR-projeksjon, altså nøyaktig verdien
`_project_from_bundle` allerede fail-faster mot, så en kaller-oppgitt konstant kunne uansett bare
vært riktig for én base av N — den eksisterende fail-fasten blir rutingsnøkkelen, og gjetningen
forsvinner. Ett `VerdictStore` trådes på tvers (kryss-base-læring, `run_portfolio`-formen), og
**delt INSTANS er påstanden — ikke lik verdi** (se vakuitets-funnet under). En base ingen approach
navngir kjøres IKKE (en kjøring koster penger, og bestillingen ba om ingenting der); med NØYAKTIG
én base absorberer den alt uten navn, som ikke er en gjetning men det eneste mulige svaret — og
det er dét som holder hvert pre-multi-base-mandat dispatchbart. `explore()` stempler `bundle_id`
på hver MYNTET approach, men **skriver ALDRI om et frø** (§ C.6 dør 1 er en bevaringsregel — å
fylle inn feltet på ekspertens vegne ville satt deres navn på en rutingsbeslutning de ikke tok);
frøene VALIDERES i stedet, **FØR første modellkall** (økt-57-hoisten: ved unntaket alene ser en
nekt etter forbruket identisk ut med en før). En umerket markør med flere baser NEKTES
(`HypothesisParseError`), med én base resolveres den. **Budsjett: de to S3.4-tennene som HAR
mening her** — oppstartsnekt (`BudgetRefused`) og aldri-startet + `budget_stop` +
`not_evaluated`-rader i `MultiBaseResult.unreached`; bølge-reservasjonen har ingen motpart, for
dispatchen er SEKVENSIELL. **Ærlighets-grenser, uttalt:** en base som RAISER propagerer
(collect-and-continue tilhører `run_portfolio`, der kalleren sendte inn en batch uavhengige
prosjekter); uten `portfolio_meter` er taket antall rutede baser × `max_tokens`, hver kjøring
bundet for seg; outboxen er IKKE wiret (N kjøringer trenger N `run_id`-er, og å mynte dem her
ville defaultet en nøkkel repoet krever at en kaller oppgir); og **CLI-en er BEVISST urørt**
§ C.8 ber om ETT nytt kallsted i `run.py` (`--explore`, levert i 57), og et repeterbart
`--bundle-dir` er en NY operatørflate, altså en egen beslutning. Load-bearing MÅLT
(`tests/test_multibase_loadbearing.py`, 22 tester), tolv mutasjoner alle røde mot HELE suiten +
grønn kontroll 1020/5 og golden `demo-transcript.stdout` BYTE-UENDRET
(`shasum -a 1` = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): detach myntet `bundle_id` (2 røde) · stille
gjennomfall ved >1 base (1) · ukjent id resolvert etter rekkefølge (1) · frø-sjekk etter forbruket
(2 — asserten er på at NULL modellkall skjedde, ikke på unntaket) · ruteren gjetter første base (1)
· uroutbar approach droppet (1) · dispatchen kollapser til én base (5) · `project_id` fra første
base (2) · detach aldri-startet-tannen (1) · `unreached` urapportert (1) · fersk store per base (1)
· detach oppstartsnekten (2). **ÉN MUTASJON FALSIFISERTE TESTEN FØRST (repoets vakuøs-gate-klasse,
åttende gang):** store-testen sammenlignet med `==`, og `VerdictStore` er en pydantic-modell med
VERDI-likhet — tre ulike TOMME stores er alle like, så «fersk store per base» lot HELE suiten stå
grønn. Delt instans er påstanden, så testen asserterer nå på `is`.
- **«Be om svar, BRUKE svarene» er nåbar fra CLI-en, og gaten er den ANDRE halvdelen (F4, økt 63):**
før dette nektet BEGGE operatørflatene `enable_plan_review` (`run.py`, `hosting.py`) og eneste dør
var `explore(..., plan_reviewer=...)` — MÅLT mot kilden, ikke lest ut av reviewens prosa.
`--plan-review` bygger en `terminal_plan_reviewer()` og gir den til den UENDREDE sløyfa: operatøren
vises planen og svarer `approve` eller `revise <hva>`; en revisjon går tilbake til manageren, som
replanlegger og spør IGJEN om den NYE planen. **Diskriminatoren er dét siste** — en dør som printer
planen, leser linja og kaster den består «operatøren ble spurt» og feiler målbildet (repoets
vakuøs-gate-klasse); T1 er derfor bygget som `test_explore_loadbearing`s T15 løftet til CLI-nivå og
er RØD mot en alltid-godkjenn-reviewer. **Vitnet er `{run_id}-exploration.json`, ikke skrapet
stdout:** `trace_payload` bærer alt tre (rekkefølge, beslutning, feedback verbatim) og skrives fra
en `finally`, så den ene kjøringen som mest trenger beviset — den et tak eller en ubesvart review
kappet — etterlater det. **Fail-closed på operatørens EGEN input:** alt utenfor det lukkede
vokabularet spørres på nytt (aldri lest som en beslutning), og **EOF raiser `PlanReviewInputError`**
— å lese stillhet som ja ville latt en autonom sløyfe kjøre på en plan ingen signerte, usynlig.
Strømmene resolveres ved KALL-tid (`shared_root()`-idiomet), ellers svarer reviewer-en fra strømmen
som fantes da den ble BYGGET. **Fire nekter, alle ved navn**, hvorav to lukker et stille dropp
ingen test dekket: `report_forbidden` (report-modus returnerer FØR hver utforsknings-nekt) og
portefølje-partisjonen. De to konfig-avhengige nektene DELER tokenet `enable_plan_review` og har
derfor bevisst ULIK særtekst («no reviewer was offered» / «no review is ever requested») — den
eksisterende testen asserterte på det delte tokenet og er rettet (økt-57-mutasjonen, niende gang).
**Hosting NEKTER fortsatt, og det er en beslutning:** reviewen er synkron, så den ville blokkert
HTTP-requesten på et menneske OG event-løkka som svarer `/readiness` — meldingen navngir nå
CLI-døra i stedet for å påstå at biblioteket er den eneste (Fase 3-klassen). **Mid-løp-spørsmål er
IKKE bygget, og fraværet er MÅLT:** `_magentic.py` har nøyaktig ETT `ctx.request_info` (`:1044`,
plan review) i hele modulen, så stacken kan ikke levere et spørsmål midt i løpet uten en ny
emitter. Reviewens «kun plan-review FØR løpet» er derimot upresist: samme forespørsel fyrer også
ved re-plan etter en stall (`is_stalled=True`), så døra ER nåbar midt i en kjøring på den ene
måten stacken støtter. Load-bearing MÅLT (`tests/test_plan_review_cli_door_loadbearing.py`, 12
tester), elleve mutasjoner alle røde mot HELE suiten + grønn kontroll 1040/5 og golden
`demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): detach
`plan_reviewer`-wiringen (5 røde) · EOF blir en godkjenning (1) · alltid-godkjenn (3) · alt som
ikke er en revisjon blir en signatur (1) · dropp `--plan-review` fra portefølje-partisjonen (1) ·
dropp den fra `report_forbidden` (1) · detach `--plan-review requires --explore` (1) · detach
review-uten-reviewer-nekten (2, hvorav én i en test som fantes fra før) · detach
reviewer-ingen-spør-nekten (1) · hostet nekt beholder påstanden fra før F4 (1) · strømmene fanget
ved bygge-tid (1).
- **Plan-reviewen kan besvares over DAGER, og det eneste som krysser prosessgrensen er DISK (U12 +
asynkron U13, planens § D.2 rad 3, økt 64):** F4 gjorde «be om svar, BRUKE svarene» nåbar, men
bare SYNKRONT — `terminal_plan_reviewer` blokkerer løkka på et menneske ved en terminal, så
svaret må komme mens prosessen lever. `--checkpoint-dir` PARKERER i stedet reviewen
(`FileCheckpointStorage` + `{run_id}-plan-review.json`), og `--resume <run_id>` leser svaret fra
`--review-inbox` i en prosess som ALDRI så kjøringen. **MÅLT FELLE (ansikt 4):**
`list_checkpoints` (`_checkpoint.py:386-388`) svelger en blokkert deserialisering til en
`logger.warning` og returnerer TOM liste — uten BEGGE
`MagenticPlanReviewRequest`/`…Response` i `allowed_checkpoint_types` feiler en resume som et
FRAVÆR, ikke som en feil, og en test som asserterte «listingen er tom, altså er det ingenting å
gjenoppta» ville vært GRØNN mot nøyaktig den defekten. `_ALLOWED_CHECKPOINT_TYPES` har derfor ÉN
kopi og `checkpoint_storage` er ENESTE konstruksjonssted (BEGGE prosesser må deklarere dem; en
andre kopi er kø-(p)-driften). **Vi er LOUDERE enn rammeverket der det tier:** en tom listing ved
park raiser `CheckpointUnreadable` i stedet for å skrive et spørsmål ingen kan besvare.
**Diskriminatoren er den ANDRE halvdelen:** en dør som skriver en spørsmålsfil og en resume som
leser en svarfil består begge «eksperten ble spurt» — så måltesten krever at et `revise` skrevet
dag 1 får manageren til å REPLANLEGGE og stille et NYTT spørsmål (indeks 1, nytt `request_id`) i
en fersk interpreter, med en approve-kontroll som beviser at døra også kan AVSLUTTE (en gate som
bare kunne parke igjen er en hengning i løkkeklær). **Budsjettet og revisjons-capen spenner over
suspensjonen:** `meter.charge(parked.tokens_spent)` (gjennom `charge`, ikke ved å sette `tokens`
— ladingen re-tester taket) og `trace.ledger.extend(parked.ledger)`, ellers får hver park et helt
budsjett på nytt: S3.4-klassen, ubundet forbruk under vakter som alle ser tilfredse ut. En
`revise` koster to manager-kall, emitterer null ledger og bruker null runde (§ F, A3), så
`max_plan_revisions` er det ENESTE båndet på den. **Fail-closed på ekspertens EGEN fil:**
`request_id`-mismatch, ord utenfor vokabularet og `revise` uten innhold refuseres alle ved navn.
`hitl.pending_plan_reviews` er registeret over hvem som fortsatt venter — tolerant på LESE-siden,
fail-closed på BESLUTTE-siden, og joinen er på `request_id` i BEGGE ender (to distinkte sømmer,
MÅLT: hver har sin egen mutasjon og sin egen røde test). Load-bearing MÅLT
(`tests/test_async_plan_review_loadbearing.py`, 17 tester), tretten mutasjoner alle røde mot HELE
suiten + grønn kontroll 1059/5 og golden `demo-transcript.stdout` BYTE-UENDRET
(`shasum -a 1` = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): tom `_ALLOWED_CHECKPOINT_TYPES` (11 røde) · park
uten checkpoint (1) · resume alltid-approve (2) · tolerant `request_id` (1) · tolerant vokabular
(1) · `revise` uten feedback (1) · detach `meter.charge` (1) · detach
`trace.plan_reviews.extend` (1) · detach ledger/hypotese-carry-overen (1) ·
`pending_plan_reviews` ignorerer `request_id` (1) · detach to-dører-nekten (1) · detach
outbox/run-id-hoisten (1) · detach `--resume`-armen i `required_scripted_roles` (4 — MAJOR-2s
`KeyError: 'navigator'` på den andre flaten som bygger en utforskning).
**ÉN MUTASJON FALSIFISERTE SUITEN (repoets vakuøs-gate-klasse, TIENDE gang):** `trace.plan_reviews
.extend(parked.plan_reviews)` kunne detaches med HELE suiten grønn (1058/5) — capen leser
`parked.plan_reviews` DIREKTE, så den binder uansett, og de to første legene er identiske under
begge implementasjoner. Gaten måtte derfor bli det TREDJE leget, der artefaktet ellers taper dag
1s revisjon og to ULIKE planer deler indeks 1; den nye testen er rød mot mutasjonen og alene.
**Ærlighets-grenser, uttalt:** den hostede flaten NEKTER fortsatt (en synkron review ville
blokkert både requesten og event-løkka som svarer `/readiness`); en park MIDT i løpet (etter en
stall) har ingen nåbar sti under det skriptede manuset, så carry-overen som betjener den drives
gjennom en CRAFTED parkert tilstand (`budget_stop`-presedensen); og resume-legets
`PlanReviewParked` er et NORMALT utfall, ikke en feil.
- **Katalogkallet koster O(BASER), aldri O(KORPUS) — og det er stigens billigste trinn, ikke dens
dyreste (ordre `20260825T213645Z`, økt 65):** `list_bundles` returnerte hele rot-indeksens body
for HVER konfigurert base samtidig, pluss ett JSON-objekt per ufulgt kryss-lenke. Begge vokser med
korpuset, så prisen på å finne ut *hvilke baser som finnes* ble satt av hvor mye de *inneholder*
progressiv disclosure snudd på hodet (målbilde §2/§4). **MÅLT med `o200k_base`, instrumentet først
validert mot commons' egne fasittall:** 112 116 tokens over tre flate Vegnormal-baser, og
**124 942 over de 171 grenbasene** som erstattet dem — grenformen (`vegnormal-okf` `8145c23`)
lukket bundle-siden (82…92 % på `read_bundle`) og gjorde katalogsiden VERRE, nøyaktig som det
repoet forutså. Etter: **362** og **21 448** (per base 37 372 → 121 og 731 → 125).
**Et premiss ble felt FØR noe ble bygget på det:** «indeksbodyen forteller hva basen handler om»
er USANT for maskin-importerte baser — grenbasenes `index.md` har verken frontmatter eller prosa,
den er en ren lenkeliste (målt: 959 bytes, første tegn `-`), så feltet var dyrt OG innholdsløst
der. **Fast vindu, aldri en andel av basen** (`_CATALOGUE_EXCERPT_CHARS = 200`): en andel skalerer
med korpuset igjen, bare med mindre konstant. **Avkorting ANNONSERES som FELT**
(`index_truncated` ved siden av utdraget, aldri en markør limt inn i det — `BudgetExceeded`s
kø-(y)-regel), og en base som PASSER blir ikke merket avkortet og får hele bodyen: omisjon, aldri
en løgn i noen av retningene. **En ufulgt lenke overlever som ANTALL** — økt 51s «et hopp er
tolerert, men ikke lenger taust» står, mens per-lenke-detaljen blir liggende der den er
handlingsbar (`RunResult.skipped_links` / `DryRunReport.skipped_links`) og ikke rir med i et kall
hvis hele jobb er å være billig. Hele indeksen er fortsatt ETT `read_file(id, "index.md")` unna —
et disclosure-nivå, ikke datatap. **Taket (500 tegn/base) bor i TESTEN, ikke i `explore.py`:** en
test som importerte implementasjonens budsjett ville flyttet seg med det, og å heve budsjettet er
nøyaktig regresjonen gaten finnes for. Load-bearing MÅLT
(`tests/test_catalogue_cost_loadbearing.py`, 7 armer), **ni mutasjoner alle røde mot HELE suiten**
+ grønn kontroll 1066/5 og golden `demo-transcript.stdout` BYTE-UENDRET
(`shasum -a 1` = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): ingen binding (4 røde) · bundet men vakuøst (2) ·
stille kutt (1) · over-annonsert (1) · per-lenke-lista rir med igjen (1) · det ufulgte faktumet
slettet (1) · suffiks i stedet for ordrett prefiks (2) · en andel i stedet for fast vindu (2) ·
`documents` gjort konstant (1). **M9 ble kjørt fordi `documents` var et felt uten gate** — et felt
ingen test kan se, råtner. **MAJOR-1 var IKKE nødvendig:** bindingen sitter i verktøykroppen bak
en uendret CLI-flate. Ærlighets-grenser, uttalt: `navigate_bundle` kalles fortsatt per base per
katalogkall (I/O og veggklokke, ikke tokens — ikke målt her); ingen LEVENDE modell har kalt det
nye verktøyet, så at en manager velger BEDRE med et utdrag enn med hele indeksen er ikke bevist
(structured-output-grensens klasse); og ordrens nevner for N100:2023 var 34 mens disken viser 40 —
tallene bruker den målte nevneren. Måling: `docs/2026-08-26-katalogkostnaden.md`.
- **Et fravær ved en signeringsport sies i ORD; i dataene sies det ved å være borte (PM-tillegg 4,
økt 77):** `PlanReviewRequest.current_progress` og `ParkedExploration.current_progress` ble begge
bygget med `str(review.current_progress)`. Verdien er en `MagenticProgressLedger | None` og er
`None` i hver kjøring målt så langt, så `str()` ga de fire tegnene `None`, rendererens
truthiness-vakt fant dem ikke-tomme, og eksperten som skulle SIGNERE en plan ble vist en
«progress so far»-seksjon hvis eneste innhold var ordet `None` — og de samme fire tegnene ble
skrevet inn i `{run_id}-plan-review.json`, det ENESTE som krysser prosessgrensen i U12s asynkrone
dør. `_progress_text` er den ENE konverteringen (ved siden av `_plan_text`): fravær blir tom
streng, aldri `"None"`. **Datalaget sier fravær ved å være tomt** (`Bundle.skipped`s
tom-tuppel-regel), mens **TERMINALEN sier det i ord** — det er den ene flaten der omisjon er
feil, fordi stillhet ved en port noen signerer er nøyaktig dét `PlanReviewInputError` alt nekter
for EOF. **Målingen endret testen:** å reversere BEGGE kallsteder lot KUN en kildeinspeksjons-arm
bli rød — en lint, ikke en gate, fordi de første armene konstruerer en `PlanReviewRequest` selv og
aldri går inn i noen av stedene. Hvert sted har nå et ATFERDSMESSIG vitne som driver den EKTE
døra: terminalen for den synkrone, den parkerte spørsmålsFILA for den asynkrone. Load-bearing
MÅLT (`tests/test_plan_review_progress_line_loadbearing.py`, 7 armer), fem mutasjoner alle røde
mot HELE suiten, hver med sin egen signatur + grønn kontroll 1202/5 og golden BYTE-UENDRET:
begge steder reversert (3 røde) · det synkrone alene (2) · det parkerte alene (2) · terminalen går
stille igjen (2) · plassholderen fyrer alltid og sluker en ekte ledger (1, kontrollen alene).
Recorder-wiringen i `resume_exploration` er URØRT (uvitnet, defensiv — S2b).
- **`evidence_for` avleder en tier KUN for nøkkelen SPEC §5.3 tierer (PM-tillegg 5, økt 77):**
`evidence_for(path, key="sources")` REISTE `ValueError`. Tieren ble avledet UBETINGET gjennom
`trust_tier`, som nekter en oppføring uten `by`-aktør — riktig, fordi en tillitsgrad avledet av
en oppføring som identifiserer ingen mynter den proveniensen den påstår å lese. Men `by` er
påkrevd av en VERIFIKASJONS-oppføring (SPEC §5.2), ikke av enhver provenienss-nøkkel: den avtalte
segmenterte formen bærer `segment_id`/`source_offset`, en `sources`-liste bærer `id`/`resource`.
Vakten tilhørende ÉN nøkkel ble anvendt på ALLE. **`trust_tier` er URØRT** — `_TIERED_KEY` navngir
den ene nøkkelen §5.3 tierer, og enhver annen nøkkel kommer tilbake med
`state`/`reason`/`items_seen`/`entries` og `tier=None`. **`admits_falsification` flyttet MED, og
det er samme faktum, ikke scope-krype:** den leste `tier != "unverified"`, og `None != "unverified"`
er SANT, så en `sources`-liste som FINNES ville klarert en terskel om verifisering; den navngir nå
tierene som klarerer. For hver verdi som var nåbar før endringen er de to skrivemåtene identiske —
derfor står de eksisterende K5-armene grønne, og derfor er dette en innstramming og ikke en ny
regel. **Målingen korrigerte testen:** en `verified`-verdi UTEN aktør når aldri `trust_tier`
gjennom `evidence_for` i det hele tatt — dekoderen nekter formen først, som
`unreadable`/`unsupported-flow`; begge vakter asserteres nå der hver av dem FAKTISK bor.
**Defekten fantes fordi parameteren aldri var ØVET:** alle 11 kallsteder brukte defaulten (målt
ved B4s slutt). Load-bearing MÅLT (`tests/test_evidence_key_parameter_loadbearing.py`, 6 armer),
fire mutasjoner alle røde mot HELE suiten + grønn kontroll 1208/5 og golden BYTE-UENDRET: avled
tieren ubetinget (3 røde) · reverter K5-terskelen (1, konsekvens-armen alene) · «fiks» det ved
aldri å tiere (3, inkludert to eksisterende falsifiserings-armer) · løsne `trust_tier` i stedet
(2, inkludert dens egen eksisterende gate).
- **`read_bundle` koster O(DOKUMENTER i én base), aldri O(bytes av den — S2c/MAJOR-3, økt 77):**
verktøyet returnerte `okf.bundle_context`, altså HELE den navigerte basen, og fordi utforskningens
deltakere deler ÉN samtalehistorikk red det ene `function_result`-et med i **hver senere prompt**
til full pris uten at noen ba om det igjen. **MÅLT FØRST, med nevner, og committet som docs før én
linje kode ble rørt** (`docs/2026-09-02-read-bundle-kontekstkostnad.md`): 3 861 / 10 406 / **12 595**
o200k-tokens for de tre eksempelbasene, **5 kopier** per CLI-`--explore`-kjøring (navigatør ×1,
manager ×3, hypotesiser ×1) = **54 % / 59 % / 59 %** av ALLE prompt-tokens. Instrumentet ble
validert mot en KJENT POSITIV før bruk (det reproduserte commons' egne publiserte
`bundle_context`-fasittall eksakt), og prompten måles som tekst + `function_call` +
`function_result``.text` alene måler en kontekstbærende prompt til noen få tegn.
**Formen er katalogens, ett trinn ned på stigen** (`list_bundles` = hvilke baser finnes,
`read_bundle` = hva er i DENNE, `read_file` = hva sier dokumentet): én oppføring per konseptfil med
`name`, `type`, `title`, `chars`. Etter: **259 tokens** på tunnelbasen, utforskningens
prompt-tokens 77 / 90 / **91 %**. **Listen bygges av `Bundle.context_files`, ALDRI `files`**
det er dén property som dropper `type: verdict`-laget (og nestede `index.md`) på hvert nivå, og en
liste bygget av `files` ville rutet tidligere dommer foran navigatøren UTENOM den gatede
ExpeL-folden mens hver kostnads-arm forble grønn. **Et premiss ble felt før noe ble bygget på det:**
«indeksbodyen er basens egen navigasjonsprosa, så den hører hjemme her» — tunnelbasens rot-indeks er
**alene 4 763 tegn ≈ 1 400 tokens**, altså nesten hele taket, for et felt katalogen alt gir et
bundet utdrag av og `read_file(id, "index.md")` fortsatt gir helt. **Taket bor i TESTEN**
(`_CEILING_CHARS = 1 500`), katalogtakets regel av katalogtakets grunn. **AVVIK fra ordren, uttalt:**
ordren ordlegger gaten i o200k-TOKENS; gaten bounder TEGN, fordi `tiktoken` ikke er en
prosjektavhengighet og en gate som skipper når en valgfri pakke mangler er en gate som kan være
stille fraværende — konverteringen er MÅLT (748 tegn / 259 tokens = 2,89 tegn/token), og ordrens
eget kriterium er verifisert direkte én gang av instrumentet. **«Ikke utløs» er bevist som en
MÅLING, ikke som en forsikring:** debattens tre `okf.bundle_context`-kopier er **byte-identiske før
og etter** i alle tre baser (12 047 / 32 567 / 39 104 prompt-tokens, hver prompt uendret) — sterkere
enn å påstå at `run.py` ikke ble rørt. **Verktøybeskrivelsen og navigatørens instruksjon er oppdatert
i samme trekk:** begge påsto «read its navigated context», og en beskrivelse som lyver om kroppen er
modellens instruks (Fase 3-klassen, påstander flaten gjør om SEG SELV). **To eksisterende asserts
ville blitt VAKUØSE i stillhet** (`read_bundle(...) != ""` er sant for enhver liste,
`test_explore_loadbearing.py` + `test_bundle_id_reconciliation_loadbearing.py`) og er styrket, ikke
latt stå. Load-bearing MÅLT (`tests/test_read_bundle_cost_loadbearing.py`, 6 armer), **sju mutasjoner
alle røde mot HELE suiten** + grønn kontroll **1 195/5** (fra 1 189/5, supersett, 0 fjernet) og golden
`demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): reverter sømmen
(7 røde) · bygg fra `files` (3) · bundet men VAKUØS tom liste (6) · dropp `chars` (2) · bær
indeksbodyen likevel (4) · `read_file` trunkerer (2 — inkludert katalog-gaten, et uavhengig vitne) ·
detach `reconcile_bundle_id` (1). **Ærlighets-grenser, uttalt:** dette er IKKE «59 % kostnad» — en
navigatør som åpner *k* dokumenter betaler *k* `read_file`-resultater, og gevinsten er at den betaler
for det den VALGTE og at hvert resultat rir fra SITT kall og framover; at en LEVENDE modell velger
BEDRE med en liste enn med hele konteksten er IKKE bevist (structured-output-grensens klasse);
multiplikatoren 5 gjelder dette manuset (`misjonsreview-v2` § 4 målte 7× med et annet); debattens 3×
er PM-ens egen beslutning og er urørt; prefiks-caching (≈ 60 % debatt / ≈ 40 % utforskning cachebart
som koden står) er NOTERT, ikke bygget. **Et fravær som var instrumentfeil, ikke faktum:** første
ETTER-kjøring rapporterte 0 kopier på to baser — sonden var en midtskive som traff norske tegn
prompten serialiserer escaped; byttet til et ASCII-konseptfilnavn ga 5, som før.
- **Ekspertdommen kan ikke oppstå av STILLHET, og fraværet er en FØRSTEKLASSES tilstand (F2,
non-goal 3, økt 66):** `run_project` KREVDE `verdict_input` og kjørte `capture_verdict`
ubetinget, CLI-en defaultet det til `{"approved", "reviewed by expert"}`, og hosting listet det
som PÅKREVD. Netto: hver flaggløs kjøring myntet en ekspertgodkjenning ingen ga, den gikk inn i
den delte storen, og `run_portfolio` bar den inn i neste prosjekts hypotese-prompt som en
*prior expert verdict* — på flaten som ble overlevert 14.08. **`RunResult.verdict` er nå
`Verdict | None`**, og `None` er hva stillhet produserer: ingenting myntes, ingenting lagres,
ingenting varsles. Prinsippet sto allerede skrevet i repoet — `RunFailure`s docstring: å fylle et
felt med en dummy legger FABRIKKERT proveniens inn i aggregatet. **Traceability koster ingenting,
fordi nøkkelen DERIVERES fra kandidaten:** `RunResult.verdict_key` (property, ikke lagret felt —
en andre kopi av en nøklingsregel er kø-(p)) er `verdicts.verdict_key`s alt dokumenterte formål,
identisk med `verdict.id` når en dom BLE gitt, og fortsatt meningsfull når ingen ble det; det er
den outboxen og den hostede responsen stempler, så et artefakt fra en ukommentert kjøring er
fortsatt dømbart og joiner tilbake via Steg-7-innboksen. **Halv dom NEKTES på begge dører**
(`FeedbackContract` er ENESTE sted formen valideres, og CLI-en nekter ved navn FØR enhver
mode-dispatch): den manglende halvdelen er ekspertens å skrive, aldri vår å defaulte — validering,
ALDRI reparasjon (`write_concept_file`-presedensen). **Hosting er WIDENING, ikke bryting:**
`verdict_input` flyttet `_REQUIRED_FIELDS``_OPTIONAL_FIELDS`, så hvert kall som finnes ute
virker uendret; en kaller som utelot det fikk før 400 på et felt som ikke KUNNE fylles ærlig.
**De to mode-partisjonene fikk `--decision`/`--rationale` inn — og det er en KONSEKVENS, ikke
scope-krype:** kommentarene på begge stedene sa ordrett at en ærlig nekt var *uimplementerbar*
fordi de non-None argparse-defaultene gjorde en eksplisitt verdi uskillbar fra defaulten. Med
defaultene borte er den implementerbar, og «refused, never ignored» er partisjonens egen regel.
`run.verdict_notice` er ENESTE renderer og leser dommen av kjøringens EGET stempel, ikke av argv.
**Ærlighets-grense, uttalt:** referanse-fixturens SYNTETISKE `verdict_input`-rader står URØRT —
de er merket SYNTETISK på fire steder og er reviewens F5 (måling av misjonspåstanden), ikke F2;
`Project.verdict_input` er nå valgfri, så en rad UTEN dom er lovlig. Load-bearing MÅLT
(`tests/test_ungiven_verdict_loadbearing.py`, 15 armer), **åtte mutasjoner alle røde mot HELE
suiten** + grønn kontroll 1080/5 og golden `demo-transcript.stdout` BYTE-UENDRET
(`shasum -a 1` = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): detach fangst-gaten (5 røde) · gjeninnfør
argparse-defaultene (22) · hosting krever fortsatt feltet (1) · CLI-en REPARERER en halv dom (2) ·
kontrakten reparerer en halv dom (1) · `verdict_key` lest av dommen i stedet for derivert (2) ·
begge partisjons-radene fjernet (2) · rendereren påstår en dom som aldri ble gitt (2). **ÉN
MUTASJON FALSIFISERTE TESTEN FØRST (repoets vakuøs-gate-klasse, ELLEVTE gang):** `--report`-armen
brukte et bart `--report`, som nekter med rc 1 uansett fordi `--ledger` mangler — testen sto
GRØNN med partisjons-raden fjernet. Den kjører nå mot en argv report-modus ellers ville AKSEPTERT
(gyldig `--ledger` + en kontroll som beviser rc 0 uten flaggene), så rc 1 er mutantens motsatte
utfall. **Migreringsnote:** ingen ekstern kaller brekker — hosting utvider, CLI-ens gamle
flaggform er uendret, og det som ENDRER seg er at en flaggløs kjøring nå SIER at ingen dømte i
stedet for å påstå `decision=approved`.
- **Planen et menneske signerer er TEKST, aldri en objekt-repr — og fraværet av repr er en EGEN,
bredere assert (BLOCKER-1, økt 67):** fire steder gjorde `str(review.plan)` på en MAF `Message`
som ikke har noen `__str__` (MÅLT: `type(Message).__str__ is object.__str__`), så BEGGE
HITL-dørene viste og lagret `<agent_framework._types.Message object at 0x…>`: terminalen F4
spør ved (`explore.py:1395`), de to opptakene i `plan_reviews` (`:1404` approve, `:1418` revise)
og den PARKERTE spørsmålsfila U12 (`:1478`) — det ENESTE som krysser prosessgrensen. En ekspert
som svarte `approve` signerte blindt. Fiksen er den eksisterende `_plan_text` (`:966`) på alle
fire; ingen ny hjelper. **Fire asserts var grønne mot defekten fordi de var TRUTHINESS eller
SELV-SAMMENLIGNING:** `reviews[1]["plan"] != ""`, `waiting[0].plan`, og
`reviews[0]["plan"][:40] in out` — den siste sammenlignet den samme repr-en med seg selv, så de
to flatene var enige mens begge var uleselige. Diskriminatoren er innhold som KUN kan komme av
`Message.text`: MAF komponerer plan-meldingen rundt managerens svar ORDRETT (målt), så en
sentinel i det skriptede svaret er til stede når teksten ble tatt og fraværende når repr-en ble
det. Sentinelen bor i et `reason`-felt fordi ingenting leser dem — å nøkle den til en ANSWER
ville endret kjøringen den måler. **`str(review.current_progress)` (`:1396`/`:1479`) er BEVISST
urørt:** den er en `MagenticProgressLedger | None`, ikke en `Message`, og pydantic renderer den
lesbart (målt) — men i disse kjøringene er den `None`, så terminalen skriver «progress so far:
None». Annen defekt, annen ordre. Load-bearing MÅLT
(`tests/test_plan_review_cli_door_loadbearing.py` + `tests/test_async_plan_review_loadbearing.py`),
fire mutasjoner — **ÉN PER LINJE**, fordi ordrens ene samlede revert undertestet og `:1418` er
revise-grenens egen kopi som ellers ikke hadde noe rødt vitne: `:1395` → 1 rød (stdout) ·
`:1404` → 2 · `:1418` → 1 (T1 alene) · `:1478` → 1 (async T9). Golden byte-uendret.
- **Generalprøven kan ÅPNE en base, og artefaktet sier hvilken (MAJOR-1, økt 67):** `--scripted-replies`
tok ÉN konstant streng per rolle, så ingen skriptet rolle kunne emittere et `function_call`
MÅLT 0 verktøykall / 0 approaches / 1 runde på 4/4 baser, mens hvert annet felt i
`{run_id}-exploration.json` så ut som en kjøring som hadde virket. Måleprotokollens gratis trinn
(«bevis så mye som mulig før det dyre») kunne altså ikke bevise at navigatøren åpner noe, og
etter en BETALT kjøring kunne ingen lese om den gjorde det. To halvdeler, hver gatet så den ANDRE
ikke kan bære den. **(a) `ExplorationToolRecorder`** — en `FunctionMiddleware`
utforskningsagentene som registrerer NAVN + `bundle_id`-argumentet i KALL-REKKEFØLGE på den
kaller-eide `ExplorationTrace`; `trace_payload` skriver det ved siden av `quick_validations`.
**SØSKEN av `mcp_tools.ToolCallRecorder`, aldri en gjenbruk:** den filtrerer til KONFIGURERTE
eksterne verktøy, dedupliserer per `(server, tool)` og returnerer SORTERT, fordi dens rad er en
egress-påstand; denne beholder rekkefølge uten dedup, fordi et sortert dedupet sett ikke kan
skille en generalprøve som LESTE en base fra en som bare listet dem. Å generalisere den ene til å
tjene begge ville brutt den andre. RESULTATET registreres ALDRI — det er basens innhold, altså
nettopp det MAJOR-3 målte til 7393 % av alle prompt-tokens. Wiret i BEGGE workflow-byggene
(`explore()` OG `resume_exploration()`) — men **resume-armen er DEFENSIV og UVITNET, og det er
målt, ikke antatt** (`budget_stop`-presedensen): å detache KUN den andre forekomsten lot hele
suiten stå grønn (1087/5), fordi ingen park/resume-scenario under det skriptede manuset når en
verktøykropp. Den står fordi et gjenopptatt leg ellers ville registrert null verktøykall — samme
stille gap som `plan_reviews.extend` i økt 64 — ikke fordi en test holder den.
**(b) et trinn-MANUS** — en utforskningsrolle kan få en LISTE der et trinn er tekst eller ETT
`{"call": "<tool>", "args": {…}}`. Formen utvider den ENE kanoniske `_inner_get_response`-kroppen
(S2.5), aldri en andre klient: manuset ligger VED SIDEN AV selektoren (en selektor returnerer
`str` ved kontrakt, og et verktøykall er ikke tekst), og et utløpt manus faller tilbake på
selektoren — degradering til konstantformen, ikke til stillhet. Listeformen NEKTES for debattens
roller ved navn, og hvert malformet trinn nektes ved navn (validering, ALDRI reparasjon).
**Å skripte navigatøren er IKKE nok, og det er MÅLT:** med en KONSTANT manager konkluderer
kjøringen etter én runde uten å ha gitt noen deltaker en tur, så `tool_calls` forblir tomt
uansett hva navigatøren fikk. Manageren må selv få et trinn-manus — én tekst per stadium (fakta,
plan, ledger, ledger, sluttsvar), samme grunn `simulation._exploration_manager_reply` nøkler på
PROMPTEN og ikke prosjekt-ID-en: manageren får fem ULIKE spørsmål og én konstant svarer alle fem
med første rundes ledger. Kontroll-testen med konstant navigatør (og manager i stadier) er dét
som holder de to formene fra hverandre.
Load-bearing MÅLT (`tests/test_scripted_explore_door_loadbearing.py`, 12 armer), **ni mutasjoner
alle røde mot HELE suiten** + grønn kontroll 1087/5 og golden BYTE-UENDRET: detach recorderen
fra begge byggene (1) · dropp `tool_calls` fra `trace_payload` (3) · sorter+dedupliser sinken (2)
· registrer navnet uten basen (3) · nekt listeformen igjen (2) · aksepter lista men emitter tekst
(1) · toler et malformet trinn (1) · la en debattrolle ta listeformen (1) · dropp
ukjent-nøkkel-whitelisten (1). **ÉN MUTASJON FALSIFISERTE TESTEN FØRST (repoets
vakuøs-gate-klasse, TOLVTE gang):** nekt-testen brukte `{"invoke": …}` og sto GRØNN med
forms-sjekken detached — UKJENT-NØKKEL-grenen fanget den i stedet, så nekten under test hadde
intet vitne. To grener, to armer, to mutasjoner. Ærlighets-grense, uttalt: at en LEVENDE modell
kaller verktøyene er fortsatt ikke bevist (structured-output-grensens klasse) — dette gjør den
GRATIS halvdelen av stigen ekte, ikke den betalte.
- **MAF-pinnen er en TRIPWIRE, ikke en frys — og det som gjorde løftet farlig var IKKE en form som
forsvant (F15, 02.09, core 1.9.0 → 1.16.0, orchestrations 1.0.1 → 1.1.1):** de to kan ikke løftes
hver for seg (orchestrations 1.1.1 krever selv `core>=1.15.0`). Gulvet bor i ÉN konstant
(`_MIN_VERSION` i `tests/test_maf_version_guard.py`) og `pyproject`-asserten DERIVERER sin
forventede streng fra den — to literaler for ett faktum drifter (kø-(p)), og et driftet gulv er en
vakt som slutter å vokte uten én lokal diff. **17 private/ugaranterte former, derivert fra repoets
EGNE siteringer** (hver `_modul.py:linje`-referanse i `src/` + hver form en søm overstyrer eller
konstruerer); **16 sjekket MEKANISK av en probe mot begge versjoner (1 endret), den 17. funnet av
TESTSUITEN (endret) — 2 endret totalt.** Splitten er ikke pedanteri: «2 av 16» ville tilskrevet
proben et funn den ikke gjorde, og skjult at proben sjekker statiske egenskaper ved KILDEN mens den
farlige endringen var en egenskap ved KJØRINGEN — nevner-disiplin anvendt på mitt eget instrument. Kjent-positiv: `MiddlewareFailure`
(ny i 1.15.0) flippet NO → YES, altså KAN proben oppdage endring; `_compaction.py`s
`@experimental`-markører ble FORKASTET som kjent-positiv fordi de teller 0 i BEGGE versjoner og
derfor ikke diskriminerer noe. **Den farlige endringen var den ordren navnga — formen som fortsatt
importerer, men har flyttet semantikk i stillhet:** en park skriver nå **TO** checkpoints og bare
ÉN bærer plan-review-typen, så en feildeklarert `_ALLOWED_CHECKPOINT_TYPES` **tømmer ikke lenger
listingen** — den taper nøyaktig den checkpointen som betyr noe, `get_latest` returnerer den ANDRE,
og `_park`s `latest is None`-vakt passerte mens kjøringen svarte `rc=0` og skrev et spørsmål som
aldri kan bære svaret. Vakten sjekker nå EGENSKAPEN den alltid mente (`str(request.request_id) in
latest.pending_request_info_events` — et DEKLARERT felt) i stedet for symptomet som pleide å
innebære den, og fjerner dermed en privat avhengighet i stedet for å legge til en. **`ExperimentalWarning`-paret
P4 pkt. 2 betalte for å BEHOLDE er borte fordi MAF sluttet å sende det** — `_feature_stage.py`s
`_add_runtime_warning` emitterer ved FØRSTE BRUK, ikke ved import, og demoen instansierer ingen av
de to typene; goldenens stderr er derfor TO linjer, regenerert som en BESLUTNING, mens
`site-packages`-maskeringen er BEHOLDT (spannet er ubebodd, ikke pensjonert) og
`test_normalisation_does_not_mask_a_new_warning` fortsatt er grønn. Load-bearing MÅLT mot HELE
suiten, grønn kontroll **1089/5** og `demo-transcript.stdout` BYTE-UENDRET
(`shasum -a 1` = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): M1 revert av vakten → 1 rød. **ÉN MUTASJON BLE IKKE
RØD, og det står som en ÆRLIGHETS-GRENSE, ikke som en gate:** spikens gjenopptak fra
`checkpoint_ids[-1]` (siste element i en glob-ordnet listing — nøyaktig anti-mønsteret `_park`s
docstring advarer mot) feilet i den første fullkjøringen etter bumpen og var GRØNN ved mutasjonen,
altså rekkefølge-avhengig og flaky. Fiksen står på den observerte feilen, ikke på et rødt vitne.
Rapport: `docs/2026-09-02-f15-maf-pinnen.md`.
- **Falsifisering MOT PROVENIENS: en dom hviler på det basen faktisk BÆRER, og det den ikke kunne
fortelle deg er en del av dommen (B4, Steg 113, økt 75+76):** `parse_frontmatter` er
linjeorientert og leser en flow-verdi som ÉN streng, så `verified: { by: …, at: … }` — SPEC §5.2s
kanoniske form — nådde konsumenten som ulesbar tekst, og en blokkform nådde den som **tom** streng.
Begge så ut som «ingen proveniens». **Den defekten er den samme fra begge sider, og produsenten
MÅLTE den selv:** `llm-ingestion-okf`s egen guard-parser avviser sin EGEN golden
(`docs/okf-nokkelinventar.md:219`, `OKFFrontmatterError … '['`) — bekreftet på nytt ved Steg 13 mot
`62b6192`. **Ett skann, to LESERE, aldri to parsere:** `_split_frontmatter` er modulens ENESTE sted
`---` sammenlignes (gatet av en skanner-tellende arm, M14 → 1 rød), og `decode_flow_value` er den
ene navngitte sømmen over de rå linjene. Dekoderen er **nøkkel-agnostisk** (aldri hardkodet
`{id, resource}` — den avtalte segmenterte formen legger til `segment_id`/`source_offset`, så en
to-nøkkels dekoder ville nektet nøyaktig de basene sømmen finnes for; M3 → 12 røde) og gjør
**ingen YAML-1.1-koersering** (`yes`/`on`/`1` forblir strenger — en bevisst divergens fra PyYAMLs
resolver, skrevet ned i stedet for arvet i stillhet; M4 → 1 rød, en ratchet grønn ved
konstruksjon).
**Tre tilstander, og den tredje ER poenget:** `evidence_for` svarer `present` / `absent` /
`unreadable`, og den ulesbare bærer trippelen `(state, reason, items_seen)` — «hvilken FORM» og
«hvor MANGE» er to ulike operative spørsmål, `BudgetExceeded`-kø-(y)-regelen anvendt på en
dokumentleser. Å kollapse `unreadable` inn i `absent` gjør en dom om MANGLENDE bevis til bevis for
FRAVÆR (M7 → 4 røde); å rapportere én fast form for alle (M8 → 9 røde). K5-terskelen bor ÉTT sted
(`admits_falsification`: `present` OG en tier over `unverified`) og har TO konjunkter som måles
hver for seg (M19a → 2 røde, M19b → 1 rød). **Nevneren er skrevet ned:** SPEC §5.1 navngir SEKS
oppføringsnøkler og produsenten skriver TO (`62b6192`), så terskelen krever kun det som faktisk
emitteres — å kreve `author`/`usage_count`/`last_modified` ville gjort den unåbar i praksis mens
den så streng ut på papiret. **`adjudication` har en TREDJE token som er VÅR:** vokabularet på
tråden er lukket (`proposed` | `adjudicated`), og `unknown` er hva FRAVÆR betyr — aldri noe et
dokument får erklære (M20a → 2 røde), og en bærer som gir fra seg en payload uten tilstanden er
vokabularet uten sømmen (M20b → 1 rød). **`evidence_for` KUNNE IKKE drive den** (D-e → 5 røde):
MÅLT er `adjudication` en SKALAR, og begge gyldige verdier kommer tilbake som ETT identisk
`unreadable`/`unsupported-flow`-record, så den ruten kan ikke skille dem i det hele tatt;
`parse_frontmatter` er skalarleseren over SAMME skann.
**Skriveren nekter nøyaktig det leseren ikke kan lese**, og det er strukturelt, ikke en konvensjon:
`verified_field` og `write_concept_file` reiser den SAMME navngitte `FlowDecodeError` (M5 → 5 røde,
M16 → 3 røde, M17 → 1 rød). Det usikre tegnsettet er TRANSKRIBERT fra produsentens eget
`_FLOW_UNSAFE_RE` (`materialize.py:176`, `[,\[\]{}]|:\s`) — ikke oppfunnet — og er BEVISST
smalere: vår parseparator er kolon-MELLOMROM, så `":\t"` kan ikke restrukturere en av våre par.
**Ko-drift er stengt av skrivesidens gate, ikke bare oppdagbar via en ekstern referent:** planen
spådde at M9 (skriver OG dekoder flyttes til blokkform sammen) ville la rundturen stå GRØNN.
**MÅLT er den spådommen ikke konstruerbar** — skriveren kan ikke flytte alene (M9a → 26 røde + 8
feil), fordi `render_frontmatter` enlinjer hver verdi OG `write_concept_file` nekter formen; M9
krevde derfor at BEGGE vaktene ble slått av samtidig, og ga 17 røde inkludert rundturen. Det er et
sterkere utfall enn planen ba om, og det er skrevet ned som målt, ikke som spådd.
**Navigasjonen forblir TOLERANT mens dekoderen nekter** (OKF SPEC §4), bevist med BYTES: M10 →
**1 rød, ett navngitt vitne**, mens begge nav-goldenene og demo-transkriptet står.
**Identitet er PARET `(bundle_id, concept_id)` (D6/B1), og `origin` har TRE verdier:**
`okf.reconcile_bundle_id` er den ENE avledningsregelen — konseptets egen frontmatter først, rot-
`index.md` som fallback, mountets basename til sist — og `ResolvedBundleId.origin` sier hvilken
(`declared-concept` / `declared-index` / `mount-derived`). **Påkrevd uten default**, av
`cost_baseline_anchored`s grunn: begge defaults ville løyet om en hendelse. **Ikke en boolean**
en kaller som ikke kan skille «konseptet sa det» fra «vi falt tilbake to ganger» har fått et
stempel den ikke kan revidere (D-i → 3 røde). **MÅLT: null `^bundle_id`-treff** noe sted under
`shared/`, `src/`, `tests/` mot en kjent-positiv kontroll på 31 filer med `^type:`, så begge
erklærte grener er DEFENSIVE (`budget_stop`-presedensen) og drives fra CRAFTED baser; alle 27
`bundle_dirs=`-kallsteder står grønne. **⚠️ TO SETNINGER I DENNE RADEN ER ENDRET 03.09 — se
slakke-raden nederst (S7a-3 pkt. 1):** mount-avviket NEKTER ikke lenger (erklært vinner), og
«begge erklærte grener er DEFENSIVE» gjelder kun dette repoet — K2 erklærer nøkkelen i 619 filer. **`explore._bundle_index` forblir REN** — to av dens egne
armer konfigurerer kataloger som ikke finnes og forventer en id-feil, ikke en I/O-feil — så
avstemmingen skjer der en base faktisk ÅPNES: `explore.read_bundle` (M11a → 1 rød),
`run_project`s bundle-arm (M11b → 2 røde) og dispatcheren (M11c → 1 rød, som erstattet en privat
`Path(raw).name`-kopi). En base uten lesbar `index.md` er **ukjent, ikke uerklært**
`navigate_bundle`s fail-fast propagerer. `BundleIdMismatch` subklasser `ValueError` så den lander
på CLI-ens nekt-tuppel og hostings 400-arm, aldri krasj-kanalen; nekten måles på **null
modellkall**, ikke på exit-koden (M12 → 2 røde. **Ærlighets-grense, MÅLT:** planens påstand
«exit-koden forblir 1 uansett» HOLDER IKKE for denne argv — mutanten reiser
`BudgetExceeded: rounds limit=12 observed=13` før noen nekt, så sink-asserten nås aldri. Asserten
på KALL er likevel riktig design; den er det som ville fanget en nekt-etter-forbruk som DID
returnerte rent).
**En kryss-base-kollisjon rapporteres, aldri droppet i stillhet (D2):** `VerdictStore.add` er
first-write-wins og `_mint_id` ekskluderer korpuset ved konstruksjon, så to baser som beskriver
SAMME kandidat kollapser på én dom. `_mint_id` er URØRT (normativ i `shared/method-spec.md`,
commons-eid) og `add` likeså — en drop DER kan like gjerne være mot en Steg-7-innboksdom eller et
bundle-frø. Regnskapet bor i dispatcheren, som er det ENE stedet som holder id→base-kartet
(M13 → 2 røde). **Id-en hentes fra `run_project`s EKSISTERENDE `notify`-søm, aldri fra
`RunResult.verdict`** (D-l): `notify` fyrer INNE i fangst-blokka, altså nøyaktig når en dom finnes
(F2), og båsen bygges FERSK hver iterasjon — hoistes den ut, leser en senere base forrige bases dom
og fabrikkerer en kollisjon som aldri skjedde (D-l → 1 rød). `MultiBaseResult.collisions`
DEFAULTER til tom tuppel (`skipped_links`-halvdelen: en tom trace er et ærlig POSITIVT utsagn), og
`collision_notice` returnerer `None` på den — omisjon, aldri tom rad.
**Metoden er en DELT Agent Skill, forfattet i commons (D4):** `shared/skills/falsification-
reviewer/` kommer KUN via `git subtree pull` — lokal forfatting ville gitt et wheel søskenet aldri
arver, og INGEN test i suiten oppdager det avviket. Terminologi-gaten er den som biter
(`OKF bundle` i kundevendt prosa → M18a, 1 rød), og den er paret med en KJENT-POSITIV kontroll på
at regexen KAN finne strengen. Rammeverks-nøytraliteten har ÉN kopi
(`test_method_spec_is_framework_neutral`), utvidet av Amendment 2 fra `expert-reviewer` alene til
`GUARDED_SKILL_DIRS` — den nye skillen hadde ingen vakt i det hele tatt (M18b → 1 rød, egen
signatur) — pluss en fail-closed arm som blir rød når et fremtidig subtree-pull bringer en TREDJE
skill som ikke er listet. Det verkede eksempelet materialiseres fra `frontmatter_verbatim`
ORDRETT (Amendment 3): den linjeorienterte `frontmatter`-projeksjonen kan ved konstruksjon ikke
bære blokkform, så å bygge fra den ville gjort det ulesbare tilfellet `absent` og armen ville stått
GRØNN mens den beviste det motsatte av sin egen docstring. Eksempelets egen dom er `undecided`, ikke
`survived` — en påstand hvis ene mulige gjendriver var ulesbar ble aldri angrepet.
**Load-bearing MÅLT: 30 mutasjoner, ALLE røde mot HELE suiten**, grønn kontroll **1189 passed /
5 skipped**, alle tre byte-fasitene OK og `demo-transcript.stdout` BYTE-UENDRET
(`shasum -a 1` = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`); node-ID-supersettet holder strengt (1094 → 1194,
**0 fjernet**). Per mutasjon: M1 27 · M2 2 · M3 12 · M4 1 · M5 5 · M6 1 · M7 4 · M8 9 · M9a 26+8E ·
M9 17 · M10 1 · M11a 1 · M11b 2 · M11c 1 · M12 2 · M13 2 · M14 1 · M15 1 · M16 3 · M17 1 ·
M18a 1 · M18b 1 · M19a 2 · M19b 1 · M20a 2 · M20b 1 · D-b 1 · D-e 5 · D-i 3 · D-l 1.
**TRE av planens spådde signaturer ble FALSIFISERT av målingen, og de står som målt:** M9s
«rundturen forblir grønn» (ikke konstruerbar), M12s «exit-koden forblir 1» (mutanten reiser i
stedet), og M17s spådde PAR (kun 1 rød — `verified_field("a: b", …)` runder faktisk trippen, fordi
`_find_pair_separator` tar FØRSTE kolon-mellomrom og verdien beholder sitt eget kolon).
**Operatørbeslutninger:** D1 én dekoder-søm · D2 dispatcher-side kollisjonsregnskap · D3 én
linjekilde bak begge lesere · D4 skillen forfattes i commons · D5 ingen ny avhengighet (ingen
PyYAML) · D6/B1 identitet = `(bundle_id, concept_id)`, konseptet først. **D7-speiling er ÅPEN** for
dekoder-semantikken, som S3.2 og S4.0. **Ærlighets-grenser, uttalt:** `evidence_for(path, key=…)`
med en ANNEN nøkkel enn `verified` REISER for enhver verdi som dekoder til oppføringer uten `by`,
fordi `tier` avledes ubetinget — MÅLT: alle 11 eksisterende kallsteder bruker defaulten, så
parameteren har aldri vært øvet, og det er RAPPORTERT, ikke fikset (utenfor denne ordren);
`verified_field` validerer ikke `at`; og at en LEVENDE modell kaller falsifiseringsskillen godt er
ikke bevist (structured-output-grensens klasse).
- **Den TREDJE projeksjonen inn i `CostBaseline` DERIVERES fra en tabell som alt er i basen — og
den nekter heller enn å oppfinne (MAJOR-4, økt 78):** `cost-baseline.json` er håndskrevet per
prosjekt og `baseline_from_project` tilhører veg-domenet, så et INGESTERT anbudskorpus kunne
navigeres og aldri forankres. `okf.derive_cost_baseline(bundle, *, project_id)` leser
prisskjemaet. **`project_id` er PÅKREVD keyword, ikke lest av basen:** `run._project_from_bundle`
fail-faster alt kjøringens id mot basens `validator-input.json`, så en andre lesing her ville vært
kø-(p) — og ville dratt en IR-projeksjon inn i en funksjon hvis hele input er en tabell.
**PREMISSET BLE MÅLT FØR NOE BLE BYGGET PÅ DET, og ordrens to pekere navnga TO ULIKE FORMER:**
`examples/*/expected-bundle/` bærer PIPE-tabeller, men hver eneste av dem er csv-/sql-kilt og
rendret av `render.render_table`**xlsx-stien når ALDRI `render_table`.** Målt (pandoc 3.10.2,
produsentens egen `_PANDOC_WRITER = "markdown"` + `_PANDOC_ARGS = ("--eol=lf", "--wrap=none")`,
mot produsentens egen `tests/fixtures/two-line-krav.xlsx` og et håndlagt Prisskjema):
`extract._extract_office` konverterer, og `inbox.py` gir teksten videre til
`render_inbox_concept(sanitized_text, …)` URØRT — resultatet er en pandoc **SIMPLE table**, der
dash-linja definerer kolonne-spennene. En pipe-only leser ville altså vært INERT på nøyaktig det
korpuset MAJOR-4 finnes for, og en simple-only leser inert på eksemplene ordren pekte på. Begge
leses, av TO skannere over ÉN rollemapping og ÉN tallgrammatikk (`_split_frontmatter`-formen: ett
skann, to lesere), aldri to kopier av semantikken. **Span-slicing, ALDRI splitt på whitespace:**
K2s hele form er tomme priseceller, og en whitespace-splitt kollapser dem og skyver hver senere
verdi én kolonne til venstre — en feilmapping som leses som DATA (M16 → 3 røde).
**Ingen skjønn noe sted:** header-vokabularet er lukket og matches EKSAKT (en delstrengregel ville
latt `Enhetspris eks. mva` og `… inkl. mva` kreve samme rolle, og leseren ville valgt mellom to
priser), tallgrammatikken er lukket og **dot-desimal** (målt output er `1250.0`/`42.5`, så et
komma ville kjøpt ingenting og importert `1,250`s tusenskille-vs-desimal-tvetydighet gratis — et
håndskrevet norsk `1 250,50` er en NEKTET celle, uttalt), og hver tvetydighet er en nekt: ingen
kandidat-tabell, mer enn én, to kolonner om samme rolle, to rader med samme kostkode.
**Delvis priset skjema nekter i SIN HELHET** — ikke forsiktighet: en halvderivert base forankrer
noen koder mens `ProvenanceStamp.cost_baseline_anchored` rapporterer `True`, og den biten er
påkrevd-uten-default nettopp fordi begge defaults ville løyet. Skannet over `context_files`, aldri
`files` (MAJOR-3-regelen). **`CostBaselineDerivationError` subklasser `ValueError`**
(`BundleIdMismatch`-presedensen) — CLI-ens nekt-tuppel og hostings 400-arm, aldri krasj-kanalen.
Wiret bak `--derive-cost-baseline`, ALDRI stille: ÉN oppløsning i `run.py`s bundle-arm tjener både
full kjøring og `live_dry_run`, og **nekten PROPAGERER** i stedet for å degradere til fil-lasteren
(`load_mandate`-regelen — en kaller som ba om derivasjon og fikk en uforankret kjøring er besvart
av en stille nedgradert ordre). Tre CLI-nekter, alle ved NAVN: krever `--bundle-dir`, refusert i
`--portfolio` (ved navn, ikke ved gjennomfall til `--bundle-dir`-kravet — `--explore`-presedensen)
og i `report_forbidden` (report-modus returnerer FØR nekten, så en utelatelse er et stille DROPP,
ikke en nekt — F4-gapet). **FIXTUREN er MÅLT, ikke håndskrevet:** begge basene under
`tests/fixtures/` er pandocs output ORDRETT, og den uprisede er K2s faktiske pre-award-form —
**kolonnene OVERLEVER som blanke** (målt), så tabellen ER en kandidat og nekten blir den skarpe:
leseren identifiserer kolonnene, leser tomme celler og nekter ved navn. `validator-input.json`
skrives KUN i testen, aldri inn i den innsjekkede fixturen (`measure`/`claimed_saving_nok` er
menneskets/mandatets). **`pytest.raises(ValueError)` ville IKKE gatet arm (b), og det er MÅLT, ikke
resonnert:** M17 (drop positivitetsvakten) får mutanten til å reise
`pydantic_core.ValidationError``isinstance(e, ValueError) is True`,
`isinstance(e, CostBaselineDerivationError) is False` — så en løsere arm ville stått grønn mot
nøyaktig den mutasjonen den finnes for. Load-bearing MÅLT
(`tests/test_cost_baseline_derivation_loadbearing.py`, 22 armer), **18 mutasjoner alle røde mot
HELE suiten** + grønn kontroll **1230 passed / 5 skipped** (fra 1208/5, supersett, 0 fjernet) og
golden `demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`):
M1 detach run-wiringen (2 røde) · M2 fallback ved nekt (1) · M3 hopp over uprisede rader (2) ·
M4 fabrikkér null (1) · M4b fabrikkér null uten tom-celle-nekten (1) · M17 drop
positivitetsvakten (1) · M5 transponer mengde/enhetspris (3) · M6 skann `files` (1) · M7 ta første
tabell ved tvetydighet (1) · M8 ta første kolonne ved duplisert rolle (1) · M9 last-write-wins på
duplisert kode (1) · M10 utvid tallgrammatikken (1) · M11 drop simple-skanneren (3) · M12 drop
pipe-skanneren (7) · M13 detach `--bundle-dir`-nekten (1) · M14 drop fra `report_forbidden` (1) ·
M15 drop fra portefølje-partisjonen (1) · M16 whitespace-splitt (3). **Ærlighets-grenser, uttalt:**
NS 3451 seksjonsrader (kode + overskrift, ingen mengde, inne i et ellers priset ark) er IKKE
klassifisert — K2 selv var ikke tilgjengelig å måle her, så et slikt ark NEKTER, og regelen skrives
når noen kan måle den ekte formen (en rad som er tom over alle tre kolonner er derimot en blank
spacer og hoppes over); stempelet sier AT en kjøring var forankret, aldri HVILKEN av de tre
projeksjonene forankret den; den hostede flaten er BEVISST urørt (feltet er ikke i whitelisten, så
4e-halvdelene står uendret); og ingen LEVENDE K2-fil er lest — fixturen er syntetisk, og at
produsenten faktisk emitterer denne formen for K2s Prisskjema er MÅLT på pandoc-stien, ikke på K2.
- **Den ERKLÆRTE `bundle_id`-en er identiteten; monteringsnavnet er en filsystem-tilfeldighet
(S7a-3 pkt. 1, økt 81):** til 03.09 NEKTET `reconcile_bundle_id` en base som erklærte en id
katalogen ikke bar. **Målt mot den første leverte basen som erklærer sin egen id** (K2: 618 av
630 konseptfiler + rot-`index.md`, alle `k2-trinn1-20260903`, levert som `K2-bundle-20260903`)
var følgen at basen **ikke kunne åpnes slik den var levert** — botemiddelet var å montere den på
nytt for hånd, én gang per leveranse, for alltid. Det er en konsument som avviser en produsents
legitime output over et katalognavn. **PM-beslutning: konsumenten slakker.** Erklært vinner
(konsept → rot-index → mount, B1s rekkefølge URØRT), avviket REGISTRERES —
`ResolvedBundleId.mount` bærer den overkjørte katalogen, `ProvenanceStamp.bundle_id_source` og
`DryRunReport.bundle_id_source` bærer hele oppløsningen inn i artefaktene, og `bundle_id_notice`
er ENESTE renderer, med TO kallsteder (returnerer `None` ved enighet — omisjon, aldri tom rad; omisjonen er selv
gatet, M5 → 2 røde inkludert et UAVHENGIG eksisterende vitne i
`test_navigation_visibility_loadbearing`). **Stempel-feltet er PÅKREVD uten default** av
`cost_baseline_anchored`s grunn, og her skjerpet: `None` er en VERDI (veg-stien har ingen base),
så et utelatt felt måtte bety det samme som «ingen base» — nøyaktig stillheten kravet lukker.
**Det som FORTSATT nekter er den ekte kollisjonen:** to KONSEPTER i ÉN base som erklærer ULIKE
id-er (`assert_declared_ids_agree`, kalt ved hver dør som ÅPNER en base). **Rot-`index.md` er
IKKE med i enighets-settet** — B1 anvendt en gang til: konsept-slår-index er en PRESEDENS-regel,
så en index i utakt med sine konsepter er fallbacken som taper, ikke to konsepter som kolliderer;
å folde indeksen inn ville nektet nøyaktig de K2-formede basene slakken finnes for (M3 → 1 rød).
Sjekken er en EGEN funksjon, ikke en gren i `reconcile_bundle_id`: den trenger en navigert
bundle, resolveren må forbli REN (`_bundle_index` løser id-er for kataloger som kanskje ikke
finnes), og separat gir den sin egen mutasjon per dør (M1/M2 → 1 rød hver).
**`explore._bundle_index` løser nå den erklærte id-en, og det er en KONSEKVENS — ikke
scope-krype:** den brukte `Path(raw).name` mens dispatcheren brukte `reconcile_bundle_id(raw).id`;
så lenge avviket ble nektet KUNNE de ikke divergere, men med erklært-vinner mynter `explore()`
approaches som navngir MOUNTET mens dispatcheren ruter på ERKLÆRINGEN — en utforskning hvis eget
mandat er uruterbart (M9 → 2 røde, M11 → 1 rød). Uleselig base faller tilbake til basenavnet
i stedet for å reise, fordi to av `_bundle_index`s egne armer konfigurerer kataloger som ikke
finnes og forventer en ID-feil, ikke en I/O-feil — ingenting utvides: den indeksen svarer på
hvilke id-er som kan NAVNGIS, og en base ingen kan lese nektes et øyeblikk senere av den døra som
faktisk åpner den. Load-bearing MÅLT (`tests/test_bundle_id_slack_loadbearing.py`, 13 armer),
**ti mutasjoner alle røde mot HELE suiten** + grønn kontroll **1243/5** og golden
`demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): M1 detach gaten i `run_project` (1) · M2 detach den i
`read_bundle` (1) · M3 fold indeksen inn i enighets-settet (1) · M4 gjeninnfør mount-nekten (9) ·
M5 rendereren skriver alltid linja (2) · M6 detach CLI-utskriften (1) · M7 konstant stempel-wiring
(1) · M8 konstant dry-run-wiring (2) · M9 `_bundle_index` tilbake til mountet (2) · M11
dispatcheren tilbake til mountet (1). **TRE ARMER I `test_bundle_id_reconciliation_loadbearing`
ble SKREVET OM, ikke slettet** — (e)/(f)/(j) pinnet nekten beslutningen fjernet; (j) ble SKARPERE
enn den den erstattet (erklært id ruter, mountet nektes — to implementasjoner som skiller seg i
BEGGE halvdeler, ikke i en exit-kode). **Ærlighets-grenser, uttalt:** uten `concept_name` svarer
rot-`index.md`, så en base hvis index erklærer X mens konseptene erklærer Y løser til X (B1s
rekkefølge, urørt); **portefølje-armen er BEVISST IKKE wiret** — der er `bundle_id_source` `None`
ved konstruksjon (intet referanse-prosjekt setter `bundle_dir`), så en tredje utskrift ville vært
død kode; det er en ANNEN avgjørelse enn `cost_baseline_anchored`s, som wiret nettopp den armen
DEFENSIVT og drev den fra en crafted `PortfolioResult`, og den står her fordi stillhet om
asymmetrien er det eneste gale svaret. Og dispatcherens «to baser deler id»-nekt er NYLIG NÅBAR — den krevde før to
monteringer med samme basenavn, nå kolliderer to ULIKT navngitte kataloger som erklærer samme id.
Kontrakt: `docs/okf-konsum-kontrakter.md § 3.1`.
- **Stigen har tre trinn: `list_bundles``read_bundle``read_dir``read_file` (S7a-3 pkt. 2,
økt 81):** MAJOR-3 bygde `read_bundle` om fra HELE basen til én oppføring per konseptfil, og på de
tre eksempelbasene var det 77…91 %. Så kom det første EKTE korpuset: K2 navigerer til **629
konsepter bak 478 nestede indekser**, og en listing av 629 koster **42 761 o200k-tokens** som rir
i 7 av 12 prompter = **89 % av alle prompt-tokens**. Bindingen holdt asymptotisk og priset likevel
hele korpuset, fordi prisen på å finne ut HVA en base inneholder var satt av hvor mye den
inneholder. De 478 indeksene ble dessuten BYGGET av navigasjonen, KONSUMERT av den og så flatet
ut — agenten så 629 søsken og fikk aldri vite at korpuset hadde en form. **MÅLT ETTER:** rotnivået
er **3 954 tegn / 1 495 tok**, listing-tokens **307 573 → 12 595**, og utforskningens
prompt-tokens **343 826 → 49 225 (86 %)**. BEFORE og AFTER er kjørt i SAMME økt med samme kode
(BEFORE er en mutasjon), og BEFORE reproduserer S7a-2s publiserte tall til 0,03 % — den
kjent-positive kontrollen på instrumentet. **`okf.directory_listing` er ENESTE renderer** og
begge verktøy ER den på hvert sitt nivå; to kopier av en listing-regel ville drevet til to svar om
én base (kø-(p)). **ET PREMISS I ORDREN BLE FELT FØR NOE BLE BYGGET PÅ DET:** `context_files` har
ALDRI holdt hierarkiet tilbake — hver `BundleFile.name` er allerede den fulle bundle-relative
stien, så treet var utledbart fra navnene; det var RENDERINGEN som flatet det ut. Dét er grunnen
til at `bundle_context` og begge nav-goldenene er BYTE-IDENTISKE etter endringen (ordrens eget
krav), gratis og ikke av forsiktighet. **Kataloger utledes av STIER, aldri av `index.md`** (en
nestet indeks er navigasjon, ikke innhold), og listingen bygges av `context_files`, ALDRI `files`
— en katalog-TELLING fra `files` ville reklamert for dokumenter navigatøren ikke får se (N2 → 7
røde). **Hver sti er BUNDLE-RELATIV, altså brukbar ordrett som neste kalls argument** — en
nivå-relativ form måtte komponeres av en modell, og en sti som aldri fantes er verre enn ingen
sti (`_index_excerpt`-regelen, ett trinn opp; N7 → 1 rød). `documents` på en katalog-oppføring er
antallet i hele SUBTREET — hva subtreet holder, ikke hva ett `read_dir` returnerer — og
beskrivelsen sier hvilken av de to det er. Ukjent sti NEKTES ved navn (`BundlePathNotFound`,
`ValueError`-subklasse som `BundleIdMismatch`): en tom listing er umulig å skille fra en katalog
som finnes og er tom (N5 → 1 rød). **Verktøybeskrivelsene og navigatørens instruksjon flyttet i
SAMME commit** — en beskrivelse som lyver om kroppen ER modellens instruks (Fase 3-klassen; N9 →
1 rød). **TO EKSISTERENDE ASSERTS VILLE BLITT VAKUØSE I STILLHET** og er styrket: `len(payload)`
er nå antallet NØKLER (tre, alltid), så `test_read_bundle_cost_loadbearing`s størrelses-arm talte
nøkler, og write-frihets-armen i `test_explore_loadbearing` kalte ikke det nye verktøyet i det
hele tatt. **AVVIK fra ordren, uttalt og målt:** ordren binder «K2 < 1 500 tegn» — K2 kan ikke
være en testavhengighet (utenfor repoet; MAJOR-3-gaten har samme begrensning), og tallet er ikke
oppnåelig: rota bærer 39 identifiserbare oppføringer og måler 3 954 tegn. Gaten binder derfor
1 500 tegn per listing over basene den KAN se, pluss egenskapen som ga fallet (kostnaden følger
oppføringer på ETT nivå, ikke dokumenter i basen), med en FLAT kontroll over 5× taket — uten den
ville en grønn binding like gjerne betydd at fixturen var liten. **Ordrens ANDRE binding
`read_dir` over største katalog bundet») er MÅLT med den SHIPPEDE funksjonen over alle 478
nivåer i K2:** verste nivå noe sted er **6 073 tegn / 2 094 tok** (65 underkataloger) = **4,9 %**
av den flate formens 42 761 — dyrere enn rota fordi hver sti er bundle-relativ, altså den målte
prisen på at en sti er brukbar ORDRETT i neste kall. Load-bearing MÅLT
(`tests/test_hierarchical_navigation_loadbearing.py`, 9 armer), **ni mutasjoner alle røde mot HELE
suiten** + grønn kontroll **1252/5** og golden BYTE-UENDRET (`shasum -a 1` =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): N1 reverter sømmen (4) · N2 bygg fra `files` (7) ·
N3 bundet men VAKUØST tom (12) · N4 dropp `chars` (5) · N5 ukjent sti blir en tom listing (1) ·
N6 `read_dir` ikke registrert (6) · N7 nivå-relative navn (1) · N8 katalog-tellingen konstant (2)
· N9 instruksjonen beskriver den gamle stigen (1). **Ærlighets-grenser, uttalt:** dette er ikke
«86 % for enhver kjøring» (en navigatør som stiger ned *k* nivåer betaler *k* listinger); at en
LEVENDE modell navigerer bedre med en struktur enn med 629 flate dokumenter er IKKE bevist
(structured-output-grensens klasse); multiplikatoren gjelder dette manuset; og `navigate_bundle`
kalles fortsatt per verktøykall (I/O, ikke tokens — ikke målt). Måling:
`docs/2026-09-03-hierarkisk-navigasjon-k2.md`.
- **Sporet sier HVILKE dokumenter navigatøren åpnet, ikke bare hvilken base (S7a-3 pkt. 3, økt
81):** `ExplorationToolRecorder` registrerte NAVN + `bundle_id` i kall-rekkefølge (MAJOR-1). Over
de tre eksempelbasene holdt det — 39 konsepter, og en kjøring som åpnet to av dem etterlot et
spor en operatør kunne resonnere om. Over K2 gjør det ikke: **629 konsepter**, og `tool_calls`
leser `read_file, k2` to ganger, så **hvilke to av 629 kan ikke leses ut av leveransen i det hele
tatt** — økt 77 og 81 måtte begge instrumentere kjøringen for hånd for å svare. `ToolCall.path`
registreres for `read_file` OG `read_dir`; et spor som navnga dokumentene men ikke katalogene
ville sagt hvor en kjøring ENDTE uten å si hvordan den kom dit. **RESULTATET registreres fortsatt
ALDRI**, og det er MAJOR-1s beslutning gjentatt nettopp fordi pkt. 3 er øyeblikket den var lettest
å oppheve: resultatet ER basens innhold, målt til 89 % av hver prompt-token i en K2-kjøring.
`""` for et verktøy som ikke tar argumentet — `bundle_id`s egen regel anvendt på det andre feltet;
en verdi oppfunnet for et argument ingen sendte er falsk attribusjon. **ÉN argumentleser for begge
felt** (`_string_argument`, kø-(p)): to kopier av «les denne nøkkelen ut av begge formene
`FunctionInvocationContext` tillater» ville stått fritt til å være uenige om hva et fraværende
argument betyr. Load-bearing MÅLT (`tests/test_tool_call_path_loadbearing.py`, 5 armer), **fire
mutasjoner alle røde mot HELE suiten** + grønn kontroll **1257/5** og golden BYTE-UENDRET
(`shasum -a 1` = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): P1 detach registreringen (3) ·
P2 dropp `path` fra `trace_payload` (3, inkludert et EKSISTERENDE vitne) · P3 koerser en
ikke-streng til en etikett (2) · P4 les kun Mapping-formen (2).
- **Forslaget kan OPPSTÅ fra kommisjonen og basens eget prisskjema — og ordrens diagnose var feil
(S7b-forberedelse, økt 82):** ordren sa at forslaget *leses fra en håndskrevet
`validator-input.json`. **Symptomet er ekte** — en base uten fila nekter med `FileNotFoundError`
før første modellkall — **men diagnosen ble felt FØR noe ble bygget på den:** `SavingsProposal`
har ALLTID blitt konstruert av `generate._parse_ir` fra MODELLENS svar; fila er en fasit VED SIDEN
AV kjørestien, påkrevd kun som prosjektets IDENTITET. Det skillet avgjorde at S7b er **to sømmer,
ikke én**, og at bare den ANDRE er bygget her. **Nevneren: tre lesere, ikke én**
`run.py:453` (hver bundle-kjøring), `verdicts.py:507` (kun med ikke-tom store) og `run.py:1662`,
dispatcherens rutingsnøkkel, som bevisst ikke tar `project_id` fordi den leser den derfra. Å gjøre
IR-projeksjonen valgfri er den ANDRE sømmen: MÅLT, dokumentert, IKKE bygget.
**Arbeidsdelingen er hele designet:** eksperten sier HVA (`Approach.label``measure`, VERBATIM),
HVILKE linjer (`affected_codes`) og HVOR MYE (`claimed_saving_nok`); dokumentet sier MENGDE og
PRIS (`derive_cost_baseline`, MAJOR-4). `candidate_from_approach` oppfinner ingenting og nekter
ved NAVN på alle tre gap. **Anslaget bor på `Approach`, aldri på `Mandate`**`settle`s egen
regel: tilnærminger er ALTERNATIVER og summeres aldri, så ett tall på mandatnivå ville vært
tvetydig over N; og det er IKKE kjøringens MÅL (`contracts.GoalContract` eier nettopp ett sådant),
hvilket står skrevet der feltet innføres, ellers leses det som den `(p)`-driften modulen forbyr.
**Null modellkall er STRUKTURELT:** `run.evaluate_mandate_candidates` er **SYNC**, så den kan ikke
awaite et chat-kall — ingen mutasjon av kroppen kan stille innføre ett; CLI-armen asserterer det
likevel ATFERDSMESSIG (`_default_factory` patchet til å raise), fordi rc 0 alene også er utfallet
til en dør som gjorde ingenting. **`allow_own_proposals` får en `not_evaluated`-RAD, ikke en
nekt:** raden kan ikke fylles uten en modell, men å utelate den gjør den uskillbar fra en
tilnærming ingen bestilte (`ApproachOutcome`s egen regel), og å nekte hele kjøringen ville vært
feil andre veien — feltet defaulter til `True`. **Fixturen brukes URØRT**, og dét er armens poeng:
`test_cost_baseline_derivation_loadbearing` må kalle `_runnable()` og skrive en
`validator-input.json` inn i en kopi før `run_project` ser på den. Load-bearing MÅLT
(`tests/test_proposal_from_mandate_loadbearing.py`, 18 armer), **seksten mutasjoner, FEMTEN røde
mot HELE suiten** + grønn kontroll **1275/5** (fra 1257, supersett, 0 fjernet) og golden
`demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`,
INNHOLD — ikke git-blob): M1 detach CLI-dispatchen (1) · M2 fabrikkér et anslag (2) · M3 default
kodene til hele skjemaet (1) · M4 toler en ukjent kode (1) · M5 bygg lazily (1) · M6 utelat
own-proposal-raden (1) · M8 detach `--mandate`-nekten (1) · M9 detach
`--derive-cost-baseline`-nekten (1) · M10 dropp fra portefølje-partisjonen (1) · M11 dropp fra
`report_forbidden` (1) · M12 `measure` er ikke ekspertens ord (1) · M13 baseline-rekkefølge i
stedet for ekspertens (1) · M14 rut på mount-navnet (1) · M15 fabrikkér usikkerhetsbånd (1) ·
M16 detach enighets-gaten ved DENNE døra (1).
**`evaluate_mandate_candidates` er den TREDJE døra som ÅPNER en base, og den fikk sitt EGET
vitne** (M16): S7a-3s rad enumererer dørene med vilje («separat gir den sin egen mutasjon per
dør»), fordi en uvitnet kopi kan regrere ALENE mens de to andre står grønne. **`project_id`
NARROWES, aldri defaultes:** `args.project_id or ""` ville nådd `derive_cost_baseline` og myntet
en `CostBaseline(project_id="")` — en fabrikkert identitet, nøyaktig formen
`cost_baseline_anchored` er påkrevd-uten-default for å forby; unåbar i dag, så det er en assert
og ikke en default som stille er uenig med guarden over.
**TRE MUTASJONER FALSIFISERTE TESTEN FØRST (repoets vakuøs-gate-klasse, TRETTENDE til
FEMTENDE gang):** (i) M5 sto GRØNN — armen asserterte kun `pytest.raises`, og BEGGE implementasjoner
reiser mens ingen rad når kalleren uansett, så de er uskillbare utenfra; det er økt 57s regel («en
nekt etter forbruket ser identisk ut ved exit-koden») anvendt på CBC-solves, og testen TELLER nå
solves med en kontroll som beviser at telleren beveger seg. (ii) M14 sto GRØNN — armen brukte
`f"not-{declared}"`, som matcher verken mount eller erklæring, og **fixturene erklærer ingen
`bundle_id`** (S7a-3 målte null `^bundle_id`-treff under `tests/`), så de to SAMMENFALLER der;
den nye armen bygger en base som erklærer en id ulik katalognavnet og asserterer BEGGE halvdeler.
(iii) M16s FØRSTE arm erklærte de to id-ene på rot-`index.md` og den ene konseptfila, og sto
GRØNN — S7a-3 holdt rot-indeksen UTENFOR enighets-settet med vilje, fordi konsept-slår-index er
en PRESEDENS-regel: en index i utakt med sine konsepter er fallbacken som taper, ikke to
konsepter som kolliderer. Armen bruker nå TO konseptfiler.
**ÉN MUTASJON FORBLIR GRØNN, OG DET ER EN ÆRLIGHETS-GRENSE — IKKE EN GATE:** M7 (døm UTEN
baselinen) er strukturelt uobserverbar, fordi kandidaten er BYGGET fra baselinen og stage 0
derfor avstemmer med 0 % avvik ved konstruksjon; `baseline=` står som en DEFENSIV, uvitnet søm
(`budget_stop`-presedensen), ikke som noe en test holder. **Flere ærlighets-grenser, uttalt:**
`assumptions` er TOM (et bånd kan ikke avledes fra én pris), så Monte Carlo er degenerert
(P10 == P50 == P90) mens stage 3 fortsatt rapporterer persentiler — det som binder er stage 0,
stage 2/4b og pydantics `claimed <= total`; `measure` er ikke bare prosa, men stage 5s
`METHOD_CAPS`-oppslagsnøkkel, så en ekspert-label treffer metode-cap-en kun om den ER et
registrert metodenavn; den hostede flaten er BEVISST urørt (feltet er ikke i whitelisten, så
4e-halvdelene står uendret); og ingen LEVENDE K2-fil er lest — fixturen er syntetisk, som i
MAJOR-4. **MÅLT, RAPPORTERT, IKKE FIKSET (utenfor ordren):** `--mandate` selv står IKKE i
`report_forbidden`, så `--report --ledger X --mandate Y` DROPPER kommisjonen i stillhet — F4-gapets
klasse, på et flagg som er eldre enn denne ordren. Måling:
`docs/2026-09-03-forslag-fra-mandat.md`.
- **Den håndskrevne IR-projeksjonen er VALGFRI, og fraværet SIES i stedet for å reises (S7b søm 1
+ syretesten, økt 83):** `okf.load_ir_projection` var fail-fast påkrevd på TRE kallsteder, så et
ingestert anbudskorpus kunne navigeres (`read_bundle`), katalogiseres (`list_bundles`) og dømmes
gjennom den deterministiske mandat-døra (`evaluate_mandate_candidates`, som ikke leser fila i det
hele tatt) — og likevel ikke kjøre åtte-stegs-løkka. `load_optional_ir_projection` er et **PAR**
ved siden av den fail-faste, ALDRI et `required=`-flagg: PM-tillegg 5 målte hva en uøvet parameter
koster (alle elleve `evidence_for`-kallsteder brukte defaulten til den andre grenen råtnet), og et
flagg ville dessuten gjort usanne de docstringene i `hitl`/`ledger`/`verdicts`/`contracts` som
siterer `load_ir_projection` som DEN fail-faste presedensen. **Toleransen stopper ved fravær**
(S4.0-radens egen setning): en projeksjon som FINNES men er malformed reiser fortsatt.
**De TRE kallstedene fikk HVER SIN stilling, og det er derfor dette ikke er ett loader-bytte:**
`_project_from_bundle` hopper over en fail-fast som ikke har noe å sjekke mot, mens en projeksjon
som FINNES og navngir et ANNET prosjekt fortsatt nekter (divergens-vakten er kontrakten
multi-base-dispatchen hviler på); `run_mandate_across_bundles` tar **FILA FØRST**, basens ERKLÆRTE
`bundle_id` som fallback (S7a-3) — presedensen bærer i BEGGE retninger, for erklæring-først ville
re-adressert hver eksisterende base der `project_id``bundle_id`; og
`optional_bundle_candidate_features` har **TO konsumenter som svarer ULIKT på samme fravær**
Steg-1-folden HOPPER OVER (fraværet av en kandidat er et faktum om basen), mens
`seed_store_from_bundle` NEKTER ved navn (`VerdictKeyUnavailable`), fordi å mynte en nøkkel for en
dom som erklærer ingen fester dommen til en kandidat den ikke handler om — nøyaktig defekten S3.2
lukker. **Synligheten er et ANTALL** (`RunResult.unkeyed_verdicts` + `run.unkeyed_verdicts_notice`
som ENESTE renderer, `None` ved null — omisjon, aldri tom rad): «folden skjedde ikke» og «to
dommer nådde aldri modellen» er ulike operative fakta (kø-(y) ett nivå ned), og null er et ærlig
POSITIVT utsagn, så feltet DEFAULTER (`skipped_links`-halvdelen, motsatt av
`cost_baseline_anchored`). **Bæreren er MÅLT:** `DryRunReport` kan ikke bære den — dry-run-kuttet
returnerer OVER folden, så et felt der kunne bare rapportert null, ulikt `cost_baseline_anchored`
og `skipped_links` som begge oppløses over kuttet; og ikke `ProvenanceStamp`, som beskriver gaten
som dømte ÉN kandidat. **TO PREMISSER FELT FØR NOE BLE BYGGET PÅ DEM:** (a) den arkiverte
selv-ordrens «navne-fallbacken er en REELL beslutning» — MÅLT er `SavingsProposal`s fem felt uten
et navn, så projeksjonen har ALDRI vært en navnekilde og `Project.name` er uendret; (b) ordrens
DEL B-kjede kan ikke være ÉN kommando — `--explore` NEKTES sammen med `--mandate`,
`--proposals-from-mandate` er en TERMINAL modus, og det finnes intet `--revise`-flagg (lest som
plan-review-døra, sagt som tolkning). **DEL C:** `--mandate` var ELDRE enn `report_forbidden` og
hadde aldri fått en rad, så `--report --ledger X --mandate Y` droppet kommisjonen i STILLHET
(F4-klassen); armen kjører mot en argv report-modus ellers ville AKSEPTERT, med en kontroll som
beviser rc 0 uten flagget. **SYRETESTEN (DEL B) er dét som gjør raden mer enn en påstand:** hele
løkka kjørte på K2 (630 konsepter, ingen `validator-input.json`) med MAJOR-4s SYNTETISK prisede
skjema montert — 850 000 NOK validert av 3 852 500, 2 av 5 felt på TO ULIKE stages (stage 4 P90,
stage 5 METHOD_CAPS), og **99,1 % av kjøringens tokens er debattens tre kopier av
`bundle_context` (648 962 tok hver)** mens utforskningen koster 18 355. Formen var kjent
(MAJOR-3-raden), nevneren på et ekte korpus er ny. **Et premiss felt:** K2 som levert har NULL
kandidat-tabeller — prissammenstillingen renderes som en SIMPLE table med ÉN kolonne-overskrift,
så den er ikke bare upriset, den navngir aldri rollene. Load-bearing MÅLT
(`tests/test_optional_ir_projection_loadbearing.py`, 15 armer), **TRETTEN mutasjoner ALLE RØDE mot
HELE suiten** + grønn kontroll **1290/5** (fra 1275/5, supersett, 0 fjernet) og golden
`demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` av INNHOLDET =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): M1 fail-fast i `_project_from_bundle` (4 røde) ·
M2 toleranse utvidet til UENIGHET (3 — hvorav TO i tester eldre enn dette arbeidet) · M3 loaderen
svelger malformed (1) · M4 presedensen invertert (7 — hvorav fire eksisterende multibase-/
bundle-id-armer, altså retningen hovedarmen ikke kan se) · M5 fail-fast i dispatcheren (1) ·
M6 folden hoppes over i stillhet (2) · M7 over-rapportering (1) · M8 antallet forlater aldri
`run_project` (2) · M9 rendereren skriver alltid linja (1) · M10 rendereren kalles aldri (1) ·
M11 unøklbar dom hoppes stille over (1) · M12 seedens fallback beholder fail-fasten (3) ·
M13 `--mandate` faller ut av report-partisjonen (1). **Ærlighets-grenser, uttalt:** feltet når
IKKE utboksen (`write_proposal` dumper stempelet, og dette er ikke på det — samme grense
`skipped_links` alt har); portefølje-armen er BEVISST ikke wiret (folden er gatet på `bundle_dir`,
som intet referanse-prosjekt setter, så en utskrift der ville vært død kode —
`bundle_id_notice`s avgjørelse, ikke `cost_baseline_notice`s, og asymmetrien står her fordi
stillhet om den er det eneste gale svaret); `run_mandate_across_bundles` har ingen CLI-flate, så
dens `unkeyed_verdicts` når kun en bibliotek-kaller; stage 0 kan strukturelt ikke felle en
mandat-avledet kandidat (bygget FRA baselinen — økt 82s M7-grense); prisene i syretesten er
SYNTETISKE og ingen levende modell er kalt. Måling: `docs/2026-09-04-syretest-s7b-k2.md`.
- **Debatten NAVIGERER basen; den får den aldri utlevert — og §4.1a-filteret flyttet MED
(S2c, økt 85):** MAJOR-3/S7a-3 gjorde utforskningen billig og lot pipelinen stå. MÅLT på K2 (630
konsepter, S7bs eget instrument, kjent-positiv-kontrollen reprodusert eksakt FØR bruk):
`okf.bundle_context` er **648 962 o200k-tokens** og rir i TRE kopier = **1 947 342 = 99,1 %** av
en kjørings prompt-tokens, mot utforskningens 18 355. **Et premiss i måledokumentet ble presisert
først:** S7b skrev «2 debatt-turer + genererings-prompten», men de tre kopiene er TRE
DEBATT-TURER (proposer ×2, checker ×1) mens genererings-prompten er **156** tokens — fordi
`gen_context = debate_output or context` tar debattens output når den finnes. Dét avgjorde formen:
**generering trengte ingen egen søm**, for å binde `context` binder siste-utvei-fallbacken ved
KONSTRUKSJON, og en verktøysløyfe inne i `generate_via_llm` ville vært en andre mekanisme for et
problem den første alt løste. `run_project`s bundle-arm sender nå en **PEKER** (`_bundle_pointer`:
fast tekst + erklært `bundle_id` + antall konseptdokumenter i scope + stigen, O(1) i korpuset) og
gir debatten de SAMME fire verktøyene utforskningen bruker — `explore.navigator_tools` GJENBRUKT,
aldri en andre kopi av policyen. Etter: **753** tokens like-for-like (samme manus, samme fire
prompter, 99,96 %) og **8 942** med en debatt som faktisk går stigen (11 prompter, 99,5 %),
mot operatørens terskel 195 000 = **4,6 % av taket**. Prompt-ANTALLET stiger, og det er handelen
MAJOR-3-raden alt beskriver: man betaler per kall, men hvert resultat rir kun fra SITT kall og
framover. **§4.1a måtte flytte, ikke forsvinne:** løftet «agentene leser KUN dimensjons-matchet
kunnskap» ble holdt av `bundle_context`s filter, og holdes nå av VERKTØYENE på **begge trinn**
en listing som skjuler et fremmed dokument mens `read_file` serverer det på sti er et filter i
navnet alene; `okf.in_dimension` er ENESTE predikat (kø-(p)), og `DimensionScopeRefused` er en
`ValueError` (`BundlePathNotFound`-presedensen: kalleren er en modell som velger en sti, så
nekten hører på CLI-ens nekt-tuppel, aldri krasj-kanalen). **Sporet er KALLER-EID**
(`ExplorationToolRecorder` på debattens middleware → `RunResult.debate_tool_calls`
`{run_id}-debate.json` fra en `finally`): en returverdi ville vært tapt på nøyaktig den kjøringen
som trenger beviset, for et budsjettstopp midt i debatten reiser ut av `debate.run` og
konstruerer aldri et `RunResult`. **Artefaktet skrives også TOMT** — motsatt av
`write_parse_failures`, hvis TILSTEDEVÆRELSE er signalet: her ER det tomme tilfellet S2c-
regresjonen (en debatt som navigerer ingenting ser billig ut av feil grunn), så det må kunne
LESES, ikke utledes av en fil som ikke er der; MÅLT på kontroll-kjøringen med det uendrede
manuset, som etterlot `{"tool_calls": []}`. `explore.tool_call_payload` er ENESTE renderer for
begge artefakter. **`--scripted-replies` tar nå steg-lister for debattens roller:** nekten som
forsvant begrunnet seg med at «proposeren svarer `generate`s eget kall, ikke en agent-løkke som
kan kalle et verktøy mellom turer» — målbart usant siden proposer og checker ER agenter med de
fire verktøyene, og å beholde den ville holdt måleprotokollens GRATIS trinn borte fra nøyaktig
den sømmen S2c bygger (MAJOR-1s vakuitet, ett lag over). **Validert besparelse og validatorens
dom er UENDRET** — 850 000 NOK av 3 852 500, 2 av 5 felt på stage 4 og stage 5, samme dom-nøkkel
`be8535e204cdc4c6` — og utforskningens 18 355 er uendret til tokenet (`dimension` defaulter til
`None`, som er dét som gjør uendretheten til en måling). Load-bearing MÅLT
(`tests/test_debate_navigation_cost_loadbearing.py`, 11 armer), **åtte mutasjoner røde mot HELE
suiten** + grønn kontroll **1306/5** (fra 1295/5) og golden `demo-transcript.stdout`
BYTE-UENDRET (`shasum -a 1` av INNHOLDET = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`):
M1 reverter sømmen (3) · M2 verktøyene ut av `debate_tools` (7, spredt over fire filer hvorav tre
eldre gates) · M3 detach recorderen (2) · M4 skriv aldri artefaktet (5) · M5 `directory_listing`
ignorerer dimensjonen (2) · M6 detach `read_file`-gaten (2) · M7b pekeren navngir ingen base (1) ·
M8 sporet dropper `path` (3 — hvorav TO i `test_tool_call_path_loadbearing`, altså uavhengige
vitner på at rendereren er delt). **ÉN MUTASJON FALSIFISERTE SEG SELV, ikke gaten:** M7 (fjern
basens id fra pekerens overskriftslinje) var GRØNN, fordi pekeren navngir basen FIRE ganger og å
fjerne én omtale ikke fjerner egenskapen; M7b er mutasjonen som treffer den. Det står som målt.
**Tre eksisterende armer er SKREVET OM, ikke slettet:** dimensjonens to §4.1a-armer flyttet fra
prompt-teksten til listingen (den positive ville ellers blitt vakuøs — sentinelen kan aldri nå en
prompt igjen), MCP-kontrollens `captured_tools[0] == []` ble til «ingen EKSTERN tool + nøyaktig
navigatør-settet», og `test_a_step_list_is_refused_for_a_debate_role` ble sin egen positive (den
ENE omdøpte node-ID-en; suiten er ellers et strengt supersett). **Ærlighets-grenser, uttalt:**
ingen levende modell har navigert (structured-output-grensens klasse); multiplikatoren gjelder
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` 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.
- **En nekt modellen skal kunne RETTE SEG ETTER er en RETURVERDI, aldri et raise — og dét gjelder
HVERT verktøy, ikke bare det ene funn 99 rakk (funn 99 D2+D3, 08.09):** MAF gjør en tools
exception om til den ugjennomsiktige strengen `"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`). Alt den nektende armen VET — hvilke base-id-er som finnes, hvilket dokument stien
egentlig navngir, hvilken rung som leser det — tilintetgjøres altså på vei ut, og tre av dem
avslutter forespørselen. MÅLT live: modellen gjettet på JSON-formatet, som var riktig hele veien,
og trippelen rett foran en Azure-400 var tre `read_file`-nekter på samme dokument. `quick_validate`
returnerer `{"decision":"refused",…}` og hver gren — refusal inkludert — står i `quick_validations`;
`read_bundle`/`read_dir` returnerer `{"refused", "refusal"}` (ingen nøkkel en vellykket listing
har), `read_file` en streng med sentinel-prefikset `REFUSED (<kind>): ` fordi en mapping DER ville
endret formen på hver VELLYKKET lesning og dermed hver prompt-byte S2c målte. **`refusal`-KINDEN er
ikke pynt:** klasse-distinksjonen `pytest.raises` bar før (F3s «dette er et dokument» vs «dette
finnes ikke») ville forsvunnet med raisen, så den bæres som felt, avledet av `type(exc).__name__`
ÉN kilde, aldri en andre tabell. **GATENE ER URØRT** — verdict-laget og §4.1a-dimensjonen nekter
nøyaktig det de nektet før — og egenskapen de finnes for asserteres nå EKSPLISITT på returverdien:
**grunnen reiser, bytene aldri.** **Armen er nøklet på KLASSEN, aldri bar `Exception`:**
`_RETURNABLE_REFUSALS` navngir hver klasse én for én, fordi `ExplorationError` selv er en
`RuntimeError`-subklasse, så `except RuntimeError` ville slukt en feil ingen har navngitt og gjort
en ukjent svikt om til et selvsikkert svar — verre enn den ugjennomsiktige strengen. Load-bearing
MÅLT (`tests/test_explore_read_tools_refusal.py`, 7 armer), åtte mutasjoner alle røde mot HELE
suiten + grønn kontroll 1543/5 og golden BYTE-UENDRET: M1 `read_file` raiser igjen (12) · M2
`read_dir` (10) · M3 `read_bundle` (3) · M4 armen fanger bar `Exception` (2 — kjent-negativen PLUSS
et eldre, uavhengig vitne, `test_a_nonexistent_sibling_is_still_an_os_error`) · 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 i eldre tester). **Ærlighets-grenser,
uttalt:** et dokument hvis første tegn ER sentinelen ville vært uskillbar fra en nekt — en ekte
luke, skrevet ned i stedet for bortforklart; en `OSError` (f.eks. `FileNotFoundError` på en sti
som ikke finnes) står UTENFOR settet og propagerer fortsatt, gatet av en eksisterende arm; og at en
LEVENDE modell faktisk RETTER seg etter nekten er ikke bevist (structured-output-grensens klasse).
Måling: `docs/2026-09-08-funn-4-5-og-read-nekt.md` § 3.
- **Et regneark-renders PADDING dør på vei inn i prompten; ingenting annet gjør det (funn 5, 08.09):**
S7c hadde alt FELT den åpenbare kuren — begge låser åpnet LEVERTE K2s prisskjema (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 hadde flyttet seg fra RANGERINGEN til LESNINGEN, og dét po eier der
er rendringen. **MÅLT PÅ DEN FAKTISKE RENDRINGS-STIEN** (`prepass.concept_text`, ikke råfila): det
leverte utdraget er **104 linjer / 67 245 tegn** — hvilket AVSTEMMER de to nevnerne (119 linjer /
101 188 B på disk, samme dokument før frontmatter-splitten og produsentens per-linje `rstrip`) — og
bærer **208** indre mellomrom-løp ≥ 2, **117** av dem ≥ 100 og det lengste **887**, til sammen
**56 806 av 67 245 tegn = 84,5 %** over **72 av 104 linjer**. Etikett og beløp nådde altså modellen
hundrevis av tegn fra hverandre (`82` · 593 mellomrom · beskrivelse · 250 mellomrom · `5647500.0`).
Etter: **67 245 → 18 531 tegn (72,4 %)**, linjeantall uendret, ikke-whitespace byte-identisk, og
linja leser `82 Prosjektering (tiltransport av prosjekterende) 5647500.0`. **INGEN SKJØNN, og det er
fire løfter med hver sin gate:** indre løp av mellomrom/tab kollapser til ÉN (K = 2, altså finnes
det ingen terskel å forsvare); **LEDENDE whitespace er URØRT** (indentering er markdown-STRUKTUR —
nestede lister, indentert kode — og en regel som flatet den ville omskrevet dokumenter i stedet for
å av-padde dem; dét er hva `(?<=\S)` kjøper); **ingen newline røres**, så linjeantallet er invariant
og ingen rad slås sammen med naboen (en naiv `re.sub(r"\s+", " ", text)` gjør en tabell til et
avsnitt); **ingen ikke-whitespace-tegn røres**, så intet tall kan endres — asserten er den
PER-LINJE ikke-whitespace-SEKVENSEN, ikke «sifrene finnes fortsatt et sted». **HVOR den bor er det
bærende valget:** i `_data_blocks`, den ENE rendreren begge armer deler (kø-(p) — en fiks i
`render_context` alene ville latt utforskningen lese padding), og derfor ETTER
`verify_against_bundle`. `concept_text` er re-utledningen en payloads bytes bindes til, 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. Load-bearing MÅLT
(`tests/test_prepass_padding_collapse_loadbearing.py`, 7 armer), fem mutasjoner alle røde mot HELE
suiten + grønn kontroll 1543/5 og golden BYTE-UENDRET: W1 detach kollapsen fra `_data_blocks` (2) ·
W2 kollaps ledende whitespace også (1, indenterings-armen ALENE) · W3 kollaps newlines også (4,
inkl. kontrollen) · W4 skriv om tall (2) · W5 kollaps inne i `concept_text` (1, separasjons-armen
alene). **Ærlighets-grenser, uttalt:** kollaps til ett mellomrom mister CELLE-GRENSEN — `Post SUM`
blir uskillbar fra prosa med de to ordene — og å finne opp en skilletegn ville vært nøyaktig det
skjønnet regelen unngår, uten en måling som sier hvilket en modell leser bedre; at en modell så
BRUKER tallene er IKKE vist (det krever en betalt kjøring, som ikke er bestilt).
Måling: `docs/2026-09-08-funn-4-5-og-read-nekt.md` § 2.
- **Eksperten kan svare på forslaget som ligger på BORDET — og svaret BRUKES, det registreres ikke
bare (MAJOR-2, økt 8889):** før dette fantes ÉN menneske-søm inne i løkka, `plan_reviewer`, og
den fyrer FØR noen hypotese finnes. **Nevneren er målt** (`docs/2026-09-02-misjonsreview-v2.md`
§ 3, re-målt mot HEAD): `grep -n "prior_" generate.py` finner nøyaktig ÉN tilbakemeldings-søm,
`prior_rejection` — MASKINENS egen falsifisering matet tilbake i samme kjøring. Et menneskes ord
landet først i NESTE kjøring (Steg-7-innboksen), så «improved proposals given feedback» var, for
en person, en to-kjørings løkke med dager imellom. `--proposal-review` viser kandidaten
validatoren nettopp AKSEPTERTE og leser `approve` eller `revise <hva>`; en `revise` **kjøper ETT
forsøk til under de EKSISTERENDE takene** (ingen ny løkke — `max_attempts` + `meter.tick_round`,
som Steg 5), og ordene går ORDRETT inn i det forsøkets prompt som en tredje komponerbar blokk
ved siden av `prior_rejection`.
**D6: validatorens SISTE dom vinner, aldri revieweren sin.** Alternativet (falle tilbake til det
sist VALIDERTE forslaget når oppfølgingen blir avvist) ble forkastet fordi det ville latt et
menneskes ønske om ett forsøk til FORBEDRE utfallet uten at noen falsifiserer sa ja — mennesket
er en tredje stemme som gater INGENTING utover å be om ett forsøk til. `M27` er dét vitnet.
**Ekspertens ord er KLEBRIGE, maskinens grunn er PER FORSØK:** `feedback` står til mennesket
svarer neste gang, `prior_rejection` overskrives hver runde (M4/M5, hver sin ene røde arm).
**`attempts_remaining` er LEDGER-BEVISST, ikke `max_attempts`-avledet:**
`min(max_attempts - i - 1, meter.budget.max_rounds - meter.rounds)` — den DELTE rundeboka
(`max_rounds*4` på run-nivå) spenner over hver tilnærming i en kommisjon og er ofte dét som
binder, så et tall regnet fra forsøkstaket alene ville vært en påstand terminalen gjør om seg
selv som måleren straks gjendriver (M38 → 2 røde, BEGGE navngir M38 i sin docstring).
**`honoured` betyr «forsøket som ble kjøpt HENTET faktisk et svar», ikke «ble kjøpt»:** posten
føres `False` og forfremmes først når `_fetch_parsed` har RETURNERT, så en revise rundeboka kappet
før den står `false` ved siden av `rounds limit=2 observed=3` (M40 → 2 røde).
**Kanalen er valgt av TRE målinger, ikke av smak:** `ProposalReviewInputError` er en
`RuntimeError` fanget VED NAVN på CLI-ens fullkjørings-dispatch og printet på en egen
`run stopped:`-linje med rc 1. En `ValueError` ville (a) landet på `run refused:`-tuppelen, som
MISLABLER en kjøring der argv var riktig og tokens allerede var brukt, og (b) — verre — blitt
fanget av `_fetch_parsed` ETT frame unna som en PARSE-feil, altså føyd til `parse_failures`
ordrett og modellen re-kalt til rundeboka fyrte. EOF er ALDRI en signatur (M15/M16).
**Sinken er KALLER-EID** (funn-1-formen, `parse_failures`-presedensen): `run_project` eier lista,
nøkler hver post på `(approach_id, attempt)``OWN_PROPOSAL_ID` for systemets eget forslag, så
to tilnærminger aldri kollapser på én rad — og skriver `{run_id}-proposal-reviews.json` fra en
**`finally`**. En returverdi ville vært tapt på nøyaktig den kjøringen som trenger beviset: et
budsjett-stopp inne i genereringen konstruerer aldri et `GenerationResult` (M35 → T9 alene).
**Skrive-regelen er «iff en reviewer ble gitt, OGSÅ når lista er tom»** (D4) — `write_debate_tools`'
regel, av samme grunn: en reviewer ingen rakk å spørre er dét som må kunne LESES, ikke utledes av
en fil som ikke er der (M12/M13). Uten reviewer er utboksen BYTE-IDENTISK (M13 → 3 røde, hvorav
to i tester eldre enn dette arbeidet).
**`proposal_review_notice` er ENESTE renderer, og den SIER fra på NULL reviews når en reviewer
ble gitt** («offered, never consulted») — et BEVISST avvik fra announce-regelens
omisjon-på-ingenting-halvdel, som står urørt i `cost_baseline_notice`, `skipped_links_notice` og
`unkeyed_verdicts_notice`: stillhet er tvetydig HER og ikke der, fordi en operatør som ga
`--proposal-review` og ser ingenting ikke kan skille «ingen kandidat ble noensinne validert, så
ingen ble spurt» fra «døra hang». Uten reviewer returnerer den fortsatt `None` — omisjonen er
beholdt nøyaktig der den er entydig. Gatet av M33 og M37.
**Fem nekter, alle VED NAVN**, og plasseringen er MÅLT: blokka ligger på FUNKSJONS-nivå rett etter
mode-dispatchen, aldri nøstet under `if args.scripted_replies` eller `if args.explore` — under
hver av dem ville et bart `--live-dry-run --proposal-review` falt rett gjennom til dry-run-
dispatchen og droppet flagget. `--portfolio` (bølgene deler ÉN terminal), `--report`
(returnerer OVER hver dispatch, så en utelatelse er et stille DROPP — F4-gapet),
`--live-dry-run`, `--proposals-from-mandate` og `--checkpoint-dir` («send `--proposal-review` ved
`--resume` i stedet» — en nekt som bare forbyr etterlater operatøren uten døra som VIRKER).
**Den siste nekten bærer `and args.resume is None`, og den halvdelen er LOAD-BEARING (økt 91):**
`--resume` KREVER selv `--checkpoint-dir`, så en bar `checkpoint_dir is not None`-test nektet
nøyaktig den komposisjonen dens egen melding anbefaler — help-teksten, README-en og denne raden
beskrev en sti ingen argv kunne ta (Fase-3-klassen, på tvers av tre flater samtidig). Det som
nektes er en PARK (en etappe som returnerer før noen kandidat finnes), aldri et LØFT. Vitnet er
`test_the_door_composes_with_resume`, som før økt 91 sendte hverken `--resume`,
`--checkpoint-dir` eller `--review-inbox` og altså var en vanlig enkeltkjøring T13 alt dekket —
grønn mot nettopp den defekten den var navngitt for (repoets vakuøs-gate-klasse, ATTENDE gang);
den driver nå en ekte park → svarfil → resume og er RØD mot den bare vakten.
Den hostede flaten nekter ved navn som en **pre-whitelist rå-payload-sjekk**, ikke en fjerde
liste-oppføring: `_CONSUMED_FIELDS` må være disjunkt fra `run_project`s parametre (Fase 4es
negative halvdel) mens `proposal_reviewer` ER en av dem, og den generiske
`unknown field(s)`-nekten fyrer FØRST — et navn overlatt til den ville gitt samme 400 med en
melding som ikke sier hvor døra faktisk er. **F2 står: en `approve` mynter INGEN `Verdict`**
(M14), og `provenance.validator_decision` speiler fortsatt KUN validatoren.
**Load-bearing MÅLT** (`tests/test_proposal_review_loop_loadbearing.py`, 49 armer),
**M1M40 i ÉN liste, 41 kjøringer (M26 er to lengder), 40 RØDE mot HELE suiten** + grønn kontroll
**1363/5** (den kontrollen mutasjonene FAKTISK kjørte mot; README-armen i steg 10 gjør den
1364/5 etterpå) og golden `demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` av INNHOLDET =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`, ALDRI git-blob-id-en): M1 detach reviewer-kallet (16) ·
M2 alltid approve (13) · M3 print-and-discard av feedback (6) · M4 ikke-klebrig feedback (1) ·
M5 akkumuler avvisninger (1) · M6 vis også en AVVIST kandidat (4) · M7 revise tikker ikke
rundeboka (1) · M8 revisjoner løkker UTENFOR `max_attempts` (36, 18 eldre testfiler) ·
M9 `honoured` konstant `True` (6) · M10 `approach_id` alltid `None` (3) · M11 skriv etter returen
i stedet for fra `finally` (2) · M12 skriv kun ved ikke-tom liste (2) · M13 skriv også uten
reviewer (3) · M14 la `approve` mynte en `Verdict` (1) · M15 EOF er approve (2) · M16 fang ikke
feilen ved navn (1) · M17 alt som ikke er revise er approve (1) · M18 drop `single_only`-raden (1)
· M19 drop `report_forbidden`-raden (1) · M20 bibliotekssømmen wiret, argparse-flagget borte (9) ·
M21 strømmene bundet ved konstruksjon (1) · M22 slett den hostede nekten (1) · M23 videresend det
hostede feltet (4) · M24 fersk reviewer per base (1) · M25 render kandidaten som repr (2) ·
M26a trunker feedback til 20 tegn (5) · M26b til 40 tegn, sentinelen OVERLEVER (3) · M27 D6-
alternativ b (1) · M28 drop `verdict_key` fra posten (2) ·
**M29 reverter exit-kontrakten (0 — se under)** · M30 drop
`--live-dry-run`-nekten (1) · M31 drop `--proposals-from-mandate`-nekten (1) · M32 rendereren
skriver linja uten reviewer (2) · M33 rendereren returnerer `None` på null (3) ·
M34 feedback løftet ut av per-approach-kallet (5) · M35 returnert
liste i stedet for kaller-eid sink (1) · M36 dispatcheren slutter å tråde revieweren (1) ·
M37 detach CLI-utskriften mens rendereren returnerer linja (2) · M38 `attempts_remaining` fra
`max_attempts` alene (2) · M39 drop `--checkpoint-dir`-nekten (1) · M40 `honoured=True` ved
revise-tid (2).
**ÉN MUTASJON FORBLIR GRØNN, OG DET ER ET FUNN — IKKE EN GATE:** M29 reverterer `last_ruling` til
`assert last is not None`, og HELE suiten står grønn. Planens «Critical risk #1» — at
«validert → revise» på hvert forsøk ville nå halen med `last is None` — er dermed **FALSIFISERT AV
MÅLINGEN**: D1(a) RETURNERER inne i løkka når `remaining == 0`, og på siste forsøk er
`max_attempts - i - 1` alltid 0, så halen er nåbar KUN etter en validator-AVVISNING, som setter
`last` også. Bæreren er derfor **UVITNET** (`budget_stop`-presedensen) — den står fordi den gjør
D6 eksplisitt og fjerner en assert som hviler på en ikke-lokal invariant, ikke fordi en test
holder den. Kommentaren i `generate.py` som PÅSTO at asserten ville fyrt er rettet i samme
slengen (Fase-3-klassen: en påstand flaten gjør om seg selv); commit-teksten for `bbf4d3b` bærer
fortsatt den gamle påstanden, og historikken skrives ikke om.
**TO ARMER VAR GRØNNE AV FEIL GRUNN (repoets vakuøs-gate-klasse, SEKSTENDE og SYTTENDE gang),
begge funnet i steg 18:** (i) `report_forbidden`-armens ledger-fikstur var et JSON-OBJEKT, som
`SavingsLedger.load` uansett nekter — rc 1 kom fra fiksturen, ikke fra raden; den er nå en JSON-
ARRAY med en rc-0-kontroll på en argv report-modus ellers ville AKSEPTERT. (ii) «offered, never
consulted»-armen kjørte et TO-stegs manus mot `max_attempts=3`, så det tredje forsøket falt
gjennom til selectorens default-svar, som aldri parser — rundeboka fyrte og armen var grønn av en
helt annen mekanisme; manuset har nå like mange oppføringer som `max_attempts`.
**README-armen har intet M-nummer** (lista lukket ved M40) og ble drevet RØD TO ganger, fordi
«blokka mangler» og «blokka er ufullstendig» er ulike feil og bare den andre er dét gaten finnes
for: først mot README-en slik den STO (uttrekket fant ingenting), så med blokka på plass men
`--checkpoint-dir`-setningen omskrevet til å beskrive nekten uten å NAVNGI flagget. Kontrollen er
`--plan-review`-blokka, som har eksistert siden F4.
**K2-omkjøringen (kriterium 8), samme base og samme syntetiske prisfikstur som S7b/S2c**,
instrumentet validert mot en KJENT POSITIV FØR bruk (rotnivå-listingen på levert K2: 3 954 tegn /
1 495 o200k-tokens over 629 konsepter, S7a-3s publiserte tall reprodusert eksakt):
utforskningen **12 prompter / 18 355 tokens UENDRET til tokenet**, debatt-promptene **UENDRET**
(proposer 2 → 2 à 314 tokens, checker 1 → 1 à 199), genererings-promptene **2 → 4** (én ekstra per
tilnærming), totalt **17 → 19 prompter og 19 274 → 19 776 tokens (+2,6 %)**. Ekspertens ord står
ORDRETT i nøyaktig de to andre-forsøks-promptene (2 av 6), utfallet flytter seg **200 000 →
150 000 NOK** og dom-nøkkelen `be8535e204cdc4c6``f23ecff85f4188b5`, mens
`{run_id}-proposal-reviews.json` bærer feedbacken ordrett med `honoured: true`.
**Ærlighets-grenser, uttalt:** Steg 5 UNDER-rapporterer på en revidert kjøring (en revise bruker
ett av de SAMME `max_attempts`-forsøkene, så `refinements` kan mangle en falsifisering som aldri
rakk å skje); `coverage`-radene navngir ALDRI en revise som årsak til en `not_evaluated`
(rundeboka er delt — sann, og `coverage` er et non-goal); feedback-teksten er UBEGRENSET som
plan-review-feedbacken, belastet det bundne `max_tokens`; checker-gaten og dimensjons-gaten
overstyrer ETTER at genereringen har returnert, så en `approve` registrert ordrett kan sitte på en
kjøring hvis utfall er en checker-kildet `Rejection` — posten sier hva mennesket SÅ og SVARTE,
aldri hva kjøringen konkluderte, og å blande dem er nøyaktig dét to-falsifiserer-raden forbyr;
F4s traceback-asymmetri er URØRT (`PlanReviewInputError` forlater fortsatt CLI-en som traceback);
`run_portfolio` tar INGEN reviewer, og fraværet er ASSERTERT; K2-prisene er SYNTETISKE og ingen
LEVENDE modell har svart på en review (structured-output-grensens klasse). Måling:
`docs/2026-09-04-major2-proposal-review-k2.md`.
- **Debatten kan få et DEKLARERT KUTT i stedet for pekeren, og kuttet kan ikke levere bytes basen
ikke holder (OKF-pre-passet, 07.09, ordre `20260907T080223Z`):** S2c ga debatten en peker og fire
navigatørverktøy, og den navigerer godt — målt 06.09 nådde en levende modell prisformen i TRE
steg av 630 konseptdokumenter. Det er samtidig et **UERKLÆRT kutt**: ingenting i kjøringen sa hvor
mange konsepter som ble vurdert, hvor mange holdt tilbake, eller etter hvilken regel.
Konsumkontraktens § 2.3 (`llm-ingestion-okf/docs/consumption-contract.md` @ `54a0bc2`, normativ)
kaller det en nevnersvikt forkledd som et svar — samme regel repoet alt holder under
`skipped_links`, `unkeyed_verdicts` og `cost_baseline_anchored`. `--prepass-payload FILE` gir
kjøringen et `okf-consumption/1`-payload: de leverte utdragene PLUSS de tre nevnerne.
**po produserer intet payload og vendrer ingen produsent** (§ 2.4: transporten er ikke del av
kontrakten) — en subprosess mot produsentens checkout ville bundet pakka til en sti på én maskin
og dødd i `git archive HEAD`; en kopi av et 1 038-linjers rangeringsinstrument er kø-(p).
**VERKTØYENE TREKKES under et payload** (§ 2.2: kontekst pre-passet holdt tilbake ble holdt
tilbake med vilje) — en debatt som holder BEGGE er fri til å gå rundt kuttet den nettopp
erklærte. MCP-appenden ligger BEVISST under forgreningen: dette trekker navigatørverktøyene, ikke
verktøylista (M17 → 4 røde). Målt: `tools=[]` når tråden som `tools: None`, så ingen uprøvd
tom-array-form innføres. **INJEKSJONSFLATEN ER LUKKET VED KONSTRUKSJON, ikke ved prosa:** `sha256`
digester HELE den monterte fila mens `text` er et AVLEDET medlem, så et payload kan bære korrekt
digest ved siden av vilkårlig tekst — og `text` er dét som lander i task-meldingen.
`verify_against_bundle` RE-UTLEDER teksten lokalt (frontmatter delt på `splitlines()`, NFC,
per-linje `rstrip` — TRANSKRIBERT fra produsentens kilde og MÅLT mot et ekte payload; en naiv
`split("\n")` er UENIG, M10 → 20 røde) og krever likhet, så et payload ikke kan levere bytes
basen ikke holder. Eksponeringen er dermed «basens eget innhold i prompten», som `read_file` alt
gjør; det som gjenstår er POSISJONEN, og teksten legges i en avgrenset DATA-blokk under
instruksjonen (§ 9.3) — lindring, uttalt som det. **De to gatene som bodde i det tilbaketrukne
`read_file` er reist på nytt på det MONTERTE dokumentet** (verdict-laget og § 4.1a), aldri
delegert til produsentens egne regler — produsenten ekskluderer verdict-laget selv, og dét er
nøyaktig grunnen til at en av repoets nyest gatede invarianter ikke kan hvile på en fil en ekstern
kaller leverte. **`delivered == 0` NEKTES ved navn før debatten**, med nevnerne, spørsmålet og
ref-en sitert: målt er den tilstanden bare nåbar når hvert konsept feilet leksikalsk, altså bevis
for FRAVÆR (§ 7.3s egen posisjon), og uten den falt kjøringen gjennom til siteringsvakten hvis
melding navngir `docs_dir``None` på denne stien. **Siteringene bygges av de LEVERTE
konseptene** (629 → 8 på K2): et stempel som siterte hele korpuset for et forslag som så åtte
dokumenter gjenoppfinner den uerklærte påstanden inne i selve etterprøvbarhets-artefaktet.
**`ref` bæres, aldri re-beregnet** — `sha256-tree` er produsentens algoritme; vi verifiserer de
leverte dokumentene, ikke hele treet (uttalt ærlighets-grense). `RunResult.prepass` og
`DryRunReport.prepass` DEFAULTER (`skipped_links`-halvdelen: `None` er det sanne utsagnet «ingen
payload ble gitt»); `ProvenanceStamp` er BEVISST urørt (stempelet beskriver gaten som dømte ÉN
kandidat). `prepass_notice` er ENESTE renderer, `None` uten payload, og omisjonen er gatet av
golden-transkriptet som uavhengig, eksisterende vitne (M23 → 2 røde).
`{run_id}-prepass.json` skrives IFF et payload ble gitt, fra `finally`, ved et DIREKTE kall (ikke
`_write_or_report`, hvis påkrevde `in_flight` bindes først i genererings-blokka og hvor `None`
ville latt en `OSError` fortrenge en `BudgetExceeded` i luften) — og tilstedeværelsen KVALIFISERER
`{run_id}-debate.json`s nå-alltid-tomme `tool_calls`, som ellers er uskillbar fra S2c-regresjonen
den fila skrives ubetinget for å synliggjøre. Seks CLI-nekter, hver ved NAVN med rc-0-kontroll;
`hosting.py` er BEVISST URØRT (MAJOR-4/S7b) — feltet er i ingen av de tre settene, så den
generiske 400-en svarer og Fase 4es to halvdeler står, gatet av en testarm i stedet for en
redigering. **Load-bearing MÅLT: 32 mutasjoner, ALLE RØDE mot HELE suiten** + grønn kontroll
**1467 passed / 5 skipped** (fra 1387/5; **+80 node-ider, 0 fjernet**, målt med `comm` mot en
baseline tatt før første commit) og golden `demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1`
av INNHOLDET = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`). **TRE MUTASJONER VAR GRØNNE FØRST, og
alle tre var TESTFEIL** (vakuøs-gate-klassen, nittende til tjueførste gang): M9 satte
`text_sha256` fra den INJISERTE teksten, så `text_sha256`-grenen fyrte og armen matchet på
`"text"` — en DELSTRENG av `text_sha256`; M18s fixturbase leverer nøyaktig de fire konseptene
`bundle_citations` returnerer, så «siter de leverte» og «siter alt» ga SAMME sett; M32 falt
gjennom til «`--explore` requires `--explore-config`», som også navngir `--explore` (økt 57s
regel ordrett). **Ærlighets-grenser, uttalt:** ingen LEVENDE modell har lest et rendret kutt;
dette er IKKE en besparelse (like-for-like på K2: 7 031 → 10 641 prompt-tokens, +51 %, ti prompter
→ tre) men et DEKLARERT kutt og et re-målbart `ref`; en TOM leveranse er bevis for fravær mens en
FULL **ikke** er bevis for tilstedeværelse — målt returnerer «Hvilken farge har fyrtårnet i
Alexandria?» åtte arkitekttegninger, og **5,5× dyrere** enn det gode spørsmålet, mens debatten med
verktøyene trukket ikke har noen vei til å oppdage det selv; `--explore` er NEKTET, ikke løst, så
utforskningens eget kutt er fortsatt uerklært; `budget.limit` er produsentens valg (vi nekter
`spent > limit`, vi setter ikke taket, og testen binder OVERHEADET — O(levert tekst) + O(1) — ikke
totalen); og **pre-passet kan ikke lese en eneste av repoets egne baser** (ingen erklærer
`bundle_id` på rot-indeksen, S7a-3s måling sett fra produsentsiden, og `shared/` er pull-only), så
fixturen er bygget på en KOPI med erklært id. Måling:
`docs/2026-09-07-okf-prepass-i-debatten.md`.
- **Det samme kuttet kan være et UTGANGSPUNKT i stedet for en erstatning — og hvilket av de to det
var er et felt, ikke en tone (Q5=B, 08.09, ordre `20260907T234344Z`):** `--prepass-payload` gir
DEBATTEN kuttet og trekker de fire navigatørverktøyene; `--prepass-seed` gir UTFORSKNINGEN det
samme kuttet som startpunkt og **beholder** verktøyene. **Nekten M32/F4 står ordrett** — B er et
NYTT flagg, aldri en løsning av den — og hjemmelen er konsumkontraktens § 2.2, som forbyr å lese
«outside what the payload delivers **or explicitly names as reachable**»: andre ledd er hele arm
B. **`admit_payload` er ÉN opptaks-gate** (form → montert base → tom-leveranse-nekt) delt av
begge dører; to kopier ville latt én dør slippe inn det den andre nekter (kø-(p)).
**`PrepassDeclaration.rest_reachable` er PÅKREVD uten default** av `cost_baseline_anchored`s
grunn — `False` ville latt en kjøring som beholdt verktøyene påstå at kuttet var alt den kunne
lese, `True` ville latt armen som TRAKK dem påstå at basen sto åpen — og `prepass_notice` er
fortsatt ENESTE renderer, nå med to armer, fordi «8 av 630» sier det motsatte av sannheten i
nøyaktig ett av de to tilfellene. **Kuttet rir i TASK-MELDINGEN, aldri i `prompt`**
(`explore(seed_context=…)`): `_finish` bygger `Mandate.objective` av `prompt`, og en kommisjon med
22 335 tokens utdrag i objektivet er uleselig for den som skrev den; tom streng ⇒ byte-identisk
med i dag. Deklarasjonen når `{run_id}-exploration.json` via `trace_payload(prepass=…)` skrevet
fra `finally`**defaultet** (`skipped_links`-halvdelen), og MÅLT bærende: den seedede kjøringen
som døde på en Azure-400 etterlot likevel kuttet deklarert. Fem nekter ved navn, og
`--checkpoint-dir` er den som bærer en beslutning: en gjenopptatt etappe kjører i en prosess som
aldri så payloaden og ville overskrevet den parkerte etappens deklarasjon med `prepass: null`.
**`--dimension-config` er BEVISST IKKE nektet** (arm A nekter den): målt bygger utforskningen
`navigator_tools(bundle_dirs)` UTEN dimensjon, så å skope seedet ville nektet tekst den samme
løkka kan åpne med `read_file` et øyeblikk senere. **MÅLT PÅ K2 MED LEVENDE MODELL, og
målingen taler MOT å gjøre B til default:** like-for-like gratis **4 317 → 227 675 o200k
(× 52,7)**, betalt er manageren **× 21** på samme antall prompter, og — viktigere — den USEEDETE
kontrollen hentet prisskjemaet i FIRE steg
(`del-ii-bilag-7-prisskjema/prissammenstilling-sheet-1.md`) mens BEGGE seedede armer lot være:
den ene med NULL verktøykall fordi manageren rutet til hypotesisereren i alle tre runder, den
andre ved å gjette stier ut av kuttets egne konsept-navn og mynte en base-id som ikke finnes.
**Erkjennelsen kom, handlingen ikke** — manageren skrev i hver runde at utdragene ikke rakk.
Ingen av de 40 svarene brukte ett eneste av kontraktens fem literaler (kontrast S7s arm A, som
brukte `[sourced-not-sufficient]` ordrett). **NOK 2,78 av taket 5, 0× 429.** Load-bearing MÅLT
(`tests/test_prepass_seed_door_loadbearing.py`, 26 armer), **16 mutasjoner alle røde mot HELE
suiten** + grønn kontroll **1493/5** og golden `demo-transcript.stdout` BYTE-UENDRET
(`shasum -a 1` av INNHOLDET = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): M1 detach CLI-wiringen
(2) · M2 `explore()` ignorerer seedet (2) · M3 kollaps B inn i A (1) · M4 seedet uten utforskning
(1) · M5 de to armene tillates sammen (1) · M6 `--checkpoint-dir` tillates (1) · M7/M8 ut av
portefølje-/report-partisjonen (1+1) · M9 konstant `rest_reachable` (1) · M10 deklarasjonen
forlater aldri CLI-en (1) · M11 feltet ut av artefaktet (2) · M12 den seedede renderingen sier
«du har ingen verktøy» (1) · M13 opptaks-gaten svelger alt (7, hvorav TRE i tester eldre enn dette
arbeidet) · M14 kuttet deklareres til ingen (1) · M15 detach id-enighets-gaten ved denne døra (1)
· README-armen (1). **TO ARMER VAR GRØNNE AV FEIL GRUNN (repoets vakuøs-gate-klasse, TJUEANDRE og
TJUETREDJE gang), begge funnet av mutasjonene:** (i) verktøy-armen asserterte på `tool_calls`
alene, og recorderen appender FØR `call_next`, så en tool som reiste «unknown knowledge base»
etterlot et byte-identisk spor — «et verktøy ble kalt» og «basen var åpen» er ulike fakta, og
armen krever nå at basens EGEN indekstekst kommer tilbake; (ii) id-enighets-armen redigerte ÉN
konseptfil, men `assert_declared_ids_agree` leser konsepter og én erklæring er en base som er
enig med seg selv — nekten kom fra den STALE DIGESTEN, og armen bruker nå TO konsepter og et
re-digestet payload. **Sonden var dessuten feil før koden var det:** første diskriminator var
norsk («rask småskala-testing»), og verktøyresultatet serialiseres med `\uXXXX`-escapes, så armen
var rød mot en virkende implementasjon — S2c-målingen gjentatt. **Ærlighets-grenser, uttalt:** tre
betalte kjøringer på ett spørsmål er ikke et utvalg; de to seedede endte ulikt (Azure-400 vs
rundetak); ingen arm nådde pipelinen, så siteringene i stempelet er IKKE talt — og for en seedet
arm ville en full kjøring kostet ~NOK 3,2 mot NOK 2,22 igjen av taket, hvilket ER funnet; arm A
og C er GJENBRUKT fra økt 98 og er dessuten DEBATT-armer mot B-ens utforskning; og
`ChatClientException` (Azure 400 etter tre `quick_validate`-nekter på rad) er RAPPORTERT, ikke
fikset — den ligger utenfor `main()`s nekt-tuppel og forlater CLI-en som traceback. Måling:
`docs/2026-09-07-prepass-mater-q5b-k2.md`.
- **`read_dir` på et DOKUMENT navngir rungen som leser det — og ordrens premiss ble FELT før noe
ble bygget på det (F3, 08.09, ordre `20260908T020419Z`):** ordren leste de to nektede live-kallene
(`read_dir('del-ii-bilag-6-teknisk-oppsett')` + `…-oppsett.md`, § 4 i syretesten) som «stien
navngir et dokument som FINNES». **MÅLT mot basen som kjørte** holder rotnivået 27 kataloger
`del-ii-bilag-N-…` og 12 dokumenter `inbox-del-ii-bilag-N-….md`; stien matcher **verken** — den er
katalog-navnekonvensjonen anvendt på et dokument hvis ekte navn bærer et `inbox-`-prefiks. De to
rundene var altså UKJENT-sti-klassen, og **denne leveransen gjenoppretter dem IKKE** (gatet av
`test_the_measured_live_path_is_still_the_unknown_class`); å resolvere dem ville vært å gjette
hvilket dokument en kaller MENTE — invensjon, ikke validering. **Det som ER ekte er asymmetrien:**
`read_file` på en katalog har siden økt 95 svart `DirectoryPathRefused` som navngir `read_dir`,
mens `read_dir` på et dokument svarte den generiske «has no directory» og navnga verken rungen
eller stien. `okf.DocumentPathRefused` lukker den ene retningen: en `ValueError`
(`BundlePathNotFound`/`DimensionScopeRefused`-presedensen) og en **SØSKEN av `BundlePathNotFound`,
aldri en subklasse** — «dette er et dokument» og «dette er ingenting» er ulike fakta, og en kaller
som switcher på det første skal ikke besvares av det andre. Oppslaget bygges av `context_files`,
ALDRI `files` (M2 → 1 rød: en suggestion fra vandringen ville navngitt et `type: verdict`-dokument
ved sti — i en NEKT — altså det ene laget ingen listing nevner og `read_file` avviser blankt), og
gjennom SAMME `in_dimension`-predikat listingen bruker (M3 → 1 rød: §4.1a invertert, å navngi et
dokument kjøringen straks ville nektet å åpne er S2cs «filter i navnet alene»). Dokumentets EKTE
navn siteres, aldri kallerens sti (M5 → 2 røde — `_index_excerpt`-regelen: en sti som aldri fantes
er verre enn ingen sti; armen mater den navngitte stien tilbake til `read_file`). De to grenene
deler BEVISST ingen ordlyd (M4 → 4 røde), og arm (g) i
`test_hierarchical_navigation_loadbearing` er SKREVET OM — ikke svekket — fra `ValueError` til
`BundlePathNotFound` ved navn, fordi begge nekter siterer kallerens sti og et treff på stien alene
ikke lenger kan skille dem. Load-bearing MÅLT (`tests/test_read_dir_wrong_rung_loadbearing.py`,
8 armer), **fem mutasjoner alle røde mot HELE suiten** + grønn kontroll **1511/5** og golden
BYTE-UENDRET (`shasum -a 1` av INNHOLDET = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): M1 detach
dokument-grenen (4) · M2 bygg fra `files` (1) · M3 ignorer dimensjonen (1) · M4 kollaps de to
grenenes ordlyd (4) · M5 ekko kallerens sti (2). **Ærlighets-grenser, uttalt:** ingen LEVENDE
modell har lest den nye nekten, så at den endrer neste trekk er ikke bevist
(structured-output-grensens klasse); `read_dir`s verktøybeskrivelse er URØRT — den påstår
ingenting usant, og en utvidelse ville vært prosa uten en gate. Måling:
`docs/2026-09-08-f3-f4-nekten-og-forankringen.md` § 1.
- **En kjøring KAN kreve at gaten er forankret, og nekten koster ingenting (F4, 08.09, samme
ordre):** MÅLT på nytt mot de fire artefaktene den betalte S7-kjøringen etterlot: alle armer
stemplet `cost_baseline_anchored: False`, stage 0 ble hoppet over, og hver arm fant på kodene sine
(`ENGRAVE_MARK` · `RITB-HOURS`/`SYSINT-HOURS` · `RITB-consultancy`/`system-integrator` ·
`Material_Cost_Concrete`/`…_Steel`/`Construction_Heating_Fuel`). **Ordrens opsjon (c) er FELT AV
MÅLING:** `derive_cost_baseline` mot den leverte basen nekter — K2s prisskjema er en pandoc SIMPLE
table med ÉN kolonneoverskrift (`Prisskjema`) og hver verdi kollapset i den, så å gjøre
`--derive-cost-baseline` nåbart der ville krevd en regel for en form ingen har målt, som er
MAJOR-4s egen ærlighets-grense. **Valgt (b), ikke (a):** synligheten (`cost_baseline_notice`)
finnes og er ærlig, men den kan ikke stoppe et maskinlesbart artefakt som sier
`validator_decision: validated` over linjer ingenting forankret. `--require-cost-baseline` /
`run_project(require_cost_baseline=…)` er **OPT-IN, aldri default** — hver base uten
`cost-baseline.json`, altså hver commons-eid golden, kjører uendret, som er dét (a) beskyttet
(M12, gaten fyrer uansett flagg → **171 røde**). `UnanchoredRunRefused` er en `ValueError`
(`BundleIdMismatch`/`CostBaselineDerivationError`-presedensen): en argv som tar feil om hva denne
basen kan tilby hører på CLI-ens nekt-tuppel og hostings 400-arm, aldri krasj-kanalen. **Gaten bor
ÉTT sted — der BEGGE grener har bundet `baseline`, og OVER dry-run-kuttet** (M7 → 1 rød): den
frie turen er den billigste å lære det på, og på den betalte fyrer den før første modellkall ved
konstruksjon — armen asserterer NULL kall, aldri bare unntaket, fordi en nekt etter forbruket ser
identisk ut ved exit-koden (økt 57s regel). Tre CLI-nekter, hver med en rc-0-kontroll på en argv
som ellers ville blitt AKSEPTERT: krever `--bundle-dir` (veg-stien er forankret ved konstruksjon,
så der kunne flagget aldri fyre — et flagg som ikke kan fyre er en påstand flaten gjør om seg
selv, Fase-3-klassen), refusert i `--portfolio` VED NAVN (M9 → 1 rød med egen signatur: uten den
STARTER mutanten et porteføljepass og når modellen med `ChatClientException`, altså er nekten dét
som holder argv-en fra å koste noe) og i `report_forbidden` (report-modus returnerer OVER hver
dispatch, så en utelatelse er et stille DROPP — F4-gapets egen klasse). Load-bearing MÅLT
(`tests/test_require_cost_baseline_loadbearing.py`, 10 armer), **sju mutasjoner alle røde mot HELE
suiten** + samme grønne kontroll og golden: M6 detach gaten (3) · M7 gaten under dry-run-kuttet
(1) · M8 dropp fra `report_forbidden` (1) · M9 dropp fra portefølje-partisjonen (1) · M10 detach
`--bundle-dir`-kravet (1) · M11 detach fullkjørings-wiringen (1) · M12 gaten fyrer uansett flagg
(171). **Ærlighets-grenser, uttalt:** den hostede flaten er BEVISST urørt (feltet er i ingen av
hostings tre sett, så den generiske 400-en svarer og Fase 4es to halvdeler står — MAJOR-4s eget
valg gjentatt); stempelet sier fortsatt AT en kjøring var forankret, aldri HVILKEN av de tre
projeksjonene som forankret den; og ingen betalt kjøring er gjort — begge funn er målt offline mot
basen og artefaktene økt 98 etterlot. Måling:
`docs/2026-09-08-f3-f4-nekten-og-forankringen.md` § 2.
- **`PrepassExcerpt` bærer utdragets `title`/`req_number`/`sources` som navngitte felt og hver
`source_*`-lokator via `model_extra` (P3, 08.09):** en re-måling av N100/N200/N500 mot okfs
oppdaterte produsent (14 medlemmer, var 9) fant at `po` droppet de fem nye feltene TO ganger —
`PrepassExcerpt` var `extra="ignore"` ved parsing, og `_data_blocks` rendrer bare
`concept_id`/`adjudication`/`trust_tier`. Konsekvensen var observerbar i modellens egne ord: et
svar siterte en UUID fra DATA-avgrenseren fordi det var eneste identifikator som nådde prompten,
mens kravnummeret lå urørt i payloaden. **`title`/`req_number`/`sources` er navngitte, valgfrie
felt** (SS-8-deklarerte, entallige — hvert payload skrevet før i dag mangler dem, så et påkrevd
felt ville refusert historikken). **`source_*`-lokatorene leses IKKE som navngitte felt**:
producerens egen melding kaller dem en PREFIKS-REGEL, ikke en allowlist (K2 bærer fem, N-bundlene
to), og målt er `extra="allow"` + `source_locators()`s prefikssøk mot `model_extra` det ENESTE av
de to formene en fremtidig tredje `source_*`-nøkkel når prompten gjennom UTEN en kodeendring her.
`_excerpt_header` legger feltene til DATA-avgrenserens parentes KUN når de finnes — et P1-form
utdrag (ingen av de fem) rendrer BYTE-IDENTISK med før, pinnet literalt (ikke en delstreng-assert,
som ikke ville fanget en lekkende tom klausul). `render_seed` og `render_context` deler
`_data_blocks` (ko-(p)); en fiks som traff bare den ene ville latt utforsknings-døra ligge bak
debatt-døra. Load-bearing MÅLT (`tests/test_prepass_excerpt_fields_loadbearing.py`, 10 armer): 8
røde før fiksen, 10/10 grønne etter, og en mutasjon (revert til § "to felt"-formen) rød på nøyaktig
de tre rendrings-armene mens parsing-armene forble grønne — beviser at de to fiksede stedene har
hver sin uavhengige gate. **Én betalt N100-arm med `--require-cost-baseline`: rc 1, 0 modellkall,
NOK 0,00** — (b) forblir STRUKTURELT umålbar under flagget (F4: en vegnormal bærer ingen
kostlinjer, uendret av denne fiksen). Måling: `docs/2026-09-08-n-bundlene-hypoteseform.md` § 10.
- **En identifikator forslaget bygger på skal finnes ORDRETT i inputen, ellers faller dommen — og
hullet var ALDRI at fabrikasjon var ufanget (P7, 09.09):** `_reconcile_against_baseline`
(`validator.py`) bærer allerede setningen «the cost code is absent from the baseline — a
fabricated line», men den nås KUN gjennom `if baseline is not None`, så falsifisereren var koblet
til om det tilfeldigvis fantes en kostnadsbaseline. MÅLT (økt 108, dom `5fd6272e3725fe68`): en
uforankret K2-kjøring endte i `ValidatedProposal` på to kostkoder — `M-04-01`/`M-04-03` — som
står i INGEN prompt av den kjøringen, og S7cs `PRD-001`/`PRD-002` falt på MAGNITUDE (stage 4),
ikke på fabrikasjon. **Inputen finnes ALLTID; baselinen gjør ikke det.** `_ground_against_input`
er derfor et EGET stadium (0b) som ikke ser på `baseline`, plassert ETTER stage 0 så en forankret
kjøring der begge ville fyrt får byte-identisk samme melding (baselinens setning navngir
prosjektet og kodetallet, og Steg 5 mater nettopp den tilbake). ÉN `Rejection`, validatorens egen
type, som navngir HVER ugrunnet identifikator `"; "`-joinet i FORSLAGETS rekkefølge (økt 94s
fullstendighets-grunn). **REGELEN HAR INTET MØNSTER, og det er en MÅLING:** sjekken er
`code in grounding` — eksakt delstreng — fordi de leverte korpusene bærer heterogene former
(K2: 499 `UPPER-num`-treff / 23 unike, 25 enkeltbokstav-koder à `B-20-00-00`, **0** `Krav`-numre i
kroppen; N-payloadene: `Krav X.Y.Z—N` i `req_number`/`title` 8/8 i hver, 71 UUID-er i N200), så et
mønster valgt for å dekke dem ville vært en regel om FASONGER. **Rene tall er den ene inerte
klassen** (K2: 46 394 forekomster / 2 117 distinkte), og feilretningen er ÅPEN — regelen kan ikke
felle en ekte kode. **Beviset er TRE ikke-modell-forfattede kilder** (`_grounding_text`):
`delivered` fra `run_project` (den leverte rendringen + basens `context_files`, **aldri `files`**
den property-en dropper `type: verdict`-laget, og å grunne et forslag i en tidligere DOM ville
rutet ExpeL-foldens materiale rundt sin egen gate), prosjektets EGNE `cost_items` (MÅLT:
`_project_from_bundle` bygger `cost_items=()`, så kilden bidrar med null på bundle-stien) og
baselinens koder når kjøringen er forankret (stage 0 har alt dømt dem EKTE; det svakere stadiet
skal ikke overprøve det sterkere). **Den rendrede PROMPTEN er BEVISST IKKE bevis, og det er to
målinger:** på S2c-stien er `gen_context` DEBATT-OUTPUTEN (en proposer som navngir en kode i en
debatt-tur grunner så sitt eget forslag i den), og fra forsøk 2 bærer prompten forrige
`Rejection.reason` ORDRETT (Steg 5) — som for dette stadiet SITERER identifikatoren den nettopp
nektet, altså **en falsifiserer som avvæpner seg selv på sin andre runde**. **Prosa-skanningen er
VALGT BORT med tall:** en typet gate fanger 2/2 (P6) og 2/2 (S7c) — 100 % av det som nådde en DOM
— mens en prosa-gate legger til fire tokens som aldri nådde noen dom og krever nøyaktig det
mønsteret regelen unngår. **Ufanget forblir, uttalt:** en ugrunnet identifikator som kun står i
agent-/debatt-prosa og aldri blir en `affected_item`-kode (2 av 4 på P6, 2 av 4 på S7c, 1 av 2 på
P4). Testene leser SPOREDE fixturer (`tests/fixtures/p7-grounding/`, de tre genererings-promptene
ORDRETT) — opptakene ligger i `scratchpad/`, som `git archive HEAD` ikke bærer, så en test som
leste dem ville felt handover-gaten. Kjent-positiven `Krav 3.3.1—13` (EM-DASH; bindestrek-varianten
scorer 0/6) flagges IKKE, med KONTROLLEN `CRS-01` på SAMME opptak. Load-bearing MÅLT
(`tests/test_identifier_grounding_loadbearing.py`, 15 armer, **9 røde / 2 grønne FØR regelen**),
**ti mutasjoner alle røde mot HELE suiten** + grønn kontroll **1558/5** (fra 1543/5, supersett,
0 fjernet) og golden `demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` av INNHOLDET =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): M1 regelen finner aldri noe (10) · M2 regelen flagger
alt (72, inkl. kjent-positiven OG golden-transkriptet) · M3 grunnen navngir bare første (3) ·
M4 stadiet bak `baseline is not None` (9) · M5 detach `generate.py`-wiringen (3) · M6 `run_project`
erklærer ingen levert input (33, de fleste eldre) · M7 bygg fra `bundle.files` (1, den armen
alene) · M8 dropp baselinens koder (1) · M9 dropp prosjektets kostlinjer (15, alle i eldre tester
— kilden har ingen egen arm, og det ER dens vitne) · M10 prompten blir bevis igjen (2).
**Tre eksisterende fixturer endret, ingen gate svekket** — mest av alt
`test_s40_cost_baseline_loadbearing::test_pre_amendment_bundle_runs_unchanged`, som sendte den
SAMME FABRIKKERTE koden og påsto at den validerte: økt-108-hullet skrevet ned som en FORVENTNING.
Den bærer nå en kode basen navner. **Ærlighets-grenser, uttalt:** ingen betalt kjøring bekrefter
at regelen endrer utfallet levende (tre opptak, ÉN modell, ETT deployment — structured-output-
grensens klasse); `assumptions`-nøkler sjekkes ikke (en nøkkel uten `affected_item` samples aldri
av Monte Carlo, så den kan ikke flytte dommen); de tre andre `validate_proposal`-kallstedene er
BEVISST urørt (`self_repair` er en ren hjelper, `run.py:450` bygger kandidaten FRA baselinen og
kan strukturelt ikke fabrikkere — økt 82s M7-grense — og `quick_validate` er nivå 1, rådgivende);
den hostede flaten er urørt (feltet er i ingen av hostings tre sett); og
`--require-cost-baseline` er IKKE gjort til default (F4/D-3). Måling:
`docs/2026-09-09-p7-forankrede-identifikatorer.md`.
- **En kjøring SIER hva den leverte inputen kan forankre, før den bruker et forsøk på et forslag
som ikke kan bli forankret (P8, 09.09):** P7 er riktig og landet — men re-målingen avdekket en
konsekvens ingen rad uttalte: med gaten live faller **29 av 29 koder i 13 av 13 leverte forslag**
over de tre gratis-opptakene (PMs nevner; på den PARSEBARE nevneren 14 av 14 i 8 forslag — de
fem blobene som skiller tallene avvises av pydantics `claimed <= total` og når aldri stadium 0b).
Alle 29 VAR oppdiktet, så gaten er riktig; men en gate som alltid nekter er like ubrukelig som en
som aldri gjør det. **Årsaken er at PROMPTEN ber om noe inputen ikke kan levere:**
`_build_messages` krever at hver `affected_item` «restate a cost line as the project's price
schedule already carries it», mens K2s LEVERTE input bærer **9 forekomster / 2 distinkte**
kodeformede tokens — `SHA-01`/`SHA-10`, begge dokumentnumre fra en sidefot — og
`derive_cost_baseline` nekter basen: det finnes ingen kostlinje å gjengi. `GroundingOffer(chars,
identifiers, cost_lines)` er svaret, og **PARET er diagnosen**: «50 identifikatorer, 0
kostlinjer» sier det ingen av tallene sier alene. **En RAPPORT, aldri en gate** — den blokkerer
ikke, fordi et blokkerende krav ER `--require-cost-baseline` (F4/D-3, opt-in, urørt), og
`_ground_against_input` er URØRT. **Kallstedet er MÅLT, ikke valgt:** `generate.py` komponerer
grunnlaget PER FORSØK, etter `await _fetch_parsed`, så en rapport derfra kan først tale når ett
forsøk er betalt; `run.py` binder begge halvdeler over `--live-dry-run`-kuttet og før første
`debate.run`, så den FRIE turen sier det. `delivered` bindes ÉN gang og gir samme variabel til
rapporten og til `_evaluate` (to komposisjoner av én tekst er kø-(p)), og rapporten komponerer
GJENNOM `_grounding_text` — samme funksjon gaten bruker. **Et mønster er tillatt HER og ikke i
gaten**, og det er skillet mellom rapport og gate: en ukjent form er et token som ikke telles,
altså under-telling, aldri falsk avvisning. Formene er TRANSKRIBERT fra målingen (K2: 50
distinkte kodeformede, 0 kravnumre; N-korpusene: 269981 distinkte kravnumre, ≤3 kodeformede);
**rene tall er BEVISST utelatt med tallet** (46 394 / 2 117 i K2 — å telle dem gjør hver rapport
positiv og målingen inert). `grounding_offer_notice` er ENESTE renderer og tier når kjøringen KAN
forankre — omisjon, aldri tom rad. Load-bearing MÅLT
(`tests/test_grounding_offer_loadbearing.py`, 12 armer), **ni mutasjoner alle røde mot HELE
suiten** + grønn kontroll **1570/5** (fra 1558/5, supersett, 0 fjernet) og golden BYTE-UENDRET
(`shasum -a 1` av INNHOLDET = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): M1 teller alltid null
(2, kjent-positiven blant dem) · M2 teller alltid positivt (7, K2-kontrollen) · M3 bygg fra
`delivered` alene (1) · M4 når aldri `RunResult` (3) · M5 når aldri `DryRunReport` (3) ·
M6 rendereren skriver alltid linja (2) · M7 detach dry-run-utskriften (1) · M8 detach
fullkjørings-utskriften (1) · M9 rene tall telles (2). **Ærlighets-grenser, uttalt:** ingen betalt
kjøring bekrefter at rapporten endrer noe levende (tre opptak, ÉN modell, ETT deployment); den
BLOKKERER ikke, så en kjøring med null tilbud kan fortsatt brenne tre forsøk — VALGT, ikke
oversett; `cost_lines` er `len(baseline.items)`, altså forankringen som ANTALL, og står her fordi
paret er diagnosen; testfixturene er P7s SPORede prompter, ikke de leverte kuttene (10 kB / 96 kB
verbatim anbuds- og standardtekst inn i et repo publisert på `open/` er operatørens
publiseringsbeslutning, ikke denne ordrens) — 8-/435-distinkt-tallene er MÅLT og står i
dokumentet; portefølje-armen og den hostede flaten er BEVISST urørt; og tilbudsmålingen er gjort
på okf sin GAMLE default-bundle (`K2-bundle-20260903`), så en re-måling på den nye (436 konsepter
/ 832 filer) er en senere, separat ordre. Måling:
`docs/2026-09-09-p8-forankringstilbudet.md`.
- **Stresstestens kontekstsett er DATA med en gate, og fasitens titler måtte leses av konseptets
EGEN erklæring (P14, 12.09):** `contexts/<prosjekt>/` bærer `mandate.json` (`Mandate` ordrett),
`bundle.txt` (symbolsk basenavn + erklært `bundle_id` — aldri en absolutt sti, som ville pinnet
settet til én maskin og ridd ut i `git archive HEAD`), `fasit.json` og en TOM `docs/`
(`--docs-dir`-omveien er frarådet; veien for et prosjektdokument er okf-ingest inn i en base).
**Fasiten er ÉN maskinlesbar fil, ikke `fasit.md` + en maskinlesbar tvilling** — to kopier av ett
faktum er kø-(p) — så prosaen (`rationale`, `honesty`, `question`) bor INNI JSON-en.
**`bundle_id` settes eksplisitt på hver approach også med én base:** `route_by_bundle` ville løst
et tomt felt til `sole`, men det er nøyaktig feltet en framtidig (c)-flate ruter på, og et sett som
alt bærer det er dispatchbart uendret. **Regel U** er den målbare formen for «basen kan ikke svare»:
hvert ubesvarbart spørsmål erklærer ≥1 `anchor` (små bokstaver, ≥4 tegn), og admitteres iff HVER
anchor er fraværende — case-insensitivt, som delstreng — fra HELE teksten i HVERT konsept.
**Ikke «deler ingen nøkkelord med noen tittel»:** et tunnelspørsmål deler «tunnel» med hundrevis av
titler og det beviser ingenting; det som gjør et spørsmål ubesvarbart er at basen mangler SAKEN.
Fullteksten koster ingenting ekstra (målt 0,77 s for r761, den største basen), så tittel-proxyen
hadde ingen pris å forsvare seg med, og skanningen bærer alltid NEVNER — null konsepter er RØDT,
aldri vakuøst fraværende (ansikt 4). **MÅLT og verdt hele ordren: 22 av 22 prøvde kostnadsord er
FRAVÆRENDE fra n100/n200/n500** (r761 bærer 4 av dem, fordi prosesskoden ER kontraktsspråk) — po
sitt oppdrag er å finne kostnadsbesparelser, og tre av fire baser inneholder ikke ett pengeord.
**Basene er IKKE en repo-avhengighet:** tre armer SKIPPER med roten navngitt når
`PORTFOLIO_VEGNORMAL_ROOT` ikke er montert (MAJOR-3-gatens egen begrensning — en hard feil ville
brutt `uv run pytest` i overleveringspakka), mens (a) mandatet laster og (d) ruting-mot-egen-base
er UBETINGEDE og aldri kan være fraværende. **FUNN, målt og IKKE fikset (egen ordre):**
`okf.parse_frontmatter` er linjeorientert last-write-wins, så `sources:`-blokkens innrykkede
`title` overskriver konseptets egen — `directory_listing``krav/N500` returnerer **269
dokumenter, alle med `"title": "N500:2024"`**, og navigasjonsstigens rung 2/3 skiller dem kun med
et UUID-filnavn og et tegnantall. En fasit-assert mot den tittelen ville vært VAKUØS, så gaten
leser toppnivå-nøkler (`own_frontmatter`, første forekomst vinner) og bærer en TRIPWIRE som
asserterer at kollapsen fortsatt finnes; blir den halvdelen rød er funnet borte og armen skal
SLETTES, ikke svekkes. Load-bearing MÅLT (`tests/test_context_sets_loadbearing.py`, 36 armer),
**seks mutasjoner alle røde på sin egen arm** + grønn kontroll **1642/5** (fra 1606/5, supersett,
0 fjernet) og golden BYTE-UENDRET (`shasum -a 1` av INNHOLDET =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): M1 fasit-sti basen ikke bærer (2) · M2 approach rutet
mot annen base (1) · M3 anchor basen FAKTISK bærer (1) · M4 duplisert approach-id (3) · M5 erklært
`bundle_id` driftet (2) · M6 registrert tittel driftet (1). Gaten var RØD før settene fantes.
**Ærlighets-grenser, uttalt:** de fire prosjektene er OPPDIKTET (hvert sett sier i sitt eget
`honesty`-felt hva jeg konstruerte — navn, lengder, ÅDT og alle tolv beløp; `affected_codes` er
syntetiske i tre sett og EKTE `prosessnr` i `kontrakt-sorasen-2027`, som gjør de tre andre bevisst
IKKE kjørbare via `--proposals-from-mandate`); Regel U beviser at ORDET mangler, ikke at
spørsmålet er ubesvarbart; og INGEN kjøring er gjort — dette er måleoppsettet, ikke målingen.
**(c), CLI-flate for `run_mandate_across_bundles`, er IKKE bygget:** motoren finnes ferdig
(`run.py:2124`), og det som mangler er ett nytt flagg (aldri et repeterbart `--bundle-dir`), en
`run_id`-myntingsregel operatøren må ta (utboksen er bevisst uwiret, `run.py:2178-2180`) og tre
partisjons-rader. Form, fire sett og måling: `docs/2026-09-12-p14-kontekstsett.md`.
- **Dommen over en kjoring er MASKINLEST, og ordrens egen (a)-definisjon var VAKUOS (P16 DEL A,
14.09):** okt 102s kriterium ((a) bygger pa riktig fasit-konsept ELLER nekter forankret · (b')
navngir konseptet · (c) 0 hallusinasjoner) ble dømt FOR HAND, og MALT 14.09 leste ingen kode
`contexts/<sett>/fasit.json` mot en utboks. `stress.score_context_set` leser KUN artefakter som
alt finnes (`{run_id}[-{approach}]-proposal.json` · `-outcome.json` · `{run_id}-debate.json`) —
ingen kjoring far et nytt felt. **ORDRENS (a) VAR EN GATE SOM BARE KUNNE BLI GRONN:** pa
S2c-stien stempler `run_project` `citations = bundle_citations(bundle)`, altsa EN sitering per
konseptfil — MALT pa n100-2023: 446 kontekstfiler, 446 siteringer, **6 av 6 fasit-stier «sitert»
for ett eneste modellkall**. En sitering grunner derfor KUN under en smalere liste (et erklaert
pre-pass-kutt); ellers ma grunningen komme av et dokument kjoringen faktisk APNET. Begge
halvdeler rapporteres uansett (`opened`/`cited`/`citation_scope`), sa avviket er uttalt, aldri
stille. **(b') ble sjekket for SAMME vakuitet og er REN:** snippetene er konsept-BODYER mens
`ref`/`title` bor i FRONTMATTER (MALT: 0 av 446 n100-bodyer inneholder `Krav 4.1.2—1`), sa
ordrens definisjon star. **NEVNER ALLTID** (ansikt 4): tool_calls, siteringer, approach-rader og
konsepter i basen; en utboks uten proposal-artefakt — eller en base som skannes til null
konsepter — REISER `EmptyMeasurement` i stedet for a rapportere «0 hallusinasjoner».
**`not_evaluated` er FRAVAER, malt:** `run_project` skriver ett artefaktpar per EVALUERT approach,
og `settle`s coverage-rader nar ingen fil, sa en bestilt approach uten artefakt rapporteres som
`not_evaluated` framfor a utelates (`ApproachOutcome`s egen regel). **Hallusinerte LESESTIER er
RUN-nivaa** (`{run_id}-debate.json` skrives en gang per kjoring, sa en gjettet sti kan ikke
tilskrives en approach) og forgifter derfor HVER rad, mens per-rad-`hallucinations` bærer kun det
som ER tilskrivbart. **Falsifiseringsarmen er D-1-formet:** po er ikke et oppslagsverktoy, sa et
«ubesvarbart sporsmal» har ingen kjorbar form — en FJERDE bestilt approach (`a4-…`) hvis
kostlinje basen ikke baerer grunnlaget for har det. `fasit.json` bærer `must_refuse`
(`approach_id`/`anchors`/`rationale`) i STEDET for `unanswerable` — EN form, aldri to kopier av
ett faktum (kø-(p)); sporsmalene overlever i `rationale`, som ingenting nokler pa. Regel U er
URORT og dens kjent-positiv fortsatt rod. **EGEN modul, aldri en gren av `run.py`:** ingen
partisjons-rad berores, og en dommer som ikke kan starte en kjoring kan ikke koste noe.
Load-bearing MALT (`tests/test_stress_judge_loadbearing.py`, 20 armer), **elleve mutasjoner alle
rode pa sin egen arm** + gronn kontroll **1663/5** (fra 1643/5, supersett, 0 fjernet) og golden
`demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` av INNHOLDET =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): M1 helbase-siteringer grunner igjen (2 rode) ·
M2 en apnet sti grunner ikke (4) · M3 (b') dropper snippet-armen (1) · M4 hallusinerte
siteringsfiler ignoreres (1) · M5 hallusinerte koder ignoreres (1) · M6 en gjettet lesesti
forgifter ikke `ferdig` (1) · M7 tom utboks gir rent resultat (1) · M8 `not_evaluated`-rader
utelates (1) · M9 kode-lekkasjearmen i `must_refuse` droppes (1) · M10 en tom base tolereres (1) ·
M11 Regel U-ens kjent-positiv (1). **Aerlighets-grenser, uttalt:** dommeren leser HVA kjoringen
apnet og siterte, aldri om modellen FORSTO det; a4-armen beviser at ingen validert rad hviler pa
den, ikke at modellen sa hvorfor (det leses for hand og rapporteres merket manuelt); og en
helbase-snippet som baerer en `ref` er svakere bevis enn modellens eget `measure` — derfor er de
to halvdelene skilt i utfallet.
- **Taket pa en BETALT kjoring hadde ingen operatorflate, og tre flater beskrev en dor som ikke
fantes (P16 B2, 14.09):** `STATE.md`, `docs/2026-09-12-p14-kontekstsett.md § 4.1` og ordre
`20260914T091846Z` publiserer alle den samme stresskommandoen, som ender `--max-rounds 8
--max-tokens 120000`. MALT: `run.py` tok ingen av dem, alle fire gratis `--live-dry-run` nektet
med `unrecognized arguments`, og `main()` sendte **aldri** `max_rounds`/`max_tokens` videre — sa
HVER CLI-kjoring noensinne var stille bundet til `_DEFAULT_MAX_ROUNDS=3` /
`_DEFAULT_MAX_TOKENS=100_000`, uten mate for en operator a heve eller senke taket pa noe de
betalte for. Fase-3-klassen (en pastand flaten gjor om seg selv), spredt over operatorens egne
instruksjoner. **UTVIDELSE, aldri bryting:** begge flagg DEFAULTER til nettopp de verdiene, sa
hver eksisterende invokasjon er byte-identisk; det som endrer seg er at taket kan UTTALES.
**Wiret til BEGGE dispatcher** (`run_project` OG `run_portfolio` — sistnevnte tar de samme to
parameterne og `main()` droppet dem der ogsaa, sa et portefoljepass kunne heller ikke kappes), og
**nektet i report-modus VED NAVN**: report-modus returnerer OVER hver dispatch, sa en utelatelse
er et stille DROPP, ikke en nekt (F4-gapet) — og de er skillbare kun fordi argparse-defaulten ER
den historiske verdien. Load-bearing MALT (`tests/test_budget_flags_loadbearing.py`, 6 armer, ALLE
RODE for fiksen), fire mutasjoner alle rode + gronn kontroll **1669/5** og golden BYTE-UENDRET:
M12 flaggene nar aldri `run_project` (2) · M13 nar aldri `run_portfolio` (1) · M14 droppet fra
`report_forbidden` (2) · M15 defaulten drifter fra det kjoringene brukte (3). **Aerlighets-grense,
MALT og IKKE fikset:** enkeltprosjekt-modus krever fortsatt `--docs-dir` (`run.py:2953`) selv nar
`--bundle-dir` er oppgitt og `docs_dir` er ubrukt pa bundle-stien — den dokumenterte kommandoen
ville nektet av DEN grunnen ogsaa; READMEs egen form (`--docs-dir <bundle> --bundle-dir <bundle>`)
er det som virker, og a lose opp guarden er en egen operatorbeslutning.
**ANNONSERINGEN LES KONSTANTENE, og flagget gjorde den USANN i samme trekk:** `announce` er det
ENE som printes FOR forste betalte kall, og hele jobben dens er a si hva kjoringen VIL gjore —
a lese `_DEFAULT_*` var korrekt kun sa lenge `main()` ikke kunne gjore annet. MALT pa den forste
gratis-turen etter at flaggene landet: samme stdout sa «Stops at: 3 rounds / 100000 tokens» TO
linjer over «max_rounds=8, max_tokens=120000» — Fase-3-klassen, innfort av nettopp det flagget
som annonseres. Rettet til argv; M16 (les konstantene igjen) → 1 rod, den armen ALENE.
- **En listing er et VINDU, og en sti kalleren fant på er en NEKT (P18/A, 14.09):** S7a-3 bandt
kostnaden til oppføringer på ETT nivå i stedet for dokumenter i basen, og på fixturbasene holdt
det. P16 målte hva ett nivå koster på et LEVERT korpus: `krav/N200` **169 974 tegn** over 1 132
dokumenter, `krav/N100` 69 250 over 445, og R761s egen rot **110 912 over 2 728 UNDERKATALOGER**
27113× taket, ridende i hver senere prompt; 3 av 7 betalte kjøringer døde på tokentaket.
**Vinduet dekker BEGGE slag, og det er en måling, ikke symmetri:** en paginering bare over
dokumenter ville latt det STØRSTE målte nivået stå upaginert. `offset`/`limit` over kataloger
FØRST, så dokumenter — ÉN sekvens, fordi to uavhengige vinduer gjør «neste ti» til et spørsmål
med to svar. `limit` KLEMMES (`_DIRECTORY_PAGE_MAX = 50`), aldri nektes: kalleren ba om en
listing, og å nekte den sender en modell som ba om for mye bort med ingenting. Default 10 er valgt
MOT taket: én oppføring er 121209 tegn (median 145) over de fire leverte basene, så ti av de
STØRSTE er 2 090 tegn med oppføringer — n100 lander på 1 493 (ordrens bundne krav), n500 1 453,
R761 479, og n200 på **1 537**, 2,5 % over, fordi taket er et TEGN-budsjett og vinduet er et
ANTALL; uttalt, ikke justert bort. **`total` er NEVNEREN og bæres alltid** (ansikt 4: et vindu
uten nevner er en måling uten nevner), mens `total_matches` er et ANNET faktum, ikke en andre kopi
— «hva er her» og «hvor mye av det slapp filteret gjennom» er to spørsmål, og en navigatør som
bare ser ett av dem kan ikke skille et for smalt filter fra et nesten tomt nivå. **`filter` er en
DELSTRENG, ikke et mønster**, av `_ground_against_input`s grunn ett hakk ned: kalleren er en
modell som velger ord, og en form regelen ikke kjenner ville returnert ingenting — en tom listing
som leses som «basen har ikke dette». Delstreng feiler mot å vise MER, som kan snevres inn;
et mønster feiler mot å vise ingenting, som ikke kan det. Matchet går over `title` +
`req_number`/`prosessnr` (toppnivå, lest rett av `BundleFile.frontmatter` — **P15 (f13dc64) gjorde
allerede toppnivå til vinner, så ordrens premiss om en egen `own_frontmatter`-leser er FELT: en
andre leser her ville vært kø-(p)**) og over en katalogs sti; `description` er BEVISST utelatt
(hvert konsept i alle fire baser har en, så prosa-match ville returnert mesteparten av et nivå for
de fleste ord — et filter som ser ut til å virke uten å binde noe). **Et filter uten treff er et
SVAR** (`total_matches: 0`), aldri en nekt: å nekte det gjør et ærlig negativt funn uskillbart fra
en sti som ikke finnes — nøyaktig forvirringen `BundlePathNotFound` finnes for.
**A3: en fraværende sti oversettes til `BundlePathNotFound` i funn-99-formen**, og den navngir
den NÆRMESTE katalogen som faktisk HOLDER dokumenter — valgt av `context_files`, aldri av
filsystemet, fordi en katalog kan finnes på disk og ikke holde noe navigert konsept (da nekter
`read_dir` den, og nekten ville levert en sti som ikke resolverer — `_index_excerpt`-regelen), og
fordi `context_files` er property-en som dropper `type: verdict`-laget, så en nekt aldri kan
reklamere ved navn for det ene laget ingen listing nevner. **Innsnevringen er BÆRENDE:** kun en
sti som er BORTE oversettes; enhver annen `OSError` propagerer urørt, fordi en nekt er et utsagn
om KALLERENS sti og en fil som ER der og ikke kan leses er et annet faktum. Målt over P16s fire
betalte kjøringer: **10 av 32** `read_file`-kall navnga en sti basen ikke holder (ordrens «24
kall» er de fire kjøringenes DISTINKTE stier, ikke kallene — re-målt 14.09), og hvert av dem nådde
modellen som MAFs ugjennomsiktige «Error: Function failed.» mens det telte mot de tre påfølgende
verktøyfeilene som avslutter en forespørsel. Etter: 10 navngitte nekter, 22 dokumenter fortsatt
servert — en gate som nektet alt ville bestått den første halvdelen alene. **TO EKSISTERENDE
ARMER ER SKREVET OM, IKKE SVEKKET:** `test_a_nonexistent_sibling_is_still_an_os_error` var en
TRIPWIRE hvis egen docstring sa «when it goes red, someone has closed it, and that is a decision
to be recorded» — dette er protokollen; og `test_every_document_is_still_reachable_and_the_counts
_add_up` ble STERKERE, ikke svakere: regnskapet må nå PAGINERE, så samme assert beviser i tillegg
at vinduet er fullstendig og ikke-overlappende. **Ærlighets-grenser, uttalt:** `navigate_bundle`
kalles fortsatt per verktøykall (I/O, ikke tokens); A3-nekten navigerer basen ÉN gang ekstra på
feilstien for å finne den nærmeste listbare katalogen; at en LEVENDE modell BRUKER `filter` er
ikke bevist (structured-output-grensens klasse) — DEL D er målingen. Load-bearing MÅLT
(`tests/test_navigation_window_loadbearing.py`, 13 armer), **sju mutasjoner alle røde mot HELE
suiten** + grønn kontroll 1685/5 og golden BYTE-UENDRET: ingen vindu (8 røde) · bundet men VAKUØST
(**26**, tolv filer hvorav ni eldre enn dette arbeidet — dét er hva som skiller bindingen fra en
gate som bare kan bli grønn) · `total` droppet (11) · filteret leser bare tittelen (1) · en
fraværende sti reiser igjen (4) · et filter uten treff NEKTER (1) · filteret snevrer ikke
kataloger (1). Verktøybeskrivelsen, navigatør-instruksjonen OG debattens `_bundle_pointer` flyttet
i SAMME commit-serie — en beskrivelse som lyver om kroppen ER modellens instruks (Fase 3-klassen).
**MÅLT LEVENDE (DEL D):** 0 gjettede lesestier i fem betalte kjøringer (runde 1: 12), og 5 av 31
`read_file`-kall åpnet dokumenter UTENFOR default-vinduet — altså ble vinduet utvidet, men sporet
sier ikke med hvilken knapp (funn 1 i rapporten).
- **En identifikator som står OVERALT identifiserer INGENTING — og grunnlaget bæres som DOKUMENTER,
ikke som én blob (P18/B1, 14.09):** P7 gjorde stadium 0b til `item.code in grounding`, ren
delstreng over én sammenslått streng. P16 kjørte den mot et LEVERT korpus og målte hva
containment ikke kan skille: falsifiseringsarmen `a4-indeksregulering` la 250 000 NOK på ÉN
kostlinje kodet **`R761`** — basens EGET NAVN, som alle 2 756 konseptdokumenter bærer — og hele
gaten sa `validated` (stage 0 hoppet over, uforankret kjøring; checker `approve`).
**`Grounding` er en STRUKTUR, ikke et andre argument ved siden av teksten:** grensene og teksten
er ÉTT faktum, og to bærere for ett faktum står fritt til å være uenige (kø-(p)); `.text` utledes,
så gaten og P8-rapporten måler nøyaktig de samme tegnene. **N og A er MÅLT, ikke valgt:** over
hver `must_cite`-referanse og hver mandat-`affected_code` i de fire kontekstsettene er den
KORTESTE ekte identifikatoren FIRE tegn (`12.1`/`52.1`), så `_GROUNDING_MIN_LENGTH = 3` ligger ETT
under målingen og kan ikke nekte noe som er målt; og over dokumentfrekvensen til hvert
kodeformet token i hver base (`_IDENTIFIER_FORMS`) når **ingen av 1 692 distinkte** 5 % —
høyeste noe sted er 6 av 446 (**1,35 %**), høyeste en fasit faktisk navngir 3 av 446 (**0,67 %**),
mens `R761` er **2 756 av 2 756 (100 %)**. `_GROUNDING_MAX_DOCUMENT_SHARE = 0.05` ligger altså
3,7× over det høyeste ekte tokenet og 20× under defekten. **Lengden er IKKE dét som gjør defekten
inert** (`R761` er fire tegn) — andelen er; N dekker sammentreffs-klassen målingen ikke tilfeldigvis
inneholdt. **Og en andel er ingen måling uten en nevner stor nok til å ta den** (ansikt 4): ett av
tre dokumenter er 33 % og sier ingenting, så `_GROUNDING_MIN_INERT_DOCUMENTS = 10` er et ABSOLUTT
gulv — høyeste absolutte dokumenttall noen ekte identifikator når i de fire korpusene er 6, og
hver fixtur i repoet ligger langt under 10, hvilket er dét som gjør at HVER pre-P18-gate er
URØRT av regelen i stedet for UNNTATT fra den. `Grounding.of` (ett dokument) er den ærlige
lesningen av en kaller uten grenser å erklære og kan ved konstruksjon aldri utløse andelen.
**Nevneren NAVNGIS i nekten** («appears in 2756 of the 2756 documents this run was given»), fordi
Steg 5 mater den grunnen ORDRETT inn i neste forsøks prompt: en proposer som bare får «ungrounded»
svarer med et nytt token av samme slag. **B2-SPIKEN FELTE ORDRENS EGEN ALTERNATIV-HYPOTESE:** (b)
«grunnlag = det kjøringen ÅPNET» ble MÅLT over P16s 16 kode-rader — `R761` står i hvert ÅPNET
dokument også, så (b) ville **ikke** fanget defekten (grunner fortsatt), mens B1 gjør den inert og
lar den ekte prosesslinja `65 ASFALTDEKKER` (29/2756 = 1,05 %) grunne. (b) er altså ikke et
substitutt for B1; målt, ikke bygget. Load-bearing MÅLT
(`tests/test_inert_identifier_loadbearing.py`, **8 armer**), **sju mutasjoner mot HELE suiten** +
grønn kontroll 1698/5: detach regelen (3 røde) · flagg alt som er til stede (**77**) · dropp
andels-konjunktet (2) · dropp det ABSOLUTTE gulvet (**74** — hver pre-P18-fixtur brekker, altså er
gulvet dét som gjør regelen URØRENDE for dem i stedet for å unnta dem) · dropp nevneren i grunnen
(1) · dropp lengde-konjunktet (1) · blob-komposisjonen i `run.py` (**0** — se under).
Kjent-positiv er P16s EGET artefakt spilt av mot basen den fikk; kjent-negativ **26 av 26**
fasit-referanser. **ÉN MUTASJON VAR GRØNN, OG DET ER ET FUNN (repoets vakuøs-gate-klasse,
SEKSTENDE gang):** å reversere `run.py` til ÉN blob lot HELE suiten stå grønn — komposisjons-armen
driver `_grounding_text` med en `Grounding` den bygger SELV, så den kan ikke se hva KJØRINGEN
leverte, og en blob har nøyaktig ÉN grense (gulvet kan aldri nås, andelen aldri fyre, defekten er
tilbake intakt). Arm (h) er gaten som mangler: en crafted base med TOLV konseptfiler som alle
bærer samme token — per dokument 12 av 17 og inert, som blob 1 av 1 og grunnende — med en kontroll
på en kode bare ÉN fil bærer. Målt rød mot nettopp den mutasjonen.
**Ærlighets-grenser, uttalt:** regelen er per-DOKUMENT, så en base med ett gigantisk dokument er
upåvirket; `assumptions`-nøkler er fortsatt utenfor (økt 109s grense); og ingen betalt kjøring
bekrefter at den endrer utfallet levende før DEL D.
- **`--docs-dir` er VALGFRI når `--bundle-dir` er gitt, og det er ikke omveien (P18/C1):** på
bundle-stien LESES `docs_dir` aldri — retrieval, chunk-verktøyet og «no citable content»-sjekken
bor alle i VEG-grenen — likevel KREVDE gaten den, så den publiserte kommandoen måtte navngi samme
katalog to ganger (P16 FUNN 2). Verdien bindes nå ÉN gang fra `--bundle-dir` når `--docs-dir`
mangler, hvilket er byte-identisk med dét READMEen alt ber operatøren skrive for hånd; hver
eksisterende invokasjon, to-flagg-formen inkludert, er uendret. **Dette er IKKE
«`--docs-dir`-omveien»** (å mate prosjektdokumenter gjennom retrieval I STEDET FOR å ingeste dem
inn i en kunnskapsbase): ingen slik sti åpnes, og veg-grenen nekter fortsatt uten en EKTE
`--docs-dir` (egen arm). Nekten navngir nå BEGGE dører, ikke bare den ene den pleide å navngi.
To mutasjoner, begge røde på de SAMME to armene (`tests/test_docs_dir_optional_loadbearing.py`,
5 armer): krev `--docs-dir` igjen (2) · la CLI-en aldri videresende basen (2).
- **Dommerens snippet-arm teller KUN under `citation_scope == "narrowed"` (P18/C2, PM-valg P16
§ 6.2):** (a) hadde alt den korreksjonen; (b) hadde den ikke. P16s egen begrunnelse for at (b)
var ren — «snippetene er konsept-BODYER mens `ref`/`title` bor i FRONTMATTER, målt 0 av 446
n100-bodyer» — holder for `Krav 4.1.2—1`, men **IKKE for R761**, der et prosessnummer som `12.1`
står i bodyene selv. Under en helbase-siteringsliste var det merket «sitert» før noe modellkall,
så raden kom tilbake `named` for en kjøring der modellen ikke hadde sagt noe slikt. Diskriminatoren
er PARET av to armer med SAMME snippet og SAMME merke, der eneste forskjell er scopet. Mutasjon
(ignorer scopet) → 1 rød, den nye armen ALENE. **Isolert målt på ekte data:** re-dømming av runde 1
med den nye dommeren tar kontrakt-sorasen fra `named=3` til `named=1`, og den ene som står igjen
er `named_in_measure` — modellens egne ord.
- **En retning må NAVNGI kravet som binder den, og ha LEST det — og ordrens egen plassering var
strukturelt inert (P19 DEL A, 15.09):** to betalte runder på rad ga **0 av 26** fasit-konsepter
åpnet (P16 § 3, P18 § 1). P18 lukket navigasjonssiden (vindu + navngitt nekt for oppfunnet sti) og
tallet rørte seg ikke — dét er hva som gjør det til en ROLLE-sak: ingenting i sløyfa ba noensinne
modellen si hvilket krav i korpuset som binder retningen den forpliktet seg til, så å åpne ett var
aldri på kritisk sti til et svar. **PREMISSET FELT FØR NOE BLE BYGGET PÅ DET:** ordrens A1 legger
kravet i `_INSTRUCTIONS[HYPOTHESISER_ROLE]` ALENE, men stresskommandoen (P18 D1, gjentatt ordrett i
P19 E1) sender `--mandate` og IKKE `--explore`, de to er nektet sammen ved navn, og **ingen av de
ni runde-1/2-utboksene har en `{run_id}-exploration.json`** — hypotesisereren kjører aldri i en
stressrunde, så A3 («kravet når forslaget») ville vært unåbar i nøyaktig de betalte kjøringene
ordren bestiller. **A2s egen setning er dét som løser det:** nekten skal gå til modellen «som en
tur den kan rette (samme mekanisme som `quick_validate`s nekt), ikke som en `raise`» — og
`quick_validate` ER et verktøy. `declare_requirement` bor derfor i `navigator_tools`, altså hos
BEGGE roller som navigerer (utforskningen, og siden S2c debatten). **Verktøyet FINNES kun når
kalleren gir begge sinkene** (`opened` + `requirements`), og dét er hva som holder hvert
pre-P19-kallsted byte-identisk; én sink uten den andre NEKTES ved konstruksjon, fordi en logg som
ikke ser hva som ble åpnet ville akseptert enhver erklæring (vakuøs-gate-klassen, uttalt på
forhånd). `opened` er den SAMME lista `ExplorationToolRecorder` fyller (alias, aldri kopi —
`_drive`-regelen), så nekten leser kjøringens EGEN lesetrace. `RequirementNotRead` er en
`ValueError` (`BundlePathNotFound`-presedensen). **HYPOTESE-LINJA: `requirement` er en PÅKREVD
nøkkel** — utelatt er en hard feil av samme klasse som en uleselig merket linje, eksplisitt `null`
er lovlig og krever `why_none` (basen uten krav er et FUNN; en ubegrunnet null er en stillhet), og
et halvnavngitt krav nektes (validering, ALDRI reparasjon). Et MYNTET forslag bærer feltet, et FRØ
får det ALDRI (§ C.6 dør 1 er en bevaringsregel). **A3:** linja `Binding requirement: <ref>
(<path>)` finnes i `_build_messages` kun når feltet finnes, så hver prompt skrevet før i dag er
byte-identisk. **A4:** dommerens `requirement_hit` måles mot DENNE approachens fasit-konsepter,
aldri mot basen, og `requirement_source` (`approach` | `run` | `absent`) sier hvilken av de to
stedene den kom fra — debatten erklærer ÉN gang per kjøring og kan derfor ikke tilskrives én
approach alene. Load-bearing MÅLT (`tests/test_binding_requirement_loadbearing.py`, 12 armer),
**fire mutasjoner alle røde mot HELE suiten** + grønn kontroll **1710/5** (fra 1699/5, supersett,
0 fjernet) og golden `demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` av INNHOLDET =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): A-i feltet valgfritt igjen (1) · A-ii nekten sjekker
ikke mot åpnede stier (1) · A-iii A3-linja fyrer ubetinget (1) · A-iv dommeren teller mot hele
basen (1). **ÉN AV ORDRENS SPÅDDE SIGNATURER BLE FALSIFISERT AV MÅLINGEN:** A-iii skulle gjøre
GOLDEN rød — den er byte-uendret, fordi demoen kjører UTEN mandat og `_build_messages`' approach-
gren derfor aldri tas på golden-stien; vitnet er byte-identitets-halvdelen av arm (g).
**OG ÉN MUTASJON FALSIFISERTE TESTEN FØRST (repoets vakuøs-gate-klasse, TJUEFJERDE gang):** A-iv
sto GRØNN mot HELE suiten, fordi arm (h) drev `_attributable` mens treffet regnes ut på KALLSTEDET
i `score_context_set`; armen driver nå hele dommeren mot en erklæring som ER i basen men IKKE er
fasitens, med en positiv kontroll. **Ærlighets-grenser, uttalt:** ingen LEVENDE modell har kalt
verktøyet (structured-output-grensens klasse); debattens erklæring er RUN-nivå, så en approach
uten eget krav tilskrives kjøringens erklæringer og raden SIER at den gjør det; og feltet når
ikke `ProvenanceStamp` (stempelet beskriver gaten som dømte ÉN kandidat).
- **En «kostkode» må ha en FORM når inputen tilbyr former — og formene bor ÉTT sted, i validatoren
(P19 DEL B, 15.09):** P18s runde 2 endte med TO `validated` forslag hvis `affected_item`-koder var
vanlige ord fra en vegnormals prosa: `impulsventilator` (4 av 270 N500-dokumenter) og
`bituminøst bærelag` (4 av 1 133 N200). Begge er GRUNNET i P7s forstand (de står ordrett i
inputen) og ingen av dem er INERT i P18/B1s forstand (langt under 5 %-andelen) — de er bare ikke
identifikatorer for en kostlinje, og gaten hadde ikke noe stadium som kunne si det. **KJENT-POSITIV
MÅLT, ikke påstått:** begge spilt av offline mot basene kjøringene faktisk fikk gir `Rejection`
med nevner («…offers 391 identifiers of its own» / «…offers 1359»).
**`IDENTIFIER_FORMS` FLYTTET fra `generate.py` til `validator.py`** — de driver nå BÅDE P8s
rapport og P19/B3s gate, og to kopier av «hvordan en identifikator ser ut» ville latt rapporten og
gaten være uenige om ÉN kjørings egen input (kø-(p)); importretningen tvang det uansett
(`generate` importerer `validator`, aldri omvendt).
**B1 — to nye former, transkribert fra måling:** R761s kravnumre er bare punktum-tall (`12.1`,
`52.11`), ALLE SEKS `ref`-verdier i `contexts/kontrakt-sorasen-2027/fasit.json` er av den formen,
og INGEN av de to pre-P19-formene matchet én av dem — r761s hele tilbud var **3 identifikatorer
over 6,5 MB**. Målt etter: **2 332** (n100 435→578, n200 982→1 512, n500 272→391). Den fjerde
formen er `65 ASFALTDEKKER`. **Den FØRSTE formen ble UTVIDET i samme slengen, og dét er en
måling:** B2 gjorde de samme formene til `prose`/`identifier`-avgjørelsen, og repoets EGEN
`ENERGI-TOTAL-EL` matchet ingen av dem (form 1 krevde siffer etter separatoren) — klassifisereren
kalte altså en ekte kostkode prosa, og den nye gaten nektet den. En gate får bare ta feil i
retningen som slipper for mye inn. Form 2 fikk et valgfritt `_<n>`-suffiks fordi ÉN av de 26
fasit-referansene er `Krav 3.3.2—1_1`.
**TRE ting holder gaten fra å bli en regel om FASONGER:** (1) **generalitetsvernet** — gaten fyrer
KUN når inputen beviselig tilbyr identifikator-former; en base som ikke bruker dem kan ikke svares
i dem (M B-i → 16 røde, spredt over syv eldre testfiler); (2) **baseline-unntaket** — en kode
`CostBaseline` bærer nektes ALDRI her, fordi stadium 0 alt har dømt den en ekte linje av dette
prosjektet og det svakere stadiet skal ikke overprøve det sterkere (samme setning `_grounding_text`
bærer om sin tredje kilde); (3) **`has_identifier_form` FULL-matcher** — `impulsventilator 12.1`
gjør ikke ordet til en kostkode, og en delstrengregel ville latt enhver prosa-kode smugle med seg
en. **ÆRLIGHETS-GRENSE, MÅLT OG UTTALT SOM EGEN ARM:** et desimaltall og et R761-prosessnummer er
TYPOGRAFISK IDENTISKE (`42.5` vs `12.1`) og ingen regel skiller dem, så formen teller begge —
P8s eksisterende «bare tall telles ikke»-arm er derfor SNEVRET til bare HELTALL (K2s målte klasse,
46 394 forekomster) og desimal-tvetydigheten står i en egen, navngitt arm i stedet for i en
docstring. **B2:** `ProvenanceStamp.code_forms` er PÅKREVD uten default (`cost_baseline_anchored`s
grunn, skjerpet av formen: en tom map ville lest som «forslaget har ingen koder», og
`affected_items` KAN ikke være tom), og dommeren rapporterer `prose_codes` per approach — lest av
artefaktets eget `code_forms` når kjøringen skrev ett, og RE-DERIVERT med samme klassifiserer når
den ikke gjorde det, så runde 1 og 2 kan dømmes med samme instrument. **MÅLT over alle ni
runde-1+2-utbokser: 26 av 36 koder er prosa** (runde 1: 11 av 15 · runde 2: 15 av 21).
Load-bearing MÅLT (`tests/test_prose_code_form_loadbearing.py`, 22 armer), **fire mutasjoner alle
røde mot HELE suiten** + grønn kontroll **1734/5** (fra 1711/5, supersett, 0 fjernet) og golden
`demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` av INNHOLDET =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): B-i gaten uten tilbuds-vilkåret (16) · B-ii
prosessnummer-formen droppet (10) · B-iii `prose` rapporteres aldri (1) · B-iv gaten detachet (2).
**Ærlighets-grenser, uttalt:** ingen betalt kjøring bekrefter at gaten endrer utfallet levende før
DEL E; formene er transkribert fra FIRE korpus og et femte kan bære en femte form (en ukjent form
er en kode som telles som prosa — feilretningen er nekt, ikke aksept, og dét er hva
generalitetsvernet og baseline-unntaket finnes for); og `assumptions`-nøkler er fortsatt utenfor
(økt 109s grense).
- **Sporet sier HVORDAN nivået ble spurt om, og en kjøring sier hva den brukte og hvorfor den
stoppet (P19 DEL C + DEL D, 15.09):** P18 ga `read_dir` et VINDU (`filter`/`offset`/`limit`) og
målte så sin egen betalte runde uten å kunne se det brukt — fem av 31 leste dokumenter lå UTENFOR
default-vinduet, altså var vinduet utvidet, og sporet kunne ikke si med hvilken knapp. `ToolCall`
bærer nå de tre argumentene, `tool_call_payload` renderer dem (alltid til stede, tomme/null når
de ikke ble sendt — `write_debate_tools`-regelen: en fraværende nøkkel og «ikke innsnevret» må
ikke leses likt), og dommeren teller `filter_calls`/`paged_calls`. **`_number_argument` er en
SØSKEN av `_string_argument`, ikke en utvidelse av den:** en modell kan sende `limit` som `10`
eller `"10"`, og en leser som bare kjente den ene formen ville rapportert et paginert kall som
upaginert; `bool` er eksplisitt ekskludert, fordi et flagg ikke er et vindu.
**P18s FUNN 4 VAR FEIL SOM FORMULERT, og rettelsen er en TILFØYELSE:** `provenance.token_usage`
er stemplet på HVERT `-proposal.json` siden S3.4, også ved rc 0 — det som manglet var en LESER.
`stress.py` leser det nå (målt runde 2: 35 406 · 45 642 · 44 468 · 73 627 · 89 911 = **289 054**
mot runde 1s 2 679 305, **89 %**), og P18-rapportens § 7 har fått en datert rettelse UNDER det
opprinnelige avsnittet, aldri i stedet for det. **Det som GENUINT manglet er `{run_id}-coverage
.json`:** `settle` printer coverage-rapporten og `ApproachOutcome` har båret `not_evaluated`
siden Trekk A3, men ingen av dem nådde en fil, så en dommer kunne se at en approach manglet
artefakt og ikke skille et budsjettstopp fra en approach ingen bestilte — nøyaktig stillheten
`ApproachOutcome` finnes for, ett lag ut. Skrives fra `finally` **IFF et mandat ble gitt**
(coverage ER mandatets rapport; uten et er det ingen approaches, og en mandatløs kjøring lar
utboksen stå byte-identisk — to eldre tester pinner en eksakt listing). **`stop_reason` kommer
fra en KALLER-EID SINK, ikke fra `in_flight`, og dét er en MÅLING:** `_evaluate_mandate` SVELGER
`BudgetExceeded` så snart noe er produsert (de nådde approachene er et ekte resultat), så
`run_project`s egen `in_flight` ser den aldri — et coverage-artefakt som sa «ingenting stoppet
denne kjøringen» om en kommisjon kappet på midten ville vært stillheten artefaktet finnes for.
Dommerens `not_evaluated_reason` er `rounds`/`tokens` fra fila, `absent` når ingen fil finnes
(hver kjøring før i dag), og `""` for en rad som FAKTISK ble evaluert. Load-bearing MÅLT
(`tests/test_trace_and_coverage_loadbearing.py`, 10 armer), **fire mutasjoner alle røde mot HELE
suiten** + grønn kontroll **1744/5** (fra 1734/5, supersett, 0 fjernet) og golden BYTE-UENDRET
(`shasum -a 1` av INNHOLDET = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): C-i vindus-argumentene
registreres ikke (2) · D-i coverage skrives med tom grunn (1) · D-ii kjøringen skriver den aldri
(2) · D-iii dommeren slutter å lese forbruket (1). **ÉN MUTASJON STO GRØNN FØRST (repoets
vakuøs-gate-klasse, TJUEFEMTE gang):** D-i lot HELE suiten stå grønn, fordi armen kalte
`write_coverage` selv og dermed VALGTE grunnen den så asserterte på; bare en kjøring et tak
faktisk kappet kan skille de to, og den armen driver nå `run_project` med `max_rounds=1` (én
runde betaler første approach, den andre er den taket kutter). **Ærlighets-grense, uttalt:**
`token_usage` er kjøringens ENE teller — den skiller ikke debatt fra generering, og en
per-fase-fordeling ville krevd en andre måler.
- **ÉN kommisjon, FLERE baser er nåbar fra CLI-en — og utboksens nøkkel er KALLERENS, aldri
motorens (P17b DEL 1, 15.09):** `run_mandate_across_bundles` har eksistert siden økt 58, nåbar
fra FEM testfiler og fra INGEN kommandolinje (MÅLT: `grep -n across-bundle run.py` = 0 treff).
`--across-bundle <dir>` (repeterbart; `--bundle-dir` forblir ÉN katalog og er NEKTET her) krever
`--mandate`, `--run-id` og `--outbox-dir`. **Motoren fikk en CALLBACK, ikke en `outbox_dir`:**
dens egen docstring har alltid sagt at N kjøringer trenger N `run_id`-er og at å mynte dem der
ville defaultet en nøkkel repoet krever at en kaller oppgir — så `outbox_for(bundle_id) ->
(dir, run_id)` er dét kravet OPPFYLT, ikke slakket, og myntingsregelen `<run-id>-<bundle_id>`
(OPERATØRVALGT 14.09) bor i `main()` der beslutningen ble tatt. Ordrens andre alternativ — en
kaller som kjører `run_project` selv over `route_by_bundle`s sub-mandater — ville vært en ANDRE
kopi av løkkas id-avstemming, delte store, per-base-prosjektoppslag, kollisjonsregnskap og
BEGGE budsjett-tenner: kø-(p) over fem regler som hver har ett hjem.
**`resolve_bundle_routing` er ÉN oppløsning, delt av motoren og dry-run-armen:** en gratis tur
som svarte med en annen `project_id`, eller tolererte en duplisert id den betalte kjøringen
nekter, ville vært en generalprøve på en annen kjøring. **Samlefila skrives fra en `finally`**
(`write_parse_failures`-presedensen) og hver rad bygges av RESOLUSJONEN + DISK — de konfigurerte
basene, kallerens egen myntingsregel, og hver bases egen `{run_id}-coverage.json` — så den
kjøringen som mest trenger regnskapet, den et tak kappet, etterlater det. `completed` er et
EGET påkrevd felt (`ExplorationTrace.completed`s grunn ordrett): «ingenting ble uoppnådd» og
«vi fikk aldri vite» må ikke være samme verdi. `stop_reason` LESES TILBAKE fra coverage-fila,
aldri utledet på nytt — P19 D2 la faktumet der, og en andre utledning her ville stått fritt til
å være uenig med den dommeren leser. **`BudgetExceeded` er i nekt-tuppelen** av
enkeltprosjekt-stiens MÅLTE grunn: den er en `RuntimeError`, og den FØRSTE tilnærmingen som
treffer taket re-raiser ved design — over flere baser er dét ikke et kanttilfelle (runde 3 målte
`stop_reason: rounds` i 5 av 5), så uten armen er en multi-base-kjørings vanligste utfall en
traceback. Tre partisjons-rader: `report_forbidden` og `--portfolio` NEKTER ved navn, mens
live-dry-run-raden er en WIRING — den driller HVER konfigurert base og printer hver bases egne
varsler, fordi en kjøring som sa dem én gang bare kunne snakket om én av N. Load-bearing MÅLT
(`tests/test_across_bundles_cli_loadbearing.py`, 17 armer), **fire mutasjoner alle røde mot HELE
suiten** + grønn kontroll **1761/5** (fra 1744/5, supersett, 0 fjernet) og golden
`demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` av INNHOLDET =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): (i) samlefila droppes (2 røde) · (ii) myntingen
kollapser til bart `<run-id>` (3) · (iii) `report_forbidden` slipper flagget stille (1) ·
(iv) `opened`/`requirements`-sinkene deles mellom basene (5, hvorav FIRE i tester eldre enn
dette arbeidet — uavhengige vitner på at sinkene er per kjøring). **Ærlighets-grenser, uttalt:**
en base som RAISER propagerer fortsatt (motorens egen dokumenterte grense — `collect-and-continue`
tilhører `run_portfolio`), så de etterfølgende basene kjøres ikke og samlefila sier `completed:
false`; `announce` sier fortsatt «the portfolio» når ingen `project_id` er gitt; den hostede
flaten er BEVISST urørt (feltet er i ingen av hostings tre sett); og `--proposal-review` trås
gjennom til ÉN terminal delt av alle basene (motorens egen begrunnelse — dispatchen er
sekvensiell).
- **Et KRAVNUMMER er ikke en PRIS, og basens EGEN nummer-ordliste er dét som sier det — ordrens
regel ble FELT av målingen før noe ble bygget på den (P20 DEL B, 15.09):** tre stressrunder og
ett multi-base-pass bar `validated` forslag hvis kostkode var et kapittelnummer i en vegnormal.
To overlever i utboksene og er kjent-positivene: **`10.4`** (tunnel-hauglia runde 3, n500) og
**`1.10.4`** (lindaas P17b, r761). Begge er GRUNNET i P7s forstand og ingen er INERT i P18/B1s
(`10.4` i 12 av 274 dokumenter, `1.10.4` i **1 av 2 756**); stadium 0 kjørte aldri, fordi ingen
vegnormal-base bærer en kostbaseline. **Ordrens B1 sier: form 2/3 OG «står som
`req_number`/`prosessnr` i toppnivå-frontmatter» → nekt.** MÅLT 15.09: n500 erklærer
`seksjon: 10.4.1``10.4.4` og `req_number: Krav 10.4.3—2`, men **aldri den bare `10.4`** — den er
et seksjons-PREFIKS; og r761 erklærer 2 727 `prosessnr` + 2 753 `seksjon`, hvorav **ingen** er
`1.10.4`, som står ÉN gang, som prosa: «iht. vegnormal N200 Vegbygging kap. 1.10.4». **Den
ordrede regelen fyrer altså på INGEN av sine egne kjent-positive.** KOMPLEMENTET fyrer på BEGGE,
og lukker et hull `_ground_against_input`s egen docstring alt innrømmer skriftlig («it fails OPEN
… on a coincidental match»): for ÉN form — et klausulnummer — gir basen oss ordlista som skiller
en ekte referanse fra et sammentreff. Regelen er derfor: **UFORANKRET + kravformet kode + basen
erklærer en ordliste + koden er IKKE i den → nekt, med nevner.** **Komplementet er også dét som
SPARER det ene kontekstsettet bygget på ekte prosesskoder:** alle fem kodene i
`contexts/kontrakt-sorasen-2027` (`12.1`, `12.12`, `22.1`, `52.11`, `51.1`) ER erklærte
`prosessnr` og passerer — under den ordrede regelen ville hver av dem blitt nektet på en
uforankret r761-kjøring, og settets positive armer blitt umålbare; dét er R761-risikoen ordren
selv navngir, ankommet gjennom døra den ble pekt bort fra. **MÅLT over ALLE 24 koder i runde 3 +
P17b (10 kjøringer):** nøyaktig to er kravformede, de er de to kjent-positive, og offline replay
flipper nøyaktig de to (`validated → rejected`) mens 22 står uendret. **Generalitetsvernet er
`_form_refusal`s mønster:** en input som erklærer INGEN referansenumre kan ikke besvares i en
ordliste den ikke har, så regelen kan ikke fyre der — dét er hva som lar hver pre-P20-fixtur stå
URØRT i stedet for UNNTATT. **`anchored` er et EKSPLISITT flagg, aldri `not anchored_codes`:** en
baseline uten linjer og ingen baseline er ulike fakta (`cost_baseline_anchored`s grunn).
**Ordlista reiser MED teksten** (`Grounding.declared_references`, DEFAULTET —
`skipped_links`-halvdelen: en tom ordliste er et ærlig POSITIVT utsagn), komponert i SAMME vandring
som dokumentene i `run.py` og propagert gjennom `_grounding_text`; to avledninger av én bases
ordliste ville stått fritt til å være uenige (kø-(p)). **`okf.REFERENCE_NUMBER_FIELDS` er ÉN
kilde**, derivert fra `_FILTER_FIELDS` pluss `seksjon` — og BEVISST ikke lagt til i
`_FILTER_FIELDS` selv, fordi hva et `filter`-ord søker i er målt og gatet (P18) og en utvidelse
ville endret `total_matches` for hvert navigatørkall. `code_forms` får en TREDJE verdi,
`requirement`, for en kode basen FAKTISK erklærer (ordrens kjent-negative (c): alle
`must_cite`-referanser klassifiseres slik) — rapport, aldri gaten, som fyrer på komplementet.
Load-bearing MÅLT (`tests/test_requirement_number_gate_loadbearing.py`, 12 armer), ni mutasjoner
alle røde mot HELE suiten. **FUNN UNDERVEIS, FIKSET:** `code_forms` bar den SELEKTERTE kandidatens
koder i HVERT per-approach-artefakt (målt i BÅDE runde 3 og runde 4) — `stamp.model_copy` overstyrte
kun `validator_decision`, mens feltets eget kommentar sier det er stemplet «off the proposal being
stamped». Følgen var at dommeren, som leser feltet FØRST, rapporterte TOM `prose_codes` for hver
approach unntatt den første.
- **Erklæringen svarer med DOKUMENTETS egne ord, og kommisjonens kriterier når leseren som kan
handle på dem (P20 DEL A, 15.09):** P19 DEL A gjorde at en retning MÅ navngi kravet som binder
den, og rungen virker — MÅLT ga runde 3 ni erklæringer over fem betalte kjøringer og P17b fire
over ett pass, og **ikke én av de 13 navnga et fasit-konsept**. Det ingen ba om var at kravet
skulle være det RIKTIGE. To halvdeler manglet: (1) verktøyet svarte `{"declared": true, …}` ved å
ekko kallerens egne tre argumenter, så en modell som hadde erklært feil krav ble fortalt, med de
eneste ordene den fikk, at den hadde lyktes; (2) `Mandate.success_criteria` nådde `announce` og
INGENTING ellers (P19 F2) — skrevet ut for et menneske og holdt tilbake fra den ene leseren som
kunne handle på det. Svaret bærer nå dokumentets EGNE `title`/`req_number`, lest av basen gjennom
`okf.reference_number` (ÉN leser av «hvilket krav er dette», kø-(p)), pluss `binds`-setningen.
**Lest av `Bundle.context_files`, aldri `files`:** en `type: verdict`-fil kan dermed ikke navngis
tilbake ved tittel — det ene laget ingen listing nevner og `read_file` nekter blankt. **En sti
basen ikke bærer som konsept (`index.md`) svarer med TOMME strenger, aldri en nekt:** lese-sporet
har alt godkjent erklæringen, og å gjøre «jeg kan ikke gjengi tittelen din» om til en nekt ville
felt en erklæring kjøringens eget bevis viser ble lest. `mandate.criteria_block` er ENESTE
renderer og TOM uten kriterier — omisjon, aldri en tom overskrift (`announce`-regelen), og dét er
hva som holder hver prompt i hver ukommisjonert kjøring byte-identisk, demoens inkludert.
**A2s plassering er MÅLT:** på utforskningsstien finnes ingenting å bære — `main()` sender
`explore()` ingen `success_criteria` i det hele tatt, så objektivet ER prompten og når oppgaven
alt. Load-bearing MÅLT (`tests/test_right_requirement_loadbearing.py`, 8 armer), fire mutasjoner røde.
**ORDRENS SPÅDDE SIGNATUR BLE FALSIFISERT:** A-iii skulle gjøre goldenen rød, men demoen kjører uten
mandat, så `criteria` er tom uansett og bare rendererens egen arm faller.
- **En parse-feil brenner ikke lenger rundeboka i stillhet, og annonseringen navngir hva den
handler om (P20 DEL C, 15.09):** `_fetch_parsed` prøvde på nytt med den BYTE-IDENTISKE prompten.
MÅLT (P19 F4): `kontrakt-sorasen-04` etterlot `{run_id}-parse-failures.json` med **elleve** rader,
hver av dem samme feil (`claimed_saving_nok` ≤ 0) — elleve av kjøringens tolv runder, brukt på å
spørre om igjen uten å si hva som var galt. Steg 5s `prior_rejection` bærer VALIDATOR-avvisninger,
og et svar som aldri parset når aldri en validator, så ingen eksisterende blokk kunne bære det.
`_fetch_parsed` tar nå en BYGGER i stedet for en ferdig meldingsliste — kallerens egen
`_build_messages`-binding, så retry-løkka ikke kan komponere en prompt den ytre løkka ikke ville
komponert (kø-(p)) — og grunnen er per RETRY, tom på forsøk 1, så attempt 1 er byte-identisk. Den
verbatime fangsten (Fase 1b funn 1) står URØRT. **C2:** `--across-bundle` tar ingen
`--project-id`, så annonseringen sa «Run mandate for the portfolio» om en kommisjon dispatchet
over to navngitte baser (P17b F5); `announced_subject` navngir de rutede basene ved ERKLÆRT id, og
en base som ikke lar seg løse faller tilbake til katalognavnet — `dimension_label`-presedensen
ordrett: å annonsere skal ALDRI endre hvilken feil en operatør ser. Load-bearing MÅLT
(`tests/test_parse_error_feedback_loadbearing.py`, 7 armer).
- **PRISEN HØRER TIL PROSJEKTET, ikke til kunnskapsbasen — og ordrens egen B2-regel ble FELT av
måling (P21 DEL A+B, 15.09):** fire betalte runder (P16/P18/P19/P17b/P20) kjørte **UFORANKRET,
alle sammen**, fordi den ene fil-lasteren leser `cost-baseline.json` ut av BUNDLE-katalogen og
ingen vegnormal bærer et prisskjema: N100/N200/N500/R761 er KUNNSKAP, og kunnskap bærer krav,
aldri beløp. Validatorens **stadium 0** — det ENE stadiet som skiller en oppdiktet kostlinje fra
en linje dette prosjektet faktisk kjøper — ble derfor hoppet over i hver eneste av dem, og
`validated` kunne ikke bety det det sier: P20 G1/G2 målte EKTE R761-prosessnumre (`12.11` ×3 på
sorasen, `1.1.1` på lindaas) som validerte med beløp ingen hadde noe sted.
`--cost-baseline FILE` er PM-beslutning **(e)**, valgt over tre alternativer P20 skrev ned:
(a) nekt enhver kravformet kode uforankret ville gjort det ENE realistiske kontekstsettet
umålbart, (b) `--require-cost-baseline` som default ville etterlatt ingen stresstest, og
(c) K2s prisskjema er nektet av MAJOR-4s egen uttalte grense. **Et LASTET objekt, aldri en sti**
(`prepass_payload`-regelen, og `mandate=`/`dimension=` før den): CLI-en eier fila, biblioteks-
sømmen tar det validerte artefaktet — lastet ÉN gang, så notisen, stempelet og hver base i et
`--across-bundle`-pass stammer fra én lesing (kø-(p)). **ÉN parse, TO dører:**
`okf.load_cost_baseline_file` er hvor bytene tolkes og `load_cost_baseline` delegerer til den;
det som skiller er OPPLØSNINGEN — `safe_resolve` blir værende på bundle-døra ALENE, fordi et
prosjekts eget prisskjema legitimt ligger utenfor hver base. **Ingen tolerant tvilling**, og det
er motsatt av `load_optional_cost_baseline`: bundle-fila er fraværende som default (en base
skrevet før amendmentet er legitimt uforankret), mens denne stien finnes KUN fordi en operatør
NAVNGA en fil — å tolerere dens fravær ville besvart en eksplisitt ordre med en stille uforankret
kjøring (`load_mandate`-regelen). **Gjensidig utelukkende med `--derive-cost-baseline`, håndhevet
BEGGE steder:** CLI-en nekter VED NAVN (så operatøren hører hvilke to flagg som kolliderer) og
`run_project` reiser `ValueError` (så en bibliotekskaller ikke kan nå en tilstand CLI-en nekter).
**`cost_baseline_source_notice` er en ANDRE renderer ved siden av `cost_baseline_notice`, aldri
en utvidelse av den:** de sier ULIKE fakta og kan ikke være uenige (å oppgi flagget INNEBÆRER
forankret, så nøyaktig én av de to kan rendres), og den POSITIVE linja er et BEVISST avvik fra
omisjons-regelen — `proposal_review_notice`-avviket, av samme grunn: stillhet her er TVETYDIG,
for en operatør som ga et prisskjema kan ikke skille «fila di forankret kjøringen» fra «basen
hadde sin egen» eller fra «flagget ble droppet». Uten fil returnerer den `None`, så omisjonen
beholdes nøyaktig der den er entydig. **`--across-bundle` får SAMME skjema per base** (ett
prosjekt, ett prisskjema) — det er den ene ankringsparameteren som IKKE er en bundle-sak, og en
base med og en uten ville forankret halve kommisjonen mens stempelet rapporterte ankring for den
halvdelen som tilfeldigvis kjørte først. Tre partisjons-rader (`--portfolio` og
`report_forbidden` nekter VED NAVN med rc-0-kontroll; live-dry-run er en WIRING, så den frie
turen sier det samme som den betalte). **DEL B: fem forankrede kontekstsett** — hvert
`contexts/<sett>/cost-baseline.json` har 48 linjer, a1a3 har SIN linje og a4/`must_refuse` har
INGEN, så stadium 0 er det som fanger falsifiseringsarmen. **Beskrivelser er BEVISST UTELATT fra
JSON-en:** `CostBaselineLine` har ingen slik nøkkel, pydantic ignorerer ekstra felt i stillhet,
og en fixtur hvis innhold droppes taust er en løgn — teksten bor i `mandate.json`s
label/description, som er nøklet på samme kode (kø-(p)). **ORDRENS ARM (h) BLE FELT AV MÅLING
FØR NOE BLE BYGGET PÅ DEN:** regelen «ingen baseline-kode er et kravnummer basen erklærer» er
MÅLT mot `okf.declared_reference_numbers` over de fire monterte basene — de fire prosjektkodede
settene bærer **0**, og `kontrakt-sorasen-2027` bærer **5 av 5** (`12.1`, `12.12`, `22.1`,
`52.11`, `51.1` er ekte R761-`prosessnr`). Det er ikke et uhell i settet; det er hva R761
Prosesskoden ER — en norsk vegkontrakts mengdebeskrivelse prises BY prosesskode — så ordrens
regel ville tvunget fram en omskriving av nettopp det settet beslutning (e) ble valgt for å
bevare. **KOMPLEMENTET beholder begge:** et prisskjema kan prise det kommisjonen NAVNGIR, og kan
ikke INNFØRE en korpus-identifikator som en kostlinje ingen bestilte. Ordrens egen mutasjon biter
fortsatt (bytt en kode til `12.11`, en erklært `prosessnr` ingen approach bestiller → arm (h)
rød). **DEL B3:** dommeren rapporterer `anchored` (lest av kjøringens EGET stempel, aldri
re-avledet), `priced` per rad (mot settets eget skjema, rapportert enten kjøringen var forankret
eller ei, så runde 14 kan dømmes med samme instrument) og `stage` per `must_refuse`-rad fra
`validator.rejection_stage`, som bor ved siden av setningene den nøkler på (kø-(p)) og er en
RAPPORT, aldri en gate — derfor er `"other"` et ærlig svar der og ville ikke vært det inne i
pipelinen. Load-bearing MÅLT (`tests/test_cost_baseline_flag_loadbearing.py` 15 armer +
`tests/test_context_sets_loadbearing.py` +11 + `tests/test_stress_judge_loadbearing.py` +6 +
`tests/test_prose_code_form_loadbearing.py` +2), **fem mutasjoner alle røde mot HELE suiten** +
grønn kontroll **1850/5** (fra 1809/5, supersett, 0 fjernet) og golden
`demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` av INNHOLDET =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): A3(i) flagget leses men baselinen brukes ikke (3
røde) · A3(ii) bare første base får skjemaet (1) · A3(iii) `report_forbidden` slipper flagget (1)
· B2(i) a4 får en linje (1, arm (g) alene) · B2(ii) en kode byttet til `12.11` (2, armene (f) og
(h)). **Ærlighets-grenser, uttalt:** skjemaet når IKKE prompten — modellen må fortsatt oppgi
mengde og enhetspris selv, og stadium 0s avvisning navngir BASELINE-verdien, så Steg 5s
tilbakemating er hva som lar løkka konvergere (økt 94s måling); den hostede flaten er BEVISST
urørt (feltet er i ingen av hostings tre sett, så den generiske 400-en svarer og Fase 4es to
halvdeler står); portefølje-armen er ikke wiret (flagget er nektet der ved navn, så en utskrift
ville vært død kode); og alle beløp i de fem skjemaene er OPPDIKTEDE størrelsesordener, som hvert
setts eget `honesty`-felt sier.
- **En erklæring må ha LETT, og en nekt navngir naboene — ordrens to kandidat-regler ble skilt av
MÅLING (P21 DEL C, 15.09):** P19 DEL A gjorde at en retning MÅ navngi kravet som binder den, og
rungen virker — runde 4 ga 13 erklæringer over seks kjøringer. **Ikke én navnga et
fasit-konsept**, og distinkte dokumenter åpnet før hver av dem var
`1,1,1,1,1,1,1,2,5,5,6,13,13`: sju erklærte basens FØRSTE krav etter å ha åpnet ETT dokument.
**C1 — ordren ba om en måling, ikke en preferanse, og målingen valgte:** alternativet («det
erklærte dokumentet må ha blitt returnert av et `read_dir` filtrert på et ord fra approachens
label») ble spilt av mot de EKTE listingene og nekter **13 av 13** — inkludert sorasens `12.11`,
som ordren navngir som det nærmeste noen kjøring kom; MÅLT kom **null** av de 13 erklæringene
gjennom en filtrert listing i det hele tatt. En gate som nekter hvert målte tilfelle, riktige som
gale, kan ikke SKILLE — det er vakuøs-gate-klassens speilbilde. Den andre regelen (**færre enn
*k* distinkte dokumenter åpnet**) nekter ved **k = 3** **8 av 13** og beholder de fem som
navigerte, `12.11` blant dem. **Terskelen står ikke på en klippekant:** k = 3, 4 og 5 nekter
NØYAKTIG de samme åtte, fordi fordelingen har et gap mellom 2 og 5 — 3 er laveste rad i platået,
altså det minste som skiller de to målte klassene. **DISTINKTE stier, ikke kall** (å lese samme
dokument tre ganger er ikke navigasjon), og **CAPPET av basens egen størrelse**
(`min(3, len(context_files))`) — et fast gulv over en liten base ville gjort erklæring UMULIG
der, altså en gate som bare kan nekte, på nøyaktig de små fixturene repoet er bygget på. Nevneren
står i nekten («1 distinct document(s) of the 5»), fordi paret er diagnosen (kø-(y) ett hakk ned),
og P19-gaten («du leste den aldri») er URØRT og sjekkes FØRST: de to er ulike fakta, og den
første kan rettes med ett kall. **C2 — nekten navngir naboene:** over de samme seks sporene navnga
**18 av 143** sti-bærende verktøykall en sti basen ikke holder, og **ELLEVE** av dem er ÉN kjøring
som vandrer `R761/4-3`, `4.3`, `4-2`, `4-1`, `4-0`, `4-5`, `4-6` — gjetting på en
kapittelnummer-skrivemåte korpuset ikke bruker, mens de ekte navnene er `R761/4`, `R761/41`,
`R761/42`. Nekten navnga alt den nærmeste LISTBARE forfaren, som er riktig rung; det den ikke
kunne si var hvilket av den rungens navn som var ment. `okf.nearest_subdirectories` +
`nearest_listable_directory` er ÉN kopi delt av BEGGE nekt-stedene (`read_file` i `explore.py` og
`directory_listing` i `okf.py`) — ett spørsmål om én base må ikke ha to svar (kø-(p)) — og
`explore._nearest_listable` er FOLDET INN i dem i stedet for å stå som en andre kopi.
**Bygget fra `context_files`, ALDRI `files`, og gjennom SAMME `in_dimension`-predikat listingen
bruker:** et forslag lest av filsystemet kunne navngitt en katalog `read_dir` så nekter, og ett
bygget fra `files` kunne navngitt `type: verdict`-laget VED STI — å reklamere i en NEKT for det
ene laget ingen listing nevner er den samme lekkasjen i unnskyldningens klær. **Rangert etter
lengste felles prefiks med segmentet som feilet**, så kortest, så navn — dét er hva som setter
`R761/4` FØRST for `4-3`; uten felles prefiks i det hele tatt degraderer ordenen til «de korteste
navnene på dette nivået», som er et ærlig «her er hva som ER her». En rangering kan ikke nekte
noe (dette er hjelpetekst på en nekt), så feilretningen er godartet. **MÅLT ETTER: 16 av 18**
nekter navngir nå minst én nabo; de to som ikke gjør det har en forfar som holder dokumenter og
ingen underkataloger, og der UTELATES klausulen (omisjon, aldri en setning med ingenting i).
Load-bearing MÅLT (`tests/test_declaration_and_neighbours_loadbearing.py`, 13 armer), **fire
mutasjoner alle røde mot HELE suiten** + grønn kontroll **1863/5** og golden BYTE-UENDRET
(`shasum -a 1` av INNHOLDET = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): C3(i) erklærings-gaten
detachet (2 røde) · C3(ii) nabolista tom (6) · C3(iii) bygget fra `files` (1, verdict-armen
ALENE) · C3(iv) tell KALL i stedet for distinkte dokumenter (1, gjentakelses-armen ALENE).
**TRE EKSISTERENDE ARMER ER SKREVET OM, IKKE SVEKKET** (`test_binding_requirement`s
korreksjons-arm, `test_right_requirement`s tunnel-arm og `test_across_bundles_cli`s
per-base-sink-arm): alle tre leste ETT dokument og erklærte, altså nøyaktig den målte
feilklassen; de leser nå tre, og armene beholder sin betydning — en erklæring kjøringens EGET
spor støtter blir AKSEPTERT og REGISTRERT. **Ærlighets-grenser, uttalt:** sporet registrerer ikke
om en `read_file` LYKTES (recorderen appender FØR `call_next`, funn-99-formen), så tre nektede
lesninger teller mot gulvet — regelen måler at kjøringen SÅ seg om, ikke at den forsto; ingen
LEVENDE modell har møtt noen av de to nektene (structured-output-grensens klasse); og C2 er
hjelpetekst, ikke en gate — den kan ikke gjøre en gjettet sti riktig, bare billigere å rette.
- **Stadium 0s ukjent-kode-nekt NAVNGIR kodene prosjektet faktisk kjoeper, i et FAST vindu
(P22 DEL A, 15.09):** P21 var den foerste FORANKREDE runden, og den kostet noe maalt like tydelig
som den kjoepte: **0 av 20** tilnaerminger validerte (runde 4: 4 av 20), og **26 av 26**
avvisninger — 20 approach-rader PLUSS 6 egne forslag, altsaa en STOERRE populasjon enn de 20 —
leste `unknown cost code '<paafunn>': not in project P's cost baseline (5 known codes)`. Modellen
fant paa `signalregulering_konstruksjon`, `VENTIL_IMP`, `RIGG01`, `baerelag_asfalt` og 22 til, og
den KUNNE ikke gjort annet: prisskjemaet naar VALIDATOREN og aldri proposeren, og nekten oppga
ANTALLET kjente koder, ikke ett eneste navn. Steg 5 mater setningen ORDRETT inn i neste forsoeks
prompt, saa «du gjettet feil, det finnes fem riktige» baerer ingenting aa korrigere mot.
**Kontrasten bodde allerede i samme stadium:** MAGNITUDE-halvdelen NAVNGIR baseline-verdien, og
DET er halvdelen som lot loekka konvergere i oekt 94. `_known_codes_clause` er den ene
renderingen, og magnitude-halvdelen faar den IKKE — der er setningen alt korrigerbar, og en
kodeliste paa begge ville gjort de to halvdelene uskillbare for en leser (M A8 → 2 roede, hvorav
ett ELDRE uavhengig vitne, `test_stage0_all_violations::test_a_single_violation_is_byte_identical`).
**Vinduet er et FAST ANTALL, aldri en andel** (`_CATALOGUE_EXCERPT_CHARS`-regelen; M A2 → 6 roede,
M A6 → 3), **og det teller KODER, ikke tegn**, av en maalt grunn: et tegn-kutt kan kappe en kode
midt i navnet og gi proposeren en identifikator som finnes ingen steder — `_index_excerpt`-regelen
invertert (M A5 → 3 roede paa hel-kode-armen). **Kuttet ANNONSERES** (`first N:`) mens nevneren
staar i begge grener, og et skjema som PASSER merkes ikke avkortet (`index_truncated`s regel;
M A4 → 2 roede). **Rekkefoelgen er skjemaets egen** — en sortering ville oppfunnet en rangering
prosjektet aldri uttalte (M A3 → 1 roed, den armen ALENE). Vinduet er 20, valgt ved MAALING med
nevner: hver kostbaseline i repoet eller dets maalte korpora er hoeyst SEKS koder (kontekstsettene
5/5/5/5/6, de to `shared/examples` 1 hver, MAJOR-4s avledning av det syntetiske K2-prisskjemaet 3),
og det stoerste EKTE leverte prisskjemaet maalt er K2s `prissammenstilling-sheet-1.md` med 14
prisede rader av 118 linjer — ingenting maalt naar vinduet; det finnes for den umaalte
R761-formede mengdebeskrivelsen, der korpuset erklaerer 2 727 `prosessnr`.
**`rejection_stage` er koblingen P21s «a4 5/5 paa stage0-baseline» hviler paa** og noekler paa
delstrengen `cost baseline (` — hadde den nye klausulen flyttet den, ville hver stadium-0-nekt
blitt omdoept til `other` i stillhet (M A7 → 2 roede, hvorav ett ELDRE uavhengig vitne).
**IKKE GJORT, og det er en beslutning:** skjemaet rendres ALDRI inn i proposer-prompten — en ny
prompt-flate med egen kostnad per kjoering som dessuten ikke fjerner behovet for at nekten er
korrigerbar. Load-bearing MAALT (`tests/test_named_known_codes_loadbearing.py`, 10 armer), **aatte
mutasjoner alle roede mot HELE suiten** + groenn kontroll **1873/5** (fra 1863/5, supersett,
0 fjernet) og golden `demo-transcript.stdout` BYTE-UENDRET (`shasum -a 1` av INNHOLDET =
`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`): A1 tilbake til det bare antallet (7) · A2 andel (6) ·
A3 sortert (1) · A4 stille kutt (2) · A5 tegn-slice (3) · A6 ingen binding (3) · A7 bryt
stage-markoeren (2) · A8 la magnitude-halvdelen vokse en kodeliste (2). **AErlighets-grenser,
uttalt:** ingen betalt kjoering bekrefter ennaa at nekten endrer utfallet levende (DEL D er
maalingen); vinduet er aldri naadd av noe maalt, saa avkortnings-grenen er oevd kun syntetisk; og
skjemaet naar fortsatt ikke prompten, saa foerste forsoek gjetter som foer.
- **`declare_requirement` svarer med en SAMMENLIGNING, ikke en bekreftelse (P22 DEL B, 16.09):**
P19 DEL A gjorde at en retning MAA navngi kravet som binder den, og P20/A1 lot svaret baere
DOKUMENTETS egen tittel og nummer i stedet for aa ekko kallerens argumenter. MAALT paa nytt ved
starten av oekt 126 mot de seks runde-5-sporene: `requirement_hit` er **0 av 20** approach-rader
og **0 av 12** erklaeringer — tredje runde paa rad paa null. P21/C1 fikk kjoeringene til aa SE
seg om, og virket paa sine egne premisser (distinkte dokumenter foer en erklaering
`1·1·1·2·5·13``3·3·5·7·11·12`), men treffet rikket seg ikke: kjoeringene ble faatt til aa lese
MER, ikke RIKTIGERE. **Ordrens egen denominator var upresis, og det er maalt:** feltet
`requirement_hit` er per APPROACH (0 av 20), mens 12 er antallet ERKLAERINGER (7 distinkte, 0
treff) — begge null, saa konklusjonen staar, men de er to populasjoner.
`_label_overlap` er den ene sammenligningen: hvilke ord fra kommisjonens retninger som finnes i
det ERKLAERTE DOKUMENTETS egen tittel og nummer. **En RAPPORT, aldri en gate** — erklaeringen
registreres uansett (M B5 → 5 roede): et krav kan binde et tiltak uten aa dele ett ord med navnet
noen ga det, hvilket er NOEYAKTIG slik den alternative regelen P21/C1 maalte og forkastet feilet,
ett trinn over. **Ordene som sammenlignes er DOKUMENTETS, aldri `ref`** — kallerens eget argument
ekkoet tilbake, og en sammenligning mot kallerens input kan bare vaere enig (M B4 → 1 roed, den
armen ALENE; P20/A1s regel anvendt paa halvdelen P20 ikke naadde). **Sjenerøs i BEGGE retninger**
(delstreng hver vei, saa `rundkjoring` moeter `Rundkjoringer` og `senkekostnader` moeter `senke`),
og feilretningen er VALGT: rapporten sier ett av to, og bare ett av dem kan gjoere skade — en
falsk «ingen overlapp» skyver en modell BORT fra en erklaering som var riktig, mens en falsk
«overlapp» bare gjoer rapporten stille. Delstreng feiler mot stille (P18s `filter` valgte samme
retning av samme grunn; M B7 → 1 roed, M B2 → 5, M B3 → 2). `_LABEL_WORD_MIN = 4`, ellers deler
hver label «for»/«med»/«til» med et halvt korpus (M B8 → 3 roede).
**MAALT FOER DEN BLE BYGGET**, offline mot de seks sporene slik ordren krevde (ingen betalte kall
i DEL B): regelen TALER paa **10 av 12** erklaeringer og tier paa 2 (begge fv412, paa
`materialer`). En regel som talte paa 12 av 12 — eller paa 0 av 12 — kunne ikke skilt de to
klassene, samme proeve P21/C1s terskel maatte bestaa. **`labels` DEFAULTER til tom**, saa hvert
kallsted skrevet foer i dag er BYTE-IDENTISK og de tre noeklene UTELATES (fravaerende, ikke tomme:
«det fantes ingenting aa sammenligne mot» og «vi sammenlignet og fant ingenting» er ulike fakta,
og bare ett av dem er sant der; M B6 → 2 roede, hvorav ett ELDRE uavhengig vitne i
`test_binding_requirement`). Utforskningen mynter sine egne retninger, saa den HAR ingen ved
erklaerings-tid. **RUN-nivaa, som erklaeringen selv (P19 A4):** debatten erklaerer ÉN gang per
kjoering, saa svaret navngir HVER retning kjoeringen baerer i stedet for aa velge én den ikke kan
tilskrive. Wiringen i `run.py` maales ATFERDSMESSIG — en kilde-assert er en lint (oekt 77s funn),
saa armen driver den EKTE debatten med et steg-manus som erklaerer og leser sammenligningen ut av
verktoeyets eget svar (M B1 → 1 roed, den armen ALENE). Load-bearing MAALT
(`tests/test_requirement_comparison_loadbearing.py`, 8 armer), **aatte mutasjoner alle roede mot
HELE suiten** + groenn kontroll **1881/5** (fra 1873/5, supersett, 0 fjernet) og golden
BYTE-UENDRET (`shasum -a 1` av INNHOLDET = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`).
**AErlighets-grenser, uttalt:** ingen LEVENDE modell har lest sammenligningen
(structured-output-grensens klasse) — DEL D er maalingen; rapporten kan ikke si at et krav ER
riktig, bare at det ikke deler ett ord med retningen; og funn 4 (`named` 1/20) er denne saken
sett fra den andre siden, saa den maales av DEL D og ikke av en egen soem.
- **Naar forfaren ikke har underkataloger, navngir nekten DOKUMENTENE den holder (P22 DEL C,
16.09):** P21/C2 lot en nekt for en fravaerende sti navngi forfarens UNDERKATALOGER, og den kjoepte
hva den var bygget for — `read_dir` mot et nivaa basen ikke holder gikk 16/104 → 8/128. Den gjorde
INGENTING for dokumenter: `read_file` mot et dokument basen ikke holder gikk **2/38 → 7/52**.
Grunnen er strukturell, ikke tilfeldig: den naermeste listbare forfaren til en GJETTET dokumentsti
holder ofte dokumenter og ingen underkataloger, og da ble naboklausulen utelatt — BEVISST, fordi en
tom liste er en setning uten innhold. **MAALT over runde 5s seks `read_file`-bom: TRE lander paa en
slik forfar** (`krav/N100` med 445 dokumenter; `R761/1` med NOEYAKTIG ETT — som to separate
gjetninger i samme kjoering, `R761/1/1-1.md` og `R761/1/R761-1-1_id-...md`, begge strakte seg
etter), og tre har underkataloger og var alt besvart. `okf.nearest_documents` er soesknet til
`nearest_subdirectories`, ALDRI en utvidelse av den: **aldri begge klausuler** (forfaren er ETT
nivaa, og aa navngi dens dokumenter naar den ogsaa har underkataloger besvarer et annet spoersmaal
enn det kalleren stilte), og underkatalog-grenen staar FOERST, hvilket er dét som holder hver
C2-nekt byte-identisk (M C6 → 1 roed). **Bygget fra `context_files`, ALDRI `files`** — en liste
lest av filsystemet ville reklamert, i en NEKT, for `type: verdict`-laget som ingen listing nevner
og `read_file` straks avviser blankt: samme lekkasje i unnskyldningens klaer (M C3 → 1 roed) — og
gjennom SAMME `in_dimension`-predikat listingen bruker (M C4 → 1 roed). **Hvert navn RESOLVERER**,
maalt ved aa mate hvert av dem tilbake inn i `read_file`, aldri ved aa asserte at lista er
ikke-tom. Bundet til fem (M C5 → 1 roed), og **ÉN hjelper for BEGGE nekt-steder** (`read_dir`s egen
og `read_file`s — kø-(p): ett spoersmaal om én base maa ikke ha to svar; M C1 → 5 roede, M C2 → 1).
**`_shared_prefix` er den ene rangeringsregelen, delt av begge soesken**, og det staar her fordi en
MUTASJON FANT DEN UVITNET: aa bytte den mot en ren revers-sortering lot HELE suiten staa groenn
(1890/5) — bindingen, kilden og resolver-egenskapen var alle gatet, og REKKEFOELGEN var det ikke.
For `R761/1` koster det ingenting (ett dokument, ett svar), men et nivaa i et levert korpus kan
holde 445, og da ER hvilke fem den navngir hele verdien av klausulen. Den nye armen bygger et nivaa
der det naermeste navnet ogsaa er det LENGSTE, saa en lengde-regel legger det sist og en
alfabetisk legger et annet foerst — bare prefiks-regelen legger det foerst (M C7 → 1 roed etter
rettelsen, groenn foer). Load-bearing MAALT
(`tests/test_document_neighbours_loadbearing.py`, 10 armer), **sju mutasjoner alle roede mot HELE
suiten** + groenn kontroll **1891/5** (fra 1881/5, supersett, 0 fjernet) og golden BYTE-UENDRET
(`shasum -a 1` av INNHOLDET = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`). **AErlighets-grenser,
uttalt:** armen for fremmed dimensjon var VAKUOEST GROENN foer endringen (ingenting ble navngitt,
saa ingenting kunne lekke) og er gatet foerst naa — M C4 er dét som gjoer den ekte; ingen LEVENDE
modell har lest den nye klausulen (structured-output-grensens klasse), DEL D er maalingen; og
klausulen er hjelpetekst, ikke en gate — den kan ikke gjoere en gjettet sti riktig, bare billigere
aa rette.
- **v1-gaten måler avstanden til v1 med exit-kode, og den definerer KONTRAKTEN, ikke generatoren
(17.09):** `uv run python -m portfolio_optimiser.evals.v1_gate` (exit 0 kun når rad 16 er grønne,
1 ellers, 2 ved feil bruk; `--json`; ingen modellkall, intet nett). Den leser en rundekatalog med
fast form (`--help`; default `v1-rounds/`, GITIGNORED fordi fagpersonens tilbakemelding aldri skal
nå den offentlige remoten) — `feedback.json` er fastsatt som JSON, ikke `feedback.*`, fordi hvert
punkt må bære id og type for at sporingskravet i rad 2 kan måles. Rad 3 og 6 kjører NAVNGITTE
tester (`evals/v1_gate.json`) i en barne-pytest med `--runxfail`; de røde probene
(`tests/test_v1_probes.py`) er `xfail(strict=True)`, så suiten er grønn mens gapet er ekte og blir
RØD på XPASS den dagen en kapabilitet lukker det. En probe for en type uten flate feiler også når
et matchende flagg DUKKER OPP — «delvis er nei», og den blir grønn først når den skrives om til å
drive døra og observere handlingen. Rad 5 er RØD så lenge datafilens `approved` er `false`, og et
MAF-punkt teller kun når typen det peker på er grønn i rad 3 (kallstedet verifisert med AST, en
kommentar teller ikke). Rad 6 leser tilnærmingens EGEN erklæring (`requirement_source ==
"approach"`) — en kjøringsnivå-erklæring kan ikke tilskrives én tilnærming — og dømmer
stressrunde 6-utboksene på nytt med dagens dommer; kan én kjøring ikke dømmes, er HELE målingen
«ikke målt», aldri 0. Load-bearing MÅLT (`tests/test_v1_gate.py`), seks mutasjoner alle røde:
sporingskravet borte (2) · AI-vakten borte (1) · `>` i stedet for `≥` 80 % (1) · godkjennings-
vakten borte (1) · rad 6 ignorerer k (1) · rad 7 blir fellende (2). **Ærlighets-grenser, uttalt:**
basene rad 67 dømmer mot er et annet repos montering og kan være under ombygging (målt 17.09:
`r761-2025` uten `index.md`) — `--bundle-root` peker da på en utpakket kopi; bevisene for type 1, 3
og 7 er EKSISTERENDE tester registrert ved node-id, så en omdøping gjør typen rød til registeret
rettes (gatet av en egen arm).
- **v1-gaten er HERDET mot forfalskning — og sier det den ikke kan bevise (uavhengig review 17.09):**
reviewen gjorde rad 1, 2 og 4 grønne fra en håndskrevet katalog på ett minutt, og 10 av 20 mutanter
overlevde `tests/test_v1_gate.py`. Nå: (M-1) hver runde må ha minst ett NYTT punkt og egne id-er,
et `given_at` med tidssone i stigende rekkefølge, og være gitt på en rapport (`<n-1>/report.md`);
hver `outcome.json` må navngi en kjøring (`run_id` + `outbox`) hvis EGEN `coverage.json` bekrefter
(a)(d) — en håndskrevet eller tom grunnkjøring nektes — og feedbacken må være gitt MELLOM de to
kjøringene (coverage-filens tid); en NOK-endring under 1 % er støy. AI-vakten er et kjent-tekst-
filter (store/små bokstaver ignoreres), ALDRI en detektor, og gaten skriver på hver kjøring at
rad 12 ikke beviser forfatterskap (`ATTESTATION`). (M-2) rad 4 teller INNHOLDSLINJER (blanke,
skillelinjer og tabellrammer ute; etterstilte mellomrom strippet) som står uendret OG i rekkefølge
(`difflib`), viser tilleggene som eget tall, og en byte-identisk kopi er «ikke rørt» med mindre
runde 3 kvitterer `report_unchanged: true`. (M-3) rad 6 teller kjøringenes egne forslag
(15 validerte i stressrunde 6, ikke 10). (M-4) type 3 og 7 bevises gjennom de EKTE flaggene med
handlingen i resultatet (`tests/test_v1_probes.py`); tallet står på 3 av 8. (M-5) kontraktens
tall og bevisregisteret er pinnet mot kilden i testen. Småfunn: rundekatalog inne i repoet uten
gitignore og manglende `--stress-root`/`--bundle-root` gir exit 2; en typeannotasjon teller ikke
som kallsted. Reviewens 20 mutanter kjørt på nytt: **20 av 20 røde**.
- **Rundekatalogen BYGGES av en kommando, og den kommandoen skriver aldri attesteringen (19.09):**
målt read-only @ `6807946` bandt ingenting en kjørings utboks til `v1-rounds/<n>/` (40 treff på
`v1-rounds|rounds_dir`, alle i gaten, dens tester, `.gitignore`, hovedboken og et deck; 0 i
`run.py`/`outbox.py`/`scripts`) og ingen steder i `src/` skrev markdown — runde 0 sto på 0 av 3
fordi den ikke KUNNE lages, ikke fordi ingen hadde holdt den. `python -m
portfolio_optimiser.evals.round_builder --outbox <dir> --round <n> --ran-at <ISO>` skriver
`<n>/outbox/` som KOPI, `<n>/outcome.json` UTLEDET av den kopien, og `<n>/report.md`. Binderen
dømmer ikke med egne regler: `verify_run` avgjør om kjøringen står inne for seg selv (motsagt
artefakt, halv familie, streifende fil — alle avvist VED KILDEN, før en byte skrives),
`stage_of` gir kolonne (c), `row_changed` gir «Endret siden forrige runde», `parse_time` nekter
et tidsstempel uten sone, `safe_rounds_dir` nekter en rundekatalog repoet ville committet;
summen er `ledger.to_ore` per beløp. **To ting gjør den ALDRI:** skriver operatørens
`attestering.txt` (gaten stopper på FORM OK uten den — ingen filsamling kan vitne om at en
kjøring skjedde), og finner på. `--ran-at` er PÅKREVD fordi ingen utboksartefakt bærer en
klokke, og `feedback_ids` står tomt fordi ingen kjøring sporer hvilken tilbakemelding som ga
hvilken rad; rapporten skriver «Ingen tilbakemelding forklarer dette» på hver endret rad i
stedet for å skjule at modellstøy og et besvart innspill ser like ut. Rapportens stadie-navn er
prosa, aldri `stage4-p90`, og et sitat bærer ANTALLET siterte steder. Load-bearing MÅLT
(`tests/test_round_builder_loadbearing.py`, 40 armer, hvert tall talt en gang til fra
fixturens egen tabell — men «MÅLT» om ANTALLET holder først fra 19.09, se raden under); MÅLT på fire EKTE arkiverte utbokser (`tunnel-hauglia-2027` -04/-06/-07
/-08): gaten leser rundene, rad 1 = **FORM OK, IKKE BEVIST**. **Ærlighets-grense, uttalt:** rad
2 blir RØD og ikke FORM OK på de samme rundene — radene endret seg (2, 5, 5), men ingen endring
er sporet til en feedback-id, fordi sporingen ikke finnes ennå. Den hører i oversettelsen
`feedback.json` → kjøringens input, som er en egen ordre.
- **Rapportens INNHOLD er voktet, og nevneren for «alle artefakter» er TALT (19.09,
rundebinder-resten):** PM-sjekkpunktet plantet 20 mutanter mot binderen, og **sju OVERLEVDE hele
suiten** — rapportens rundenummer · en artefakt-TYPE utenfor proposal/outcome/coverage droppet
stille · en aldri-vurdert tilnærming utelatt fra sin egen liste · kilde/sitat borte · sitatets
ANTALL borte · de berørte kostnadslinjene borte · en avvist rads `saving_nok` talt med i summen.
Ingen av dem overlevde fordi koden var gal — binderen gjorde alle sju riktig. De overlevde fordi
ingen arm så etter: `grep` på sitat- og kostnadslinje-ord ga 2 treff i 709 testlinjer, begge i
fixturen, null i en assert. En uvitnet søm er en søm neste endring kan slette gratis. To
fixturfeil gjorde tre av dem uoppnåelige, ikke bare umålte. **(1) Nevneren var 3 av 7.** Kjøringene som er MÅLT legger
igjen SJU artefakt-typer — ikke «en ekte kjøring», som lovet mer enn målingen (RETTET 19.09:
`run.py` kaller TI av `outbox.py`s ti skrivere, så `exploration`, `prepass`, `multibase`,
`plan-review` og `proposal-reviews` er fem typer til, skrevet når flaggene som lager dem er
gitt. FIRE av de fem ligger ikke i en utboks som også har coverage — og for `plan-review` sier
det ingenting, for den typen finnes ikke som artefakt i repoet i det hele tatt (0 filer).
`multibase` GJØR det: fire utbokser (`p17b-multibase/`, `p20-stress/`, `p21-stress/`,
`p22-stress/`, alle `lindaas`) har både multibase og coverage, og hver av dem har to
coverage-filer. Det er derfor de faller utenfor «nøyaktig én coverage»-regelen unionen telles
over — og samtidig beviset på at sju er GULVET målingen gir, ikke et tak. Binderen kopierer
dessuten på glob, ikke på denne lista, så en type utenfor den bæres uansett). **Setningen er
skrevet om TRE ganger og var usann hver gang; den er nå pinnet** av en arm som teller utboksene
og krever at raden sier det tellingen sier
(`test_the_ledgers_claim_about_the_five_other_types_is_what_the_repo_measures`). Talt over de
fire arkiverte kjøringene sjekkpunktet leste (`tunnel-hauglia-2027` -04/-06/-07/-08; hver
`<run_id>-<rest>.json` typet som
`proposal`/`outcome` når `<rest>` ender der, ellers `<rest>` selv): `-06`, `-07` og `-08` har
alle sju (15 filer hver), `-04` har seks (12 filer, ingen `parse-failures` — den skrives bare når
noe ikke parset, så FRAVÆRET er signalet). Union = 7, skrevet av TO kommandoer: `run.py` seks,
`stress.py` `-verdict.json`. Talt om igjen 19.09 over HVER utboks i repoet med nøyaktig én
coverage — 15 kataloger, av 25 coverage-filer i 20 kataloger — er unionen 7 der også. **(2) Hvert forslag bar samme sitat-stempel**, så «1 av 1 siterte
steder» kunne ikke skille et droppet antall fra et beholdt; fixturen gir nå hvert forslag sitt
eget antall. Fire ting er NY atferd, alle røde på ASSERT først: **hengende symlenke** som
rundekatalog avvises med grunn og exit 1 (`exists()` FØLGER lenka, så den hengende svarte False,
slapp forbi «overskrives aldri» og lot bygget dø på filsystemets egen `FileExistsError` i stedet
for en setning operatøren kan handle på) · **én kildeliste delt av alle forslag sies ÉN gang**
årsaken ble MÅLT før noe ble skrevet, fordi «binderen leser feil felt» og «utboksen sier det
samme fem ganger» vil ha motsatte fikser: alle fem forslag i hver av de fire kjøringene bærer
BYTE-IDENTISKE 270-sitat-lister (én sha256 på tvers av alle fem, i alle fire kjøringer), altså
kjøringens hele hentede kontekst stemplet én gang per forslag. Rapporten kan ikke gjøre det
sitatet informativt; den kan slutte å gjenta det, og si hva lista faktisk er · **samme
kostnadslinje på begge sider av dommen navngis der det skjer** (den ekte rapporten avviste
`TUN-LYS-01` under én etikett og validerte den under en annen uten å si det — `TUN-VENT-01`
gjorde det samme) · en **fjernet tilnærming** skrives med etiketten fagpersonen så, med id-en i
parentes, lest fra coverage i FORRIGE rundes egen utboks; `outcome.json` beholder sine fire
kolonner. **12 av 12 mutanter felt** i scratch-klone, kontroll 40 av 40. Den tolvte var først
GRØNN, og det var et funn: `validated_ore` sin egen vakt er ekvivalent så lenge `derive_outcome`
sin holder, så den skilles av en arm som kaller den PUBLIKE funksjonen med utfallet en framtidig
coverage-skriver kunne lage. Fixturens avviste rad bærer et beløp MED VILJE — målt på de samme
fire utboksene har hver `rejected`-rad `saving_nok = None`, så vakten sikter mot en skriver som
ikke finnes ennå, og en fixtur som ikke kan lage tallet kan ikke vitne om vakten.
- **Rapportens FØRSTE SKJERM er voktet ord for ord, og en delstreng er ikke lenger en vakt
(19.09, rundebinderens to siste uvoktede utsagn):** PM-sjekkpunktet fant to overlevende mutanter
i nøyaktig det en fagperson leser FØRST. Begge er reprodusert som OVERLEVENDE mot de 40 armene
før noe ble skrevet: **domsordet** (`_status_word`, «rejected» → «validert») og **kroner per
tiltak** (overskriftens beløp kuttet til hel krone). Jeg plantet åtte til mot samme skjerm —
**8 av 10 overlevde**: ordet droppet helt, etiketten paret med NESTE rads ord, `not_evaluated`
lest som «avvist», `unsupported` lest som «validert», antallet kommisjonen ba om av med én, og
overskriftens «kroner» byttet til «kr». Ingen av dem var en kodefeil — binderen gjorde alle ti
tingene riktig — og **derfor kan ingen av de tre nye armene være RØD ved HEAD**: det finnes
ingen fiks å være rød før. Beviset er mutantkjøringen, ikke commiten: **12 av 12 felt, hver på
en AssertionError om atferd, 0 på import/AttributeError**, kontroll 43 av 43.
**ÅRSAKEN VAR MÅLT, IKKE GJETTET:** `«60 000,01» in text` traff også «Berørte
kostnadslinjer»-linja, som bygges av `unit_cost` og som mutanten ikke rørte. Talt over fixturens
egen rapport har **4 av 11 positive delstreng-assert-steder** i fila nåla på MER ENN ÉN linje;
**3 av de 4** var asserts om ÉN bestemt av dem. De tre er nå sammenligninger av HELE linja
(`- **{etikett}** — {ord}`, `### {etikett} — {beløp} kroner`, `### {etikett} — falt på …`), den
fjerde påstår bare tilstedeværelse og måler tilstedeværelse. **Ordforrådet er pinnet til
MANDATETS egen statusliste** (`ApproachOutcome.status`, fire verdier), slik scene-ordforrådet er
pinnet til validatorens: `_status_word` faller tilbake på `str(row["status"])`, så en status lagt
til der uten ord her når fagpersonen som en bar engelsk id. Ordene skrives ut i testfila, aldri
importert fra binderen — og «validert» er et PREFIKS av «validert, men uten erklært krav», som er
selve grunnen til at ingen delstreng-assert kan skille dem.
- **Et forslag uten tilnærmingens EGEN erklæring kan ikke bære `validated` (rad 6, 17.09):** målt
på stressrunde 6 hadde alle 10 validerte tilnærmingene bare kjørings-erklæringer, som ingen kan
knytte til én tilnærming — og tre falsifiseringsarmer validerte. `declare_requirement` tar derfor
et PÅKREVD `approach_id` (mandatets id-er + `own-proposal`; ukjent id → `UnknownApproach`, en
returnert nekt som navngir de gyldige), og `DeclaredRequirement`/`requirement_payload` bærer det.
I `_evaluate_mandate` blir en `ValidatedProposal` hvis tilnærming verken har `requirement` i
mandatet eller en erklæring under sin egen id til `validator.Unsupported` — en `Rejection`-
SUBKLASSE med validatorens egen `ValidatedProposal` på seg, så hver `isinstance(...,
ValidatedProposal)` sier nei uten å røres, mens de som NAVNGIR statusen (coverage `unsupported`,
`outcome_payload` `outcome_type: "unsupported"` med persentilene, `settle` `UNSUPPORTED`,
`rejection_stage` `unsupported`, dommeren) sjekker klassen FØRST. `validator_decision` forblir
`validated` (den speiler kun validatoren). **Regelen er aktiv nøyaktig når debatten hadde
erklæringsverktøyet** — også på mikro-basen, som har 0 kravnumre (PM-rettelse: ingen
spesialbehandling); veg-stien og pre-pass-stien har ingen trapp og er urørt. Erklæringens
KVALITET dømmes ikke (P22 § 4), så regelen kan spilles ved å erklære et hvilket som helst lest
dokument — uttalt svakhet. Dommeren leser en erklæring under tilnærmingens id som `approach`, en
uten `approach_id` (eldre artefakter) som `run`; v1-gatens rad 6 sier da «IKKE MÅLT», og IKKE
MÅLT feller exit-koden (aldri grønn). Load-bearing MÅLT
(`tests/test_row6_declaration_rule_loadbearing.py` + rad 6-probene), ti mutasjoner alle røde.
- **Målingene leser en FROSSET kopi av korpuset, pinnet med sha256 — aldri et annet repos levende
build-mappe (18.09, ordre `20260917T223645Z-1296211942`):** gaten, stressdommeren og fire
korpus-tester leste `~/repos/vegnormal-okf/build/ferdig` DIREKTE. **MÅLT 17.09 17:43:** vegnormal
bygget om `r761-2025`, rad 67 sa «IKKE MÅLT» og fem tester falt, for en endring ingen her gjorde.
**Feilmodusen var aldri usannhet** — gaten sier IKKE MÅLT og exit 1, aldri falskt grønn — den var
USTABILITET: to prosjekter delte en mappe ingen av dem eier, så hva dette repoet MÅLER kunne
flytte seg uten en commit her. **En kopi alene ville bare skjøvet den mappa ett hakk unna**, så
kopien kommer med en PIN: `frozen_bundles.json` (tracked) bærer sti + sha256 + filantall per base,
mens BUNDLENE ALDRI committes her (vegnormal-korpus skal ikke til en offentlig flate).
**Tre tilstander, skilt VED KONSTRUKSJON, og den tredje er hele poenget:** kopien MATCHER → den
eneste stien som måler noe; kopien er BORTE → `FrozenBundleMissing`, en `OSError`, så gatens
eksisterende `except OSError` gir IKKE MÅLT + exit 1 uendret og korpus-testene SKIPPER (MAJOR-3s
tak: en hard feil ville brutt `uv run pytest` i overleveringsarkivet, der intet korpus er
montert); kopien AVVIKER → `FrozenBundleDrift`, en `ValueError`, høylytt og navngitt og ALDRI en
skip — en drevet kopi er ikke en uleselig måling, den er en måling av FEIL korpus, altså den ene
tilstanden som produserer et stille galt tall. **De to klassene er BEVISST uten slektskap:** en
kaller som fanger «mangler» for å skippe må ikke svelge «avvik». **NAVNET hashes ved siden av
bytene** — uten det ville et korpus stokket om under samme bytes pinnet rent — og katalognavnet
BÆRER de 12 første tegnene av digesten, så en foreldet kopi er synlig i `ls`, ikke bare for
verifisereren. **Fornyelse er en BESLUTNING, aldri rydding:** ny kopi + ny pin i SAMME commit
(README § Frozen knowledge bases). `--bundle-root` / `PORTFOLIO_VEGNORMAL_ROOT` består som
operatørens EKSPLISITTE, UPINNEDE levende montering — måten å se på et ferskt korpus før man
bestemmer seg for å fryse på nytt; uten den kan ikke gaten brukes til å ta den beslutningen.
**Grep-gaten dekker BEGGE stavemåtene, hver med sin egen kjent-positiv:** `vegnormal-okf/build`
(3 treff før) og det siterte sti-segmentet `"vegnormal-okf"` (4 treff før) — en fil-bred gate med
ÉN av dem ville vært grønn mot fire av de sju stedene, og prosa som dokumenterer historikk
(3 treff) er eksplisitt tillatt. Testfila bygger tokenet med `"-".join(...)`, fordi `ruff format`
MÅLT folder `"vegnormal" "-okf"` tilbake til én literal og gaten da blir rød mot sin egen kilde.
Load-bearing MÅLT (`tests/test_frozen_bundles_loadbearing.py`, 17 armer), **åtte mutasjoner alle
røde mot HELE suiten** + grønn kontroll **1984/5 + 5 xfailed** og node-ID-supersett (1977 → 1994,
**0 fjernet**): M1 pinnen verifiseres aldri (7 røde) · M2 avvik kollapset inn i «mangler» (5) ·
M3 navnet hashes ikke (40) · M4 gate-sømmen reverteres til `root/name` (1) · M5 korpus-testene
skipper på avvik også (4 — én per fil) · M6a `vegnormal-okf/build` tilbake i `src` (1) ·
M6b det siterte sti-segmentet tilbake i en test (1) · M7 katalognavnet dropper den korte digesten
(1, og 45 skipped — som beviser at fravær er en SKIP, ikke en falsk grønn) · M8 den eksplisitte
overstyringen ignoreres (3, hvorav TO i `test_stress_judge_loadbearing.py`, uavhengige vitner
eldre enn dette arbeidet). **M2 FALSIFISERTE TESTEN FØRST (repoets vakuøs-gate-klasse,
TJUEFJERDE gang):** de fire parametriserte armene gikk ikke røde, de gikk til SKIP (5 → 9 skipped
over suiten) og sto grønne — `pytest.skip` inne i en `pytest.raises` er ikke en feil. Armen fanger
`pytest.skip.Exception` EKSPLISITT og gjør den til en `AssertionError`. **Ærlighets-grenser,
uttalt:** en overstyrt montering er UPINNET ved konstruksjon (operatøren navnga den), så gaten
kjørt med `--bundle-root` måler ikke det pinnede korpuset og sier det ikke — pinnen er default,
ikke et påbud; digesten dekker hver fil, så en `.DS_Store` som dukker opp i kopien er et AVVIK
(MÅLT: null `.DS_Store` og null symlenker i alle fire basene da kopien ble tatt); og kopien ble
tatt 18.09 fra vegnormals mappe KUN ved lesing — kildens mtimer er uendret.
- **B-gaten måler po som VERKTØYKASSE Claude Code driver — og po får aldri en vei tilbake til
Claude (19.09, ordre `20260919T040628Z-4756715055`, REPARERT samme dag etter PM-sjekkpunktet,
ordre `20260919T082156Z-338455001`):** operatørbeslutningen er at Claude Code LEDER i utvikling
og test, at po er verktøykassen, og at produksjon kjører Foundry uten Claude i det hele tatt.
`python -m portfolio_optimiser.evals.b_gate` er kontrakten den kapabiliteten skal leveres inn i,
skrevet RØD før noe bygges: **0 av 17 · 0 av 2 · 12 av 12 · 0 av 3 · 4 av 5 · IKKE MÅLT**, exit 1.
(Utgave 1 sa `3 av 13 · … · 6 av 6 · … · 1 av 2`, utgave 2 `3 av 17 · … · 9 av 9 · … · 4 av 5`;
begge sjekkpunktene viste at nevnere var gatens egne tall. **Ingen rad har skiftet FARGE i noen av
de to reparasjonene — men tall har flyttet seg i begge retninger, og det skal sies presist:** rad
5 gikk `1 av 2``4 av 5` fordi ENHETEN ble delt opp (0,50 → 0,80 — grønnere i tall, samme
farge), rad 3 `6 av 6``9 av 9``12 av 12` fordi flaten og vaktene vokste, og rad 1 `3 av 17`
`0 av 17` fordi proben ble bundet til steget. Ingen rad har blitt grønnere av en svakere prøve.)
**Rad 1s nevner UTLEDES av kjørestien** (`run_path_calls`): 41 po-funksjoner kalles i
`run.py::run_project` (PMs 39 deterministiske + `generate_via_llm`/`fresh_workflow`, som holdes
utenfor fordi de krever chatklient). Et kall som verken er erklært som steg eller navngitt som
holdt utenfor, teller i nevneren UTEN en dør — derfor kan den ikke krympe stille slik en kuratert
liste i gatens egen `b_gate.json` kunne: fjernes et steg fra kontrakten, står N uendret og
foreldreløsen navngis. 28 kall er holdt utenfor, hvert med sin grunn skrevet i gatens output. De
fire utboks-skriverne kjørestien bruker og ingen hadde erklært (`write_prepass`,
`write_parse_failures`, `write_proposal_reviews`, `write_debate_tools`) er steg nå: artefakt-
familien er sju skrivere av ti definerte, ikke tre. **En dør må være REGISTRERT og BEVIST:**
`entry["kind"]` leses (den ble lest 0 ganger før) og må være én av tre arter gaten har kode for å
etterprøve — `console-script` i pyproject, `module-main` med sin egen `__main__`-vakt,
`subcommand` registrert i modulens egen argparse — og hvert steg må dessuten ha en navngitt probe
som er BUNDET til steget (avsnittet under). Målt: en modul med bare `def main(): return
<symbol>()` tok rad 1 fra 3 til 4 av 13 før; nå avvises den under alle tre artene (`ENTRY_KINDS`
har TRE arter, ikke fire), med grunn.
**«Kallbar utenfra» betyr uten chatklient:** en inngang som når steget via en vei der
`create_chat_client`/`client_factory`/`_default_factory` nevnes, teller IKKE (`entry_reaches`) —
det er hele grunnen til at `run.py`-stegene er røde mens rundebinderen og v1-gaten er grønne.
Sjekken er med vilje strengere enn nødvendig: den leser hele det `main` når i sin egen modul,
ikke bare den ene veien ned. **Rad 3 er den eneste raden som er grønn, og den er grønn som en
MÅLING:** tolv vakter, hver med sin kjent-positive OG kjent-negative prøve, over **512 publiserte
filer lest av REPO-MANIFESTET** (`git ls-files`, eller filtreet selv i et rent uttrekk — som ER
det publiserte). Håndlista på elleve `roots` den erstattet så 433 av dem: `main.py`,
`examples/`, `spikes/`, `contexts/`, `CLAUDE.md` og `llms.txt` lå utenfor, og alle seks
kjent-positive kunne plantes i `main.py` uten at raden merket det. Manifestet gjør tallet
reproduserbart: 433 i uttrekk og 435 i arbeidstreet var de to gitignorerte `.local.md`-filene
under `docs/plan/`. **Tre av de tolv vaktene feller INDIREKTE kall** — absolutt sti, liste lagt i en
variabel, konstant, shell-streng — så 5 av 5 av sjekkpunktets varianter avvises, med 0 falske
positive målt over hele flaten. **En tom flate er `IKKE MÅLT`, aldri grønn:** raden krever en
sentinel-fil og skriver både filtallet, hvilket manifest den leste og hvor mange filer som ikke
lot seg avkode (1 — en `.sqlite`-fixture). **I markdown teller kun linjer inne i kodeblokk**
(«docs med kjørbare kommandoer»): uten den regelen blir raden rød av TO prosa-linjer — målt på
den nye flaten 19.09 — `docs/research/2026-06-24-maf-vs-claude-agent-sdk.md:185`, som vurderer og
forkaster et pakkenavn, og `docs/plan/2026-08-09-fable-egnethetsreview-prompt.md:11`, som siterer
en kommando operatøren kjørte i SIN egen økt. Ingen av dem er en vei po kan gå.
**Mønstrene ligger base64-kodet i `b_gate.json`** fordi flaten gaten leser er den samme flaten
gaten bor i; klartekst ville registrert kontrakten som sitt eget funn og tvunget fram en
unntaksliste, og en rad med unntaksliste kan skrus av ved å legge en fil på lista. Samme grunn
gjelder de plantede variantene i testfila. **Rad 4, 5 og 6 har nevnere med navngitt kilde:**
rad 4 teller bare sjekker hvis kilde-symbol faktisk finnes i koden (`run_project`, `build_round`,
`v1_gate.FORM_OK`), rad 5 teller hvert strukturkrav for seg (to profil-medlemmer + fabrikk + søm
+ probe = 5) i stedet for å blande tre til én enhet, og rad 6s N er artefaktene kontrakten
navngir. **Attesteringen VALIDERES nå:** den må navngi kontraktens kjørebok, bære dens sha256,
si hvem som kjørte den, og ha en ekte ISO-dato som ikke ligger i framtiden (v1-gatens egen
`_parse_given`, gjenbrukt; BOM tåles som der). Før reparasjonen ga `kjørebok: x`, `dato: x`,
framtidsdatoen `3026-01-01` og en peker til en annen fil alle **2 av 2 GRØNN**.
**To valg gaten uttaler i sin egen output** (operatøren kan ikke svare på dem uten å lese kode):
budsjettvernet i B er IKKE po sitt — `BudgetMiddleware` er fail-closed på manglende usage og
konstrueres aldri uten chatklient, så å beholde det her ville gjort fail-closed til fail-open;
taket i B er Claude Code-øktens eget forbruk, som po verken ser eller styrer, og Foundry-veien
beholder sitt tak uendret · rad 6 er `IKKE MÅLT` og aldri grønn før operatøren bekrefter at
kjøreboka faktisk drev en analyse — en fil gaten ALDRI skriver selv, samme regel som
`attestering.txt` på v1-gaten. **Påstanden om at gaten teller en MCP-registrert dør er STRØKET:**
den beskrev kode som ikke fantes.
**Load-bearing:** `tests/test_b_gate.py` (86 armer, hver nevner talt uavhengig i testen).
**12 av 12 mutanter felt i scratch-klone** (kontroll 65 av 65): nevneren krymper stille (3 armer)
· udeklarert kall teller ikke (2) · stub teller som dør (5) · ukjent inngangsart godtas (1) ·
navn teller som atferd (3) · tom flate blir grønn (1) · flaten snevres inn til en håndliste (6) ·
de tre indirekte vaktene fjernet (5) · sjekksummen ignoreres (1) · framtidsdato godtas (1) ·
rad 4s kilde ignoreres (1) · rad 5 teller strukturen som én enhet (3). Runden før felte 8 av sine
egne. **v1-gatens tall er uendret** (0/3 · 0/3 · 3/8 · ingen rapport · 3/8 · IKKE MÅLT · 1/20,
målt etter). **Grensen, uttalt:** gaten beviser ikke at verktøykassen VIRKER — den sier hvor
langt unna den er. Rad 2, 4 og 5b er navngitte prober som ikke finnes ennå, og en test som ikke
finnes er RØD, aldri hoppet over. Rad 3 er en TEKSTVAKT, ikke en dataflyt-analyse: tre veier
står igjen (se under), og raden sier det selv i stedet for å la GRØNN bety mer enn den bærer.
**ANDRE REPARASJON samme kveld (19.09, ordre `20260919T184337Z-3169111514`), etter at PM MÅLTE
at kontrakten var oppfyllbar UTEN kapabilitet:** rad 1 kunne tas fra `3 av 17` til
**`17 av 17` GRØNN med fjorten stubb-dører i én modul og ÉN urelatert bestått test** brukt som
«atferdsprobe» for alle sammen. Gaten slo bare opp om probens nodeid var `passed`;
`EXTERNAL_DOOR` lovet at proben «kaller døren og leser artefaktet den skriver», og det fantes
ingen kode — samme klasse som `entry["kind"]` runden før. **Proben er nå BUNDET til steget, og
bindingen er en MÅLING i probens egen kilde** (`probe_binds`), aldri en erklæring i kontrakten:
fire krav, hvert med sin arm og sin mutant — proben må RØRE DØREN (dørens dotted modulnavn eller
dens registrerte kommandonavn, brukt som en hel streng), NAVNGI STEGET (symbolet, id-en eller
underkommandoen, som et helt ORD i det proben sender inn i et kall eller kaller), ASSERTERE i
det hele tatt, og ikke være DELT — en probe to steg gjør krav på beviser høyst ett av dem, og
gaten vet ikke hvilket. **Valgt å lese probens kilde framfor å kreve at den ligger i en
kontrakt-navngitt probe-fil, fordi et filnavn er en konvensjon en stub oppfyller like lett som
en ekte probe.** To feller ble målt fram underveis og er lukket: en DELSTRENG-regel ville latt
«gate» være navngitt av `portfolio_optimiser.evals.v1_gate`, og første utgave godtok steget
`gate` fordi probefila importerer modulen SOM `gate` — bindingen var til et lokalt alias. Navn
leses derfor bare der de SENDES eller KALLES; dørens navn leses videre (den ekte formen bygger
argv i en variabel først), men aldri fra en streng som står alene. **Prisen, målt mot kontrakten
som sto: rad 1 gikk `3 av 17``0 av 17`** — `rundebinding` og `gate` driver riktig dør uten å
navngi hvilket steg de beviser, `rapport` går ikke gjennom døren i det hele tatt (den kaller
`build_round` i prosess). Ingen av de tre var en kodefeil; det var kontrakten som godtok dem.
**Radens egen grenseerklæring var USANN:** den oppga NØYAKTIG TO gjenstående veier til Claude;
PM plantet 21 kallformer og målte at SEKS sto åpne. Fire er lukket med hver sin vakt —
`sdk-anthropic` (den offisielle Python-SDK-en, begge skriveformer), `node-runner` (node- og
uv-kjørerne, både som shell-linje og som argv-liste) og `dynamisk-import` — og rad 3 gikk
`9 av 9``12 av 12`, fortsatt GRØNN med 0 treff over 512 filer. **TRE veier står igjen og er
navngitt i attesteringen:** et navn satt sammen ved kjøretid, et navn lest ut av en
miljøvariabel, og et navn som avkodes først (base64). Den siste står bevisst åpen: kodingene er
ikke oppregnelige, og kontrakten lagrer selv base64 med vilje. Den nye vakten fant umiddelbart
en kommando skrevet i DENNE rundens egen test-docstring; den ble skrevet om, ikke unntatt.
**`held_out` er ikke lenger en dør ut av nevneren:** en TOM grunn er ingen grunn — symbolet blir
stående i nevneren som et kall uten dør, og sammendraget teller GRUNNER, ikke oppføringer (det
sa «holdt utenfor med grunn» uansett før). De fire stegene som er erklært UTENFOR kjørestien har
ingen utledet nevner i det hele tatt, og står nå navngitt under raden, ett for ett, i stedet for
å telles stille. **Fem små hull lukket:** et BESKÅRET manifest (451 av 512 filer ga fortsatt
GRØNN) er nå `IKKE MÅLT` — kontrakten planter én sentinel per område den gamle håndlista utelot
(`main.py`, `examples/`, `spikes/`, `contexts/`, `src/`) · en fil som ikke lar seg avkode som
UTF-8 leses som byte-tekst i stedet for å telles og hoppes over · en symlenke UT av treet
navngis og feller raden · en kjørebok hvis hele innhold er «x» er ikke lenger `2 av 2 GRØNN`
kontrakten navngir seksjonene · og raden sier selv at k av n **ikke er et dekningsmål**.
**To grenser er UTTALT, ikke lukket, hver med sin grunn i radens egen attestering:** et po-kall
flyttet én etasje ned, til en hjelper `run_project` kaller, faller ut av nevneren (å følge
hjelpere transitivt ville trukket private hjelpere inn og gjort nevneren til den kuraterte lista
raden finnes for å unngå), og rad 3s k/n kan fortsatt polstres med en vakt uten en målt omgåelse
bak seg. **13 av 13 mutanter felt i scratch-klone** (kontroll 86 av 86, isolasjonen verifisert på
`b_gate.__file__` FØR første tall). **Den trettende overlevde TO ganger og er rundens funn:**
leses hele probens kropp, teller en streng som STÅR ALENE som å røre døren — og første forsøk på
å felle den plantet navnet i en SETNING, som gaten uansett aldri ville godtatt, så armen
bekreftet noe som allerede var sant. Nålen måtte være dørens navn BART.
- **Domsgrunnen er ikke lenger binderens eget svar, og nevner-setningen er TELT (19.09,
rundebinderens siste rest):** rapportens avvisnings-overskrift sier HVILKET stadium en
tilnærming falt på, og armen som voktet den bygget forventningen sin av `STAGE_PROSE` selv — den
spurte binderen hvilken setning den valgte og var enig med den. PMs mutant (setningene for
`stage4-p90` og `stage0b-grounding` byttet) passerte **43 av 43 armer**, og rapporten fortalte da
fagpersonen at et forslag falt på forankringen i kunnskapsbasen mens det falt på
usikkerhetsberegningen — det ene den seksjonen finnes for å si, sagt galt, uten noe som fanget
det. REPRODUSERT I BEGGE RETNINGER her: overlevende 43 av 43 mot de gamle armene, felt av tre
armer etterpå. Rettelsen er `_STAGE_SENTENCES` i testfila — stadium → (innledningsleddet
overskriften må åpne med, et ord bare DET stadiets forklaring bærer) — sammenlignet mot den ENE
overskriftslinja, funnet på prefiks og krevd å være den eneste. At hvert merkeord hører til
nøyaktig ett stadium er TALT i testen, ikke antatt, og HELE tabellen voktes, ikke bare de to
stadiene fixturen kjører: en fixtur er ingen nevner. **Klassen er telt og lukket: 4 av 12**
assert-steder som rører `rb.<tabell>` hentet forventningen fra binderen selv — de to
overskrifts-stedene, pluss to som bare påsto FORM på tabellen (lengde > 20, kolon finnes) uten
at noe utenfor binderen sa hva en setning skulle være. De åtte andre har en uavhengig side, og
den er navngitt: validatorens egen stadieliste, `_STATUS_WORDS`, eller en utskrevet literal.
**7 av 7 egne mutanter felt** i scratch-klone, hver på `AssertionError` om atferd (0 `IndexError`,
0 `ImportError`, 0 `AttributeError`), kontroll 43 av 43 + 1 skipped før og etter, isolasjonen
verifisert på `round_builder.__file__` FØR første tall. Blant dem: to som bytter BARE
forklaringene, en som bytter BARE innledningsleddene, en som gir alle falne samme stadium, en
som dropper innledningsleddet i overskriften, og ett stadiepar fixturen ALDRI rører (felt av
tabell-armen alene). **`_section(report, heading)`:** hver `split("## …")[1]` i fila går nå
gjennom den og nekter med rapportens egne overskrifter i meldingen. PMs P13 (overskriften
«## Hva ble vurdert» døpt om) felte fire armer før, tre av dem på `IndexError` — en tilbakesporing
som sier at en liste var for kort, ikke at rapporten mistet seksjonen fagpersonen leser først.
Etterpå: fire armer, alle på `AssertionError`. **Setningen om typene utenfor de sju var usann for
TREDJE gang og er nå pinnet:** `multibase` ligger i fire utbokser som også har coverage, og hver
av dem har to coverage-filer — nettopp derfor faller de utenfor «nøyaktig én coverage»-regelen
unionen telles over, og nettopp derfor er sju et GULV. Armen teller utboksene og krever at raden
sier det tellingen sier; den hopper over uten `scratchpad/` (som i et rent uttrekk) og FELLER på
en tom telling, fordi en spørring som ikke kan finne noe ikke er en måling.
- **Verktøykassens fire første dører, og bindingen som måler UTFØRELSE (20.09, ordre
`20260920T052739Z-9456915952`, operatørdirektiv «godt nok, bygg»):** `portfolio-optimiser-toolbox`
er den TREDJE konsoll-kommandoen, og den er der fordi den er det ENE de to andre ikke kan brukes
til: hver vei gjennom `run` bygger en chatklient, og stegene debatten er bygget PÅ trenger ingen
modell. Fire underkommandoer, ett kjernekall hver — `navigate-bundle``okf.navigate_bundle`,
`cost-baseline``okf.derive_cost_baseline`, `retrieve-chunks``datasource.retrieve_chunks`,
`prepass-admit``prepass.admit_payload` — med JSON på stdout og en exit-kode som sier
sannheten (0 kjørte, 2 feil kall, 3 steget NEKTET, med grunnen navngitt). **Hver håndterer er en
tynn adapter med vilje:** en håndterer som REGNET noe selv ville vært en andre implementasjon av
et kjørestegs-steg, og da slutter den eksterne kalleren å få det debatten får — hele påstanden
bak døren. **Dispatch er én gren per kommando, aldri `set_defaults(handler=…)`:** tabellen
skjuler det ene en leser vil se, og rad 1 spør kilden om nøyaktig det samme (den går kallgrafen
fra `main` ned til stegets symbol), der en callable i et Namespace er et hopp ingen av dem kan
følge. Rad 1: **0 → 5 av 17**, exit 1 uendret, ingen annen rad flyttet seg.
**Probene (`tests/test_toolbox_doors.py`, 10 armer) importerer ALDRI kjernefunksjonen:** hver
starter døren som subprosess med underkommandoen i argv og asserterer på det den SKREV. Fasiten
er utenfor døren i hver arm — filsystemet (`navigate-bundle`, inkludert den ene bevisste
lenken ut av basen), en tabell transkribert fra prisskjema-fixturen (`cost-baseline`), det
in-prosess API-et den må være byte-lik (`retrieve-chunks`), og produsentens egen innsjekkede
nyttelast (`prepass-admit`). Hver avvisningsarm har en rc-0-kontroll ved siden av seg.
**B-gatens binding, TREDJE reparasjon — og den første som ikke leser et NAVN:** dommeren målte
rad 1 til 17 av 17 med 17 énlinjes-prober og en dørmodul uten én eneste import. Det som måles nå
er et UTFØRELSESSTED (en prosess-starter med dørens navn i argumentene, eller inngangen importert
fra dørens modul OG kalt) og en assert som er DATAAVHENGIG av det kallet. Død kode beskjæres
først. De ærlige formene suiten alt bruker teller videre: kommandoen bygget i en variabel først,
og subprosessen startet i en hjelper som returnerer den. **Dommerens sju former (a1, a2, b1, b2,
c1, c2 + oppskriften) gir alle 0 av 1**, hver med rc-0-kontroll i samme oppsett.
**Navngivningen av steget er en DISKRIMINATOR, rettet som klasse:** den kreves bare når mer enn
ett steg står bak samme dør. Å kjøre en dør med ett steg bak seg ER å kjøre det steget — og det
var derfor `gate` (en ekte ende-til-ende dørprobe mot v1-gaten) ble avvist på en
navneteknikalitet. For en underkommando må kommandonavnet stå i det som FAKTISK ble kjørt, og
CLI-en selv må være registrert eller `-m`-kjørbar: en `add_parser` i en modul ingen kan starte er
ingen dør. **`held_out`-grunnen må være navngitt prosa** («-», «todo», «x», «.» ble alle godtatt
av `.strip()`), målt mot kontraktens egne 28 grunner (korteste: 30 tegn, tre ord).
**Rad 3 lukker de fem veiene sjekkpunktet målte som åpne OG billige å lukke**`importlib` for
begge SDK-navn, `deno run … npm:` / `npm exec` / `yarn dlx`, og den offisielle TypeScript-SDK-en:
**12 av 12 → 15 av 15**, fortsatt 0 treff over **514** publiserte filer (nevneren vokste med de to
filene DENNE leveransen la på flaten — pinnen fanget det). Grenseerklæringen slutter å regne opp
hva som står igjen («NØYAKTIG TO», så «TRE» — begge falsifisert av den første nye målingen) og
sier hva vakten ER: tekstmønstre over git-manifestet, som feller et navn som STÅR SKREVET og
ikke ser et navn som blir til når koden kjører.
**Rad 6: en overskrift er ikke en seksjon.** De fem kontrakt-navngitte overskriftene pluss «x»
(125 tegn) ga `2 av 2 GRØNN`; seksjonsnavnet bindes nå til en OVERSKRIFTSLINJE og det som teller
er kroppen under den (`section_bodies`, `RUNBOOK_MIN_BODY = 80`). Gulvet er mot den tomme
overskriften, aldri et mål på om kjøreboka er SANN — det blir stående som operatørens, og raden
er fortsatt `IKKE MÅLT`.
**Grensen raden uttaler selv:** gaten leser at proben KJØRER døren og leser resultatet; den
kjører ikke proben på nytt med døren brutt. Den eneste formen som ikke kan skrives seg forbi er
å MUTERE inngangen til å reise og se proben bli rød, og det gjør gaten ikke. **N7 står åpen i
GATEN og er lukket i SUITEN:** et slettet off-path-steg krymper fortsatt nevneren stille der,
så de fire står utskrevet i en arm som blir rød når én av dem forsvinner.
**Load-bearing:** `tests/test_b_gate.py`, `tests/test_toolbox_doors.py`,
`tests/test_console_entry_points.py`. **17 av 17 mutanter felt** i klone (kontroll 133 av 133,
isolasjon verifisert på `b_gate.__file__` OG `toolbox.__file__` før første tall), 0 andre
unntakstyper enn assertions. **To funn kom AV mutantkjøringen, ikke av lesing:** beskjæringen av
død kode OVERLEVDE to mutanter fordi ingen arm nådde den — formen som trengs er en probe som er
GRØNN i pytest (en ekte prosess som ikke er døren binder navnet asserten leser, dørkallet i død
kode under samme navn), og begge formene er armer nå. **Tre mutanter var ikke målinger og sies
det om:** to omdøpte bare en etikett/id uten å fjerne en vakt, og én rundet `score` til to
desimaler — EKVIVALENT, fordi scorene er 1.0/0.75/0.5.