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

@ -1529,6 +1529,54 @@ Python ≥3.10. MAF (`agent-framework-core` 1.16.0, `-orchestrations` 1.1.1 —
rekkefølge, urørt); 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. 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`.
- **STATE.md er local-only** (gitignored). Voyage session-state er efemert; STATE.md er kanonisk kontinuitet.
- Prosess: Voyage-plugin (`/trekbrief → /trekplan → /trekexecute → /trekreview`) per større fase.