Skip to content

docs: correct the --no-update claim in the CI and pre-commit recipes - #70

Merged
edochi merged 1 commit into
mainfrom
docs/no-update-semantics
Aug 20, 2026
Merged

docs: correct the --no-update claim in the CI and pre-commit recipes#70
edochi merged 1 commit into
mainfrom
docs/no-update-semantics

Conversation

@edochi

@edochi edochi commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Both recipes documented a validation gate that does not exist.

The false claim

ci.md and pre-commit.md each stated that mdvs check --no-update fails with a Disallowed violation when a commit adds a new frontmatter field. Verified against the current binary — it exits 0:

Checked 2 files — no violations, 1 new field(s)
EXIT: 0

check/validate.rs:150 iterates the fields declared in mdvs.toml rather than the keys found in a file, and dsl_to_canonical emits the root schema with additionalProperties: true, so a key appearing in no [[fields.field]] entry is never examined. Disallowed means something narrower: a declared field appearing outside its allowed globs.

This matters because anyone following the CI recipe believes they have a gate against schema drift that isn't there.

What auto-update actually does

The old text was also vague on the flag's real effect, so I measured it:

Scenario auto-update (default) --no-update
Brand-new undeclared field silently written into mdvs.toml, exit 0 listed under "New fields", exit 0
Value violating existing categories exit 1 exit 1
Wrong type on existing field exit 1 exit 1

Re-inference only ever adds fields — it never widens an existing field's type or relaxes its constraints. The real difference is that auto-update rewrites mdvs.toml on disk mid-run, while --no-update leaves it alone and reports new fields instead.

--no-update remains the right default in CI and in a hook. The justification changes, not the advice.

Changes

  • ci.md — rewrote the --no-update section around the measured behavior; added a check does not fail on undeclared fields section; fixed a second instance of the same falsehood in the "What check does" list (✓ Disallowed fields (anything not in mdvs.toml and not in ignore) → the correct narrow meaning).
  • pre-commit.md — replaced the inherited claim. The hook framing is stronger for it: without --no-update, committing a new field silently edits mdvs.toml in your working tree mid-commit, leaving a modification you never staged.

For anyone who wants the gate today, the new section documents a workaround, verified to exit non-zero only when a new field is present:

mdvs check --no-update --output json | jq -e '.new_fields | length == 0'

Notes

  • getting-started.md:121 looks like the same bug but is correctsensor_type is a declared field with allowed = ["projects/alpha/notes/**"], so placing it in a blog post is genuinely Disallowed. Left as-is.
  • The reference pages (commands/check.md:37, concepts/validation.md:121) already described this accurately. Only the two recipes had drifted — an argument for recipes citing the reference pages rather than restating them.
  • Book builds clean; all new and existing anchors verified in the generated HTML.

Both recipes claimed that `mdvs check --no-update` fails with a
`Disallowed` violation when a commit adds a new frontmatter field. It
does not. Verified against the current binary:

    Checked 2 files — no violations, 1 new field(s)
    EXIT: 0

`check/validate.rs` iterates the fields declared in mdvs.toml rather than
the keys found in a file, and the canonical schema is emitted with
`additionalProperties: true`, so a key that appears in no
`[[fields.field]]` entry is never examined. `Disallowed` means something
narrower — a *declared* field appearing outside its `allowed` globs.

Also verified what auto-update actually does, since the old text was
vague: re-inference only ever adds new fields. It does not widen an
existing field's type or relax its constraints, so a bad category value
or a wrong type fails in both modes. The real difference is that
auto-update rewrites mdvs.toml on disk mid-run while `--no-update`
leaves it alone and reports new fields instead.

`--no-update` is still the right default in CI and in a hook; the
justification changes, not the advice. Adds a section documenting the
undeclared-field gap explicitly, with a working jq gate for anyone who
wants it to break the build today:

    mdvs check --no-update --output json | jq -e '.new_fields | length == 0'

The reference pages (commands/check.md, concepts/validation.md) already
described this correctly — only the two recipes had drifted.

Co-Authored-By: Claude <noreply@anthropic.com>
@edochi
edochi merged commit f1e7d91 into main Aug 20, 2026
8 checks passed
@edochi
edochi deleted the docs/no-update-semantics branch August 20, 2026 13:08
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.

1 participant