chore(release): v0.5.0a1 — version sync, and the entry that makes the pilot provisional
The tag was specified to land on 128109b, where the package still declared
0.4.0 in both places a version is written. The pilots install FROM the tag, so
they would have pinned a pre-release that reports the previous release.
Two requirements the "minimally requires" list did not cover, both stated
elsewhere in the plan:
- The CHANGELOG entry is load-bearing, not ceremony: the plan makes the
provisional status real by having the profile docstring AND the entry both
say the surface may change without a deprecation cycle, and name the pilot
repos. The docstring had it (profiles.py:694); the CHANGELOG stopped at
0.4.0.
- pyproject.toml and __init__.py both said 0.4.0.
Nothing in the run path reads __version__, which is why a stale one survives a
green suite. test_the_declared_version_agrees_with_the_packaged_one is the only
machine check on it — written failing first, against a one-sided bump. The tag
NAME remains a human step; no test can catch that one.
README keeps pointing at v0.4.0 on purpose: a pre-release for three named
pilots is not the general install line, and OKF_LATEST does not move until GA.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVTup4v7tW9QiVyBENk2LV
This commit is contained in:
parent
128109bef0
commit
af6e6afe36
4 changed files with 75 additions and 2 deletions
58
CHANGELOG.md
58
CHANGELOG.md
|
|
@ -5,6 +5,63 @@ 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).
|
||||
|
||||
## [0.5.0a1] — 2026-07-31
|
||||
|
||||
**Pre-release. PROVISIONAL surface.** Shipped to a named pilot set —
|
||||
`portfolio-optimiser-claude`, the plugin marketplace catalog, and
|
||||
`claude-code-llm-wiki` — so that real data can find what fixtures cannot. The
|
||||
v0.2 surface may change on their feedback **without a deprecation cycle**.
|
||||
Saying so up front is what buys the freedom to act on the feedback; discovering
|
||||
it later is what would make a pilot a de-facto release. Do not pin this tag
|
||||
outside the pilot set.
|
||||
|
||||
Support for a new upstream version is **additive — a new profile, never a
|
||||
migration**. `OKF_LATEST` still points at `DEFAULT`; flipping it is the GA
|
||||
event, not a side effect of this tag.
|
||||
|
||||
### Added
|
||||
|
||||
- **`OKF_V0_2` profile.** Google OKF v0.2 as a profile alongside `DEFAULT` and
|
||||
`STRICT_V1`. It closes nothing: §14 forbids a conformant consumer to reject on
|
||||
an unknown `type` value or on unknown additional keys, so `type` is the only
|
||||
required key. It NAMES `okf_version` but never carries its value — that value
|
||||
tracks the upstream Google version and belongs to catalog (decision E1), so
|
||||
the caller supplies it via `materialize_bundle(..., root_frontmatter_values=…)`
|
||||
and the profile fixes only the key and its position.
|
||||
- **`root_frontmatter_values`** on `materialize_bundle`, keyword-only: the
|
||||
mechanism behind "a profile names a key, a caller owns its value".
|
||||
- **`sources` emitted as an inline flow sequence**, populated from the manifest.
|
||||
- **The v0.2 golden fixture**, compared byte-for-byte like the others.
|
||||
|
||||
### Changed
|
||||
|
||||
- **`profile` on `materialize_bundle` is keyword-only**, so existing positional
|
||||
call sites stay source-compatible.
|
||||
- **`_is_ingest_owned` is profile-aware.** Ownership is a policy on the profile,
|
||||
not a literal; recognition stays one-way.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **`root_frontmatter` permitted a key without requiring it — the two had been
|
||||
the same profile field.** Upstream says MAY where the field said MUST, so a
|
||||
root index that legally omitted an optional key was rejected. `root_frontmatter`
|
||||
now permits and orders; the new `root_frontmatter_required` requires.
|
||||
`STRICT_V1` keeps requiring its three (unchanged for its consumer), `OKF_V0_2`
|
||||
requires none, `DEFAULT` is untouched. Measured against the eight root indexes
|
||||
available locally: 7 of 8 failed before, 0 of 8 after.
|
||||
|
||||
### Notes
|
||||
|
||||
- **`DEFAULT` and `STRICT_V1` are byte-stable across this release.** The emit
|
||||
path is byte-identical; the golden suite is the check.
|
||||
- **Known, deliberately unfixed:** `TypePolicy`'s closed branch does not strip
|
||||
quotes from a declared type. All three call sites pass `DEFAULT.types`, and
|
||||
both `DEFAULT` and `OKF_V0_2` set `allowed=None`, so the branch is
|
||||
unreachable in shipped code — it fires only for a caller constructing
|
||||
`STRICT_V1` and calling `rejection` directly. Fixing it would repair a write
|
||||
path that never sees quotes, and would fix the meaning of a quote character
|
||||
without a value model that can express one, in a line-oriented format.
|
||||
|
||||
## [0.4.0] — 2026-07-25
|
||||
|
||||
Phase 2. The bundle inbox (Door B) and external-bundle import (Door C) ship,
|
||||
|
|
@ -187,6 +244,7 @@ Phase 1 (Door A) implemented against the normative `ingest-spec.md` owned by
|
|||
- The Door A public surface: `materialize_bundle` plus the typed error hierarchy
|
||||
rooted in `IngestError`.
|
||||
|
||||
[0.5.0a1]: https://git.fromaitochitta.com/open/llm-ingestion-okf/compare/v0.4.0...v0.5.0a1
|
||||
[0.4.0]: https://git.fromaitochitta.com/open/llm-ingestion-okf/compare/v0.3.2...v0.4.0
|
||||
[0.3.2]: https://git.fromaitochitta.com/open/llm-ingestion-okf/compare/v0.3.1...v0.3.2
|
||||
[0.3.1]: https://git.fromaitochitta.com/open/llm-ingestion-okf/compare/v0.3.0...v0.3.1
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||
|
||||
[project]
|
||||
name = "llm-ingestion-okf"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0a1"
|
||||
description = "Shared OKF (Open Knowledge Format) ingestion library: spec-based connectors, bundle inbox, and external-bundle import, with security delegated to llm-ingestion-guard."
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ from .manifest import (
|
|||
)
|
||||
from .materialize import IngestResult, materialize_bundle
|
||||
|
||||
__version__ = "0.4.0"
|
||||
__version__ = "0.5.0a1"
|
||||
|
||||
__all__ = [
|
||||
"BlockedFile",
|
||||
|
|
|
|||
|
|
@ -32,3 +32,18 @@ def test_the_only_runtime_dependency_is_the_security_boundary() -> None:
|
|||
tomllib = pytest.importorskip("tomllib") # stdlib from 3.11; the pin holds on 3.10 too
|
||||
pyproject = tomllib.loads((PROJECT_ROOT / "pyproject.toml").read_text(encoding="utf-8"))
|
||||
assert pyproject["project"]["dependencies"] == ["llm-ingestion-guard>=0.2,<0.3"]
|
||||
|
||||
|
||||
def test_the_declared_version_agrees_with_the_packaged_one() -> None:
|
||||
"""The two places a version is written must not drift apart.
|
||||
|
||||
The install channel is a direct git reference, so a consumer pins a TAG
|
||||
while pip records `project.version`. Nothing in the run path reads
|
||||
`__version__` — which is exactly why a stale one survives a green suite,
|
||||
and why a consumer installing at a pre-release tag can end up with a
|
||||
package that reports the previous release. This is the only machine check
|
||||
on that; the tag name itself remains a human step.
|
||||
"""
|
||||
tomllib = pytest.importorskip("tomllib")
|
||||
pyproject = tomllib.loads((PROJECT_ROOT / "pyproject.toml").read_text(encoding="utf-8"))
|
||||
assert llm_ingestion_okf.__version__ == pyproject["project"]["version"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue