# Katalogkallet — `list_bundles()` fra 112 116 til 362 tokens **Ordre:** `20260825T213645Z-9019120455-from-.claude`. **Dato:** 2026-08-26 (økt 65). **Kode:** `src/portfolio_optimiser/explore.py` (`_index_excerpt`, `navigator_tools`). **Gate:** `tests/test_catalogue_cost_loadbearing.py` (7 tester). **Suite:** 1066 passed / 5 skipped. **Golden `demo-transcript.stdout` byte-uendret** (`ea8c534773acdbe41ae68f2c55724d69aaf8be4f`). **Eksponerings-grense (arvet fra syretesten, holdt):** dette repoet pusher til `open/`. Rapporten bærer kun tall, stier, kommandoer og egne observasjoner. Ingen bundle-fil er kopiert, og ingen kravtekst er gjengitt — alle konsept-tall er lengdemålinger, ikke innhold. --- ## 1. Instrumentet, validert før noe tall ble trodd `tiktoken.get_encoding("o200k_base")` over `json.dumps(list_bundles(), ensure_ascii=False)`, kjørt med `uv run --with tiktoken` (`tiktoken` er fortsatt **ikke** en prosjekt-avhengighet). Samme instrument som syretesten 25.08. **Kjent-positiv kontroll (Verifiseringsloven ansikt 4):** de tre flate Vegnormal-basene målte **201 196 tegn / 112 116 tokens** før endringen — tallet syretesten publiserte, reprodusert eksakt. Uten den kontrollen ville «etter»-tallet vært en måling ingen visste kunne treffe. ## 2. Før og etter, med nevner | Katalog | Baser (nevner) | Tegn før | **Tokens før** | Tegn etter | **Tokens etter** | Endring | |---|---:|---:|---:|---:|---:|---:| | Tre flate baser (syretestens sett) | 3 | 201 196 | **112 116** | 877 | **362** | **−99,7 %** | | Grener, N100:2023 | 40 | 63 375 | **33 889** | 11 679 | **5 017** | −85,2 % | | Grener, N200:2024 | 99 | 134 667 | **71 726** | 28 894 | **12 396** | −82,7 % | | Grener, N500:2024 | 32 | 36 569 | **19 329** | 9 408 | **4 037** | −79,1 % | | **Alle grener samlet** | **171** | 234 611 | **124 942** | 49 981 | **21 448** | **−82,8 %** | | *kontroll:* commons' tre eksempelbaser | 3 | 11 050 | 3 472 | 989 | 321 | −90,8 % | Per base: **731 → 125 tokens** i grenformen, **37 372 → 121** i den flate. **Nevner-avvik mot ordren, uttalt:** ordren oppgir 34 grener for N100:2023. Målt på disk (`ls ~/repos/vegnormal-okf/build | grep -c '^B-n100-2023-gren-.*-importert$'`) er tallet **40**. N200:2024 = 99 og N500:2024 = 32 stemmer. Tallene over bruker den målte nevneren, ikke ordrens. **Ordrens hypotese bekreftet:** grenformen lukket bundle-siden og gjorde katalogsiden **verre** — 124 942 tokens over 171 grener mot 112 116 over tre flate baser. Etter endringen er hele maksimal-konfigurasjonen 21 448 tokens, altså under en femtedel av ett 128k-vindu. ## 3. Hva som ble endret, og hvorfor akkurat det `list_bundles` returnerte `Bundle.index_summary` — **hele** rot-indeksens body — for **hver** konfigurert base samtidig, pluss ett JSON-objekt per ufulgt kryss-lenke. Begge vokser med korpuset. Prisen på å finne ut *hvilke baser som finnes* ble altså satt av hvor mye de basene *inneholder*. Det er progressiv disclosure snudd på hodet (målbilde §2/§4): katalogen er stigens billigste trinn, og den var loopens dyreste kall. Hver oppføring er nå bundet ved konstruksjon: `id`, en **ordrett prefiks** av indeksbodyen på maks `_CATALOGUE_EXCERPT_CHARS` (200) tegn, `index_truncated`, `documents`, `verdict_count`, `cost_baseline`, `unreachable_links`. Kostnaden er **O(baser), aldri O(korpus)**. **Et premiss ble felt FØR noe ble bygget på det.** «Indeksbodyen forteller en manager 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: `B-n200-2024-gren-1-1-importert/index.md`, 959 bytes, første tegn er `-`). Feltet var altså ikke bare dyrt, det var dyrt **og** innholdsløst der. En avkortet prefiks taper ingenting en manager brukte. Tre valg, hvert med sin begrunnelse: - **Fast vindu, ikke en andel av basen.** En andel ville skalert med korpuset igjen — bare med en mindre konstant. Mutasjon M8 (`body[:len(body)//10]`) er rød mot nettopp den formen. - **Avkorting ANNONSERES, som felt.** `index_truncated` står **ved siden av** utdraget, ikke som en markør limt inn i det — samme grunn som `BudgetExceeded` bærer trippelen sin som felt (kø-(y)): en konsument som må re-parse prosa for å vite om den holder helheten, har fått en diagnostikk den ikke kan handle på. En base som **passer** blir ikke merket avkortet og får hele bodyen — omisjon, aldri en løgn i noen av retningene (M3 og M4 er begge røde, hver sin vei). - **En ufulgt kryss-lenke overlever som ANTALL.** Fakta fra økt 51 («et hopp er tolerert, men ikke lenger taust») står; per-lenke-detaljen blir liggende der den er handlingsbar — på `RunResult.skipped_links` / `DryRunReport.skipped_links` — og rir ikke med i et kall hvis hele jobb er å være billig. Hele indeksen er fortsatt **ett** `read_file(id, "index.md")` unna. Dette er et disclosure-nivå, ikke datatap. ## 4. Gaten Taket (500 tegn per 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 den regresjonen fila finnes for. Syv armer: (a) taket over mange store baser · (b) kostnaden sporer **ikke** korpus-størrelse · (c) katalogen identifiserer fortsatt hver base — anti-vakuitets-armen, uten den består «returner bare id-ene» (a) perfekt · (d) avkorting annonsert, utdraget ordrett, begge retninger · (e) stigen er intakt, hele indeksen er ett kall unna · (f) ufulgte lenker overlever som antall · (g) **kontrollen** — én bases rå indeksbody alene sprenger taket for hele katalogen, så en grønn (a) betyr at bindingen fyrte, ikke at fixturen var liten. **Ni mutasjoner, alle røde mot HELE suiten, hver med sin egen signatur** (grønn kontroll 1066/5): | # | Mutasjon | Røde tester | |---|---|---:| | M1 | ingen binding i det hele tatt (tilbake til hele bodyen) | 4 | | M2 | bundet, men vakuøst (utdraget tømt) | 2 | | M3 | avkorting ikke annonsert (stille kutt) | 1 | | M4 | over-annonsert (en hel indeks meldt avkortet) | 1 | | M5 | per-lenke-lista rir med igjen | 1 | | M6 | det ufulgte faktumet slettet | 1 | | M7 | bundet, men suffiks i stedet for ordrett prefiks | 2 | | M8 | en andel av basen i stedet for et fast vindu | 2 | | M9 | størrelses-signalet (`documents`) gjort konstant | 1 | M9 ble kjørt fordi `documents` var et felt uten gate — et felt ingen test kan se, råtner. ## 5. Grenser, uttalt - **MAJOR-1 (repeterbart `--bundle-dir`) var ikke nødvendig for dette.** Bindingen sitter i verktøykroppen, bak en uendret CLI-flate. Operatørbeslutning 26.08: repeterbart `--bundle-dir` er **nei** — multi-base forblir bibliotek-partisjonen (`run_mandate_across_bundles`). - **`navigate_bundle` kalles fortsatt per base per katalogkall**, altså leses hver fil på disk for å telle dokumenter og dommer. Det er I/O og veggklokke, ikke tokens, og er utenfor denne bestillingen — men det er ikke gratis ved 171 baser, og det er ikke målt her. - **Ingen levende modell har kalt det nye verktøyet.** Formen er bevist offline; at en manager faktisk velger bedre med et utdrag enn med hele indeksen er ikke målt (samme klasse som structured-output-grensen). - **N101 er ikke berørt** — utenfor bestillingen (operatørpresisering 26.08).