1
0
Fork 0

chore(release): 1.5.0

This commit is contained in:
Kjell Tore Guttormsen 2026-10-31 14:28:48 +01:00
commit 3eb8e9e9a9
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
7 changed files with 64 additions and 13 deletions

View file

@ -5,6 +5,52 @@ 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).
## [1.5.0] — 2026-10-31
### Changed — every OWASP number carries the 2026 edition (**filters on the old value lose hits**)
OWASP published the Top 10 for LLM Applications **2026** on 2026-08-04 with a new
order. Only LLM01 and LLM02 kept their meaning. Every `Finding.owasp` up to 1.4.2
was written against 2025, without a year, so it now reads as a different risk.
EchoLeak findings said `LLM05`, which in 2026 means Data and Model Poisoning.
From 1.5.0 every number is written the way OWASP writes it, with the year:
| Finding (examples) | ≤ 1.4.2 | 1.5.0 |
|---|---|---|
| injection lexicon, carriers, entropy, fence, decoded injection | `LLM01` | `LLM01:2026` |
| `egress:*`, `decoded:egress:*` (secret egress) | `LLM02` | `LLM02:2026` |
| `active:*`, neutralize (Improper Output Handling) | `LLM05` | `LLM10:2026` |
| `*:oversize-input`, scan caps (Unbounded Consumption) | `LLM10` | `LLM06:2026` |
**If you filter, route or alert on `owasp`, update the value.** A filter on
`"LLM05"` matches nothing from 1.5.0, and a filter on `"LLM10"` now means a
different risk. `Finding.label`, severities and dispositions are unchanged, so no
detection behaviour moved. Only the catalog field changed. The exported surface is
unchanged: `owasp` was, and is, an optional string.
The number now comes from one table keyed by risk name. The vendored lexicon stays
byte-equal with `llm-security-commons` and gets its year where the finding is made.
A commons number whose meaning moved between editions raises instead of being
relabelled by guesswork.
**Coverage matrix.** The rows map the same way. 14 rows whose class no edition
describes now carry **no number** (`Case.owasp` is `None`, printed `-`):
- the un-scannable artifact failing closed (the guard's own failure semantics);
- four OKF frontmatter parser-surface refusals;
- `resource` URL and cross-link scheme validation of received metadata;
- the five OKF path rows, which carried `LLM01` by default.
The factual-poisoning gap (PoisonedRAG) moves from `LLM09` (Misinformation) to
`LLM05:2026`, whose example 6 is RAG knowledge-base poisoning. 136/136 classes and
6/6 gaps are unchanged.
**Held at zero.** `tests/test_catalog_numbers.py` counts every number in the
tracked files with `docs/catalog-census.py`. It fails on an older or wrong meaning,
and on a missing year anywhere except the vendored lexicon. It also records every
finding the coverage matrix drives and fails on one without the newest year. The
newest edition is read from `docs/threat-2026/catalogs.json`. Row 2 of the 2026
plan went from **95 sites to 0** (frozen denominator at `6702d7a`, unchanged).
## [1.4.2] — 2026-10-29
### Fixed — invisible-character smuggling passed with 0 findings

View file

@ -11,7 +11,7 @@ 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å **v1.4.2** (release-commiten bumper alle levende versjonsflater:
Repoet er på **v1.5.0** (release-commiten bumper alle levende versjonsflater:
`pyproject.toml`, `__init__.py`, README-badge + status + install-pin,
ADOPTION-BRIEF, BRIEF, CHANGELOG-overskrift). NB: v1.4.0-taggen bærer `1.3.0` i
dokumentflatene — dens release-commit daterte bare CHANGELOG-en — og tags
@ -69,6 +69,11 @@ siffer, ZWJ mellom to emoji. En rekke er alltid bærer, og privat bruk fanges he
(operatøren 28.10). Ett predikat (`sanitize._invisible_carriers`) på begge flater.
Leksikonraden for orddeling dømmer leddet sitt med samme predikat, mens regex-en
er byte-lik med commons.
**OWASP-numre (1.5.0):** hvert nummer bærer utgavens årstall (`LLM10:2026`), og
produsentene navngir risikoen, aldri nummeret. Det er én tabell (`_owasp.py`).
Leksikonet får årstallet når det lastes. En klasse som ingen utgave beskriver, får
INGEN nummer (`Case.owasp is None`), for eksempel fail-secure, parserflate og
URL- og sti-validering. `tests/test_catalog_numbers.py` holder tellingen på 0.
Start med `docs/BRIEF.md` for design, `README.md` for bruk, `docs/PLAN.md` for
byggerekkefølgen.

View file

@ -2,7 +2,7 @@
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-1.4.2-blue)
![Version](https://img.shields.io/badge/version-1.5.0-blue)
![Status](https://img.shields.io/badge/status-stable-brightgreen)
![Python](https://img.shields.io/badge/python-3.10%2B-purple)
![License](https://img.shields.io/badge/license-MIT-lightgrey)
@ -33,7 +33,7 @@ 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:** `v1.4.2`. The stdlib-only core — its detector, contract, and
**Status:** `v1.5.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 exported
Python surface is now frozen under semver: nothing exported is removed, renamed or
@ -58,14 +58,14 @@ are real limitations, stated plainly below; read them.
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@v1.4.2"
pip install "llm-ingestion-guard @ git+https://git.fromaitochitta.com/open/llm-ingestion-pipeline-security.git@v1.5.0"
```
Or take a version range from the Forgejo package index, which carries `1.4.2`,
`1.4.1` and `1.1.0` (`1.2.0`–`1.4.0` were never published there):
Or take a version range from the Forgejo package index, which carries `1.5.0`,
`1.4.2`, `1.4.1` and `1.1.0` (`1.2.0`–`1.4.0` were never published there):
```bash
pip install --index-url https://git.fromaitochitta.com/api/packages/open/pypi/simple/ "llm-ingestion-guard>=1.4.2,<2"
pip install --index-url https://git.fromaitochitta.com/api/packages/open/pypi/simple/ "llm-ingestion-guard>=1.5.0,<2"
```
The `open/` mirror is anonymously readable, so CI needs no deploy key, token, or

View file

@ -4,7 +4,7 @@
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:** `v1.4.2`. Stdlib-only core, framework-agnostic. The
**Status of the guard:** `v1.5.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
@ -142,9 +142,9 @@ live payload:
python -m llm_ingestion_guard.coverage # exit 0 = all as documented
```
As of `v1.4.2`: **136 / 136 defended classes demonstrated (recall 100%)** and **6 /
As of `v1.5.0`: **136 / 136 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 (**1049
update). The matrix is the single source of truth for the test suite (**1071
passing**), which also asserts total recall, that every lexicon pattern has a
case (so the matrix cannot fall behind the lexicon), the full LLM02:2026 secret-egress
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*
pipelines — the write-time siblings of query-time chatbot guardrails.**
Status: implemented — v1.4.2, exported surface frozen under semver. This document defines what the repo contains
Status: implemented — v1.5.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).

View file

@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "llm-ingestion-guard"
version = "1.4.2"
version = "1.5.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"

View file

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