tok._rx_lits bindingRXLITS (regex → literal runs, the Russ Cox trigram-filter feed) sits in beagle/spot/RXLITS.c.rl but is another grammar for dog/tok by nature: a self-contained ragel machine over pattern bytes, depending on abc/INT.h only. /todo/SPOT/SPOT-003's JS regex filter needs it, and jab links only the dog submodule + abc-core — spot's C is out of reach from JS land; hand-parsing regex in JS is banned.
RXLITSu8sDrain(pattern, cb, ctx) — cb gets each literal byte, flush=YES at meta-boundaries, final flush always.tok._tok_parse_into, tok.cpp); the binding follows that pattern.Move the machine into the dog submodule and expose it to JS.
RXLITS.c.rl/RXLITS.h from beagle/spot/ to dog/tok/ (DOG-002 relocation model); spot's C includes update.((a|b)c|d) makes flush-only insufficient — emit group open/close, alternation bar, quantifier, literal-run events; the ragel machine stays the ONLY regex reader.tok._rx_lits(pattern) → the event/token stream; JS folds it: concat = AND, | = OR, ?/*-quantified subtree = contributes nothing → an AND-of-OR trigram filter (CNF), consumed by /todo/SPOT/SPOT-003 candidates.dog/INDEX.md + spot includes; both trees build; C consumer (GREP.c regexlits) migrates or keeps a compat shim.foo|bar yields two intersectable runs → over-filtering, silently dropped matches (GREP.c regexlits may carry this today; check, ticket separately if real). The structural stream is the fix; the fold's truth table is the repro.tok._rx_lits JABC binding (event stream) + jab test leg (test/tok.js)foo|bar → OR, ((a|b)c|d) → nested, (abc)?def → def only, class/shorthand legs(pending)