1
0
Fork 0
llm-ingestion-pipeline-secu.../pyproject.toml
Kjell Tore Guttormsen 75ae48277b release(0.3.2): the ReDoS fix, with both residuals measured against the v0.3.1 tag
Version sync in all four places (pyproject, __version__, README badge, README
install pin) plus the changelog entry for cff0437.

Two claims that were about to ship in the release note did not survive being
measured against a v0.3.1 worktree, and are corrected in LIMITATIONS first:

- "Report-only, so the cost is a review, not a block" was wrong twice. HIGH under
  a low-trust preset is fail_secure, not a review -- report-only means the text is
  never mutated, not that a finding cannot block. And the new script-tag false
  positive costs no consumer a disposition at all: any text containing a literal
  `<script>` already produced active:raw-html at HIGH on 0.3.1, so the same prose
  disposed fail_secure under PRESET_USER_UPLOAD before this change and after it.
  The fail-open that was closed is narrower for the same reason -- it existed only
  in scan_lexicon called on its own; through either composed gate, raw-html
  already caught the unclosed tag. What changed is the label, not the outcome.

- "The realistic long value is still caught by egress:jwt-token" was true and
  hid the part that matters. Measured at the 257-char boundary: a generic long
  password still trips entropy:base64-blob at CRITICAL, disposition unchanged.
  A JWT used as a DB password is the case that moves -- its remaining detections
  top out below CRITICAL, so the any-tier block is lost and PRESET_TRUSTED_SOURCE
  drops from fail_secure to quarantine_review. PRESET_USER_UPLOAD still
  fail_secures. Recorded as a behaviour change in the changelog, not buried.

The first probe for that boundary used a 300-char run of "A" and found nothing on
either version: all-same-char values are suppressed as placeholders. The probe was
wrong, not the pattern.

662 passed, coverage matrix exit 0, LIMITATIONS still 29 items = README's 29.
2026-07-31 21:16:45 +02:00

38 lines
1.5 KiB
TOML

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "llm-ingestion-guard"
version = "0.3.2"
description = "A minimal, dependency-light defensive layer for LLM ingestion pipelines — the write-time siblings of query-time chatbot guardrails."
readme = "README.md"
requires-python = ">=3.10"
license = { file = "LICENSE" }
authors = [{ name = "Kjell Tore Guttormsen" }]
keywords = ["llm", "security", "prompt-injection", "rag", "ingestion", "guardrails", "write-time"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Topic :: Security",
]
dependencies = [] # stdlib-only core — see design principle 1
[project.optional-dependencies]
ml = [] # pluggable embedding/classifier detectors (placeholder)
judge = [] # LLM-judge / source-grounding implementation (placeholder)
# Showcase-only extraction parsers for the two-stage OKF inbox demo (docs/PLAN.md
# §247). Deliberately in `dev`, NOT the core `dependencies` (which stays []) and
# NOT a public `[extract]` extra — the front-end is an in-repo demonstration, not
# v1 shipped code. They pull lxml/Pillow transitively; that footprint is dev-only.
dev = ["pytest>=8", "python-docx>=1.2", "python-pptx>=1.0", "openpyxl>=3.1"]
[tool.hatch.build.targets.wheel]
packages = ["src/llm_ingestion_guard"]
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src"]
addopts = "-q"