1
0
Fork 0

docs(readme,limitations): stop advertising a version that was not chosen

LIMITATIONS said "Since 0.3.5" and the README stated the new refusal in present
tense under a 0.3.4 badge and a @v0.3.4 install pin. Both are on the public
mirror, and both contradict the same commit's CHANGELOG ("the version this lands
under is not yet decided") and what we told llm-ingestion-okf an hour earlier:
no tag until they answer.

A reader installing the advertised pin would get a library that does not do what
the README says. Same failure the clean-venv rule already covers for tags —
extended to behaviour.

Also fixes a test that passed for the wrong reason: `"101" not in details` is
tuple membership over ("sanitize",), trivially true, and would stay true if a
size were ever folded into the string. Now a substring check, matching the
canary assertion two lines above it.
This commit is contained in:
Kjell Tore Guttormsen 2026-08-02 21:21:21 +02:00
commit 0add3e7e96
3 changed files with 11 additions and 5 deletions

View file

@ -90,9 +90,11 @@ the disposition is `FAIL_SECURE`, never a silent persist. Pass
together with a transform failure is treated as a probable forced-fallback attack
and halts regardless of trust tier.
`prepare_input` fails **closed** on size too: above `MAX_INPUT_CHARS`
(1 000 000) it raises `OversizeInputError`, a `ContractViolation` subclass, rather
than returning a half-sanitized document. The scanners bound their work by
**Unreleased — on `main`, not in `v0.3.4`.** The tag advertised above does not do
this yet; the version it lands under is still open. `prepare_input` fails
**closed** on size too: above `MAX_INPUT_CHARS` (1 000 000) it raises
`OversizeInputError`, a `ContractViolation` subclass, rather than returning a
half-sanitized document. The scanners bound their work by
reading a prefix and flagging, which costs only detection in the tail; a
transform returns *content*, where the same move would either drop your data
silently or hand back an untransformed tail — the exact place an attacker would

View file

@ -303,7 +303,8 @@ items; this is the full list, each with the mechanism.
at all.
- **Two detection surfaces still accept unbounded input; the transform surfaces
no longer do.** Since 0.3.5 `sanitize`, `fence` and `neutralize` raise
no longer do.** Unreleased, on `main` at `2d98d68`: `sanitize`, `fence` and
`neutralize` raise
`OversizeInputError` above `MAX_INPUT_CHARS` (1 000 000) rather than returning
a partially transformed document, which bounds the whole input path — `sanitize`
is step 1 of `prepare_input`, and it only ever removes, so everything after it

View file

@ -63,7 +63,10 @@ def test_error_carries_sizes_never_content(name, call):
call(secret * 100, 100)
assert secret not in str(exc.value)
assert not any(secret in d for d in exc.value.details)
assert "101" not in exc.value.details # details name the surface, not sizes
# Substring, not tuple membership: `details` is ("sanitize",), so `"101" not
# in details` would pass trivially and keep passing if a size were ever
# folded into the string.
assert not any("101" in d for d in exc.value.details)
assert name in exc.value.details