Skip to content

schema: add diff engine + real schema corpus (foundation, no CLI yet) - #20

Merged
Paritsingla7 merged 2 commits into
mainfrom
feat/schema-diff-foundation
Aug 28, 2026
Merged

Paritsingla7 merged 2 commits into
mainfrom
feat/schema-diff-foundation

Conversation

@Paritsingla7

Copy link
Copy Markdown
Owner

Summary

Phase 0+1 of the schema-diff idea (comparing Hyprland's API between two versions to eventually warn a config about upcoming breakage, not just validate against whichever one version it's pointed at today). Deliberately foundation only — no CLI surface — wanted the core comparison logic validated against real version transitions before deciding how to expose it.

  • schemas/v0.55.0.json .. v0.56.2.json — one real schema per tagged Hyprland release (all 8 that exist), not synthetic fixtures. Cross-checked against schema.json already in this repo — identical.
  • scripts/generate_schema_history.py — regenerates/extends the corpus. Confirmed generateLuaStubs.py is pure static analysis over C++ source text (no build needed), and that it must be run as each tag's own copy against that tag's own source, since the generator's own parsing logic has changed across versions. Verified end-to-end against the live Hyprland repo — regenerating a removed schema reproduced it byte-for-byte.
  • hyprvalidate/schema/diff.py — diff_schemas(): classes/fields/aliases/config-keys added, removed, type-changed, plus a conservative "possible rename" heuristic (fires only on a clean 1:1 same-type match, never guesses past that).

Grounded in two real, dated Hyprland regressions

  • hl.permission{}'s allow → mode (hyprwm/Hyprland#14400, broke one day after Lua config first shipped) — a clean 1:1 match the heuristic catches confidently.
  • HL.Window's over_fullscreen → allowed_over_fullscreen (hyprwm/Hyprland#15367) — genuinely ambiguous by type alone (two new booleans were added, not one) and is deliberately left as a plain removal rather than guessed at. Asserting this negative is the point: a wrong confident guess is worse than an honest gap.

Every diff is phrased as "the schema changed," never "this will break" — the generated stub has itself lagged real Hyprland behavior more than once (the allow/mode field was wrong from the version it first shipped in), so a schema diff is evidence of a possible behavior change, not proof of one.

Test plan

  • pytest tests/ — 203 passed (3 pre-existing/environmental entry-point failures unrelated, deselected)
  • scripts/generate_schema_history.py run end-to-end against the live Hyprland repo (temporarily removed one schema, regenerated it, byte-identical to the original and to the repo's own schema.json)
  • Tag-discovery logic verified to exclude ancient pre-rewrite tags (e.g. v0.6.0beta) and find exactly the 8 real Lua-era releases

Phase 0+1 of the schema-diff idea: comparing Hyprland's API between two
versions to eventually warn a config about upcoming breakage, not just
validate against whichever one version it's pointed at today. This PR
is the foundation only - a diff engine and the data it needs - no CLI
surface, deliberately: wanted the core comparison logic validated
against real version transitions before deciding how to expose it.

- schemas/v0.55.0.json .. v0.56.2.json: one real schema per tagged
  Hyprland release (all 8 that exist), not synthetic fixtures.
  Cross-checked against schema.json already in this repo - identical.
- scripts/generate_schema_history.py: regenerates/extends the corpus.
  Confirmed generateLuaStubs.py is pure static analysis over C++
  source text (no build needed), and that it must be run as *each
  tag's own* copy against *that tag's own* source, since the
  generator's own parsing logic has changed across versions. Verified
  end-to-end against the live Hyprland repo - regenerating a removed
  schema reproduced it byte-for-byte.
- hyprvalidate/schema/diff.py: diff_schemas() - classes/fields/
  aliases/config-keys added, removed, type-changed, plus a
  conservative "possible rename" heuristic (fires only on a clean 1:1
  same-type match, never guesses past that).

Tested against two real, dated Hyprland regressions found while
researching this: hl.permission{}'s allow -> mode (Hyprland#14400,
broke one day after Lua config shipped) is a clean 1:1 match the
heuristic catches; HL.Window's over_fullscreen -> allowed_over_fullscreen
(Hyprland#15367) is genuinely ambiguous by type alone (two new
booleans were added, not one) and is deliberately left unguessed.

Every diff is phrased as "the schema changed," never "this will
break" - the generated stub has itself lagged real Hyprland behavior
more than once (the allow/mode field was wrong from the version it
first shipped in), so a schema diff is evidence of a possible behavior
change, not proof of one.
@Paritsingla7
Paritsingla7 merged commit 476e863 into main Aug 28, 2026
6 checks passed
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