docs: add TODOs 0194-0196 — directory-scoped policy, cross-field rules, duplicate names - #71
Merged
Merged
Conversation
…s, duplicate names
Three related gaps found while reviewing how mdvs scopes validation.
TODO-0194 (high): a frontmatter field declared in no `[[fields.field]]`
entry is never a violation — `check` reports it as informational and
exits 0, in both auto-update and `--no-update` modes. Proposes a
`[[scope]]` section so a directory can be frozen against undeclared
fields. Records the measured behaviour of auto-update: re-inference only
ever adds fields, never widens an existing field's type or relaxes its
constraints.
TODO-0195 (medium): conditional requiredness ("closed_date is required
when status is closed"), plus the variant-type idea as its expensive
endpoint. Notes that the file format is not the obstacle for tagged
unions — YAML and TOML both express them — and that the flat encoding
via conditional rules covers most of the value.
TODO-0196 (high): duplicate `[[fields.field]]` names are silently
accepted and the last one wins, because field lookup collects into a
HashMap keyed by the bare name. Reproduction included.
All three are specs only; no behaviour changes here.
Co-Authored-By: Claude <noreply@anthropic.com>
This was referenced Aug 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Specs only. No behaviour changes.
Three related gaps found while reviewing how mdvs scopes validation. All three trace to the same root: every rule in
mdvs.tomlhangs off exactly one[[fields.field]], so anything cross-cutting — directory policy, cross-field conditions, per-directory meaning — has nowhere to live.TODO-0194 — directory-scoped schema policy (high)
A frontmatter field declared in no
[[fields.field]]entry is never a violation.checkreports it as informational and exits 0, in both auto-update and--no-updatemodes:Two mechanisms:
validate.rsiterates declared fields rather than the keys present in a file, andto_canonical.rsemits the root schema withadditionalProperties: true.Also records what auto-update actually does, measured — re-inference only ever adds fields; it never widens an existing field's type or relaxes its constraints:
--no-updatemdvs.toml, exit 0categoriesProposes a
[[scope]]section withpath/frozen/ignore, wherepath = "**"makes the whole-repo case fall out of the same mechanism. Open questions on precedence and on[fields].ignore's future are recorded rather than settled.TODO-0195 — cross-field rules (medium)
Conditional requiredness — "
closed_dateis required whenstatusisclosed" — viadependentRequired(presence-based) orif/then(value-based). Argues conditional-disallowed is not optional: required-when alone is a footgun, since nothing then stopsclosed_dateappearing on an open item.Part B records the Rust-style variant-type idea and corrects a common assumption: the file format is not the obstacle. YAML and TOML both express tagged unions (externally- and internally-tagged are just serde's enum representations). The real blockers are three deliberate mdvs decisions — the
oneOfreject list, the fixed Arrow Struct in storage, and inference. Concludes the flat encoding via Part A captures most of the value at a fraction of the cost.depends_on: [194]— both need the same container, so it should be designed once.TODO-0196 — duplicate field names (high)
A live bug, not just a missing feature. Two
[[fields.field]]entries sharing anameare accepted silently and the last one wins:Both violations are artifacts of the collapse — the
blog/**declaration was discarded. Cause iscollect()into aHashMapkeyed by the bare name (validate.rs:43, and the same shape infield_meta.rs). None of the nine existing invariants covers it; invariant 8 catches shape conflicts, not two declarations of the same leaf.Fix is invariant 10 — reject duplicates at config load. Self-contained and worth doing independent of the other two.