A gap is a position where, on valid input (accepted by the language’s external
authority — typescript / yaml / parse5), the flat TextMate highlighter paints a token a
different visual role than the Monogram parser assigns it by construction. These are the
floor-blind divergences the generative scope≡role check (test/generative.ts) DISCOVERS over
grammar-derived inputs — the monogram#23/#24 class — which the corpus-bound scope-gap metric is
blind to (a small/clean corpus may never contain the shape, and the role-graded metric ignores
punctuation-floor mis-paints). Each gap’s input is minimized (delta-debugged to a minimal
repro that still parses and still diverges) and fingerprinted (a content hash, stable across
commits) so the ledger is deterministic and commit-trackable.
Regenerate: node test/gap-ledger.ts --write · verify up-to-date: node test/gap-ledger.ts --check.
2 gaps across 7 grammars · 0 dropped.
- Language: html
- Minimal repro:
<A A=""/> - Divergent token:
/(parser token$punct) - Role vs scope: want punct, got string (highlighter scope
string.unquoted.html) - Fingerprint:
525e867dc205
{
"id": "525e867dc205",
"language": "html",
"kind": "#24 structural-literal→content",
"repro": "<A A=\"\"/>",
"tokenType": "$punct",
"tokenText": "/",
"want": "punct",
"got": "string",
"gotScope": "string.unquoted.html"
}- Language: vue
- Minimal repro:
<A A=""/> - Divergent token:
/(parser token$punct) - Role vs scope: want punct, got string (highlighter scope
string.unquoted.vue) - Fingerprint:
85c793d02a86
{
"id": "85c793d02a86",
"language": "vue",
"kind": "#24 structural-literal→content",
"repro": "<A A=\"\"/>",
"tokenType": "$punct",
"tokenText": "/",
"want": "punct",
"got": "string",
"gotScope": "string.unquoted.vue"
}