Skip to content

refactor: adopt property_spec() for all PROPERTY_MAPPING specs - #87

Merged
TomKaltofen merged 3 commits into
mloda-ai:mainfrom
TomKaltofen:refactor/property-spec-builder
Jul 13, 2026
Merged

refactor: adopt property_spec() for all PROPERTY_MAPPING specs#87
TomKaltofen merged 3 commits into
mloda-ai:mainfrom
TomKaltofen:refactor/property-spec-builder

Conversation

@TKaltofen

Copy link
Copy Markdown
Collaborator

Closes #84.

All 259 PROPERTY_MAPPING specs across 66 files move from hand-written dicts to mloda 0.10.0's property_spec() builder. Spec invariants are now validated at import, and every option carries a real explanation, which is what declared_option_keys() and the docs surface to users.

The trap this had to avoid

property_spec() defaults context=True and always writes the key. mloda's parser reads a missing context as False (FeatureChainParser._is_context_parameter). 87 specs (every connector spec) omitted context and were therefore group options. Migrating them naively would have silently flipped them to context, changing feature-group resolution and hashing.

Those 87 sites get an explicit context=False. The context=True count is 172 before and 172 after.

How behavior preservation was verified

Every FeatureGroup's effective spec was snapshotted before and after (allowed_values, default, effective context, effective strict_validation, validators), normalizing each absent key to the parser's own fallback.

Result across 67 classes and 259 specs: zero semantic differences. The only delta is the added explanation strings.

The 54 authored explanations

54 specs carried no explanation (their text lived inside the value dict, e.g. {"sentence": "Sentence-boundary aware chunks"}). These collapse to 13 distinct option keys, because a base and its concretes share an option and differ only in the value space they allow. Each key gets one explanation, used identically by the base and its concretes. The per-value descriptions still live in allowed_values, so nothing was lost.

Also

  • New guard test_group_context_split_is_stable pins connector options as group and every other family as context. Nothing locked this before, and it is the single highest-risk failure mode of this refactor. Mutation-checked: it fails if an explicit context=False is dropped.
  • demo.ipynb taught the old hand-written dict form under "swap in your own embedder"; it now teaches property_spec.

Verification

tox green: 706 passed, 7 skipped, ruff format, ruff check, mypy --strict (241 files), bandit.

Reviewed independently by two deep reviews (Claude Opus and codex); both confirmed no behavior change. Findings on import ordering and on two leaf explanations that disagreed with their base are fixed in 04d3d64.

Note for reviewers

The registry guide feature-group-patterns/11-options.md is stale and was not used as the source of truth here. It still documents the retired flattened form as valid, and it claims property_spec accepts validation_function and type_validator (both raise TypeError; the real parameters are element_validator and match_guard). This PR was written against the verified 0.10.0 signature. Worth a separate upstream fix.

Closes mloda-ai#84. All 259 specs across 66 files move from hand-written dicts to the
property_spec() builder, so spec invariants are validated at import and every
option carries a real explanation for declared_option_keys() and the docs.

The builder defaults context=True while the parser reads a missing context as
False (_is_context_parameter). 87 specs omitted context and were therefore group
options: they get an explicit context=False so their resolution and hashing are
unchanged. Verified by snapshotting every FeatureGroup's effective spec
(allowed_values, default, effective context, effective strict, validators)
before and after: the only delta across all 259 is the added explanation.

The 54 specs that carried no explanation (their text lived inside the value
dict) collapse to 13 distinct option keys, since a base and its concretes share
an option and differ only in the value space they allow. Each key gets one
explanation, used identically by the base and its concretes.
Add a repo-wide guard that connector options stay group and every other family
stays context. The builder defaults context=True while mloda reads a missing
context as group, so a spec authored without an explicit context=False would
silently flip a connector option and change resolution and hashing. Nothing
locked that before.

Reuse the base wording for llm_method and retrieval_method: these were the only
two keys where the base already had an explanation and the concrete did not, so
the concrete had picked up freshly authored text that disagreed with its base.
@TomKaltofen
TomKaltofen merged commit 11baf5f into mloda-ai:main Jul 13, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adopt property_spec() builder for PROPERTY_MAPPING specs

2 participants