| id | 136 | ||
|---|---|---|---|
| title | Field deprecation flag in schemas | ||
| status | 🔲 | ||
| model | sonnet | ||
| depends-on |
|
||
| summary | Let a schema mark a front-matter field deprecated. MDS020 emits a warning (not an error) when the field appears, naming the replacement and the schema that introduced the deprecation. Soft-deprecation lets a project migrate without breaking the build. |
Let a schema declare a field deprecated and let mdsmith warn — but not fail — when files still carry it. The warning names the replacement field and the schema where the deprecation lives, so the user can fix the file without opening the schema.
The mdbase research records this as S-6.
Schema migration is a real workflow: a project
renames legacy_owner to owner, adds the new
field, and wants to clean up the old one over
weeks or months without breaking CI.
Today MDS020 has only two postures: a field is in the schema (validated) or it is not (allowed or forbidden depending on whether the schema is closed). There is no middle ground for "tolerate but warn".
- Auto-rewrite. A
mdsmith fixthat copieslegacy_ownerintoowneris plausible, but the field-rename mapping is project-specific and out of scope here. This plan only emits the warning. - A separate rule. The deprecation diagnostic is an MDS020 sub-diagnostic with a different severity, not a new rule code.
- Deprecating sections (
structure:entries). Sections come and go via<?allow-empty-section?>already; no real workflow is asking for soft deprecation of structure.
A field's value can be a map carrying metadata instead of the bare CUE expression:
schema:
frontmatter:
legacy_owner:
type: string
deprecated: true
message: 'use "owner" instead'
owner:
type: stringThe loader recognizes the map form when it sees
a type: key (which is otherwise illegal at the
top of a CUE expression in this position). The
short string form continues to work for the
common case.
A proto.md schema uses the same shape inside
its CUE front matter. CUE structs support
extra metadata fields out of the box; the
loader treats deprecated, message, and
replaced-by as known keys and the rest as
constraints.
When a file's front matter contains a deprecated field:
legacy_owner: deprecated field
message: use "owner" instead
schema: plan/proto.md:12
severity: warning
The diagnostic uses plan 147's shape with
Severity: Warning instead of Error. The
file's exit code (with --error-on warning
unset) does not change.
replaced-by: is a richer alternative to
message: — when set, mdsmith can render a
canonical sentence:
legacy_owner:
type: string
deprecated: true
replaced-by: owner→
legacy_owner: deprecated; replaced by `owner`
A schema may set both; message: wins for the
human-facing line, replaced-by: is exposed in
the structured diagnostic for tooling.
A deprecated field stays in the schema and
continues to be validated. A file with
legacy_owner: 42 (where the schema says
legacy_owner.type: string) emits two
diagnostics: a warning for deprecation and an
error for the type violation. The deprecation
does not mute other checks.
When the project is ready to remove the deprecated field entirely, the maintainer deletes the entry from the schema. From that point the field is "unknown" and falls under the schema's existing closed/open posture.
- Extend the inline-schema parser (plan 146)
and the
proto.mdfront-matter parser to accept the map form ({type, deprecated, message, replaced-by}) for a field. - Pipe the deprecation metadata into the schema engine's per-field state.
- Emit a Warning-severity diagnostic when a
deprecated field is present in front matter,
using plan 147's
SchemaDiagnosticshape. - Continue evaluating the field's
type:constraint; emit a separate diagnostic if it fails. The warning and the type error coexist. - Add a
Deprecated boolandReplacedBy stringto the structured diagnostic so LSP clients and CI scripts can route warnings without parsing the message. - Document deprecation semantics in the MDS020 README and link from the file-kinds guide.
- Tests:
- a deprecated field present in FM emits a
Warning diagnostic with the
message:payload, replaced-by:renders the canonical sentence in the absence ofmessage:,- a deprecated field that violates its type emits both a deprecation Warning and a type Error,
- removing the field from the schema returns the file to its closed/open posture.
- An inline-schema field with
deprecated: trueemits a Warning-severity MDS020 diagnostic when present in a file's FM. - A file-schema field with
deprecated: truedoes the same. -
message:text appears in the diagnostic;replaced-by:renders a canonical sentence whenmessage:is absent. - A deprecated field that also violates its
type:produces two diagnostics — one Warning, one Error. - Exit code is unchanged when only Warning
diagnostics fire (default
--error-onthreshold). - Removing the field from the schema returns the file to its prior posture (no warning, closed/open behavior unchanged).
- All tests pass:
go test ./... -
go tool golangci-lint runreports no issues.