feat(ingest): P2/S1.b — innholdsgaten står, rundt materialize og ikke i den
Planens §3 sa at `ingest.materialize` er repoets ENE skrivepunkt på Door A, og det premisset ble felt av måling FØR bygging: `materialize` er en ren delegasjon til pinnet 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 der kunne bare kjørt ETTER at bytene landet — en opprydding, ikke en gate. Sømmen ble i stedet kopier bundelen → materialiser inn i kopien → skann det som ble generert → publiser eller forkast. Kopien er bærende, ikke bekvemmelighet: bibliotekets §3 eierskaps-skann, kollisjonsgaten mot kuratert innhold og §6 index-merge leser alle den EKSISTERENDE bundelen. Staging i tom katalog mister alle tre og publiserer en bundle uten kuraterte naboer — datatap forkledd som sikkerhetsfiks. De fire §4-beslutningene, tatt og målt: (1) ingen av guardens to preset — Origin.EXTERNAL/AUTOMATIC, fordi trust_for utleder policy fra origin alene og PRESET_USER_UPLOAD bærer en quarantine-semantikk Door A ikke har; (2) 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; (3) Report til log.md, aldri konsept-frontmatter, der fire golden-suiter pinner bytene; (4) mypy-override OG adapter, siden override alene gjør sømmen type-blind i stedet for type-sikker. `materialize` forblir ugatet med vilje — goldenene pinner den, og en kaller som vil ha gaten ber om den ved navn. Fem mutasjoner alle røde + grønn kontroll (hele suiten, ~120 s hver): 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 trust-tierene, så Origin.INTERNAL-mutasjonen lot alle tre avvisningstestene stå grønne — beslutning 1 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 før mutasjonen ble re-målt. Mutasjon 4 ble på sin side felt av KUN én test; 809 andre merket ikke at bundle-kopien forsvant. Laveste disposition er `warn`, ikke `allow` — `allow` finnes ikke i guarden. En gate skrevet mot == allow ville avvist hvert dokument som noensinne ingestes. Kriterium 5 står: demo-stdout er byte-identisk med tests/golden/demo-transcript.stdout, målt både i suiten og ved eksplisitt kjøring. shared/ er urørt. 801 -> 810 passed / 4 skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDu94KoyxAmhJsG2n63X8Q
This commit is contained in:
parent
50232fb88d
commit
c255662802
8 changed files with 575 additions and 9 deletions
|
|
@ -1,5 +1,18 @@
|
|||
# Inkluderingsplan — `llm-ingestion-guard` som write-time persist-gate
|
||||
|
||||
> **⚠️ UTDATERT PÅ TO PUNKTER — REALISERT 2026-08-09 av
|
||||
> [innholdsgate-planen](2026-08-09-innholdsgate-og-aerlighet.md) (P2/S1.b).** Dokumentet beholdes
|
||||
> som kartleggingen den var; disse to påstandene skal IKKE leses som gjeldende:
|
||||
>
|
||||
> 1. **«Guard-modenhet: `v0.2` (alpha)» er FEIL** (målt 2026-08-09: syv publiserte tagger, siste
|
||||
> `v0.3.4`, `dependencies = []`). Det premisset gjorde adopsjonen urimelig risikabel og er
|
||||
> grunnen til at innholdsgate-planen ble skrevet. Adoptert pin: `v0.3.4`.
|
||||
> 2. **Gate-plasseringen i denne planen er FEIL.** Den plasserer gaten i `ingest.materialize`,
|
||||
> «repoets ene skrivepunkt». Målt er `materialize` en ren delegasjon til det pinnede
|
||||
> `llm_ingestion_okf`-bibliotekets `materialize_bundle`, som stager i minnet og skriver selv —
|
||||
> ingen callback mellom staging og disk. Gaten bor derfor i `materialize_gated`
|
||||
> (kopi → materialiser → skann → publiser eller avvis), ikke der denne planen sier.
|
||||
>
|
||||
> **Status:** PLAN (ikke implementert). Denne økta KARTLA repoets untrusted-ingest og la denne
|
||||
> planen; guarden er IKKE wiret inn ennå (per adopsjons-briefens §7: «kun planlegg og oppdater
|
||||
> planene»). Utløst av konsument-inkluderings-prompten fra `llm-ingestion-pipeline-security`.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,70 @@
|
|||
# Innholdsgate og ærlighet — plan fram til demoen 13. august
|
||||
|
||||
> ## ✅ SPOR B LANDET 2026-08-09 — alle seks kriterier grønne
|
||||
>
|
||||
> `materialize_gated` i `src/portfolio_optimiser/ingest.py`; gate-pin `v0.3.4`.
|
||||
> **801 → 810 tester.** Fem mutasjoner målt røde mot HELE suiten + grønn kontroll.
|
||||
>
|
||||
> **§3s premiss var FEIL, og målingen felte det før byggingen.** Planen plasserer gaten i
|
||||
> `ingest.materialize`, «repoets ENE skrivepunkt på Door A». Målt er `materialize` 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. **Ingen callback finnes mellom de to** — en gate plassert
|
||||
> der kunne bare kjørt ETTER at bytene hadde landet, altså en opprydding, ikke en gate.
|
||||
> Sømmen ble i stedet: **kopier bundelen → materialiser inn i kopien → skann det som ble
|
||||
> generert → publiser eller forkast.**
|
||||
>
|
||||
> **Kopien er bærende, ikke bekvemmelighet.** Bibliotekets §3 eierskaps-skann, kollisjons-gaten mot
|
||||
> kuratert innhold og §6 index-merge leser ALLE den EKSISTERENDE bundelen. Staging i en tom
|
||||
> temp-katalog ville mistet alle tre og publisert en bundle uten kuraterte naboer og deres
|
||||
> index-lenker — et datatapsbug forkledd som en sikkerhetsfiks. Mutasjon 4 beviser det.
|
||||
>
|
||||
> ### De fire beslutningene i §4, tatt og målt
|
||||
>
|
||||
> | # | Beslutning | Utfall | Begrunnelse |
|
||||
> |---|---|---|---|
|
||||
> | 1 | Policy-preset | **Ingen av dem** — `Origin.EXTERNAL` + `Channel.AUTOMATIC` | `import_bundle` tar ikke et preset; `trust_for` utleder policy fra origin alene. `PRESET_USER_UPLOAD` bærer `quarantine_default=True` (opplastings-semantikk Door A ikke har); `PRESET_TRUSTED_SOURCE` gir en tier en manifest-navngitt ekstern kilde ikke har fortjent |
|
||||
> | 2 | Fail-closed, per dokument eller per bundle | **Utfall per BUNDLE, diagnostikk per DOKUMENT** | `materialize_bundle` er allerede alt-eller-ingenting per manifest — den sletter hver stemplet fil og regenererer `index.md`. Delvis publisering ville etterlatt en bundle + index som svarer til INTET manifest. Planens motargument («ett av femti avvist gir en halv bundle») er argumentet FOR: per-bundle gir ingen halv bundle. `import_bundle` itererer likevel forbi første avvisning, så visibiliteten taper ingenting |
|
||||
> | 3 | Hvor havner `Report` | **`log.md` (OKF §7), ALDRI konsept-frontmatter** | Konseptbytene er det pinnede bibliotekets, og fire golden-suiter pinner dem. Et gate-felt i frontmatter ville brutt alle fire. `test_gated_output_is_byte_identical_to_ungated_materialize` er vakten som holder det ute |
|
||||
> | 4 | `mypy --strict` over sømmen | **Override OG adapter**, som planen krevde | Override alene gjør sømmen type-BLIND, ikke type-sikker: alt ankommer som `Any`. `_stamp_line` + koersering i `verdicts` stopper `Any` ved grensen |
|
||||
>
|
||||
> ### Kriterier (§6)
|
||||
>
|
||||
> 1. `uv sync` grønn; `llm_ingestion_guard.__version__` → **`0.3.4`** ✅
|
||||
> 2. Load-bearing-test grønn; **fem** mutasjoner røde (planen krevde tre) + kontroll ✅
|
||||
> 3. `uv run pytest -q` grønn, antall **økt 801 → 810** ✅
|
||||
> 4. `ruff check` + `ruff format --check` + `mypy src` rene ✅
|
||||
> 5. **Demo-stdout BYTE-IDENTISK med `tests/golden/demo-transcript.stdout`** ✅ — gaten lekket ikke
|
||||
> inn i det som fryses. Målt både av golden-testen i suiten og ved eksplisitt kjøring
|
||||
> 6. `git diff --stat shared/` tomt ✅
|
||||
>
|
||||
> ### Mutasjons-manifest (alle mot HELE suiten, ~120 s hver)
|
||||
>
|
||||
> | # | Mutasjon | Utfall |
|
||||
> |---|---|---|
|
||||
> | 1 | Detach gate-kallet (`if False`) | 🔴 4 tester |
|
||||
> | 2 | Gaten fyrer ETTER publisering (advarsel, ikke gate) | 🔴 3 tester |
|
||||
> | 3 | `Origin.INTERNAL` som default | 🔴 2 tester |
|
||||
> | 4 | Staging i TOM katalog i stedet for kopi | 🔴 1 test — og KUN den; 809 andre merket ingenting |
|
||||
> | 5 | Rapporter kun FØRSTE avviste dokument | 🔴 1 test |
|
||||
> | — | **Kontroll: urørt kode** | 🟢 810 passed / 4 skipped |
|
||||
>
|
||||
> **Lærdom — mutasjon 3 avslørte en vakuøs test, og rettelsen kom av å måle.** Første kjøring av
|
||||
> mutasjon 3 felte KUN logg-testen; alle tre avvisnings-testene forble GRØNNE. Årsak: en hard
|
||||
> injeksjon scorer `fail_secure` under BEGGE trust-tierene, så beslutning 1 så dekket ut uten å
|
||||
> være testet. Målingen fant båndet der tieren faktisk avgjør — et høy-entropi-innhold gir
|
||||
> `quarantine_review` under EXTERNAL og `warn` under INTERNAL — og
|
||||
> `test_external_origin_refuses_what_internal_would_publish` (med trusted-kontroll) ble skrevet
|
||||
> mot nøyaktig det. Uten den re-målingen ville §4-beslutning 1 stått ubevist bak en grønn suite.
|
||||
>
|
||||
> **Lærdom 2 — den lave dispositionen er `warn`, ikke `allow`.** Et RENT konsept scorer `warn`;
|
||||
> `Disposition` er `warn < quarantine_review < fail_secure`, og noe `allow` finnes ikke. En gate
|
||||
> skrevet mot `== allow` ville avvist hvert dokument som noensinne ingestes. Kontroll-testen er
|
||||
> det som fanger den klassen.
|
||||
>
|
||||
> **§5-ærlighetsavsnittet: bruk JA-varianten.** Gaten er landet, så setningen som leses på scenen
|
||||
> er «ingest-veien skanner nå innholdet før det skrives, med en egen sikkerhetskomponent».
|
||||
> P1 og P3 (håndkuratert bundle, ingen generisk fabrikk) er UENDRET ærlighets-punkter.
|
||||
|
||||
> **Utløser.** Demoen viser «last ned → kjør». Sier vi, eller antyder vi, at man kan peke systemet
|
||||
> mot sine egne kilder og bygge en kunnskapsbase, påstår vi noe koden ikke bærer. Det er A5-brudd i
|
||||
> muntlig form — koden får ikke påstå mer enn den gjør, og det gjelder også presentatøren.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue