Skip to content

Qualify the last two genuine bare-name reads, and stop at the five that are not - #11146

Merged
briansrls merged 1 commit into
mainfrom
session/witty-moth-510-b4
Sep 12, 2026
Merged

briansrls merged 1 commit into
mainfrom
session/witty-moth-510-b4

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Final qualification batch of the bare-name-ambiguity campaign. Census: #11078. Earlier batches: #11137, #11145.

It is two lines, because auditing the last seven sites the census names found that only two of them are defects.

The two that are

gunbc.cli_services reads Unit and String in the shell-exit fold (0 => Unit / nonzero => String "..."), the same shape the extdeps tool modules carry. Unit joins the std.types import that declares it; String moves to std.string_type, which is the module that actually declares it.

The five that are not, and why they must not be swept

Each is a bare read of a variant arm, not of either claimant type:

site name what it actually means
std.fidelity Unit arm of its OWN type TestClass = Unit | Hermetic | Integration
gunbc.live_deploy.unit_standing Unit arm of SystemdUnitProperty in extdeps.systemd, already imported by name — the site is property: Unit, the systemd Unit= property
v2.test.lens_cost.valuation Unit arm of TestgenLayer in v2.std.verification, already imported by name — the site is layer: Unit
v2.test.manual.infer_ground_add Unit same
v2.extdeps.languages.cpp Int arm of its OWN type CppSignedIntegerSurfaceSpelling — the site is spelling: Int

None means std.types.Unit, v2.std.cardinality.Unit, or v2.std.integer.Int. Adding an import naming one of those would not qualify a read — it would point a correctly-written site at a declaration whose meaning is different, while the census reported the corpus getting cleaner. That is the worst available outcome, so these are left alone.

Why the census counts them

Its resolver is PreparedScopeIndexes::site_resolved_fn, two tiers over fn_nodes: the site's own module, then the file's import binding. fn_nodes is populated from fragment.fn_entries, and fn_entries is built by walking module.items — top-level items only. A variant arm is not a top-level item, so no arm is reachable under either tier, and a bare read of one is reported as falling through to the shared slot even when it is locally declared or explicitly imported.

Confirmed from the other side too: the census's claimant lists for these rows name only the two type claimants — neither cpp nor v2.std.verification appears — so arms are invisible to the declaration census as well.

This is not a new error class. It is an instance of gunbc.recurring_failure_mode.binding_chosen_by_pool_membership_rather_than_by_the_declared_rule, whose root sentence is exactly this asymmetry: a coproduct arm is pool-visible corpus-wide while not being a local binding under its own spelling.

What this means for the wall

The refusal this campaign is building toward is specified to key on the same value-position population this census reports, and these five are sites that must NOT refuse. The instrument needs a third resolution tier — variant arms of a coproduct the site's module declares or explicitly imports — before a refusal over this population is safe. That tier is not in this PR; it belongs with the wall, and it needs its own discriminating controls.

Where that leaves the campaign

100 of the 105 reported reads are bound to the authority their own module means. The residual five are not qualification targets but the instrument's own next correction.

Worth stating plainly, because it is the campaign's real result: this was funded as a rename campaign and produced zero renames. What it found instead is that the corpus's bare-name ambiguity is qualification residue and mid-self-host migration doubles, plus an instrument that could not see variant arms.

🤖 Generated with Claude Code

https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT

…at are not

Fourth and final qualification batch of the bare-name-ambiguity campaign
(census: #11078; batches one to three: #11137 and its successors). It is
two lines, because auditing the last seven sites the census names found
that only two of them are defects.

THE TWO THAT ARE. `gunbc.cli_services` reads `Unit` and `String` in the
shell-exit fold (`0 => Unit` / `nonzero => String "..."`), the same shape
the extdeps tool modules carry. `Unit` joins the `std.types` import that
declares it; `String` moves to `std.string_type`, which is the module
that actually declares it.

THE FIVE THAT ARE NOT, and why they must not be swept. Each is a bare
read of a VARIANT ARM, not of either claimant type:

  std.fidelity                 Unit  -> arm of its OWN `type TestClass
                                       = Unit | Hermetic | Integration`
  gunbc.live_deploy.unit_standing
                               Unit  -> arm of `SystemdUnitProperty` in
                                       `extdeps.systemd`, ALREADY
                                       imported by name; the site is
                                       `property: Unit`, the systemd
                                       `Unit=` property
  v2.test.lens_cost.valuation  Unit  -> arm of `TestgenLayer` in
  v2.test.manual.infer_ground_add     `v2.std.verification`, ALREADY
                                       imported by name; the site is
                                       `layer: Unit`
  v2.extdeps.languages.cpp     Int   -> arm of its OWN `type
                                       CppSignedIntegerSurfaceSpelling`;
                                       the site is `spelling: Int`

None of these means `std.types.Unit`, `v2.std.cardinality.Unit`, or
`v2.std.integer.Int`. Adding an import naming one of those authorities
would not qualify a read -- it would point a correctly-written site at a
declaration whose meaning is different, and it would do so while the
census reported the corpus getting cleaner.

WHY THE CENSUS COUNTS THEM. Its resolver is
`PreparedScopeIndexes::site_resolved_fn`, two tiers over `fn_nodes`:
the site's own module (`{module_path}.{name}`), then the file's import
binding (`{source_module}.{name}`). `fn_nodes` is populated from
`fragment.fn_entries`, and `fn_entries` is built by walking
`module.items` -- TOP-LEVEL items only. A variant arm is not a top-level
item, so no arm is ever reachable under either tier, and a bare read of
one is reported as falling through to the shared slot even when it is
locally declared or explicitly imported.

This is a bounded over-approximation in the instrument, five sites wide
at this revision, and it is load-bearing for the refusal this campaign is
building toward: that wall is specified to key on the SAME value-position
population this census reports, and these five are sites that must NOT
refuse. The instrument needs a third resolution tier -- variant arms of a
type the site's module declares or explicitly imports -- before a
refusal over this population is safe to land. That tier is not in this
PR: it is a change to the census's own resolver, it wants its own
discriminating controls, and it belongs with the wall rather than with a
batch of import lines.

With this batch the qualification stage is complete: 100 of the 105
reported reads are bound to the authority their own module means, and
the residual five are not qualification targets but the instrument's own
next correction.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
@briansrls
briansrls merged commit 11e0dfa into main Sep 12, 2026
4 checks passed
@briansrls
briansrls deleted the session/witty-moth-510-b4 branch September 12, 2026 06:36
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
…asured

THE CENSUS POPULATION IS NOT STATIC, and that is the finding here rather
than the two lines. Main's own floor at 0c93af0 -- with #11137, #11145
and #11146 merged -- reports `read_name_module_pairs=25`, and two of the
seventeen `Filesystem` sites in it are NEW: they arrived from another
lane in `extdeps.realization.materialization_store_local` and its wet
witness, after this batch's population was measured.

So sites are being ADDED while the campaign removes them. That matters
for the refusal this campaign is building toward: a wall cannot wait for
a permanent zero it will never see, because a wall is precisely the thing
that KEEPS the count at zero once reached. The landing window is narrow
and follows immediately after this batch.

Both are the same decision every other site in this batch took --
`Filesystem.Read` / `.Write` are operations of `service Filesystem` in
`extdeps.filesystem.filesystem_io`, and no rival claimant declares them.
`materialization_store_local` already imported that module with a braced
list and simply lacked `Filesystem`; its wet witness had the bare form.

QUALIFIED PREDICTIVELY THIS TIME, not reactively, because the mechanism
behind review 64402's finding and the six stranded names is now known
exactly: A BARE IMPORT RE-EXPORTS THE IMPORTED MODULE'S OWN BINDINGS.
`extdeps.clock` imports `v2.std.optional { Present }` and
`extdeps.filesystem.filesystem_io` imports `std.types { ... List ... }`,
which is why narrowing those stranded `Present` and `List` in files that
never mention either module.

That makes the risk computable before the edit rather than discoverable
after it. For the wet witness the set of names reachable ONLY through its
bare import is exactly `{Filesystem}`, so narrowing strands nothing;
`materialization_store_local` gains a name and can strand nothing by
construction. It compiles at 0 blocking errors.

A note on the pre-check, so it is not trusted further than it earns: it
OVER-APPROXIMATES. Run over this batch it flags fourteen files where the
floor found six, because it unions both narrowed modules' re-exports
regardless of which module a given file imports, and counts a name as at
risk even when another import already supplies it. It is a candidate list
worth inspecting before a push, not a verdict, and the floor's
`NewUnresolvedness` deltas remain the authority.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant