WORK-213
ID:WORK-213Status:done

Frontmatter schema extension (tint, tint-mode, tint-lock)

Add the three cascade fields — tint, tint-mode, tint-lock — to the validated frontmatter shape for both _layout.md files and page frontmatter. Validates values, rejects invalid types/values with clear errors, distinguishes YAML null from missing per the cascade semantics.

Priority:highComplexity:smallMilestone:v0.14.0Source:SPEC-052
claude/v0.14.0-spec-052-cascade-machinery View source

Criteria completion

Criteria completion: 7 of 7 (100%) checked; tracking started on May 18, no incremental history yet0%25%50%75%100%May 18Jun 15

Tracking started May 18 — check back for trends.

Branches 2
claude/v0.14.0-spec-052-cascade-machinery current done
main doneclaude/spec-053-tint-authoring-notes ready
History 1
  1. e515b1c
    Created (done)by bjornolofandersson

Acceptance Criteria

  • tint?: string | null accepted in layout and page frontmatter; named tints validated against the configured tint registry where possible (warn rather than fail if an unknown tint is referenced, since tints may be added/removed at runtime)
  • tint-mode?: 'auto' | 'light' | 'dark' accepted; invalid values produce a clear error ("tint-mode must be one of: auto, light, dark")
  • tint-lock?: boolean accepted; non-boolean values rejected with a clear error
  • YAML null (tint: ~ or tint: null in YAML) is preserved as JS null through parsing — distinguishable from missing
  • Missing fields don't appear in the parsed frontmatter object (or are explicitly undefined) — distinguishable from null
  • Validation errors include the source file path and line number when possible
  • Unit tests cover: each valid value, each invalid value type, null vs missing distinction, validation failure messages

Approach

Schema extension in whichever module owns frontmatter parsing — likely packages/content/ or packages/types/. Most projects use a runtime schema validator; check what refrakt already uses.

The null vs missing distinction is the most error-prone part. Most YAML parsers handle it correctly by default, but the JS layer often coerces both to undefined. Write a specific test that parses both tint: (empty) and tint: ~ and confirms the parsed object distinguishes them.

The named-tint validation is advisory, not strict — a tint might be added in a plugin loaded after the page is parsed, or removed at runtime via config changes. Warn on unknown names; don't fail builds. The cascade resolution in WORK-212 will just pass the unknown name through; the engine in WORK-214 will set data-tint="unknown-name" which simply won't match any defined tint.

Dependencies

None (or minimal — independent of SPEC-048 since frontmatter parsing already exists). Can start in parallel with the foundation work.

References

  • SPEC-052 — "Frontmatter Authoring Surface" section
  • The frontmatter validation surface — locate during implementation; the field-naming convention is the same as the existing rune attributes