Skip to content

fix: NodeAdapter system-code identity + the ISC_SWEEP measurement gate - #778

Merged
ronaldtse merged 4 commits into
mainfrom
feat/isc-sweep-harness
Sep 29, 2026
Merged

ronaldtse merged 4 commits into
mainfrom
feat/isc-sweep-harness

Conversation

@ronaldtse

Copy link
Copy Markdown
Contributor

Two pieces of the sweep-enablement work (task: full-corpus conformance):

The fix

The NodeAdapter read isc_doc[:system_code] but DocumentBuilder emits :systemCode — every ISC-parsed document got name: nil. The Ruby compiler registers compiled maps under Document#name, so every ISC map compiled under the empty string and every Compiler::Ruby transliteration crashed with undefined method 'call' for nil. This was the detector walk crash, and it masked Ruby-compiler corpus coverage entirely.

Pinned by a spec on the adapter (red on main: name was nil).

The measurement gate

ISC_SWEEP=1 un-gates the corpus sweep in spec/interscript_spec.rb (per-example timeouts already bounded it). Measured with this fix:

  • 16,262 examples, 6 failures — all iso-mal-Mlym-Latn-15919-2001 on the Ruby compiler: one lookahead character class is compiled from an object inspect-string (#<Interscript::Isc::Items::Primitive:0x…> interpolated character-by-character) instead of the ZWJ/ZWNJ codepoints, so the ം → m rule over-fires. Root cause located (compiler/ruby.rb Any-value construction); the fix is the next unit.

The gate keeps CI on the legacy scope while that tail closes; the sweep exists to measure exactly this gap.

The per-example timeouts already bound the sweep (16,262 examples,
16k pass, 6 fail — all iso-mal-Mlym-Latn-15919-2001 on the Ruby
compiler; the Interpreter passes the same map, so it is a codegen
divergence, not a corpus gap). The gate keeps CI on the legacy scope
while the conformance tail closes.
The adapter read isc_doc[:system_code] but DocumentBuilder emits
:systemCode — every ISC-parsed document got name: nil, and the Ruby
compiler (which registers compiled maps under Document#name) compiled
every ISC map under the empty string. Transliterate then crashed with
'undefined method call for nil' — the same crash the detector's
full-corpus walk hit. Interp-vs-compiled divergence on
iso-mal-Mlym-Latn-15919-2001 is also gone for the direct paths; the
remaining sweep failures there are a separate codegen bug (an object
inspect-string interpolated into a lookahead character class).
any([boundary, ZWNJ, ZWJ]) leaked the boundary primitive as a raw
Isc::Items::Primitive into Any's value; the Ruby compiler then baked
the object's inspect string into the compiled character class
character-by-character, and the rule's lookahead matched positions it
must not. Set entries now convert through the alias/primitive paths.
@ronaldtse
ronaldtse merged commit 7aed64e into main Sep 29, 2026
4 of 10 checks passed
@ronaldtse
ronaldtse deleted the feat/isc-sweep-harness branch September 29, 2026 14:17
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