1
0
Fork 0

docs(plan): kill the pointer that sent this session to the wrong section

`PLAN-v1.md`'s Session H block ended with "Neste: Session G", and that line is
a trap two ways over. "Session G" is a WRITTEN section at :231 — and it is
*v1.0 freeze + release*, not the axis separation. No plan section for the axis
separation ever existed; the pointer resolved to this one forward-reference
line. A session following it designs against the wrong section, which is
exactly what this session started doing before measuring the file.

The number was wrong too: 0.4.0 went to the input cap by operator choice, so
the axis separation landed under 0.5.0 instead.

STATE.md is LOCAL-ONLY and gets overwritten every session, so the plan file and
the CHANGELOG are the only durable record. Leaving the line meant the next
session would re-derive the same wrong pointer from the same text.

Also corrects a citation this session nearly propagated: the locked 0.3.1
grading table is at :288-290. `:246-252` is the okf pin discussion, and the
table at :302-309 is the *broken* v0.3.0 one — the row it asserts for an
ordinary image is `fail_secure`, the regression 0.3.1 exists to fix. Citing it
as the baseline would have inverted the check.

Adds the partial-action-map test: every level a caller leaves unnamed must fall
back rather than raise. The existing test passed a complete map, so the
fallback branch had no coverage — and a KeyError there would have been caught
by `guard` and rendered as a fail-closed with a useless reason.

716 passed; matrix 128/128 + 6/6.

Note on the one red seen while landing this: test_output.py's ReDoS wall-clock
budget failed on a loaded run (suite 37s vs 13.9s), then passed alone and in a
clean full run. It asserts `scan_output` under 2.0s, and `output.py` neither
imports `disposition` nor references it in code — its three mentions are
docstring prose — so this change cannot reach that timing. Load, as STATE
documents, not a regression.
This commit is contained in:
Kjell Tore Guttormsen 2026-08-10 21:01:19 +02:00
commit 398eb7407b
2 changed files with 31 additions and 1 deletions

View file

@ -291,7 +291,21 @@ Nøkkelantakelser (+ test) · Verifisering. Testkommando alltid:
> (128/128 recall, 6/6 gap holder), anonym ren-venv-install av `@v0.3.1` verifisert.
> Nye residualer skrevet inn i `docs/LIMITATIONS.md` (beaconing, kort opak URL-del,
> percent-escape-FP) og asserteres av matrisen. Alle 7 varslede repo har fått MÅLINGENE.
> **Neste: Session G.** 0.4.0 er akse-separasjon (deteksjon ≠ disposisjon), ikke ny preset.
> **Neste: akse-separasjonen** (deteksjon ≠ disposisjon), ikke ny preset.
>
> **RETTET 2026-08-10 — denne linja sa «Neste: Session G» og var en felle.**
> «Session G» er en skrevet seksjon lenger opp (`:231`) og den er *v1.0 freeze +
> release* — noe helt annet. Det fantes ALDRI en skrevet plan-seksjon for
> akse-separasjonen; pekeren traff denne ene framoverlinja, og en økt som fulgte
> den ville designet mot feil seksjon. Tallet ble heller ikke 0.4.0: **0.4.0 gikk
> til input-cappen (operatørvalg 08-10), og akse-separasjonen landet som del av
> 0.5.0-arbeidet.** Den er nå BYGD og committet — se `CHANGELOG.md`
> `[Unreleased]` for hva den faktisk ble (`Risk`-aksen, `Policy.action_map`,
> `DispositionResult.assessment`), målt additiv: 703 → 715 tester uten at én
> eksisterende test ble endret, matrise 128/128 + 6/6, og `PRESET_USER_UPLOAD`-
> tabellen på `:288-290` re-målt rad for rad uendret. **Begge låste løfter under
> `:370` ble målt mot det og fyrer IKKE.** 0.5.0 er ikke tagget: taggen venter på
> en release-commit som bærer alle fem versjonsflater samtidig.
- **Mål:** gjøre den utrustede upload-stien brukbar igjen uten å miste EchoLeak-
deteksjonen, og lukke testgatens blindfelt som slapp regresjonen forbi 522 grønne tester.

View file

@ -334,6 +334,22 @@ def test_custom_action_map_changes_the_action_not_the_assessment():
assert decide(report, lenient).assessment is Risk.SEVERE
def test_partial_action_map_falls_back_per_level():
# A partial override is a likely way to reach for this, so the levels left
# unnamed must fall back rather than raise. A KeyError here would be caught
# by `guard` and turned into a fail-closed — silently, with a useless reason.
policy = Policy(trust=Trust.UNTRUSTED,
action_map={Risk.SEVERE: Disposition.QUARANTINE_REVIEW})
severe = decide(_report(_finding(severity=Severity.HIGH)), policy)
elevated = decide(_report(_finding(severity=Severity.MEDIUM)), policy)
assert severe.assessment is Risk.SEVERE
assert severe.disposition is Disposition.QUARANTINE_REVIEW # overridden
assert elevated.assessment is Risk.ELEVATED
assert elevated.disposition is Disposition.QUARANTINE_REVIEW # defaulted
def test_overlays_escalate_the_assessment_not_only_the_action():
# Compound escalation and the quarantine floor are assessment-level moves;
# if they only moved the action, a custom action_map would silently drop