You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor: convention-default helpers live in base.py, not yaml_source (#77)
OssieSource had been importing _parse_convention_default and
_apply_convention_default -- two private functions -- across from
yaml_source.py. Every other helper shared between the sources lives in
base.py and is imported by both: validate_decompositions,
validate_drill_by, parse_review_date, jsonify_extras,
build_relationship_index.
Two things made the old placement the odd one out. Both helpers operate
purely on MetricDefinition / Decomposition and touch nothing
YAML-specific, and both had to import VALID_CONVENTIONS and
_CROSS_TERM_OPERATORS back out of base.py to do their work. After the
move yaml_source.py needs neither constant for anything else -- it had no
other consumer of them -- which is the clearest evidence the vocabulary
they enforce already lived where the functions belonged.
parse_review_date's docstring states the principle the move follows: it
is shared rather than per-source because every format reaching the same
field reaches the same arithmetic, "so a second copy of this would be a
second chance to get the subclass ordering wrong." Both sources resolve a
house default onto the same Decomposition.convention field, and
fold_into-is-not-a-valid-default is exactly the rule that drifts if it is
ever copied.
No behavior change. Both source paths keep their existing tests, and
verified directly that a YAML default still resolves (split_evenly), an
Ossie vendor-block default still resolves (explicit), a fold_into
source-level default is still rejected, and the pinned round-trip digest
is unmoved. 1078 passing.
No version bump: both functions are private, so nothing on the public
surface changed. Rides along with the 0.43.1 already on main.
Closes#74
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
10
10
11
11
### Internal
12
12
13
+
-**The convention-default helpers moved to `semantic/base.py`.**`OssieSource` had been importing `_parse_convention_default` / `_apply_convention_default` — two *private* functions — across from `yaml_source.py`, while every other helper shared between sources (`validate_decompositions`, `validate_drill_by`, `parse_review_date`, `jsonify_extras`, `build_relationship_index`) lives in `base.py`. The giveaway was that both had to import `VALID_CONVENTIONS` and `_CROSS_TERM_OPERATORS` back out of `base.py` to do their work, and that those two constants had no other consumer in `yaml_source.py` — the vocabulary they enforce already lived where the functions belonged. `parse_review_date`'s own docstring states the principle: a second copy is a second chance to get the rule wrong, and both sources resolve a default onto the same `Decomposition.convention` field. No behavior change; both source paths keep their existing tests. ([#74](https://github.com/flyersworder/agentic-data-contracts/issues/74))
13
14
- **The pinned round-trip digest now covers metric serialization.** `_PINNED_ROUNDTRIP_DIGEST` is the repo's broadest guard against canonical-bytes drift, but it was computed over a semantic source with no `metrics:` key at all, so `_dump_metric` was never called and it could not see any change to metric serialization. That is worse than a missing test, because the assertion passed either way: every optional field added to `_dump_metric` since the pin was written could have been made unconditional — moving the digest of every real contract and invalidating every published ARD attestation — with the test still green. The fixture now carries a metric exercising every optional field the dump writes plus two leaves for the omit-when-empty branches, verified by mutation (removing the `if m.decompositions:` guard now fails the pin), and a companion test asserts the pinned contract's canonical bytes still carry those fields so the coverage cannot be silently narrowed again. No shipped code changed. ([#73](https://github.com/flyersworder/agentic-data-contracts/issues/73))
0 commit comments