# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] Nothing yet. ## [1.0.0] — 2026-08-13 ### Changed — the exported Python surface is frozen under semver No code changed in this release. `1.0.0` is a governance promise, not a claim that the library is finished: **no name exported from `llm_ingestion_guard` is removed, renamed or given a different meaning without a `2.0.0`.** Measured before the tag, the surface has been stable in form since `0.3.4` — four names added, none removed or renamed — while behaviour moved across five releases (`0.4.0` … `0.7.0`). **Detection behaviour is deliberately outside the freeze.** Severities, thresholds, lexicon entries and the dispositions they produce are calibration, and calibration moves in minor and patch releases. A payload that disposes `WARN` here may dispose `FAIL_SECURE` in a later `1.x`; that is a fix, not a break. Assert on the disposition your policy requires, not on a severity you observed. The behaviour changes this freeze rests on are not repeated here — see `[0.3.0]` for the active-content gate and the OKF adapter, and `[0.3.1]` for the ordinary-link/image calibration that the two consumer promises pin. ### Changed — three limitations are conceded for `1.x` rather than deferred `docs/LIMITATIONS.md` no longer says "deferred" or "pending" about any of them: - `Severity` still carries disposition intent on the detection side. Separating *what was seen* from *how bad it is* changes `Finding` and `Severity`, so it is a `2.0.0` change. Read a finding's `id` for the capability. - The input-cap asymmetry at `MAX_INPUT_CHARS` is permanent in `1.x`: surfaces that return content raise `OversizeInputError`, surfaces that return findings truncate and emit `active:oversize-input`. - The multilingual homoglyph false positive is conceded more narrowly — no fix is promised, but it is calibration, so one may land in any `1.x` release. `SECURITY.md` carries all three as documented boundaries and states the support window for a `1.x` line. ### Known at the freeze, deliberately not blocking it `docs/LIMITATIONS.md` §`:43` — an OKF block sequence with exactly one key per element misparses silently in `okf.import_bundle`, so a pointer can ride through in a key the `resource` allowlist never inspects. Closing it tightens what the adapter admits: behaviour, not form, and shippable in a `1.x` minor. It is recorded here because "we knew, and froze first" is a defensible position and "we forgot" is not. Runtime coverage at the freeze: `llm-ingestion-okf` has measured `0.3.4` and run a `0.3.4`→`0.6.1` differential on its own door across two Python versions; `llm-security-commons` differentially tested its independent reconstruction of the raw-HTML classifier against ours over 42 probe tags with 0 disagreements. **No external consumer has run the `0.7.0` runtime**; the four symbols added since `0.3.4` are additive, so a caller that does not invoke them is unaffected. ## [0.7.0] — 2026-08-13 ### Added — `active:raw-html-link`, a click-required carrier class for raw HTML Raw HTML graded on activity alone: every active tag was HIGH. So the *same URL* was LOW as `[t](https://example.com/guide)` and HIGH as `` — an asymmetry produced by syntax, not by affordance. Following an anchor needs a human, exactly like the markdown inline link that has been MEDIUM since 0.3.1. `` and `` now report as **`active:raw-html-link` at MEDIUM**. Everything a renderer fetches or executes unattended keeps `active:raw-html` at HIGH, and the event-handler test runs *first*, so `` is graded as the execute-class carrier it is rather than downgraded with the anchors. The URL-attribute branch deliberately stays on the HIGH side: a name outside the active set has unknown rendering, and `href` is not the only URL attribute it may carry. Grading `` as a link would be reasoning, not measurement. **This is a new label, and labels are a contract surface consumers pin against.** A document that previously produced one `active:raw-html` finding may now produce two findings, one per carrier class. ### Changed — a tag whose whole affordance is a URL it does not carry is inert ``, ``, `