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:
parent
e9d8fb2b9d
commit
98ebc07b56
7 changed files with 76 additions and 17 deletions
52
CHANGELOG.md
52
CHANGELOG.md
|
|
@ -10,6 +10,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
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
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ framework-agnostisk kode.
|
|||
Referanse-implementasjon: `claude-code-llm-wiki` Stage B (`tools/wiki_ingest/`).
|
||||
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-
|
||||
detektor (EchoLeak-klassen) i output-gaten. Mode-b `import_bundle` skanner
|
||||
reserverte strukturfiler (`index.md`/`log.md`) i mottatte bundles i stedet for å
|
||||
|
|
|
|||
17
README.md
17
README.md
|
|
@ -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.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
|
|
@ -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
|
||||
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
|
||||
an end-to-end showcase and adversarial + false-positive corpora. The public API
|
||||
may still change. There are real limitations, stated plainly below; read them.
|
||||
an end-to-end showcase and adversarial + false-positive corpora. The exported
|
||||
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
|
||||
|
||||
Not on PyPI. The guard is distributed from its Forgejo origin — pin a release tag:
|
||||
|
||||
```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
|
||||
|
|
@ -65,7 +68,7 @@ pip install -e ".[dev]" && pytest # the whole suite
|
|||
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
|
||||
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
|
||||
channel at the first patch release or the second downstream consumer, whichever
|
||||
comes first. The distribution name (`llm-ingestion-guard`) and the version
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@
|
|||
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.
|
||||
|
||||
**Status of the guard:** `v0.7.0` (alpha). Stdlib-only core, framework-agnostic.
|
||||
Public API may still change. Read the known-limitations section before you rely
|
||||
on it.
|
||||
**Status of the guard:** `v1.0.0`. Stdlib-only core, framework-agnostic. The
|
||||
exported Python surface is 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`. Read the known-limitations section before you rely on it.
|
||||
|
||||
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).
|
||||
|
|
@ -140,9 +142,9 @@ live payload:
|
|||
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
|
||||
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
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
**A reusable, minimal, dependency-light defensive layer for LLM *ingestion*
|
||||
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
|
||||
`docs/PLAN.md` for the build order).
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||
|
||||
[project]
|
||||
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."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
|
|
@ -12,7 +12,7 @@ license = { file = "LICENSE" }
|
|||
authors = [{ name = "Kjell Tore Guttormsen" }]
|
||||
keywords = ["llm", "security", "prompt-injection", "rag", "ingestion", "guardrails", "write-time"]
|
||||
classifiers = [
|
||||
"Development Status :: 3 - Alpha",
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Programming Language :: Python :: 3",
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ from .grounding import (
|
|||
)
|
||||
from . import okf
|
||||
|
||||
__version__ = "0.7.0"
|
||||
__version__ = "1.0.0"
|
||||
|
||||
|
||||
# --- §6 bookends: the two library-side halves around the transform ---------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue