1
0
Fork 0

docs: finish the 1.4.0 release on the doc surfaces

The 1.4.0 release commit (d19de8c) dated the CHANGELOG heading and nothing
else, so the tag went out with README, ADOPTION-BRIEF and BRIEF still
naming 1.3.0 and the install pin still installing 1.3.0. This bumps the
badge, status line and install pin in README, the status and "as of"
lines in ADOPTION-BRIEF (test count 868 -> 893) and BRIEF's status line.
The tag itself is not moved.

Three claims that went false earlier are corrected against the code:

- README said `resource` is deliberately not on the frontmatter allowlist
  and that a `sources` block list of mappings is refused. Both stopped
  being true in 1.3.0. The paragraph now names the four mapping carriers
  and says `resource` / `usage_window` are admitted inside a `sources`
  entry only.
- README described the `resource` https-allowlist without its scope. It
  covers the top-level `resource` only; `sources[].resource` is never
  URL-validated (measured: `javascript:` there imports with no error).
- LIMITATIONS still listed `tags: [a, b]` among the routes that fail.
  It parses since 1.4.0.

Gates after the edit: 893 passed, coverage exit 0, redos-sweep exit 0,
45 LIMITATIONS entries.
This commit is contained in:
Kjell Tore Guttormsen 2026-09-23 12:25:33 +02:00
commit 79285e1265
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
5 changed files with 30 additions and 25 deletions

View file

@ -11,11 +11,10 @@ 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å **v1.4.0 i koden, UUTGITT** (`pyproject.toml` + `__init__.py` er Repoet er på **v1.4.0, tagget og pushet** (`d19de8c`). Release-commiten daterte
bumpet; README-badge, install-pinnen, ADOPTION-BRIEF og BRIEF står med vilje bare CHANGELOG-en; de fire dokumentflatene (README-badge + install-pin,
igjen på `1.3.0`, som er den siste taggen som FINNES — en install-pin må peke på ADOPTION-BRIEF, BRIEF) ble bumpet i en egen docs-commit etterpå — taggen selv
en ekte tag). Release-commiten (CHANGELOG-overskrift datert, de fire bærer fortsatt `1.3.0` i de flatene, og tags flyttes aldri. Den eksporterte Python-surfacen er frosset under semver
dokumentflatene bumpet, tag) er ikke tatt. Den eksporterte Python-surfacen er frosset under semver
(deteksjonsatferd er det IKKE; kalibrering flytter seg i 1.x). Stdlib-kjernen er (deteksjonsatferd er det IKKE; kalibrering flytter seg i 1.x). Stdlib-kjernen er
bygget og testet (15 moduler + 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-

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. 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.3.0-blue) ![Version](https://img.shields.io/badge/version-1.4.0-blue)
![Status](https://img.shields.io/badge/status-stable-brightgreen) ![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,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 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:** `v1.3.0`. The stdlib-only core — its detector, contract, and **Status:** `v1.4.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 exported 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 Python surface is now frozen under semver: nothing exported is removed, renamed or
@ -58,7 +58,7 @@ are real limitations, stated plainly below; read them.
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@v1.3.0" pip install "llm-ingestion-guard @ git+https://git.fromaitochitta.com/open/llm-ingestion-pipeline-security.git@v1.4.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
@ -165,20 +165,26 @@ Per-concept gates: **path / reserved-name** (rejects `..` traversal and reserved
reject-by-default loader that refuses anchors, aliases, and explicit tags *by reject-by-default loader that refuses anchors, aliases, and explicit tags *by
construction*, so a billion-laughs alias expansion or a `!!python/object` coercion construction*, so a billion-laughs alias expansion or a `!!python/object` coercion
cannot occur (it is deliberately **not** a general YAML engine, whose own features cannot occur (it is deliberately **not** a general YAML engine, whose own features
are the attack surface). The one mapping form it accepts is OKF v0.2's flow are the attack surface). A mapping has four carriers: the flow mapping as a value
mapping — `generated: { by: x, at: y }`, `verified: { … }` bare or listed, (`generated: { by: x, at: y }`) or as a block-list item, a flow sequence of flow
`usage_window: { from: …, to: … }` — admitted key-by-key against a nine-name mappings (`sources: [{ id: a, resource: x }]`), and a block sequence of block
allowlist (`by`, `at`, `from`, `to`, `id`, `title`, `author`, `usage_count`, mappings (SPEC §5.1's own form). Every carrier is admitted key-by-key against a
`last_modified`) with plain-scalar leaves only. A key off that list, a nested nine-name allowlist (`by`, `at`, `from`, `to`, `id`, `title`, `author`,
collection or a duplicate key is refused, and `resource` is deliberately not on `usage_count`, `last_modified`) with plain-scalar leaves only; `resource` and
it; the block, dotted and inline-colon routes to a mapping still raise. A `usage_window` are admitted *inside a `sources` entry only*, so an `executor` or
`attester` `resource` is refused through every carrier. A key off that list, a
nested collection or a duplicate key is refused; a top-level block mapping and
the dotted and inline-colon routes to a mapping still raise. A
*sequence* value has two carriers — the block list, and (as of `1.4.0`) the flow *sequence* value has two carriers — the block list, and (as of `1.4.0`) the flow
sequence `tags: [a, b, c]`, which is SPEC §4.1's own skeleton — whose elements sequence `tags: [a, b, c]`, which is SPEC §4.1's own skeleton — whose elements
are either all plain scalars or all flow mappings, never a mix. A scalar element are either all plain scalars or all flow mappings, never a mix. A scalar element
carrying any of `{ } [ ] : , " ' #` is refused rather than guessed at. See carrying any of `{ } [ ] : , " ' #` is refused rather than guessed at. See
[LIMITATIONS](docs/LIMITATIONS.md) for what that admits and what it still walls [LIMITATIONS](docs/LIMITATIONS.md) for what that admits and what it still walls
off (a `sources` block list of mappings is still refused); **`resource` https-allowlist** (hard-rejects off; **`resource` https-allowlist** (hard-rejects
`data:`/`javascript:`/`file:` before commit — a reject-gate, not defang); `data:`/`javascript:`/`file:` before commit — a reject-gate, not defang — on the
top-level `resource` only: a `sources[].resource` is never URL-validated, because
SPEC §5.1 allows bundle-relative paths there, so a consumer that follows it calls
`validate_resource_url` itself);
**whole-concept scan** (frontmatter *values* + body through `scan_output`); **whole-concept scan** (frontmatter *values* + body through `scan_output`);
**cross-link graph** (surfaces dangling targets, the dormant-injection signal, and **cross-link graph** (surfaces dangling targets, the dormant-injection signal, and
rejects bundle-escaping links); **provenance stamping** (`Origin` × `Channel` → rejects bundle-escaping links); **provenance stamping** (`Origin` × `Channel` →

View file

@ -4,7 +4,7 @@
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:** `v1.3.0`. Stdlib-only core, framework-agnostic. The **Status of the guard:** `v1.4.0`. Stdlib-only core, framework-agnostic. The
exported Python surface is frozen under semver — nothing exported is removed, 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 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 *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 python -m llm_ingestion_guard.coverage # exit 0 = all as documented
``` ```
As of `v1.3.0`: **130 / 130 defended classes demonstrated (recall 100%)** and **6 / As of `v1.4.0`: **130 / 130 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 (**868 update). The matrix is the single source of truth for the test suite (**893
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 — v1.3.0, exported surface frozen under semver. This document defines what the repo contains Status: implemented — v1.4.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

@ -49,10 +49,10 @@ items; this is the full list, each with the mechanism.
block sequence of block mappings (SPEC.md §5.1's own form). **The routes that block sequence of block mappings (SPEC.md §5.1's own form). **The routes that
still fail, each on a different rule:** a top-level block *mapping* still fail, each on a different rule:** a top-level block *mapping*
(`k:\n sub: v`) on the nested-mapping check, dotted keys (`k.sub: v`) on the (`k:\n sub: v`) on the nested-mapping check, dotted keys (`k.sub: v`) on the
key pattern, the inline second colon (`k: sub: v`) on the mapping-construct key pattern, and the inline second colon (`k: sub: v`) on the mapping-construct
check, and a flow sequence of plain *scalars* (`tags: [a, b]`) on the `[` check. (A flow sequence of plain *scalars*, `tags: [a, b]`, parses since
indicator — the sequence carrier is opened for the mapping element and nothing `1.4.0`; it is a sequence carrier, not a mapping one — see the `tags`
else. **Every carrier is admitted only when every key is on an allowlist** entry below.) **Every carrier is admitted only when every key is on an allowlist**
(`by`, `at`, `from`, `to`, `id`, `title`, `author`, `usage_count`, (`by`, `at`, `from`, `to`, `id`, `title`, `author`, `usage_count`,
`last_modified` — the keys SPEC.md @ `62432a09` §5.1/§5.2 names inside a mapping, `last_modified` — the keys SPEC.md @ `62432a09` §5.1/§5.2 names inside a mapping,
plus `resource` and `usage_window` *under `sources` only*, see below) plus `resource` and `usage_window` *under `sources` only*, see below)