1
0
Fork 0

release: 1.0.0 -- the exported Python surface is frozen under semver

Nine current-state surfaces bumped by hand. The classification sweep ran
FIRST, before the first edit: 421 hits on 'v?0.N(.N)' across all tracked
files, each read and sorted current-state vs provenance. Provenance is
untouched -- 'New in v0.4.0', 'measured against 0.3.1', every '0.7.0'
in a code comment or a census candidate name still says what it measured.

The sweep found two surfaces the plan's nine-item list did not name:
README's status BADGE (still 'alpha' -- a version string grep cannot see
it) and ADOPTION-BRIEF's test count, which said 791 against a suite that
runs 792. Both corrected.

pyproject also moves Development Status :: 3 - Alpha -> 5 -
Production/Stable, likewise invisible to a version grep.

CHANGELOG [1.0.0] references [0.3.0] and [0.3.1] for the behaviour
changes rather than repeating them, and carries the freeze point itself:
what is frozen (the exported surface), what is deliberately NOT (all
detection calibration), the three conceded limitations, the one known
open defect (:43), and the runtime-coverage gap -- no external consumer
has run 0.7.0.

No code changed. Per docs/PLAN-v1.md the release gate is the whole suite
green, not a new test: 792 passed, coverage matrix 129/129 + 6/6, exit 0.
This commit is contained in:
Kjell Tore Guttormsen 2026-08-13 22:20:48 +02:00
commit 98ebc07b56
7 changed files with 76 additions and 17 deletions

View file

@ -10,6 +10,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Nothing yet. 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 ## [0.7.0] — 2026-08-13
### Added — `active:raw-html-link`, a click-required carrier class for raw HTML ### Added — `active:raw-html-link`, a click-required carrier class for raw HTML

View file

@ -11,7 +11,9 @@ framework-agnostisk kode.
Referanse-implementasjon: `claude-code-llm-wiki` Stage B (`tools/wiki_ingest/`). Referanse-implementasjon: `claude-code-llm-wiki` Stage B (`tools/wiki_ingest/`).
Lexikon-seed: `injection-patterns.mjs` fra `llm-security`-pluginen. Lexikon-seed: `injection-patterns.mjs` fra `llm-security`-pluginen.
Repoet er på **v0.7 (alpha)**: stdlib-kjernen er bygget og testet (15 moduler + Repoet er på **v1.0.0** — den eksporterte Python-surfacen er frosset under semver
(deteksjonsatferd er det IKKE; kalibrering flytter seg i 1.x). Stdlib-kjernen er
bygget og testet (15 moduler +
topp-nivå wiring, showcase + korpus), inkl. OKF-adapter og aktivt-innhold- topp-nivå wiring, showcase + korpus), inkl. OKF-adapter og aktivt-innhold-
detektor (EchoLeak-klassen) i output-gaten. Mode-b `import_bundle` skanner detektor (EchoLeak-klassen) i output-gaten. Mode-b `import_bundle` skanner
reserverte strukturfiler (`index.md`/`log.md`) i mottatte bundles i stedet for å reserverte strukturfiler (`index.md`/`log.md`) i mottatte bundles i stedet for å

View file

@ -2,8 +2,8 @@
Write-time defensive layer for Python pipelines that persist LLM output: sanitize, fence, tool-less quarantined transform, capability isolation, scan before persist, fail-secure. Write-time defensive layer for Python pipelines that persist LLM output: sanitize, fence, tool-less quarantined transform, capability isolation, scan before persist, fail-secure.
![Version](https://img.shields.io/badge/version-0.7.0-blue) ![Version](https://img.shields.io/badge/version-1.0.0-blue)
![Status](https://img.shields.io/badge/status-alpha-orange) ![Status](https://img.shields.io/badge/status-stable-brightgreen)
![Python](https://img.shields.io/badge/python-3.10%2B-purple) ![Python](https://img.shields.io/badge/python-3.10%2B-purple)
![License](https://img.shields.io/badge/license-MIT-lightgrey) ![License](https://img.shields.io/badge/license-MIT-lightgrey)
@ -33,17 +33,20 @@ at write time, never assumed from the format. Any pipeline ingesting external da
into an agent-read store has this shape; an OKF wiki is its canonical form — which into an agent-read store has this shape; an OKF wiki is its canonical form — which
is why the guard ships a first-class OKF adapter (below). is why the guard ships a first-class OKF adapter (below).
**Status:** `v0.7`, alpha. The stdlib-only core — its detector, contract, and **Status:** `v1.0.0`. The stdlib-only core — its detector, contract, and
OKF-adapter modules plus the top-level wiring — is built and tested, exercised by OKF-adapter modules plus the top-level wiring — is built and tested, exercised by
an end-to-end showcase and adversarial + false-positive corpora. The public API an end-to-end showcase and adversarial + false-positive corpora. The exported
may still change. There are real limitations, stated plainly below; read them. Python surface is now frozen under semver: nothing exported is removed, renamed or
given a different meaning without a `2.0.0`. **Detection behaviour is not frozen**
severities, thresholds and lexicon entries are calibration and move in `1.x`. There
are real limitations, stated plainly below; read them.
## Install ## Install
Not on PyPI. The guard is distributed from its Forgejo origin — pin a release tag: Not on PyPI. The guard is distributed from its Forgejo origin — pin a release tag:
```bash ```bash
pip install "llm-ingestion-guard @ git+https://git.fromaitochitta.com/open/llm-ingestion-pipeline-security.git@v0.7.0" pip install "llm-ingestion-guard @ git+https://git.fromaitochitta.com/open/llm-ingestion-pipeline-security.git@v1.0.0"
``` ```
The `open/` mirror is anonymously readable, so CI needs no deploy key, token, or The `open/` mirror is anonymously readable, so CI needs no deploy key, token, or
@ -65,7 +68,7 @@ pip install -e ".[dev]" && pytest # the whole suite
Two consequences worth knowing before you depend on this: Two consequences worth knowing before you depend on this:
- A git URL is a PEP 508 *direct reference*: it pins one exact tag, not a range - A git URL is a PEP 508 *direct reference*: it pins one exact tag, not a range
like `>=0.2,<0.3`. Real range pinning — and therefore automatic pickup of patch like `>=1.0,<2.0`. Real range pinning — and therefore automatic pickup of patch
releases — arrives with a Forgejo PyPI registry, which becomes the durable releases — arrives with a Forgejo PyPI registry, which becomes the durable
channel at the first patch release or the second downstream consumer, whichever channel at the first patch release or the second downstream consumer, whichever
comes first. The distribution name (`llm-ingestion-guard`) and the version comes first. The distribution name (`llm-ingestion-guard`) and the version

View file

@ -4,9 +4,11 @@
especially one converging on Google's Open Knowledge Format (OKF v0.1) — and needs especially one converging on Google's Open Knowledge Format (OKF v0.1) — and needs
to decide **when** and **where** to add a write-time ingestion guard. to decide **when** and **where** to add a write-time ingestion guard.
**Status of the guard:** `v0.7.0` (alpha). Stdlib-only core, framework-agnostic. **Status of the guard:** `v1.0.0`. Stdlib-only core, framework-agnostic. The
Public API may still change. Read the known-limitations section before you rely exported Python surface is frozen under semver — nothing exported is removed,
on it. renamed or given a different meaning without a `2.0.0`. Detection behaviour is
*not* frozen: severities, thresholds and lexicon entries are calibration and move
in `1.x`. Read the known-limitations section before you rely on it.
This brief is self-contained: you can plan an inclusion from it alone. Every This brief is self-contained: you can plan an inclusion from it alone. Every
technical claim below is checkable against the guard repo (commands given inline). technical claim below is checkable against the guard repo (commands given inline).
@ -140,9 +142,9 @@ live payload:
python -m llm_ingestion_guard.coverage # exit 0 = all as documented python -m llm_ingestion_guard.coverage # exit 0 = all as documented
``` ```
As of `v0.7.0`: **129 / 129 defended classes demonstrated (recall 100%)** and **6 / As of `v1.0.0`: **129 / 129 defended classes demonstrated (recall 100%)** and **6 /
6 documented gaps still hold** (a *closed* gap fails the test, forcing a doc 6 documented gaps still hold** (a *closed* gap fails the test, forcing a doc
update). The matrix is the single source of truth for the test suite (**791 update). The matrix is the single source of truth for the test suite (**792
passing**), which also asserts total recall, that every lexicon pattern has a passing**), which also asserts total recall, that every lexicon pattern has a
case (so the matrix cannot fall behind the lexicon), the full LLM02 secret-egress case (so the matrix cannot fall behind the lexicon), the full LLM02 secret-egress
set, and the container-layer front-end (CSV formula-injection, zip-slip/bomb, set, and the container-layer front-end (CSV formula-injection, zip-slip/bomb,

View file

@ -3,7 +3,7 @@
**A reusable, minimal, dependency-light defensive layer for LLM *ingestion* **A reusable, minimal, dependency-light defensive layer for LLM *ingestion*
pipelines — the write-time siblings of query-time chatbot guardrails.** pipelines — the write-time siblings of query-time chatbot guardrails.**
Status: implemented — v0.7 (alpha). This document defines what the repo contains Status: implemented — v1.0.0, exported surface frozen under semver. This document defines what the repo contains
and why; the stdlib-only core is built and tested (see `README.md` for usage and and why; the stdlib-only core is built and tested (see `README.md` for usage and
`docs/PLAN.md` for the build order). `docs/PLAN.md` for the build order).

View file

@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "llm-ingestion-guard" name = "llm-ingestion-guard"
version = "0.7.0" version = "1.0.0"
description = "Write-time defensive layer for Python pipelines that persist LLM output: sanitize, fence, tool-less quarantined transform, capability isolation, scan before persist, fail-secure." description = "Write-time defensive layer for Python pipelines that persist LLM output: sanitize, fence, tool-less quarantined transform, capability isolation, scan before persist, fail-secure."
readme = "README.md" readme = "README.md"
requires-python = ">=3.10" requires-python = ">=3.10"
@ -12,7 +12,7 @@ license = { file = "LICENSE" }
authors = [{ name = "Kjell Tore Guttormsen" }] authors = [{ name = "Kjell Tore Guttormsen" }]
keywords = ["llm", "security", "prompt-injection", "rag", "ingestion", "guardrails", "write-time"] keywords = ["llm", "security", "prompt-injection", "rag", "ingestion", "guardrails", "write-time"]
classifiers = [ classifiers = [
"Development Status :: 3 - Alpha", "Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers", "Intended Audience :: Developers",
"License :: OSI Approved :: MIT License", "License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",

View file

@ -63,7 +63,7 @@ from .grounding import (
) )
from . import okf from . import okf
__version__ = "0.7.0" __version__ = "1.0.0"
# --- §6 bookends: the two library-side halves around the transform --------- # --- §6 bookends: the two library-side halves around the transform ---------