A comment claimed an enumeration was "exactly the same" as a relation's and reproduced it WITHOUT the exclusion beside it — build_recv_origin bypassed #57 for four years of commits, and nothing could have told a reader #203
Labels
No labels
code-review
correctness
dos
performance
security
severity/high
severity/low
severity/medium
tech-debt
Kind/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
h-dv/code-index#203
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found while inspecting #69's new binds. The bind defect is fixed there; this issue is about the shape of the defect, because it is the class this repo keeps closing and the next person to copy an enumeration will make it again.
The claim, and what it left out
index::build_recv_origin(#65) builds tier 1R's origin evidence. Route A:The claim is true about the enumeration and false about the relation.
temp.import_key_rel's build, roughly a thousand lines away, opens with:Route A reproduced the enumeration and not the exclusion. So a relative specifier that
import_key_relrefuses — because a leading dot names a PATH and not a segment key — was handed totemp.file_keysanyway, where a file's BASENAME STEM is a key.What it cost
from .models import Articlenormalises to the keymodels.temp.file_keysholdsmodelsas the basename stem of everymodels.pyin the repository. On the pinnedpy-djangothat is 47 Django test apps, each handed the other 46 as origins for a type it can only mean its own.Measured, all read at source:
Article.id,User.email, crossing between unrelated test apps).<app>.save()binding totests/model_forms/models.py#Article.save, another app's override. These predate #69 entirely and no gate had ever seen them.Fixing route A to consult
temp.import_rel— the RESOLVED relation the exclusion defers to — removes all 56 and costs zero correct binds:+4906 / -38 / 0 retargetedon nine repos, with every repo except py-django byte-identical.Why this is a prose defect and not a logic defect
Three things were true at once and no instrument could see the contradiction:
import_key_rel's exclusion is documented, deliberate and correct.build_recv_origin's comment asserts the two enumerations are the same.Nothing grades a claim of equivalence between a Rust enumeration and a SQL relation. The
tier1r_indexed_join_equals_cross_product_oracleproves the decision pass matches its own oracle — both of which consume this relation, so both were equally wrong.corpus_ratchetcounts resolutions and these were resolutions.precision_gateindexes zero corpus repositories.That is the same family as the checks this repo already ships —
tier3_field_gateandTIER1R_CONTAINER_KINDSspliced from one place "so a mutation cannot make them disagree",pool_class_admits(added in #69) replacing a hand-copiedm.kind = 'method'. Every one of those exists because a copy drifted. This one drifted in the same way and the copy was in a comment rather than in code, so splicing could not have saved it.What would catch the next one
Suggestions, none implemented:
import_key_candidatescould take the exclusion — aRelativepolicy argument, or amodule_is_relative()helper both sites call — so "the same enumeration" is enforced rather than asserted. Cheapest, and it is this repo's standing move.pool_capability_registryalready scans production SQL and demands every relation declare a stance. A comment saying "the same X as Y" is a checkable assertion: the two sites' predicates could be extracted and compared, or at minimum the claim could be required to name both sites so a grep finds the pair.precision_gate's oracles are the natural home; the shape is twomodels.pyin sibling packages and afrom .models import X.Related
#57 (the relation and its exclusion), #65 (
build_recv_origin), #69 (where it surfaced and where the fix ships), #199 (the inherited/implicit member class — these phantoms needed BOTH: the bypass supplied the wrong file, and the missing inherited symbol made the wrong file look unique), #134 / #168 (the absolute-module half of the same stem hazard, still open —from django.contrib.auth.models import …matches everymodels.pytoo, and this fix does not touch it).from .models importreaches everymodels.pyin the tree, and it produced 3 of #69's 5 measured phantoms #196Triage 2026-09-09: STAYS OPEN, and the split needs stating because it is easy to misread as done
This issue has never been triaged, and the reason it is easy to close by accident is that the thing it describes is fixed and the thing it asks for is not.
temp.import_rel, all 56 phantoms gone (18 from #69's member arm, 38 that predate #69 and no gate had ever seen),+4906 / -38 / 0 retargetedacross nine repos with every repo exceptpy-djangobyte-identical.So the open work is prevention, not repair.
Disposition on the three suggestions
1. Splice the predicate, not the prose — DO THIS. It is this repo's standing move (
tier3_field_gateandTIER1R_CONTAINER_KINDSspliced from one place "so a mutation cannot make them disagree";pool_class_admitsreplacing a hand-copiedm.kind = 'method'), and it converts an asserted equivalence into an enforced one. Concretely:import_key_candidatestakes the exclusion, or both sites call onemodule_is_relative()helper. A comment then cannot drift from the code because there is no second copy to drift.3. The negative fixture — DO THIS TOO, and it is not optional. The issue records the fact that decides it: "No test in the tree contained a relative import whose stem collided with another file's basename, which is why every gate was green." Two
models.pyin sibling packages plus afrom .models import Xinprecision_gate's oracles. Without it, the splice in (1) ships with no arm that could have failed — and a fix whose test could not have shown the bug is exactly the vacuity class this tracker is full of.Order matters: build the fixture first and watch it go RED against today's binary, then splice. A fixture written after the fix, against the fixed binary, grades nothing.
2. A registry test for equivalence CLAIMS — NOT NOW. It is the intellectually interesting one and it is the one I would refuse on cost. Extracting two sites' predicates from prose and comparing them is a parser for English, and the failure mode of a weak version is worse than nothing: it would report "claims checked: N" while checking a population that cannot contain the next instance. That is the exact defect this repo keeps closing, rebuilt as the fix for itself. If (1) is done, the class of claim that can drift shrinks to the ones with no shared predicate to splice, and that residue is small enough to leave to review.
Recording the refusal rather than leaving it as an unranked option, because the issue offers all three neutrally and the middle one is a trap.
What a fix must prove
py-djangobind delta is inspected at source, not counted. Three cuts this year raised the resolved count and every extra bind was a phantom.Note on scope
#134 / #168 are explicitly not covered:
from django.contrib.auth.models import …matches everymodels.pytoo, and this fix does not touch the absolute-module half of the same stem hazard. A lane picking this up should not let that expand into it, and should not claim the stem hazard is closed.Closed on
masteratbb47b99. The prevention this issue asked for now exists, and the lane corrected my triage on the way.The splice
index::module_is_relative(&str) -> boolis the single definition. Callers:build_recv_originroute A (index.rs:2007)temp.import_key_rel's build (index.rs:4934)That third one is the good catch. A test that reproduces the predicate it is grading cannot detect the predicate drifting — it drifts with it. This issue is about a claim that was reproduced without its exception; the oracle was one edit away from the same shape.
One thing could not be spliced, and is graded instead.
generation_build.rs:1609pinsSELECT COUNT(*) FROM imports WHERE module NOT GLOB '.*'by its literal source text, so the SQL must stay a literal.module_is_relative_matches_the_sql_globtherefore grades the Rust predicate against the SQL spelling rather than deriving one from the other. That is the right handling — where you genuinely cannot splice, assert the equivalence and run the assertion, which is precisely what this issue's defect lacked.The negative fixture
write_relative_stem_decoysstages 7 files into the python tempdir only (never the shared fixture): twomodels.pyin sibling packages plusfrom .models import RelArticle, with 5 new probes in the python oracle.I verified the splice myself rather than taking the report — mutating the single helper to always return
false:One edit, both call sites red —
rel_saveis route A,rel_two_onlyisimport_key_rel. That is the proof the splice is real and not two copies that happen to agree. Restored bycp, md5 verified, re-run 7/7 withphantoms=0.The two arms are separately attributable, which matters for the next reader: a site-A-only mutation reddens
rel_saveand leavesrel_two_onlygreen, and vice versa.The survivor, and it is the most useful thing here
Mutation 3 — gutting route A's relative arm — SURVIVED against the fixture's first draft. Green,
phantoms=0,recall=1.000.The anti-vacuity arm graded nothing: with one reachable candidate for
rel_tweak, tier 1b and tier 3 collapsed the pool to the file the relative import made reachable, so the receiver origin was never load-bearing. Adding a second relatively-imported definition removes reachability's ability to choose and leaves only route A. Re-run:That is the anti-vacuity guard which is itself vacuous — the shape this tracker keeps closing, found by the lane in its own new work and recorded verbatim in the fixture's block comment. A fixture that cannot distinguish "route A did it" from "reachability did it" is not a fixture for route A.
Corpus binds — proven, not argued
The change is a function extraction, so rather than reason about it the lane built the old binary (
git show HEAD:index.rs, cp-installed, md5 verified both directions), indexedpy-djangowith each, and joined every ref on(path, line, col, kind, name) -> (target_file#target_name, resolved_by):Byte-identical.
tests/corpus/baseline.jsonunmoved,corpus_ratchet6/6. That is the standard — a bind census against the prior binary, not a count that did not change.My triage was wrong on one point, and the lane was right to say so
I wrote "the negative fixture is RED before the splice and GREEN after". That cannot be literally true: the splice is semantics-preserving, so nothing can be red before it. The bind fix shipped in #69; a fixture run against today's tree is green by construction, which is exactly what the lane measured and reported.
The gradable claim is RED before the bind fix, GREEN after — established via mutations 1 (route A restored to its pre-#203 form) and 2 (the
import_key_relexclusion deleted). My instruction to "build the fixture first and watch it go RED against today's binary" would have sent a less careful lane hunting for a redness that could not exist, or worse, manufacturing one.Population
Declared and moved deliberately: python
probes 9→14,forbid_sites 3→7,files 9→16,code_lines 133→194,name_fallback_ceiling 3→5with the +2 measured (each decoy call leaves exactly one nf row; therel_tweakdecoy contributes zero because that call resolves).forbid_sitesis the entire denominator ofphantom_count == 0for python, and it more than doubled. That is the part of this change that will still be paying next year.Scope held
#134 / #168 untouched — the absolute-module half of the stem hazard is not closed and no claim is made about it. Suggestion 2 (the registry test for equivalence claims) was not built, per the refusal in my triage.
One deliberate omission, flagged rather than hidden: the fixture is Python-only. The predicate has no per-language arm, so a TypeScript fixture would re-grade one branch twice for a second POPULATION row. Reasonable, and recorded as a judgement rather than an oversight.
Gates
fmt✓ ·clippy --workspace --all-targets -D warnings✓ ·cargo test --workspace --no-fail-fast2495 passed / 0 failed ·corpus_ratchet✓ ·precision_gate --release --nocapture7/7, phantoms=0, re-run by me post-merge.user.emailbinds across unrelated Django test apps via TIER1R_RECEIVER — 2 live phantoms on master, and #199's own comment says they were gone #246LineIndexphantoms survive on rust-analyzer because tier 1Q anchors on a file STEM — directions 1 and 2 (package_root_of/lib) measured and REFUSED, direction 3 is what remains #168