1
0
Fork 0

docs(pdf): concede .pdf as a deliberate design boundary (Session F1)

Reframe .pdf from a 'known gap'/TODO to a deliberate concession across the
honest-limits and OKF-upload docs. A top-level .pdf drop is already refused as
an unsupported format (inbox_frontend.py raises on the else branch), not
half-scanned; adding a PDF parser + reportlab (solely to author white-on-white
test fixtures) is disproportionate for a dev-scoped showcase, and the OCR /
font-render stego carriers a PDF would smuggle are out of scope regardless.

- README honest-limits: .pdf = concession, not TODO; only the numeric CSV FP
  remains a known gap.
- docs/PLAN.md: upload table .pdf row marked 'conceded'; honest-scope paragraph
  names .pdf; assertions tightened to 'every accepted format'.

Closes the last format gap before v1.0 freeze (Session G). No code touched;
357 tests green.
This commit is contained in:
Kjell Tore Guttormsen 2026-07-15 10:15:39 +02:00
commit 66f3cbf4f5
2 changed files with 15 additions and 7 deletions

View file

@ -172,9 +172,13 @@ that a green scan means safe content:
needing OCR, font/render steganography, and encrypted / password-protected files
— the binary layer needs a separate scanner. The front-end owns the container
threats it *can* see (zip-slip → path gate, zip-bomb → size cap, symlink
refusal, CSV/XLSX formula-lead cells). Known gaps: `.pdf` extraction, and the
numeric `-`/`+` CSV false positive (an XLSX numeric cell is typed, so it does not
trip the gate).
refusal, CSV/XLSX formula-lead cells). **`.pdf` is a deliberate concession, not a
TODO:** a top-level `.pdf` drop is *refused as an unsupported format* rather than
half-scanned, because a PDF parser (plus `reportlab` solely to author white-on-white
test fixtures) is disproportionate for a dev-scoped showcase, and the OCR /
font-render stego carriers a PDF would smuggle are already out of scope above. The
one remaining known gap is the numeric `-`/`+` CSV false positive (an XLSX numeric
cell is typed, so it does not trip the gate).
- **Lexicon findings are deduplicated by pattern id**`count=1` and the first
offset are reported, so the same class matched across several channels/variants
collapses to one finding at its first location. This keeps reports readable, but