@@ -15,7 +15,8 @@ does not add its own parity harness, property suite or E2E file.
1515` native_fallbacks.toml ` is the one allow-list of all work native code still hands back to Python.
1616It covers both kinds of record:
1717- shipped-stage fallbacks, from ` report_native_fallback(site=NativeFallbackSite.<SITE>, kind=...) ` ;
18- - preview analysis-stage deferrals, from ` record_analysis_deferral ` and ` record_lineage_deferral ` .
18+ - preview analysis-stage deferrals: every ` analysis-deferrals-*.jsonl ` record (analysis session,
19+ lineage, semantic checks, contracts).
1920
2021Every entry names an engine, stage, site and kind, with its exact count per corpus. Use
2122` max_counts ` instead of ` counts ` only for a count that is not stable, and give the reason in a
@@ -29,28 +30,38 @@ sets. `--native-fallbacks check` runs in both make targets and fails CI in both
2930
3031The counts hold for the make targets' corpus (` --seeds 12 ` ); other seed ranges are refused.
3132
32- ** How a PR updates the list**
33-
34- 1 . A port deletes the Python code it replaces in the same PR. Its sites drop to zero and the gate
35- names the entries to remove; removing them is the port's test that the fallbacks are gone.
36- When the last entry for a ` NativeFallbackSite ` goes, delete the member and its
37- ` report_native_fallback ` call too.
38- 2 . If the corpus does not reach a site yet, first add a failure case or seed feature that does.
39- 3 . To rewrite the list from a run, use the same arguments as CI and add `--native-fallbacks
40- update` to both targets:
41-
42- ``` sh
43- make compiler-differential COMPILER_DIFFERENTIAL_ARGS=" --stage-captures \
44- --require-discovery-coverage --require-render-coverage --require-analysis-coverage \
45- --native-fallbacks update"
46- make compiler-differential-shipped COMPILER_DIFFERENTIAL_ARGS=" --stage-captures \
47- --require-discovery-coverage --require-render-coverage --native-fallbacks update"
48- ```
49-
50- Review the diff. Any added entry or higher count needs a reason in the PR body; never add one
51- just to make CI pass.
52- 4 . The gate is proven by sabotage in ` test_native_fallback_gate.py ` : forcing a native stage to
53- defer everything must fail it. A new "native did the work" gate needs the same proof.
33+ ** How a PR updates the list and the goldens**
34+
35+ One command rewrites both from the current tree:
36+
37+ ``` sh
38+ make compiler-baselines
39+ ```
40+
41+ It deletes ` tests/goldens/compiler ` , then runs the two CI differentials with `--native-fallbacks
42+ update --goldens update` . Commit the resulting ` native_fallbacks.toml` and ` tests/goldens/` diff
43+ in the same PR as the change that caused it.
44+
45+ - A port deletes the Python code it replaces in the same PR. Its entries then disappear from the
46+ list, and that removal is the port's test that the fallbacks are gone. When the last entry for
47+ a ` NativeFallbackSite ` goes, delete the member and its ` report_native_fallback ` call too.
48+ - If the corpus does not reach a site yet, first add a failure case or seed feature that does.
49+ - A PR that merges after a list or golden change on main reruns ` make compiler-baselines ` after
50+ rebasing and commits the result.
51+
52+ ** What a reviewer checks in the diff**
53+
54+ - ` native_fallbacks.toml ` :
55+ - Removed entries and lower counts are expected from ports.
56+ - Every added entry, higher count or new ` max_counts ` needs a stated reason in the PR body.
57+ Never add one just to make CI pass.
58+ - Goldens:
59+ - Every changed golden is an intended output change, named in the PR body.
60+ - An output-neutral port changes no golden.
61+ - New goldens belong to new corpus cases.
62+ - Proof by sabotage: ` test_native_fallback_gate.py ` proves the gate by sabotage, so forcing a
63+ native stage to defer everything must fail it. A new "native did the work" gate needs the same
64+ proof.
5465
5566### Golden outputs
5667
@@ -63,16 +74,17 @@ Project paths, the SQLBuild version, invocation ids and timings are masked.
6374
6475- ` --goldens check ` (in both make targets) compares every engine with the goldens, so an
6576 output-neutral port needs no new parity suite.
66- - ` make compiler-goldens ` rewrites them from the python oracle. Run it only when output changes
67- on purpose, and review the diff like code.
77+ - ` make compiler-baselines ` rewrites them from the python oracle. Run it only when output
78+ changes on purpose, and review the diff like code.
6879- Seeds outside the recorded range have no golden and are skipped; any other project without a
6980 golden fails.
7081- Once the Python stages are deleted, goldens are rewritten from ` native ` .
7182
7283### All-engine user-facing errors
7384
74- ` engine_error_cases() ` in ` _helpers/corpus/failure_cases.py ` lists user-facing errors with their exact text. Each case
75- is part of the failure corpus, so it runs in both differentials and has a golden. It also runs in
85+ ` engine_error_cases() ` in ` _helpers/corpus/failure_cases.py ` lists user-facing errors with their
86+ exact text. Each case is part of the failure corpus, so it runs in both differentials and has a
87+ golden. It also runs in
7688` tests/e2e/scripts/compiler_differential/test_engine_error_cases.py ` on the ` python ` , ` native `
7789and ` native-preview ` engines, which must all report its ` expected_code ` and ` expected_message ` .
7890
@@ -87,4 +99,4 @@ failure_case(
8799)
88100```
89101
90- Then it runs ` make compiler-goldens ` to record the new case's golden.
102+ Then it runs ` make compiler-baselines ` to record the new case's golden.
0 commit comments