feat(explore): stigen faar sitt manglende trinn - read_bundle gir ETT nivaa, read_dir det neste

S7a-3 pkt. 2. MAJOR-3 bygde read_bundle om fra HELE basen til en oppfoering per
konseptfil. Saa kom det foerste 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. De 478 indeksene ble bygget, konsumert og flatet ut
- agenten saa 629 soesken og fikk aldri vite at korpuset hadde en form.

MAALT (BEFORE og AFTER i samme oekt, samme kode, BEFORE som mutasjon):
  read_bundle-nyttelast  110 581 tegn / 42 761 tok  ->  3 954 tegn / 1 495 tok
  listing-tokens totalt         307 573 (89 %)      ->  12 595 (26 %)
  prompt-tokens i kjoeringen         343 826        ->  49 225   (-86 %)
BEFORE reproduserer S7a-2s publiserte tall til 0,03 % - kjent-positiv kontroll
paa instrumentet, som ogsaa maatte rettes (resultatet baerer name=None, saa en
sonde nøklet paa verktoeynavn rapporterer 0 kopier og leses som en ekte null).

- okf.directory_listing er ENESTE renderer; begge verktoey ER den paa hvert sitt
  nivaa. Kataloger utledes av STIER, aldri av index.md. Bygget av context_files,
  ALDRI files. Hver sti er bundle-relativ, brukbar ordrett i neste kall.
- Ukjent sti NEKTES ved navn (BundlePathNotFound) - en tom listing er umulig aa
  skille fra en katalog som finnes og er tom.
- Verktoeybeskrivelsene og navigatoerinstruksjonen flyttet i SAMME commit.

PREMISS FELT FOER BYGGING: context_files har aldri holdt hierarkiet tilbake -
navnene er fulle bundle-relative stier; det var RENDERINGEN som flatet det ut.
Derfor er bundle_context og begge nav-goldenene byte-identiske, gratis.

AVVIK fra ordren, uttalt: K2 kan ikke vaere testavhengighet (utenfor repoet), og
1 500 tegn er ikke oppnaaelig for en rot med 39 identifiserbare oppfoeringer
(maalt 3 954). Gaten binder 1 500 tegn per listing over basene den KAN se, pluss
egenskapen, med en FLAT kontroll over 5x taket.

Load-bearing MAALT: 9 mutasjoner alle roede mot HELE suiten, groenn kontroll
1252 passed / 5 skipped, golden byte-uendret. N1 4 / N2 7 / N3 12 / N4 5 / N5 1 /
N6 6 / N7 1 / N8 2 / N9 1.

Maaling: docs/2026-09-03-hierarkisk-navigasjon-k2.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-03 07:38:30 +02:00
commit baa6f450e8
8 changed files with 584 additions and 40 deletions

View file

@ -0,0 +1,103 @@
# Hierarkisk navigasjon — målt på den ekte K2-bundelen
**Dato:** 2026-09-03 · **Ordre:** `20260903T034323Z-7704222791` punkt 2 (S7a-3) · **Økt 81**
**Base:** `~/corpora/okf-telling-20260829/K2-bundle-20260903` — 629 konsepter, 478 nestede
indekser, 1 108 filer på disk. Åpnet **slik den er levert** (mulig først etter punkt 1 i samme
ordre; før det nektet `BundleIdMismatch` fordi katalogen heter noe annet enn den erklærte id-en).
## 1. Hva som ble målt, og med hvilket instrument
Instrumentet er S7a-2s rettede sonde: hver prompt telles som **tekst + `function_call` +
`function_result`**, aldri `Message.text` alene (som måler en kontekstbærende prompt til noen få
tegn). Tokenisering: `o200k_base` (`tiktoken`), som er en utviklingsavhengighet i målingen og
**ikke** i pakka.
**Instrumentfeil funnet og rettet under målingen** (samme klasse som S7a-2s midtskive-sonde):
verktøyresultatet bærer `name=None` på transporten, så en sonde som nøkler på
`result:read_bundle` rapporterer **0 kopier** — som er umulig å skille fra en ekte null.
Sonden nøkler nå på resultatets eget INNHOLD (`"directories"`), og BEFORE-kjøringen reproduserer
S7a-2s publiserte tall (307 573 mot 307 496 tokens, 0,03 % avvik), som er den kjent-positive
kontrollen på at instrumentet kan finne det det leter etter.
BEFORE og AFTER er kjørt **i samme økt med samme kode**, der BEFORE er en mutasjon som gir
`read_bundle` den flate MAJOR-3-formen tilbake (mutasjons-harness-idiomet), ikke en historisk
kjøring hentet fra en rapport.
## 2. Resultat
| | BEFORE (flat listing) | AFTER (ett nivå) |
|---|---|---|
| `read_bundle`-nyttelast alene | **110 581 tegn / 42 761 tok** (629 oppføringer) | **3 954 tegn / 1 495 tok** (28 kataloger + 11 dokumenter) |
| Kopier i prompter | 7 | 8 (rot) + 7 (én `read_dir`) |
| Listing-tokens totalt | **307 573** | **12 595** |
| Andel av alle prompt-tokens | **89 %** | **26 %** |
| Prompt-tokens i hele kjøringen | **343 826** | **49 225** |
| Antall prompter | 12 | 13 |
**Utforskningens prompt-tokens faller 86 %** (343 826 → 49 225). `read_bundle`-nyttelasten alene
faller **96,5 %** (42 761 → 1 495 tokens).
**Den 13. prompten er en ærlig kostnad, ikke støy:** navigatøren tar nå ett steg til (`read_dir`
ned i prisskjema-katalogen) før den leser et dokument. Stigen har fått et trinn, og et trinn
koster en tur.
## 3. Premisset som ble felt før noe ble bygget på det
Ordren sier at `context_files` «ikke lenger skal forkaste hierarkiet». **Den har aldri holdt det
tilbake.** Hver `BundleFile.name` er allerede den fulle bundle-relative posix-stien
(`del-ii-bilag-7-prisskjema/prissammenstilling-sheet-1.md`), så treet var alltid utledbart fra
navnene alene. Det som flatet det ut var **renderingen**.
Det er ikke pedanteri — det er grunnen til at `okf.bundle_context` og begge nav-goldenene er
**byte-identiske** etter endringen, som ordren krever eksplisitt. Egenskapen kom gratis, ikke av
forsiktighet.
Kataloger utledes derfor av STIER, aldri av `index.md`-filer: en nestet indeks er navigasjon, ikke
innhold (`context_files` dropper den på hvert nivå, og må fortsette med det, ellers følger
dom-laget med). Utledning fra navn betyr også at en katalog nådd via en lenke som hoppet over
indeksen fortsatt er synlig.
## 4. Avvik fra ordrens ordlyd, målt
Ordren formulerer taket som «`read_bundle` over K2-bundelen < 1 500 tegn». **Begge halvdeler av den
setningen holder ikke, og begge er målt:**
1. **K2 kan ikke være en testavhengighet.** Basen ligger utenfor repoet (`~/corpora/`). MAJOR-3-gaten
hadde samme begrensning og løste den likt: gaten binder den største basen som faktisk shippes,
og K2-tallene bor i en rapport. Gaten her binder derfor `shared/examples/tunnel-hauglia` (flat),
`shared/examples/nav-golden-hierarchy/bundle` (nestet) og en syntetisk base på 242 konsepter bak
20 kataloger — der den FLATE formen er over 5× taket den nivå-formen ligger godt innenfor.
2. **1 500 tegn er ikke oppnåelig for K2s rotnivå, og skal ikke være det.** Rota bærer **39
identifiserbare oppføringer** (28 kataloger + 11 toppdokumenter) og måler **3 954 tegn ≈ 1 366
o200k-tokens** (2,89 tegn/token). Å presse den under 1 500 tegn ville krevd at titler eller
oppføringer ble droppet — repoets vakuøs-gate-klasse. Taket i testen er 1 500 TEGN per listing
over de basene gaten kan se, og egenskapen som produserte fallet er gatet direkte (kostnaden
følger oppføringer på ETT nivå, ikke dokumenter i basen).
## 5. Ærlighets-grenser
- **Dette er ikke «86 % kostnad» for enhver kjøring.** En navigatør som stiger ned *k* nivåer
betaler *k* listinger; gevinsten er at den betaler for det den VALGTE, og at hver listing rir fra
SITT kall og framover.
- **At en LEVENDE modell navigerer BEDRE med en katalogstruktur enn med 629 flate dokumenter er
IKKE bevist** (samme klasse som structured-output-grensen). Manuset er skriptet.
- **Multiplikatoren gjelder dette manuset.** 8 og 7 kopier er hva denne kontrakten og dette
manuset ga; en annen kontrakt gir andre tall.
- **`navigate_bundle` kalles fortsatt per verktøykall** — I/O og veggklokke, ikke tokens; ikke målt
her (samme grense som katalogmålingen i økt 65).
- **Debatten er urørt.** `okf.bundle_context` er byte-identisk, og demo-transkriptet er
byte-uendret (`shasum -a 1` = `ea8c534773acdbe41ae68f2c55724d69aaf8be4f`).
## 6. Kommandoer
```sh
# AFTER
uv run --with tiktoken python scratchpad/s7a3/k2_profile.py after
# BEFORE (patcher kilden, kjører, gjenoppretter)
uv run python scratchpad/s7a3/k2_before.py
# gatens egne tall
uv run python scratchpad/s7a3/measure_sizes.py
```
Kontroll ved slutten av punkt 2: **1 252 passed / 5 skipped**, `ruff` og `mypy` rene, golden
byte-uendret. Ni mutasjoner, alle røde mot HELE suiten (N1N9).