Ray's Knowledge Base

Record the old parser's output over every in-repo query before replacing the parser

RecipeVerified 27 Sep 2026Holds anywhere
Recipe. When to use it, the steps, and what showed that they work.

When to use#

You replace a parser (a query language, a config format) and promise that every input accepted before keeps its meaning. Unit tests of the new parser do not prove that: they test what you thought of, not what the repo already writes.

Steps#

  1. Before touching the old parser, collect every input string the repo uses: scan tests, docs, examples and benchmarks for the call sites that take the language (for a query DSL: from_string(, parse(, .query(, --query, query=), decoding raw strings and escapes. Deduplicate.
  2. Build a small recorder against the current library, outside the repo (a scratch source compiled with the compile and link lines of an existing test target, from ninja -t commands <target>). For each input, write one JSON line: the input, whether it parsed, and the old parser's printed tree.
  3. Commit that file as a golden corpus, and add a test that parses each input with the new front end and requires the same printed tree, or the same failure.
  4. Run it right after the cutover. Every difference is either a listed, intended break or a regression to fix.

Evidence#

  • dftracer-utils duql stage 12a1 (2026-09-27): scripts/collect_duql_corpus.py found 402 filter strings (393 parsed with the old parser); tests/duql/golden_filters.jsonl and test_duql_golden. The first run after the cutover found two regressions that the new unit tests had missed: "sub" in any(tags) no longer parsed, and a numeric key after a dot (tags.0 > 5) failed. Both were fixed before the change was done.