Parent epic: #929
Design proposal: PR #1080
Phase: 0 (Wave 1 — file immediately, independent of 0.1)
Blocks: 2.2 (revision-aware prepare())
⚠️ Pre-flight dependency: PR #1078 must be merged before starting this issue. PR #1078 adds canned I/O test data for requirement-check and uncertainty formatters that this issue's tests build on. Revision-pinning (here) supersedes the last_validated_commit approach in #1078; close #1029 when #1078 merges.
Problem
mellea/backends/adapters/catalog.py does not record which revision of an upstream HF repository Mellea expects. When upstream pushes new weights, every Mellea install silently picks them up.
PR #1008 is the worked example: requirement-check output changed schema upstream; requirement_check_to_bool returned False for every call until someone noticed.
Current state (verified main 2026-05-21): IntriniscsCatalogEntry has fields name, internal_name, repo_id, adapter_types — no revision. 14 entries across _RAG_REPO, _CORE_REPO, _CORE_R1_REPO, _GUARDIAN_REPO. Note: typo IntriniscsCatalogEntry (missing 'i') is intentional convention — do not fix it in this issue.
Additionally, the catalogue has two entries for the same adapter: requirement_check (underscore) and requirement-check (hyphen) — dead state that creates confusion.
Agreed design
Each catalogue entry gains a revision field pinned to a 40-character HF commit SHA. Mellea pins to that SHA when auto-loading. Callers may pass revision="main" to opt into tracking-latest.
Deduplication: Collapse requirement_check + requirement-check to a single canonical requirement_check entry with role="requirement-check" set on the Identity. Role-based lookup (introduced in 1.A) routes correctly regardless of key used at construction time.
This implements Jake req 5.
Scope
mellea/backends/adapters/catalog.py — add revision field to IntriniscsCatalogEntry; populate all 14 entries with current upstream SHA at PR time
- Validation:
revision must be 40-char lowercase hex OR literal "main"
- Validation function lives next to the catalogue type
- Collapse
requirement_check / requirement-check duplicate to one canonical entry
- Update any catalogue-construction examples in
docs/examples/ and test/ to include the field
Out of scope
Acceptance criteria
Test plan
test/backends/adapters/test_catalog_revision.py:
test_catalog_entries_have_revision — every entry has a valid value
test_revision_validation_rejects_malformed — short, long, non-hex
test_revision_validation_accepts_main_literal
test_revision_round_trip — construct entry, retrieve, assert preserved
test_no_duplicate_requirement_check_entry
⚠️ SHA staleness: The SHA pinned at PR-write time may be stale by merge time. Reviewer should re-fetch upstream HEAD just before merging and confirm the SHA is still current.
Breaking changes
None for end users. Downstream code constructing IntriniscsCatalogEntry directly must add the new field (or handle implementer's None behaviour).
References
Parent epic: #929
Design proposal: PR #1080
Phase: 0 (Wave 1 — file immediately, independent of 0.1)
Blocks: 2.2 (revision-aware
prepare())Problem
mellea/backends/adapters/catalog.pydoes not record which revision of an upstream HF repository Mellea expects. When upstream pushes new weights, every Mellea install silently picks them up.PR #1008 is the worked example:
requirement-checkoutput changed schema upstream;requirement_check_to_boolreturnedFalsefor every call until someone noticed.Current state (verified main 2026-05-21):
IntriniscsCatalogEntryhas fieldsname,internal_name,repo_id,adapter_types— norevision. 14 entries across_RAG_REPO,_CORE_REPO,_CORE_R1_REPO,_GUARDIAN_REPO. Note: typoIntriniscsCatalogEntry(missing 'i') is intentional convention — do not fix it in this issue.Additionally, the catalogue has two entries for the same adapter:
requirement_check(underscore) andrequirement-check(hyphen) — dead state that creates confusion.Agreed design
Each catalogue entry gains a
revisionfield pinned to a 40-character HF commit SHA. Mellea pins to that SHA when auto-loading. Callers may passrevision="main"to opt into tracking-latest.Deduplication: Collapse
requirement_check+requirement-checkto a single canonicalrequirement_checkentry withrole="requirement-check"set on theIdentity. Role-based lookup (introduced in 1.A) routes correctly regardless of key used at construction time.This implements Jake req 5.
Scope
mellea/backends/adapters/catalog.py— addrevisionfield toIntriniscsCatalogEntry; populate all 14 entries with current upstream SHA at PR timerevisionmust be 40-char lowercase hex OR literal"main"requirement_check/requirement-checkduplicate to one canonical entrydocs/examples/andtest/to include the fieldOut of scope
prepare()behaviour — 2.2 consumes the pinned revisionIntriniscsCatalogEntrytypo (preserve)Acceptance criteria
revisionfield with a valid 40-char hex SHA"main"accepted as explicit opt-in for tracking-latest"main"accepted,Nonehandling tested explicitly (implementer chooses accept-as-main vs reject-with-error — must be tested)requirement_checkandrequirement-checkentries collapsed to one; no duplicate keyruff format,ruff check,mypycleanTest plan
test/backends/adapters/test_catalog_revision.py:test_catalog_entries_have_revision— every entry has a valid valuetest_revision_validation_rejects_malformed— short, long, non-hextest_revision_validation_accepts_main_literaltest_revision_round_trip— construct entry, retrieve, assert preservedtest_no_duplicate_requirement_check_entryBreaking changes
None for end users. Downstream code constructing
IntriniscsCatalogEntrydirectly must add the new field (or handle implementer'sNonebehaviour).References