Skip to content

v2.3.0 — deferred-item close-out: ingestion failure surfacing, reproducible container

Latest

Choose a tag to compare

@franciszver franciszver released this 27 Jul 20:53
· 2 commits to main since this release
5f21371

Closes out the two items deferred from the v2.2.0 release, plus a version-alignment ruling. 3 PRs, 15 commits since v2.2.0.

Behaviour change — read this if you call ingestion

  • Issue 206 — a fully-failed document ingestion previously returned normally with zero facts and no exception, byte-identical on disk to a genuinely empty document. That silence is what let issue 204's text-only vision wiring survive undetected. attach_and_extract now raises IngestionError when every page fails; no facts sidecar is written, so the document reads as not-ingested and is safely re-runnable. Any caller relying on the old silent-empty return will now see an exception. Partial failure is unchanged — surviving pages' facts are kept, and the facts sidecar now records pages_total/failed_pages so partial degradation is durable on disk instead of invisible. The pre-wired extraction_failure_rate dashboard alert (threshold, explanation text, and banner all existed but were permanently fed None) is now populated. Measured live in-container before and after, against both a total-failure case and an 8-fact success control.

Reproducible container builds

  • Issue 213 — the container build was not reproducible: bounds narrow the resolution window but do not pin it, and transitives (notably starlette, the layer actually under FastAPI) were unbounded. The container — the actual shipped artifact — now installs from a hash-locked requirements.txt generated by pip-compile inside the same digest-pinned base image the Dockerfile uses, with --require-hashes enforced at install. CI gains a job that builds the image (previously no workflow built it at all) and audits the lock. Verified empirically at review: double --no-cache builds byte-identical, lock regeneration byte-identical to the committed file, and a corrupted hash genuinely fails the build.

Version alignment

  • Issue 214 — the package previously declared version = "0.1.0" while releases were tagged v2.x. By owner ruling, the package version tracks the release tag from this release onward; pyproject, the app, and the OpenAPI document all read 2.3.0, and this tag closes the loop. A red-first test forces every future release PR to bump deliberately.

Known limits, stated plainly

  • The hash lock covers the container only. Dev venvs and CI's pip install -e ".[dev]" remain range-based by design — the lock is the machine-facing contract for the shipped artifact; the pyproject ranges stay the human-facing one.
  • The issue-204 vision-capability pre-flight is a name heuristic; a vision-named model that is not actually pulled passes it. Ruled acceptable because the issue-206 change makes that case raise loudly at first ingestion instead of failing silently.
  • --allow-unsafe produced no setuptools/pip pins because nothing in the runtime graph declares them; the build-backend closure is locked via the digest-pinned base image plus --no-build-isolation instead. A base-digest bump mandates lock regeneration.

Full test state at tag, verified independently on main immediately before tagging (not inherited from the last PR's CI): 1393 passed, 1 skipped, 18 deselected, 12 xfailed (agent), 383 passed, 12 deselected, 15 xfailed (evals), mypy clean (64 source files), CI green on 5f213718.