chore(deps): move the ingest library pin to v0.3.2 — as far as latest goes today

The pin had sat at v0.3.1 with STATE calling the hold "deliberate" and
recording no reason. Measured: no coord message ever announced v0.4.0 or
v0.5.0a* to this repo, so the hold was drift wearing a decision's clothes.

v0.3.2 is a pure fix (frontmatter and index labels emit verbatim; only
source_query is whitespace-collapsed, per ingest-spec §5), keeps
`dependencies = []`, and is green here: 668 passed.

WHY NOT FURTHER, both measured rather than assumed:

1. v0.4.0 introduces a REGRESSION that breaks our §6 removal path.
   Bisected v0.3.2 OK / v0.4.0 RED with a minimal repro: materialize a
   bundle, then re-materialize it with a CHANGED manifest, and the library
   no longer recognises its own stamp —

     MaterializationError: generated filename 'ingest-costs.md' collides
     with an existing file that does not carry the ingest stamp

   The stamp carries the manifest's name+hash (`ingest_manifest: m2@…`), so
   editing a manifest makes every file it previously wrote look curated.
   Re-ingesting the SAME manifest is fine, which is why fixtures miss it.
   It is `tests/test_ingest_loadbearing.py::test_reingest_with_active_
   removal_preserves_promoted_and_curated` that catches it. Reported
   upstream; not ours to fix.

2. Everything past v0.3.1 adds `llm-ingestion-guard>=0.2,<0.3` as a HARD
   runtime dependency (v0.3.1/v0.3.2: `dependencies = []`). That flips two
   documented invariants here — pyproject's "zero runtime deps" comment and
   the STATE marker line the guard repo reads machine-readably ("not a
   runtime dependency today"). An operator decision, not a version bump.

3. v0.5.0a2 is an alpha whose own CHANGELOG scopes it to a named pilot set
   — portfolio-optimiser-claude, the marketplace catalog, claude-code-llm-wiki
   — and says "do not pin this tag outside the pilot set", with the v0.2
   surface free to change without a deprecation cycle. This repo is not a
   pilot. Joining is llm-ingestion-okf's call, requested via coord.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GyAbxJoyypnLLUDcMvnKh8
This commit is contained in:
Kjell Tore Guttormsen 2026-08-05 12:11:12 +02:00
commit b33ea00055
7 changed files with 10 additions and 10 deletions

View file

@ -82,7 +82,7 @@ agents' job, not the connector's.
> **Where to change it (2026-07-20):** `ingest.py` is a thin adapter — Door A is implemented by
> the shared [`llm-ingestion-okf`](https://git.fromaitochitta.com/open/llm-ingestion-okf) library
> (git-pinned to `v0.3.1`), so connectors, materialization and index generation improve in ONE
> (git-pinned to `v0.3.2`), so connectors, materialization and index generation improve in ONE
> place across every consumer. `shared/ingest-spec.md` remains the normative spec — the library
> implements it, it does not replace it, and spec changes go via commons. The API below is
> unchanged; only the implementation moved. Note that Door A is **ungated**: it calls no

View file

@ -34,7 +34,7 @@ dependencies = [
# verified in consumer CI): git pin against the public Forgejo repo — reproducible for every
# consumer, uv.lock pins the exact commit behind the tag. Bump the rev on a new library tag.
[tool.uv.sources]
llm-ingestion-okf = { git = "https://git.fromaitochitta.com/open/llm-ingestion-okf.git", rev = "v0.3.1" }
llm-ingestion-okf = { git = "https://git.fromaitochitta.com/open/llm-ingestion-okf.git", rev = "v0.3.2" }
# Dev tooling as a PEP 735 dependency-group (uv includes it by default in `uv sync`/`uv run`),
# so the documented bare `uv sync` + `uv run pytest` workflow installs it without `--extra`.

View file

@ -6,7 +6,7 @@ bundle, which the existing 8-step loop then consumes UNCHANGED. Zero model calls
for the ``file``/``sql`` source types.
Since the library adoption (2026-07-20) the implementation IS the shared
``llm-ingestion-okf`` library (git-pinned to ``v0.3.1``). The spec in ``shared/ingest-spec.md``
``llm-ingestion-okf`` library (git-pinned to ``v0.3.2``). The spec in ``shared/ingest-spec.md``
remains the normative source — the library implements it, it does not replace it — and the
repo-local goldens under ``examples/`` remain the fasit (verified byte-exact across all three
source types, before and after the swap).
@ -152,7 +152,7 @@ def load_manifest(path: str | Path) -> tuple[Manifest, str]:
any source.
The two-value return is the repo-local shape: the library returns the manifest alone and
mints the stamp INSIDE ``materialize_bundle``, exposing no stamp helper (v0.3.1). The
mints the stamp INSIDE ``materialize_bundle``, exposing no stamp helper (v0.3.2). The
formula is therefore restated here, which is the one place this adapter is not purely
delegating — so it is pinned by
``tests/test_ingest_library_seam.py::test_adapter_stamp_equals_library_stamp``, which

View file

@ -9,7 +9,7 @@ expects, so every contract downstream of the transport is the EXISTING one.
**Where the transport discriminator lives, and why.** The shared library validates manifests
fail-fast and rejects unknown keys (``llm_ingestion_okf.manifest._require_keys``): an ``http``
source admits exactly ``{type, id, base_url}`` plus optional ``credential_ref``. We consume that
library PULL-ONLY at a pinned ``v0.3.1``, so introducing ``server_ref``/``tool`` as manifest fields
library PULL-ONLY at a pinned ``v0.3.2``, so introducing ``server_ref``/``tool`` as manifest fields
would mean a spec amendment plus a library release. It buys nothing: the library's own URL join
composes ``base_url`` + ``/`` + ``query``, so

View file

@ -52,7 +52,7 @@ def _project(tmp_path: Path, source: dict[str, Any] | None = None) -> tuple[Path
def test_adapter_stamp_equals_library_stamp(tmp_path: Path) -> None:
"""LOAD-BEARING ANTI-DRIFT: the adapter's ``load_manifest`` restates the §5 stamp formula
because the library (v0.3.1) mints the stamp inside ``materialize_bundle`` and exposes no
because the library (v0.3.2) mints the stamp inside ``materialize_bundle`` and exposes no
stamp helper. That is the ONE place the adapter is not purely delegating, so the two
formulas can drift apart silently — this compares the adapter's value against the stamp the
library actually writes into ``ingest_manifest`` frontmatter. RED the moment either side

View file

@ -10,7 +10,7 @@ is STALE and deliberately not followed here.
**Why the discriminator lives in ``base_url``, not in new manifest fields.** The shared library
rejects unknown manifest keys fail-fast (``llm_ingestion_okf.manifest._require_keys``): an ``http``
source admits exactly ``{type, id, base_url}`` plus optional ``credential_ref``. We are a PULL-ONLY
consumer pinned at ``v0.3.1``, so adding ``server_ref``/``tool`` as fields would require a spec
consumer pinned at ``v0.3.2``, so adding ``server_ref``/``tool`` as fields would require a spec
amendment plus a library release. It is not needed: the library's own URL join already composes
``base_url`` + ``/`` + ``query``, so ``mcp+stdio://<server_ref>`` + ``<tool>`` reproduces exactly
the two-part structure the stale plan wanted — with zero schema change. Field names were explicitly

6
uv.lock generated
View file

@ -1100,8 +1100,8 @@ wheels = [
[[package]]
name = "llm-ingestion-okf"
version = "0.3.1"
source = { git = "https://git.fromaitochitta.com/open/llm-ingestion-okf.git?rev=v0.3.1#692f2df2ba5aa160810b126dab3574cd297218b9" }
version = "0.3.2"
source = { git = "https://git.fromaitochitta.com/open/llm-ingestion-okf.git?rev=v0.3.2#f14c075a6508257253c0df318f3e10b2fae51d39" }
[[package]]
name = "mcp"
@ -1514,7 +1514,7 @@ requires-dist = [
{ name = "agent-framework-orchestrations", specifier = ">=1.0.0" },
{ name = "anyio", specifier = ">=4.14" },
{ name = "azure-identity", specifier = ">=1.25" },
{ name = "llm-ingestion-okf", git = "https://git.fromaitochitta.com/open/llm-ingestion-okf.git?rev=v0.3.1" },
{ name = "llm-ingestion-okf", git = "https://git.fromaitochitta.com/open/llm-ingestion-okf.git?rev=v0.3.2" },
{ name = "mcp", specifier = ">=1.28.0" },
{ name = "numpy", specifier = ">=2.0,<2.3" },
{ name = "pulp", specifier = ">=2.8" },