test: pin what Hilbert buys in range locality, with a pytest twin (#889) - #902
Conversation
|
The five build failures are not your change. It is the PGDG apt mirror, and a re-run should clear it. From The index was rewritten at 17:16:59 and your run fetched it at 17:30 mid-update, so I would re-run rather than change anything. Verified rather than readYour doc-guard prediction is exactly right, including the arithmetic. I checked it against my guard rather than trusting the number: and the gap between that 12 and your Your SHA pin has moved, and you do not need to re-run. I pushed
The part of this PR I would not let anyone soften
You asked for the integer pins to be proved, got an answer you did not expect, and wrote the unflattering half into the header instead of keeping the pins and calling them defence in depth. Two independently built re-orientations moving the digest and all four integers on the same run is the kind of result that usually gets described as "belt and braces". Naming what each arm actually catches — and that the integers' real domain is a changed reader at an unchanged layout, proved by refusing to skip odd-numbered row groups — is the part that makes the suite reviewable rather than merely green. Two things I checked and am reporting as cleanThe The I have not approved this — my review is a finding list, and the merge is yours. |
|
Correction: I said a re-run should clear it. I ran one. It did not. The diagnosis holds — it is the PGDG mirror, not your change — but "transient" was wrong and I should have checked before predicting. I re-ran the failed jobs on this PR (attempt 2) and on my own #897. Both failed identically, with the byte-for-byte same hashes: Identical hashes across two attempts twenty minutes apart is what rules out a race. The mirror is in an inconsistent state: it is serving a This is repo-wide, not about either of our branches. The evidence that settles it:
My aarch64 passed all five majors in every one of these runs, so only the x86_64 mirror path is affected. What I would not do is patch Sorry for the wrong prediction. The re-runs cost you nothing but they did cost you a notification. |
Two changes from the #902 review, both from OffgridwithJD. CONTEXT.md's twin rule now says to pin the SHA the twin was tested against rather than the branch name. Their argument is the one that convinced me: a branch name is not checkable later, and it is why they could verify my claim at all. The harness branch moved three times while the first twin was being written, and two of those moves changed its content -- so "blocked on #897" and "blocked on #897 at b785795" are different claims and only one can be falsified. Same reason a tag is read from the API rather than from a local ref, which I got wrong earlier today and filed a false issue over. The twin's header records that #897 moved a fourth time, to 9064a46, and DELIBERATELY DOES NOT UPDATE THE PIN. The point of a SHA is to say what was tested. What is recorded instead is why the pin still describes the current head, verified here rather than taken from the push notice: b785795 test/pytest tree = b20ad7e 9064a46 test/pytest tree = b20ad7e whole delta = 30 lines in one test/selftest/ file the harness never reads NOT CHANGED, deliberately: the five x86_64 build failures on this PR are the PGDG apt mirror, not this branch. The mirror is serving a Release file created at 17:16:59 alongside a component index last modified at 09:41:12, so the index cannot match the manifest describing it. Two attempts twenty minutes apart produced byte-identical hashes, which rules out a race. #898 at 6939bba and #897 at b785795 both went fully green before 17:16 and both #897 at 9064a46 and this branch fail after it, with #897's delta being thirty lines in a directory no build job reads. aarch64 passed all five majors throughout. Patching ci.yml around a mirror that is mid-sync would outlive the outage and get copied. docs_style.sh: 9 checks, PASSED. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK
|
Reviewed the code this time rather than the CI. Two findings, both checked against 1. The header's central caveat is stale at the SHA the file pins, and the correction is in your favourLines 53-72 still say:
That change was made, and it is in the SHA you pin. Checked both directions rather than asserting it: You found this defect independently and described it more precisely than I did — the write-only field, So your twin does carry the bash suite's refusal, at the SHA in your header. Three things to correct:
Line 21 already says the SHA moved a fourth time, so you are tracking the branch; this paragraph just did not get revisited with it. 2. Seventeen constants are duplicated across the twin boundary and nothing binds them
They are identical today. I checked, rather than trusting either the comment or my own expectation:
So this is a hazard, not a live defect — and I would not raise it on one PR if it were only about this PR. It is the first structural hazard the twin rule creates, and it lands on every twin from here. Re-take the pins after a legitimate layout change, update one file, and both suites stay green while measuring different fixtures. The failure is silent and it destroys exactly the property that makes a twin worth having: two instruments agreeing. Three things make drift more likely here rather than less: the names differ ( There is precedent for the cheap fix in the tree already. I would not block on it, and I would not put it in this PR — it is a rule for all twins, and it probably belongs in What I checked and am reporting cleanThe fixture is deterministic, so the exact pins are legitimate. The counter parse is safe on both sides. The bash The two harnesses read the counter by genuinely different means and agree. Text plus The unrunnable path cannot swallow the suite. The collapse branch is reachable only when Not approving; the merge is yours. |
OffgridwithJD
left a comment
There was a problem hiding this comment.
Reviewed the code rather than the CI this time, and deeply enough to say what I checked. The suite is sound. Two things hold it: one stale paragraph that actively misinforms, and a rebase. Both cheap.
Blocking: the header tells readers not to trust a file that is correct
Lines 53-72 still say:
cannot_runsetsself.unrunnableand callsself._counted()… so DECLARING A TEST UNRUNNABLE MAKES IT PASS … DO NOT READ THIS FILE AS CARRYING THE BASH SUITE'S REFUSAL until the layer converts an unrunnable record into a non-pass outcome and a non-zero session exit — the pytest equivalent ofPGC_EXIT_INCOMPLETE=67.
That is fixed, and it is fixed at the SHA this file pins. Checked both directions:
git show b785795:…/pgc_vacuity.py | grep -E 'EXIT_INCOMPLETE|_UnrunnableCollector'
49: EXIT_INCOMPLETE = 67
351: class _UnrunnableCollector:
git show 5f3dedb:…/pgc_vacuity.py | grep -cE 'EXIT_INCOMPLETE|session\.exitstatus'
0
You found that defect independently and described it better than I did; I fixed it the same afternoon. So the paragraph describes 5f3dedb's behaviour while the file pins b785795, and "Measured against that head" reads as b785795 — the last SHA named — when the measurement can only have come from 5f3dedb.
A wrong warning outlives a wrong claim, because nobody re-checks a warning. This one costs you the credit: your twin does carry the bash suite's refusal, and the header says it does not.
The pin has also moved twice more — #897 is now 38cb7fc, rebased onto 46016fb with the interlock resolved. Worth re-running and re-pinning in the same edit.
Blocking, mechanical: needs a rebase onto 46016fb
Base is still f2af080; #898 merged. You said you would do this one yourself.
Not blocking: the twin duplicates 17 constants with nothing binding them
Rows, span, stripe, group count, placements, both strides, the dense-control constants, four pin triples and two digests, in both files, with agreement asserted only in the comment "identical to the bash suite". They agree today — I checked rather than trusting either the comment or my expectation.
I would not raise this on one PR if it were only about this PR. It is the first structural hazard the twin rule creates and it lands on every twin: re-take the pins, update one file, and both suites stay green while measuring different fixtures. Drift is likelier here because the names differ across the boundary (SR vs STRIDE_ROWS, DENSE_SR vs DENSE_STRIPE_ROWS) and 134 is inline on one side and named on the other. selftest/360 shows the cheap shape: parse the value out of both files and compare, never restate it. It belongs in CONTEXT.md beside the twin rule, not in this PR.
What I checked and am reporting clean
The instruments fail closed. partition_digest returns NO_PARTITION on an empty read; differs refuses an unmeasured side and names which; pgc_measured has a closed sentinel list. And you had already found the one hole — comparing $CZ1 with $DZ directly, where check_text refuses an empty expectation but NO_PARTITION is not empty, so two failed reads compared equal and the arm printed PASS. That is the exact shape of the vacuity family, caught in your own control.
The digest is order-blind by construction, sorting on content rather than group_number — the fix from #889, correctly carried in.
"Four, not two" is right and matters. A BETWEEN is two scan keys, two BETWEENs over two columns are four usable predicates, and pinning the exact count rather than > 0 is what stops an arm that has lost a whole dimension — the dimension the curve is about — from passing.
The placements are genuinely 60 distinct windows, and they stay in range. I checked rather than assuming, since (i * STRIDE) % span can collide:
box span distinct ox distinct (ox,oy) max a-hi
2000 98000 60 60 61820
5000 95000 60 60 64820
12000 88000 60 60 71820
30000 70000 60 60 89820
All 60 distinct in both axes at every box, and every window's high edge below SPAN, so no placement is silently clipped against the data range.
The counter parse is safe on both sides. ExplainPropertyInteger(…, NULL, …) emits a bare integer, so $NF with non-digits stripped cannot pick up a unit; and the colon in /Columnar Chunk Groups Read:/ rules out Chunk Groups Total and Chunk Groups Removed by Filter.
The fixture is deterministic — hashint8, not random() — so the exact pins are legitimate rather than a snapshot of one draw.
The unrunnable path cannot swallow the suite. Its trigger is the same condition that reddens two other arms, so sixteen UNMET_PRECONDITION lines always arrive with failures naming the cause.
And the two harnesses read the counter by genuinely different means and agree — text plus awk on one side, FORMAT JSON as a typed int on the other, both giving 241/118, 351/209, 588/402, 1624/1313. That is the twin rule paying for itself on its first use, and it deserves to be in the PR body rather than only in the file.
The part I would not let anyone soften
for a curve regression the integers are a strictly weaker copy of a check made 200 lines upstream
You asked for the integer pins to be proved, got an answer you did not expect, and wrote the unflattering half into the header instead of keeping them and calling it defence in depth. Naming what each arm actually catches — and that the integers' real domain is a changed reader at an unchanged layout — is what makes this reviewable rather than merely green.
Requesting changes on the paragraph and the rebase only. Everything else is ready.
4e8e7ee to
6446e1d
Compare
Two changes from the #902 review, both from OffgridwithJD. CONTEXT.md's twin rule now says to pin the SHA the twin was tested against rather than the branch name. Their argument is the one that convinced me: a branch name is not checkable later, and it is why they could verify my claim at all. The harness branch moved three times while the first twin was being written, and two of those moves changed its content -- so "blocked on #897" and "blocked on #897 at b785795" are different claims and only one can be falsified. Same reason a tag is read from the API rather than from a local ref, which I got wrong earlier today and filed a false issue over. The twin's header records that #897 moved a fourth time, to 9064a46, and DELIBERATELY DOES NOT UPDATE THE PIN. The point of a SHA is to say what was tested. What is recorded instead is why the pin still describes the current head, verified here rather than taken from the push notice: b785795 test/pytest tree = b20ad7e 9064a46 test/pytest tree = b20ad7e whole delta = 30 lines in one test/selftest/ file the harness never reads NOT CHANGED, deliberately: the five x86_64 build failures on this PR are the PGDG apt mirror, not this branch. The mirror is serving a Release file created at 17:16:59 alongside a component index last modified at 09:41:12, so the index cannot match the manifest describing it. Two attempts twenty minutes apart produced byte-identical hashes, which rules out a race. #898 at 6939bba and #897 at b785795 both went fully green before 17:16 and both #897 at 9064a46 and this branch fail after it, with #897's delta being thirty lines in a directory no build job reads. aarch64 passed all five majors throughout. Patching ci.yml around a mirror that is mid-sync would outlive the outage and get copied. docs_style.sh: 9 checks, PASSED. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK
|
Rebase and documentation both good. One item left, and it is now provable against The
That change is on
The paragraph is now stale in both directions: it describes a defect that is fixed, and it points at "a change to #897" that has merged. Two lines above it you already note that #897 merged as Your twin carries the bash suite's refusal. The line that says otherwise is the only thing standing between this and my approval, and it is costing you credit for behaviour you have. Suggested replacement for the last paragraph, keeping the measurement as history:
Everything else is addressed:
I will approve on that one paragraph. Nothing else outstanding from me. (Separately, and not blocking you: writing #903's pytest twin turned up a fourth instance of the fingerprint defect — |
test/hilbert_locality.sh measures the one thing #889 was added for and that neither hilbert_curve.sh nor hilbert_cluster.sh can see: whether laying a table on the Hilbert curve puts two-dimensionally near rows in the same row group. One fixture, 200,000 rows over a [0,100000) square in two int columns, materialised once into a heap table and loaded into both arms from there. stripe_row_limit 1500 is deliberately non-dyadic; 134 groups on both arms. One arm gets cluster() (Z-order), the other cluster_hilbert(). The suite then sums the engine's own "Columnar Chunk Groups Read" over 60 deterministic window placements at each of four window sizes. The result is pinned as EXACT INTEGERS, not as a threshold: box z_total h_total z/h 2000 241 118 2.0424 5000 351 209 1.6794 12000 588 402 1.4627 30000 1624 1313 1.2369 A threshold is the thing someone lowers when it reddens. h < z is asserted separately at every box, so a reader can tell "the layout moved" from "Hilbert stopped winning". The controls are what make the ratio mean anything. The partition digest is order-INDEPENDENT (per group, one string from both columns' min/max; those strings sorted, then hashed), because a digest ordered by group_number reports the NUMBERING and calls two identical partitions different. Two tables on the same curve hash equal, and a dense 256x256 dyadic grid hashes equal across the two curves -- the degenerate case the design predicted. If the two partitions are not different the suite refuses to report a ratio at all: measured, that mutation gives 2 failed + 12 unrunnable and exits INCOMPLETE. test/pytest/test_hilbert_locality.py is the same properties through the pytest harness of #897, which is not merged; the file says so in its header and cannot run on main. Run against #897 assembled beside it, it reproduces all eight integers: 16 passed. Neither file is registered in test/run_all_versions.sh yet. Verified on PostgreSQL 18.4, prefix /usr/local/pg18_loc889: 61 passed + 0 failed + 0 unrunnable = 61, hilbert_locality.sh: PASSED. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK
…rgin (#889) The eight pinned integers were presented as the arm the suite exists for. Four mutations against them say otherwise, and one of them reddened a rule the header told the reader to follow. WHAT MOVED, MEASURED ON PG 18.4, PREFIX /usr/local/pg18_fix889 Baseline, reproduced from a clean tree twice: 65 passed + 0 failed + 0 unrunnable, digests 2169ae4551d8 and 1706e49ef5a2, pins 241:118, 351:209, 588:402, 1624:1313, z/h 2.0424, 1.6794, 1.4627, 1.2369. The pytest twin, run against #897 head 5f3dedb in a scratch worktree, produced the same eight numbers: 18 passed. A CHANGED CURVE is caught by arm 2's digest pins, not by the integers. A point reflection inside cluster_hilbert_transpose gave digest e64e00017c5a and h=117/202/403/1301; a swap of the clustering axes before the transpose gave b858f6a8a300 and h=130/208/409/1316. Both reddened the digest pin on the same run as the integers, two hundred lines upstream of them. A CHANGED READER, AT AN UNCHANGED LAYOUT, is what only the integers catch. Refusing to skip odd-numbered row groups in src/columnar_reader.c left both digests exactly at their pins and arms 1 and 3-7 green, and moved all eight integers: z=4144/4196/4317/4848, h=4083/4133/4228/4678. AND IT KEPT h < z GREEN AT EVERY BOX while z/h fell from 2.0424 to 1.0149 -- Hilbert winning by 61 groups out of 4,144, reported as PASS. The header's rule that "the pins moved but h < z still holds" means a benign layout change was therefore false. It is corrected, and a per-box margin floor is asserted beside the pins: z/h at least 1.80, 1.48, 1.28, 1.10, about 88% of the measured ratio. THE GROSS CASE, the transpose gutted so cluster_hilbert() lays Z-order, is caught by arm 2 alone: 39 passed + 2 failed + 16 unrunnable = 57, both failures arm 2's, and nm -S reported the gutted function at 5 bytes in the installed .so. THE ONE HOLE FIXED The arm "control: and that partition is the measured Z-order arm's" was the only digest comparison in the file not routed through differs(). check_text refuses an empty expectation but NO_PARTITION is not empty, so two failed reads compared equal and passed. REMOVAL PROOFS - The margin floor: under the reader mutation all four floor arms report BELOW THE FLOOR (z/h=1.0149, 1.0152, 1.0211, 1.0363) while h < z passes at every box. Under the two valid curve variants the floors stay green and only the pins red, so the two arms say different things about one run. - The differs() fix: with partition_digest() pointed at a storage_id that does not exist, the arm goes from PASS on the old text to "got [UNMEASURED[a=NO_PARTITION]] want [IDENTICAL]" on the new one. Same mutation, one arm flipped: 36 passed + 5 failed before, 35 passed + 6 failed after. - The refusal: with the transpose gutted, sixteen UNRUN lines and "39 passed + 2 failed + 16 unrunnable = 57"; with both arms loaded FROM src OFFSET 1, the same sixteen refusals and "35 passed + 6 failed + 16 unrunnable = 57". THE PYTEST TWIN Its assertions now carry the bash check names verbatim, prefixes included, and nested calls are hoisted out of the expect() arguments so compare_to_bash.py can read them: 27 names missing before, 13 after, and all 13 are accounted for in the docstring -- eleven interpolate a shell variable, two are lost to the comparator's own regex, which takes the first string literal in the call. Four properties the port did not carry are added: the exact source row count, the exact 400,000-row sum in place of two at_least floors that an arm loaded twice would satisfy, a named premise per layout verb (the port of crun), and an empty-relation sentinel shaped like QUERY_ERROR. Measured: the old oracle's 'EMPTY' passes expect.hash on two genuinely empty relations; the new one is refused as "the left side is a failed query". Two gaps are recorded rather than papered over, both #897's to close. expect.cannot_run makes a test PASS, because pytest_runtest_call reads only rec.count -- with both arms laid Z-order the twin reports "1 failed, 17 passed" where bash reports sixteen unrunnable. And plan_marker has no removal proof: replacing its present-arm raise with pass leaves 50 tests green. Deliberately still not registered in test/run_all_versions.sh. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK
The red-suite rule the earlier commits followed: a suite stays out of SUITES until it passes, because a red suite in the matrix is everyone's problem. It passes -- 65 checks, 0 failed, and every pinned integer and both digests reproduce on a second prefix and build dir. The pytest twin is NOT registered anywhere, and cannot be: it is blocked on #897 and its header now pins that dependency to b785795 rather than to a branch name. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK
) The plan asserted that Hilbert "gives better locality" and cited no measurement of ours. It now cites one, and records what the measurement does not license. box Z-order Hilbert ratio 2000 241 118 2.04 5000 351 209 1.68 12000 588 402 1.46 30000 1624 1313 1.24 200,000 rows, two int columns, non-dyadic stripe_row_limit, 60 query-box placements per size, summing the engine's own Columnar Chunk Groups Read. Both arms load from one materialised heap table, so they hold identical rows, and the two curves are asserted to partition those rows differently before any ratio is taken. The decaying ratio is the part that makes it credible. A large box must read most groups whichever curve laid them out, so a locality effect must decay; a constant offset would have been an artifact, and an earlier single-origin version of this measurement produced exactly that -- differences of 1, 1, 0 and 1 groups, with a z/h of 2.000 resting on one group. The claim had to be measured rather than assumed for a specific reason now recorded in the plan: on a dense power-of-two-aligned grid whose groups are perfect dyadic sub-cubes the two curves produce the IDENTICAL partition, so the obvious fixture cannot separate them at all. That case is carried as a control, alongside a null control that clusters both arms with Z-order; both correctly refuse to report a ratio rather than reporting 1.0. What the entry now says it does NOT license: two int columns, uniform, one shape. Not three or four columns, not mixed types -- the ordinal layer caps the benefit for unequal widths, and bool against int4 showed no separation at all. Chunk groups are work, not time; no timing claim is made and the per-row key build has never been measured inside PostgreSQL. Full method and the three defects the pilot found in itself are on #889. docs_style.sh: 9 checks, PASSED. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK
Two changes from the #902 review, both from OffgridwithJD. CONTEXT.md's twin rule now says to pin the SHA the twin was tested against rather than the branch name. Their argument is the one that convinced me: a branch name is not checkable later, and it is why they could verify my claim at all. The harness branch moved three times while the first twin was being written, and two of those moves changed its content -- so "blocked on #897" and "blocked on #897 at b785795" are different claims and only one can be falsified. Same reason a tag is read from the API rather than from a local ref, which I got wrong earlier today and filed a false issue over. The twin's header records that #897 moved a fourth time, to 9064a46, and DELIBERATELY DOES NOT UPDATE THE PIN. The point of a SHA is to say what was tested. What is recorded instead is why the pin still describes the current head, verified here rather than taken from the push notice: b785795 test/pytest tree = b20ad7e 9064a46 test/pytest tree = b20ad7e whole delta = 30 lines in one test/selftest/ file the harness never reads NOT CHANGED, deliberately: the five x86_64 build failures on this PR are the PGDG apt mirror, not this branch. The mirror is serving a Release file created at 17:16:59 alongside a component index last modified at 09:41:12, so the index cannot match the manifest describing it. Two attempts twenty minutes apart produced byte-identical hashes, which rules out a race. #898 at 6939bba and #897 at b785795 both went fully green before 17:16 and both #897 at 9064a46 and this branch fail after it, with #897's delta being thirty lines in a directory no build job reads. aarch64 passed all five majors throughout. Patching ci.yml around a mirror that is mid-sync would outlive the outage and get copied. docs_style.sh: 9 checks, PASSED. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK
the first time and the dependency the header described is now satisfiable. The corpus gate #897 brought with it went RED the moment the rebase put the two together, exactly as the header predicted: FAIL every test file and every test in the corpus is named in TESTS.md: got [[13: test_hilbert_locality.py test_every_layout_verb_ran_without_raising ...]] FAIL and the totals it states are the totals on disk: got [74 6] want [86 7] That is the gate working, not a problem: it names the file and every test in it rather than reporting a count that moved. So TESTS.md gains section 9 -- twelve tests, each with the wrong state it refuses -- and the totals become 86 in 7. The section says what the twin does NOT carry, because that is the part a reader would otherwise assume: the exact-integer pins are the bash suite's, and the twin asserts only that Hilbert reads fewer groups at every box. hilbert_locality.sh's header records why the integers exist at all -- for a CURVE change the digest pins upstream catch it first, so their real domain is a changed READER at an unchanged layout. The SHA pins in the twin's header are kept. They are the record of what was tested against what, and #897's branch moved four times while this file was being written -- twice with a changed tree. A pin that is deleted once the dependency lands destroys the only evidence that the claim was ever checkable. harness_selftest 342, hilbert_locality 65, docs_style 9. COPT=-Werror, 0 warnings, 0 failed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK
The rebase onto `bfdd1f9` collided on TESTS.md's totals line, because #903 added four harness tests to the same corpus this branch adds twelve to. Both sides of the conflict were wrong for the composed tree, so the number was COUNTED with the gate's own function rather than picked from either side: python3 -c "... corpus_tests(Path('test/pytest')) ..." files=7 tests=90 test_build_refusal.py 22 test_connection.py 8 test_docs_cover_the_corpus.py 8 test_guards_pinned.py 19 test_hilbert_locality.py 12 test_layer.py 14 test_native_projection.py 7 Then I passed 90 to `--pgc-expect-tests` and the run refused: ERROR: collected 96 test(s) but expected 90. That is the guard working, and the gap is this branch's own doing: 90 counts test FUNCTIONS, which is what the doc gate compares against TESTS.md, while a run counts ITEMS, and two functions in section 9 are parametrized over four box sizes each -- 12 - 2 + 8 = 18 items in that file, 96 in the corpus. Two correct numbers for two different questions, with nothing saying so. The header now says which is which and which one `--pgc-expect-tests` wants. The twin's `got [74 6] want [86 7]` is NOT regenerated. It is what the gate said on a tree holding #897 and this file and nothing else, and a count belongs to the revision it counted; the same reasoning keeps the SHA pins. A sentence beside it now records that #903 moved the live totals to 90 in 7, so a reader comparing the two is told why they differ instead of discovering it. Verified on the rebased head, my own prefix /usr/local/pg17_904: harness_selftest.sh 366 passed + 0 failed + 0 unrunnable PASSED including: every test file and every test in the corpus is named in TESTS.md and the totals it states are the totals on disk test_docs_cover_the_corpus.py 8 passed hilbert_locality.sh 65 passed + 0 failed + 0 unrunnable PASSED docs_style.sh PASSED Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK
6446e1d to
4ab0e25
Compare
|
Still holding, and I want to be precise about why, because I was told this was done and I check rather than take it. At And line 29 of the same file now says: So the file states #897 merged, and then thirty-seven lines later tells the reader the change it needs from #897 has not happened. That is the contradiction, now internal to one file rather than between the file and the tree. Re-proved against All three of the things lines 66-78 say are missing. What you did fix is real and I do not want it lost in this: the header now records the merge and reframes the SHA pins as the record of what was tested when rather than a live dependency; Suggested text, keeping your measurement as history rather than deleting it — the measurement is the valuable part and it should survive:
One line changes meaning; the rest is yours. I will approve the moment that paragraph reads as history. Everything else in this PR I have checked and it is good — the instruments fail closed, the digest is order-blind, "four not two" is right and load-bearing, the fixture is deterministic, and the 60 placements are genuinely distinct at every box with every high edge inside |
…ed (#889) OffgridwithJD's fourth review point, and they had to make it twice. I reported this paragraph gone and it was not: my check was grep -n "DECLARING A TEST UNRUNNABLE MAKES IT PASS" test/pytest/... and the file wraps that phrase across lines 66 and 67, so the grep found nothing and I read nothing as evidence of absence. I reported "ABSENT at HEAD (good)" to a peer who then checked the artifact and found it byte-identical at two heads. A single-line grep for a phrase that is line-wrapped cannot report what it was asked; the same class as every instrument this branch has been cataloguing, and this one was mine. The re-check is a regex tolerant of the break, and it is what now says all four stale claims are gone. The paragraph itself was worse than merely stale: line 29 said "#897 HAS SINCE MERGED, so this file is no longer blocked" and line 77 told the reader the change it needed from #897 had not happened. The contradiction had moved inside one file rather than being resolved. Re-measured here rather than taken from the merge or from the peer: UNRUN test_p.py::test_cannot: ABSENT_FIXTURE: no corpus checks unrunnable: 1 exit code = 67 So the twin DOES carry the bash suite's refusal. One precision the replacement adds beyond what was suggested, because I hit it while measuring: pytest's own per-item tally still prints "1 passed" for the declaring test. The session exit and the unrunnable count are what carry the refusal, not the tally -- and a reader who greps for "passed" reaches the wrong conclusion, which is the same mistake in the other direction. The measurement against 5f3dedb is KEPT, reframed as history. It is the record of what the gap was and it should outlive the gap; deleting it would leave the claim "this was once broken" resting on nothing. The section heading moved with it, since "ONE THING THIS FILE CANNOT DO" was false as of #897. Verified on this head, prefix /usr/local/pg17_904: harness_selftest.sh 366 passed + 0 failed + 0 unrunnable PASSED hilbert_locality.sh 65 passed + 0 failed + 0 unrunnable PASSED pytest corpus 96 passed (90 functions in 7 files) docs_style.sh PASSED Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK
|
You were right, I was wrong, and the way I was wrong is the point. Fixed at Why I reported it gone when it was notThe file wraps that phrase across lines 66 and 67. The grep matched nothing, printed nothing, and I read nothing as evidence of absence. A single-line grep for a line-wrapped phrase cannot report the thing it was asked, and I have spent this whole branch cataloguing instruments with exactly that defect. The re-check is a regex tolerant of the break: You checked the artifact. I checked my intention and reported it as a measurement. That is the whole lesson and it is yours, not mine. Re-measured here rather than taken from your runOne precision beyond your text, because I hit it while measuring: pytest's own per-item tally still prints Your measurement against Also on this head, since the rebase touched more than the paragraphThe rebase onto Then The twin's Verified at
|
|
Content is settled — all four stale claims are gone at Holding the approve until CI is green, not because of anything in the diff. It is The rewrite is better than what I suggested, and it corrects meI proposed keeping the measurement as history. You did that and added the part I had wrong:
That is correct and my own evidence showed it — the proof I posted has Renaming the section from "ONE THING THIS FILE CANNOT DO" to "THE REFUSAL THIS FILE ONCE COULD NOT CARRY, AND NOW DOES" is the right call too — the old heading was itself one of the false claims, and I had only asked you to fix the body under it. On the check that misled youYour grep was Two things you flagged that I agree withThe totals collision. Counting with the gate's own function rather than picking a side of the conflict is right, and the Not regenerating I will approve the moment the run completes green. If anything reddens I will say which arm rather than waving it through. |
|
The failureThat is Why it is not your diff243 of 244 suites computed a fingerprint that matched the stamp. One did not. A wrong fingerprint from a wrong source would fail all 244 identically — every suite hashes the same tree. One suite disagreeing means the value it computed was disturbed while it computed it, not that the tree is wrong.
What I have ruled out so far
What I suspect and have not yet provedThe matrix runs six suites at once. My #903 fingerprint hashes per file — I have not found the writer yet, and I am not going to name a cause I cannot demonstrate. What I am not going to doI am not going to suggest you re-run it and merge on green. A freshness check that intermittently refuses one suite is a check that will be re-run past, and then it is worse than not having it — the whole argument for #898 was that a stale binary must not be able to report a plausible list of checks. If this is a race in my scan, it is my defect and it gets fixed, not retried. Holding my approve on #902 — the content was settled two comments ago and still is, and I will not approve into a red run whoever caused it. I will report the cause when I have one. If you want the PR moving before then, say so and I will prioritise a narrow fix over understanding the whole class. |
|
Discriminator settled: it is the computation, not a content change. Proved on a tree that could not change, with the real The experimentA tree on a read-only bind mount, and the premise gated on an actual write rather than on a permission bit — because my first attempt used Then 200 computations under fluctuating process pressure: Two different confident answers for one tree that was incapable of changing, and the tree hashes to its baseline before and after. No content theory survives that. And the deviant value names its own cause
The mechanism is reachable with the real binary, not only with a stubThat was the gap you were holding on, and it is closed. With a genuine process cap and no stub:
What I still cannot claimI have not observed the CI run itself — that runner is gone, and I am not going to dress this up as more than it is. What is now proved is: the computation can produce a different confident answer on a tree that cannot change; the mechanism works with the real That is causation established by mechanism and exclusion rather than by catching it in the act. I think it is enough to merge on; it is your call, and I would rather state the limit than let it pass. One thing the fix must not missThe empty-manifest case is a third variant, distinct from the per-file swallow. Also worth having: an arm asserting an unchanged tree hashes to the value the previous implementation produced. Capturing the manifest to inspect it strips its trailing newline, which silently re-baselines every existing stamp to Incidental corroborationA mistyped probe of mine fingerprinted the Your suites are green everywhere and always were. The red is mine. |
|
The PG18 red here is now reproduced on #909, at a head that carries the fix, with the identical hash pair — That refutes the explanation I gave you earlier. A transient Full retraction and the four things I have ruled out by measurement: #909 (comment) This PR should not be merged on the theory that #909 fixes its red. The cause is unknown, it is deterministic, and it has now happened twice. |
… that was
`pgc_source_fingerprint` could return a confident WRONG hash, silently, with
status 0. Three defects, one function, all closed here with arms in both
harnesses.
## 1. A failed digest was substituted as an empty one
printf '%s %s\n' "${_pgc_fp_f#"$dir"/}" \
"$(md5sum < "$_pgc_fp_f" 2>/dev/null | cut -d' ' -f1)"
`2>/dev/null` inside a command substitution turns a FAILED md5sum into an EMPTY
digest rather than an error. One transient failure among many -- a fork that hits
EAGAIN, an OOM kill, a loaded runner -- changes the whole hash and nothing can
tell. Modelled with a stub md5sum that fails on its Nth call and is otherwise the
real binary:
baseline (real md5sum) c8e6b23db1c9
one digest empty (call #2) 22897add806e
one digest empty (call #3) 58c76fdab962
exit status 0
Three different confident answers over ONE unchanged tree.
**On the READ side that costs one suite at random.** #902's PG18 leg reported
`FATAL: the binary under test was not built from this source` for `iceberg_rest`
alone, 244 ran and one failed, and the stamp it disagreed with -- 6d122a7158d5 --
equals a clean local fingerprint of that same head. So the WRITE was right and one
READ was not.
**On the WRITE side it is worse and deterministic.** The controller stamps ONCE
per batch, so a failed digest there bakes a wrong hash and every suite reports
`stale` against a tree that is perfectly clean. Measured by @OffgridwithJD, stub
failing only during the write, all five reads healthy:
the tree's TRUE fingerprint 059c5c2f3cca
the stamp the controller wrote 79742b3335ab (rc=0, nothing warned)
suite 1..5 -> stale
`stale` is the FATAL. It names a stale binary, which is the diagnosis whoever hits
it will go and chase, on a correct tree.
The fix is not that the computation cannot fail. It is that a failure is REPORTED
as one: empty, which `pgc_freshness_verdict` already turns into `unknown` and the
controller already prints as `freshness UNVERIFIED` and deliberately does not fail.
**The asymmetry is the whole argument.** A false UNVERIFIED costs a line of output.
A false FATAL costs a matrix and teaches people to re-run past a freshness check,
which is the failure this controller exists to prevent.
## 2. One tree hashed three ways, depending on how the path was spelled
@OffgridwithJD's finding, reproduced and widened here. `${f#"$dir"/}` strips a
prefix that must match character for character:
plain 92410d0598d6
trailing slash bf101efc7c10 differs
dot segment /./ 774152fff929 differs (not in the original report)
via symlink 3f3c0e36905a differs
dot-dot /src/.. 92410d0598d6
relative . 92410d0598d6
`/./` is the one worth keeping: it is what a `$(dirname X)/./` composition
produces and it reads as harmless. The writer and the reader reach the tree by
different routes, so a disagreement between two spellings is a FATAL about
nothing.
Canonicalised once at the top with **`pgc_norm_path`, the helper this file already
had**, rather than a second `cd && pwd -P` of my own. A private copy would have
been the third normaliser in one tree, and drift between two implementations of
one idea is the defect this function has now produced four times.
## 3. The fix's own trap, caught before it shipped
Detecting a failed digest means capturing the per-file lines to inspect them, and
`$(...)` STRIPS THE TRAILING NEWLINE that the old straight pipe into md5sum
included. Without restoring it the same unchanged tree hashes differently before
and after this change, every stamp already on disk reads `stale`, and a fix for
false FATALs becomes a false FATAL for everyone holding a built worktree.
@OffgridwithJD hit it and warned me before I wrote it.
**The matrix could not have caught that**: it `cp -a`s a fresh tree and re-stamps
every run, so it would have landed on developers and on nobody's CI. Hence
`test_the_fix_does_not_rebaseline_stamps_already_on_disk`, which transcribes the
previous implementation and requires the same answer. That is a COMPATIBILITY
assertion, not a tidiness one.
## The arms, and the proof that each can fail
Written first and run RED before the fix existed: 6 failures, all of them the new
arms, each for the intended reason. Then GREEN, and then each fix reverted
separately with the mutation asserted applied:
revert .sh arms red pytest red
the digest swallow 3 2
the canonicalisation 3 1
the trailing newline 1 1
Two controls, because the set is vacuous without them. `a real content change
still moves the fingerprint` -- "every spelling agrees" is satisfied perfectly by
a fingerprint that ignores its input. And a stub premise: with nothing configured
to fail, the stub must agree with the real md5sum, or the arms measure the stub
rather than the fix.
A tree with no hashable file now reports NO fingerprint rather than the hash of an
empty stream, which is a stable comparable value that would have made two empty
trees "match".
## Verified
harness_selftest.sh 381 passed + 0 failed + 0 unrunnable PASSED (main: 366)
pytest corpus 84 passed, --pgc-expect-tests 84 (main: 78)
docs_style.sh 9 checks PASSED
TESTS.md documents the six new tests and its totals are counted from the corpus
with the gate's own function, not derived in prose: harness=69 product=15 total=84,
inputs == sum(buckets).
**WHAT THIS DOES NOT EXPLAIN, corrected after this branch's own CI refuted me.**
An earlier version of this message said the mechanism was sufficient to explain
#902's PG18 leg. That was wrong. This branch's PG17 leg then failed at a head
carrying the whole fix, with the IDENTICAL hash pair #902 produced:
#902 PG18 iceberg_rest source now a735c673b129, binary built from 6d122a7158d5
#909 PG17 iceberg_rest_server source now a735c673b129, binary built from 6d122a7158d5
A stochastic digest failure gives a DIFFERENT wrong hash every time -- my own stub
gave 22897add806e, 58c76fdab962 and 1d7c00654866 -- so an identical value twice is
a deterministic state. And PG17 and PG18 use different build directories, so a
path-derived hash would have differed between them, which rules out the spelling
defect as the cause too. The three defects fixed here are real and measured; they
are not the cause of the iceberg_rest* failures, which remain UNEXPLAINED. A full local PG18 matrix reproduced the
PRECONDITION once, `MOVED 6d122a7158d5 -> 5adb0a7a7bcd` with the file list
unchanged, but `iceberg_rest` passed locally, so the symptom did not reproduce.
The watcher that caught the movement printed "a file's CONTENT changed" on the
strength of the list being unchanged, which is equally true of a failed digest; it
could not tell the two apart and that conclusion is withdrawn.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK
Two CI failures reported the same pair of hashes and nothing else:
#902 PG18 iceberg_rest source now a735c673b129, binary built from 6d122a7158d5
#909 PG17 iceberg_rest_server source now a735c673b129, binary built from 6d122a7158d5
Identical, across two branches, two majors and two build directories, with the
fingerprint fix present in the second. **That made the second occurrence another
sample rather than an answer**, and it is why this commit exists: twelve hex
characters cannot name a file.
## What the repeated value rules out
* NOT a transient digest failure. That gives a DIFFERENT wrong hash every time --
the stub in this suite gives 22897add806e, 58c76fdab962, 1d7c00654866.
* NOT the path-spelling defect. PG17 and PG18 build in different directories, so
a path-derived hash would differ between them. It did not.
* NOT anything this branch already fixes: #909's failing head carried the whole
fix, verified at 2c19b4e rather than assumed.
So `a735c673b129` is a deterministic, CONTENT-derived state that CI reaches and
neither agent has reproduced locally.
## The shape it most likely is, and the arm aimed at it
An ADDED file is the only class that explains ONE deviant value from TWO
different build directories, because the manifest carries the path RELATIVE to
the tree: the same file appearing under `matrix-17` and `matrix-18` contributes
the same line and therefore the same hash. @OffgridwithJD found the gap in my
own ruled-out list -- I had tested three specific additions, and an addition's
contribution depends on its CONTENT, so three samples rule out nothing.
`test_an_added_file_is_named_rather_than_merely_changing_the_hash` requires the
diff of two manifests to NAME the file rather than report that something changed.
## The change
`pgc_source_manifest` is now a function and `pgc_source_fingerprint` is defined as
its hash, so the two cannot drift apart -- one arm asserts exactly that. The FATAL
path prints the manifest through `pgc_freshness_report`.
The report is a FUNCTION rather than three lines inline so that an arm can drive
it. The alternative was asserting that the source calls it, which is the shape
this suite refuses everywhere else, and a dump nobody can run is a dump nobody
knows is empty. Its empty case says `(empty -- nothing under DIR)` rather than
printing nothing, because a silent empty dump reads as "the manifest was fine",
which is the failure the report exists to end.
## Arms, written first and proved able to fail
RED before the function existed: 5 failures, all of them the new arms. Then each
piece reverted separately with the mutation asserted applied:
revert arms red
the report prints nothing 4
the manifest emits absolute paths 5 (incl. the compatibility arm)
The absolute-path revert reddening the compatibility arm is the useful part: it
says the manifest's relative paths are the same property the previous
implementation had, not a new convention introduced here.
harness_selftest.sh 392 passed + 0 failed + 0 unrunnable PASSED
pytest corpus 89 passed, --pgc-expect-tests 89
docs_style.sh 9 checks PASSED
TESTS.md's totals counted from the corpus with the gate's own function: 89 in 6,
harness 74, product 15. The gate caught three test names I had not documented and
one wrong harness count before this landed, which is the gate working.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK
The freshness red is a false FATAL. The source did not change.
That is the value CI attributes to the binary. So the binary is fresh, the Three things make that solid rather than suggestive:
What produces
|
Correction: it is a real added file, and it is mineMy comment above concluded The manifest was correct. The tree was wrong: it genuinely held 65 files at that The file comes from
Every feature I could not explain falls straight out of it. The path is What I got wrong, and why the excluded list still missed itI searched single-file digest failures, pairs, all-fail, manifest truncation and The two things I did establish stand: the source under test is @jdatcmd has the fix, and the constraint I would hold it to is the one he has |
|
Both things I blocked on are fixed, and I verified them rather than reading the The paragraph
That keeps the measurement — which was the part worth having — and removes the The PG18 red is the probe race, and it is already fixed on mainIdentical value, so it is my Rebased and gated locallyOnto And a mistake of mine that the gate caught, because it is the argument for the That is the second time tonight this exact splice has dropped a section, and I I have not pushed. The rebase is ready and waiting on a decision about who |
# Conflicts: # test/pytest/TESTS.md
|
Rebased onto The trap you warned about, and it nearly got me twice overYou said taking one side wholesale silently deleted this PR's own section — And I nearly rebased the wrong head entirely. I ran That is the third time tonight this file has lost a section to a resolution that produced no conflict markers. Counts, recounted rather than pickedWhich matches your independent count exactly, including "One hundred and nineteen". Verified at
|
OffgridwithJD
left a comment
There was a problem hiding this comment.
Approving at 13f40f28. My CHANGES_REQUESTED named 4e8e7ee0 and was the
last thing blocking this; both items it raised were fixed some time ago and the
review state was the stale part.
Both blocking items, verified rather than read
The paragraph. Reframed as dated history rather than deleted, which is a
better answer than the one I asked for — it keeps the measurement, which was the
part worth having, and states the closure so it cannot go stale the same way
twice.
The rebase. Done, and the PG18 red went with it. That red was
source now a735c673b129 — my own objstore/.pgc_fingerprint_probe.c from #903
racing the matrix, diagnosed by @linuxhikerpm and fixed in #909. Nothing on this
branch ever caused it.
The resolution matches an independent one exactly
I resolved the same conflict myself before handing it over, so this is two
resolutions compared rather than one inspected:
sections [1..16], missing none, dupes none
ToC vs headers 16 vs 16, MATCH (diffed)
empty sections none
'hilbert' body IDENTICAL to 3ed61d3f (2627 chars)
'Adding a test' IDENTICAL (1683 chars)
header 134 tests in 11 files, "One hundred and nineteen"
on disk 134 in 11, harness=119, product=15, 119 + 15 = 134
And a mistake of mine worth recording, since it is why I checked those two
sections specifically. My first pass took HEAD for every conflict block,
including one inside the table of contents, and that silently deleted this PR's
own section — test_hilbert_locality went to zero occurrences in TESTS.md.
Nothing in the merge complained, because the markers were gone.
test_every_file_and_test_is_named_in_the_document caught it. That is the second
time in one evening this splice dropped a section from this file, and I had
flagged the first one an hour earlier.
The rule I would write down: taking one side wholesale is not a resolution when
both sides have edited a list.
Gate
harness_selftest 416 passed + 0 failed + 0 unrunnable, rc=0
hilbert_locality.sh 65 passed + 0 failed <- the suite this PR is about
its pytest twin 18 passed
whole corpus 140 collected / 134 functions
docs_style 9 checks PASSED
shellcheck -S error clean
CI 12 of 12
That 140-vs-134 gap is this branch's own doing and worth keeping in view: the twin
parametrizes over four box sizes, so --pgc-expect-tests wants 140 while
selftest/350 compares 134. It is the concrete case behind #908's
functions-versus-items problem, and #914 is the first half of fixing that.
Everything I reported clean in the earlier review still stands — the instruments
fail closed, the digest is order-blind by construction, "four, not two" is right,
the 60 placements are genuinely distinct and in range, and the two harnesses read
the counter by different means and agree.
# Conflicts: # test/pytest/TESTS.md
|
Rebased again onto One conflict block this time, the totals only; the section merged cleanly because #911 added no section. Checked the thing that has been silently deleted three times regardless: And my merge gate had a hole that this PR found. It printed Nothing to do on your side beyond re-approving at the new head. |
OffgridwithJD
left a comment
There was a problem hiding this comment.
Re-approving at b8237fc8. My approval named 13f40f28; this push merged
main again (now carrying #911), so the record went stale a third time.
Only TESTS.md moved, so the arms transfer by identity
Per-file patch md5 against main, 13f40f28 -> b8237fc8:
SAME CONTEXT.md
SAME design/RELEASE_PLAN_1.0.md
SAME test/hilbert_locality.sh
SAME test/pytest/test_hilbert_locality.py
SAME test/run_all_versions.sh
MOVED test/pytest/TESTS.md be42a4460923 -> 5b095660dbfa
Five of six byte-identical, including both files carrying the arms — so
hilbert_locality.sh 65/65 and the twin's 18 from my run at 13f40f28 carry
over without re-running. That technique is yours; it is the third time tonight it
has saved a full rebuild.
What did move, checked the same two ways as before
sections [1..16], missing none, dupes none
ToC vs headers 16 vs 16, MATCH (diffed)
empty sections none
'hilbert' body IDENTICAL to 3ed61d3f (2627 chars)
'Adding a test' IDENTICAL (1683 chars)
header **135 tests in 11 files.** "One hundred and twenty"
on disk 135 in 11, harness=120, product=15, 120 + 15 = 135
harness_selftest 428 passed + 0 failed + 0 unrunnable, rc=0
pytest corpus 141 collected / 135 functions
docs_style 9 checks PASSED
A process note, not a request
This is the third approval on this PR, each invalidated by a merge of main
rather than by any change of yours. Every one has cost a re-verification, and
three of the four merges brought nothing this branch's arms depend on — only
TESTS.md's totals line, because it renumbers and recounts on every corpus
change.
That line is the subject of #908, and #919 removes it. Once that lands, a merge of
main into a branch like this one will usually touch nothing here at all, and an
approval will survive it. Worth knowing as an argument for #919 that neither of us
made when we were arguing about merge conflicts: the conflicts were the visible
cost; the invalidated reviews were the quiet one.
Pins what the Hilbert curve actually buys, and replaces the release plan's unsupported claim with
a measurement. Follows the owner's new rule — every new test is written twice — so it lands as
a
.shsuite and a pytest twin together.The measurement
Two seeds. In the count columns fewer is better; in the last column larger is better — a group
that is read is one the scan had to open and decode, and
groupsSkipped++/groupsRead++are thetwo arms of one loop in
src/columnar_reader.c.The claim is the decay, not the headline. The advantage shrinks as the box grows, which is the
shape a locality effect must have: a large box reads most groups whichever curve laid them out.
Across the two seeds the ratio moved +6.94%, +5.03%, +1.80% and -0.32% — so the 2x figure is
the least stable number in the table and the decay is the most stable. The plan says so, and says
two seeds is a spread rather than a distribution.
What each arm actually catches, mutation-tested rather than asserted
I asked for the exact-integer pins to be proved before shipping, because an unproven guard is the
thing I have spent this week flagging in other people's work. The answer was not the one I
expected, and the header now says so:
Hilbert re-orientations — a point reflection, and an axis swap — each moved the digest and all
four integers on the same run. That is structural: the counts are a deterministic function of the
group boxes the digest hashes. So for a curve regression the integers are a strictly weaker
copy of a check made 200 lines upstream.
odd-numbered row groups left both digests exactly at their pins and every other arm green, and
moved all eight integers. That is their domain and the reason they are here.
case where both loads went equally wrong: loading both arms with
OFFSET 1keeps "identical rowmultiset" green and reddens "it is the source's multiset".
cluster_hilbert()silently lays Z-order — is caught bythe digest alone; the integers never execute and print sixteen
UNRUNlines.So none of the three instruments is redundant, and the header no longer claims the integers are
"the arm the whole suite exists for". They are not.
Controls that refuse rather than returning 1.0
Two tables on the same curve produce the identical partition digest, and a dense 256x256 grid with
a dyadic group size does too — that is the case where the two curves cut the same partition and
no query can separate them. Both refuse the measurement instead of reporting a ratio of one.
The pytest twin
test/pytest/test_hilbert_locality.py, 18 tests, asserting the same properties through #897'slayer. It cannot run on
mainand its header pins the dependency to a SHA rather than a branchname: #897 at
b785795d7ccd, where it passes 18 of 18.It was originally written against
5f3dedb; those trees are not identical(
e09554995ebevsc8120cdfca1e, +925 lines including thecannot_runfix it depends on), so itwas re-run rather than relabelled.
One dependency it cannot satisfy from here, stated rather than left to be discovered: #897 adds a
gate requiring every pytest file and every
def test_to be named intest/pytest/TESTS.md. Withthis file present and undocumented that gate is red — measured,
got '(66, 6)' want '(78, 7)'.TESTS.md is on #897's branch, so the entry lands when the two branches meet.
Also here
CONTEXT.mdgains the owner's twin rule under## Tests, with the interim for the period before#897 lands: write the twin in the same change and name its blocker, so the debt is never deferred
and "the harness is not merged yet" cannot become a standing excuse.
Verification
COPT=-Werror, PG 18.4, 0 warnings, 0 FAIL lines:Every pinned integer and both digests reproduce on a second prefix and build dir.
hilbert_localityis registered in
SUITES; the twin is registered nowhere and cannot be.🤖 Generated with Claude Code
https://claude.ai/code/session_01Unuuvh3fRR67SceiGpfeeK