Standing differential regexp fuzzer + 12 new reject classes (TASK-54) - #40
Merged
Conversation
ahrzb
approved these changes
Jul 27, 2026
…t classes from its first deep run (TASK-54) Grammar-biased duckdb-vs-engine fuzzer in the normal gate (~4s, fixed seed, env-overridable). First deep run: 122 divergences in 3k cases; after the retrans.rs fixes (reject list + POSIX class tracker + rewrite MaxSubmatch pre-scan), zero divergences over 40k cases / 8 seeds. Pins: pins-waveB/fuzzer-task54.json + spec addendum. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
claude-agent-ahrzb
Bot
force-pushed
the
task-54
branch
from
July 27, 2026 02:05
24bf173 to
89acbd0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A standing differential fuzzer for the wave-B regexp engine, plus the reject-list additions its first deep run demanded. Stacked on #39 (
task-53) — will retarget to master automatically when that merges.tests/test_duckdb_regexp_fuzz.py— generates patterns from a grammar biased toward the divergence-prone axes (Perl classes in/out of char classes, inline flags, alternation, bounded repetition incl. the 1000-cap edge, escapes, Unicode properties, class edge shapes, options strings, replacement templates) and runs each through BOTH duckdb andDuckDBInferFnon a tiny table. Per-case contract: identical rows, OR engine build-time reject, OR both error; duck-errors-while-engine-serves and mismatches fail withseed + case index + SQLin the message. Fixed seed,REGEXP_FUZZ_SEED/REGEXP_FUZZ_Noverrides, ~4s at the default N=250 (in the normal gate, no marker needed).What it found (all fixed in
retrans.rs, pinned inpins-waveB/fuzzer-task54.json+ spec addendum)First run: 122 divergences in 3k cases, 12 construct classes — including three silent wrong-answer shapes and one DuckDB self-inconsistency:
\1-\9outside a class — RE2 backref-reject vs rustoctal(true)serve → reject{2}*,?*,*{2},a???) → quantifier-state machine(c{3,}..){1,999}) → reject past product{1, 3}spaced bounds — literal to RE2, repetition to rust (wrong answers) → reject--/&&/~~in classes — RE2 literals/ranges vs rust set operations (wrong answers) → reject[in classes — rust nested classes (wrong answers) → reject[:...:]desynced the class tracker ([[:alpha:]\d]mis-rewrote) → fixed, consumed atomically[a-\d],[\x08-\s]) → reject]([]-Z]) → reject$\z,^^): DuckDB's row path literal-optimizes to string equality (FALSE for'hello') while its own constant fold says TRUE — unservable, reject(x){0}— rust erases the capture group, shifting group numbers and the rewrite pre-check → rejecttranslate_rewritepre-scansAfter fixes: zero divergences over 40k cases / 8 seeds.
Verification
uv run python scripts/gate.pygreen: 155 Rust + 802 py (corpus replay intact — the new rejects demote nothing that was matching)retrans.rstask-54Done, all ACs checked🤖 Generated with Claude Code