chore(release): 1.5.0
This commit is contained in:
parent
1c6816cdfe
commit
3eb8e9e9a9
7 changed files with 64 additions and 13 deletions
46
CHANGELOG.md
46
CHANGELOG.md
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
12
README.md
12
README.md
|
|
@ -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.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 ---------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue