portfolio-optimiser/examples/nav-golden-escape
Kjell Tore Guttormsen 8a86f2ab6d Squashed 'shared/' changes from 7aa53fc..a2b57d2
a2b57d2 docs(plan): V1 — «de 5 linjene» var ikke homogene; :214 er ikke en literal
d63e45d docs(plan): okf-versjonssjekken utført — hypotesen falsifisert på to stale premisser
ef31dda docs(plan): V1 §4.2 — pin + id + sitering avgjort, og ratifiseringsgaten funnet
35220f7 docs(plan): V1 §4.1 — serialiseringsformen er bundet av :158, så 6 sider er invariant
8a7d430 docs(plan): operatøren avgjorde V1 (O2) og B1 (O1) — B1 utført, V1 gated
f306c7b docs(plan): V1 §5.1 — konsument-kostnaden målt @ 8a14137, O3-raden priset
ab0ea8f docs(plan): innboksrunden — V1 utvidet med tre målte funn, §7.2-siteringen ref-bundet
84a3010 docs(plan): §7.2 — MCP-spørsmålet er avgjort av frossen tekst, S2.2 og S2.4 er ugated
e984d51 docs(plan): D-B ankret, D-A#3s årsak er repo-avhengig, V1 utvidet med oppstrøms-evidens
3de702b docs(plan): V1 §6 — rekkevidde-forbeholdet korrigert, og funnet under funnet
249425b docs(plan): amendment-underlag — D-A#3s ÅRSAK rettet, drift ikke avvik
4876970 docs(plan): V1-underlag — generated-feltets form etter OKF v0.2
3f18ca7 docs(plan): B1/D4 operator question — nav-golden's normative status, four costed options
29ad8ca docs(plan): amendment-underlag — frossen tekst per køpunkt, med målt fasit-effekt
a67a243 docs(plan): ordering-axes ruling — three distinct axes, as an interpretation record
381d9e5 docs(plan): guard adoption plan pins no version — v0.2 header was stale
54ca0ff docs(plan): D3 ratified — status vocabulary landed in coord register
fe6b998 docs(plan): D3 status vocabulary — canonical 7-token set for roll-up register
c66ccc3 docs(plan): D2 register-form fix — two-output model resolves ÅS#5
b641741 docs(examples): nav-golden fixture class — bundle → read-context goldens
9801d35 docs(spec): method-spec §3 Step 1 — Q3 navigation contract (hierarchy)
bfa5a9b docs(spec): ingest-spec — land ratified D1 stamp model
5f046ab docs(plan): Q3 finding — method-spec §3 silently forbids hierarchical bundles
a013e8b docs(plan): F1 direction — free-text sources belong in ingest-spec door A
84191c6 docs(plan): record commons↔implementation-repo coordination boundary
cae9972 docs(plan): llm-ingestion-guard adoption — planned at future untrusted ingest boundaries

git-subtree-dir: shared
git-subtree-split: a2b57d20fc0953c19776c21ce1311f234386a590
2026-07-31 18:37:48 +02:00
..
bundle Squashed 'shared/' changes from 7aa53fc..a2b57d2 2026-07-31 18:37:48 +02:00
expected-read-context.md Squashed 'shared/' changes from 7aa53fc..a2b57d2 2026-07-31 18:37:48 +02:00
README.md Squashed 'shared/' changes from 7aa53fc..a2b57d2 2026-07-31 18:37:48 +02:00
SHOULD-NOT-BE-READ.md Squashed 'shared/' changes from 7aa53fc..a2b57d2 2026-07-31 18:37:48 +02:00

nav-golden-escape — negative navigation golden (the gate must be able to go red)

Per catalog's requirement that step 0's gate must be able to fail (a gate that can only pass proves nothing), this negative case makes a conformant navigator and a naive one provably diverge. It is the counterpart to nav-golden-hierarchy (the positive case).

bundle/index.md links one valid sibling and three escaping / trap targets:

Link Class Conformant outcome
valid.md in-bundle returned
../SHOULD-NOT-BE-READ.md .. escape (the decoy really exists, one level up) skipped; decoy never read
../../../../etc/passwd deep .. escape skipped
/etc/passwd root-relative trap skipped

The trap is the load-bearing one. Under the ratified rule, a leading / denotes the bundle root, so /etc/passwd resolves to {bundle}/etc/passwd (no such file → skip), NOT the filesystem path. A naive implementation that reads / as filesystem-absolute opens the real /etc/passwd — a path-traversal breach. This case fails for any implementation that raises, reads the decoy, or leaks /etc/passwd content; it passes only when the read-context is exactly valid.md.

The malformed-target sub-class (an embedded null byte, other invalid path components) is covered by the method-spec §11 Navigation boundary seam as a unit test — a literal null byte does not belong in a committed text fixture. (See the relocated finding docs/plan/2026-07-20-funn-portfolio-optimiser-nullbyte.local.md for the concrete null-byte reproduction that motivates the seam.)