Skip to content

refactor(frontmatter): derive writability facets + predicate from one source - #290

Merged
mtskf merged 2 commits into
mainfrom
chore/enforce-writability-facet-sync
Jul 29, 2026
Merged

refactor(frontmatter): derive writability facets + predicate from one source#290
mtskf merged 2 commits into
mainfrom
chore/enforce-writability-facet-sync

Conversation

@mtskf

@mtskf mtskf commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Summary

isWritable() and writabilityFacets in reveal-state.ts were two independent hand-written enumerations of the same "which facets gate writability" fact, tied together only by a KEEP-IN-SYNC JSDoc comment — no compile-time or test-level enforcement. This mechanizes the sync so the two can no longer drift.

Changes

  • Introduce a single polarity-tagged writabilityInputs table ([{ facet, writableWhen }]) as the one source of truth.
  • Derive both writabilityFacets (the reactive compute() dependency list) and isWritable() (the predicate) from that table — adding a writability input is now one row, and both update by construction.
  • Add test/webview/frontmatter/cm-frontmatter-writability.test.ts: pins the isWritable truth table, asserts writabilityFacets covers exactly the gating facets, and verifies no dead dependency entries. Verified non-vacuous (goes red on polarity drift).

Related

Test Plan

  • pnpm compile green
  • pnpm test:unit green (4116 tests)
  • New writability test goes red if either facet's polarity is inverted or a facet is dropped from the dependency list

mtskf added 2 commits July 29, 2026 16:58
… source

isWritable() and writabilityFacets were two hand-written enumerations of
the same 'which facets gate writability' fact, tied only by a KEEP-IN-SYNC
JSDoc comment. Adding a third writability input to isWritable() without
extending writabilityFacets would silently reintroduce the stale
aria-description bug PR #279 fixed (the reactive dependency list would stop
covering a facet the predicate reads).

Both now derive from a single polarity-tagged writabilityInputs table, so
the predicate and its reactive dependency list stay in lockstep by
construction. A new unit test pins the contract and goes red on polarity
drift or a dropped dependency.
…est drive the list

Review-cycle findings on the prior commit:
- writabilityFacets was widened to a mutable Facet[] by .map(); type it
  readonly (and freeze the writabilityInputs row fields) so the derived list
  is as immutable as the old 'as const' tuple, preserving the drift guarantee.
- The 'no dead entries' test asserted the same two combinations as the truth
  table without ever referencing writabilityFacets. Rewrite it to iterate the
  real list: flipping any one listed facet away from its writable value must
  break isWritable, so a facet listed but ignored by the predicate now fails.
@mtskf
mtskf merged commit 0823c64 into main Jul 29, 2026
1 check passed
@mtskf
mtskf deleted the chore/enforce-writability-facet-sync branch July 29, 2026 07:13
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