Skip to content

A 0 -> 1 binding is two states: split AuthoredReferenceResolution out of NewPoolCoincidenceResolution - #9495

Merged
briansrls merged 4 commits into
mainfrom
session/merry-lynx-302-wave-classifier
Aug 27, 2026
Merged

briansrls merged 4 commits into
mainfrom
session/merry-lynx-302-wave-classifier

Conversation

@briansrls

@briansrls briansrls commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

The defect

binding_disposition (the wave-admission wall, #9365) compares candidate sets
only, so every binding whose set went {} -> {one} is NewPoolCoincidenceResolution,
which refuses unless an operator admission names it. The function's own header says
that arm means "a name that began denoting something WITHOUT ANYONE AUTHORING A
REFERENCE — resolution arriving from a pool"
.

0 -> 1 is two states sharing one symbol, with opposite owners and opposite
repairs:

cause lives in repair
the target grew a name this module was already reaching for another module the coincidence the containment rule exists to remove — refuse
this module's own author wrote the import resolving a name it already spelled this diff the repair the wall was built to want — admit

The wall was refusing the second while naming it the first.

How it was found

gunbc#9485 — a one-line import repair, 5 blocking diagnostics -> 0 on a
discriminating pair — could not merge. It could not be admitted either:
NAMESPACE_TRANSITION_ADMISSIONS is a const &[TransitionAdmission] over a
DeltaSubject carrying String fields, so a row naming an actual module is E0015
(cannot call non-const associated function). That second half is escalated
separately and is deliberately not repaired here
— this change removes the need
for admission rows in this class, so the unauthorable roster is off the critical
path rather than fixed by a rider.

The fix

The discriminator is the module's own source, and it was already in hand: the
membership arm one function over consults membership_supported, which is what
auto-admitted the membership edge of the very change whose bindings it refused.

locally_authored_claim_added answers it from the two ModuleDeclarationRecords
alone — deliberately index-free, because consulting either index reintroduces
the conflation (a blanket import m whose target grew the leaf would read as
authorship). false is the fail-closed answer: it leaves the delta on the refusing
arm, so nothing here can turn a refusal into silence by accident.

AuthoredReferenceResolution auto-admits, amending the 2026-08-26 operator
partition recorded on gunbc.compiler_frontend_program_interlock per the
2026-08-27 ruling relayed through swift-badger-524. The .dag coproduct is the
authority and the host enum is one realization; the vocabulary-join tests in both
directions gate the pair.

Executed evidence

The test file asserted NewPoolCoincidenceResolution over a head that authored
import probe.home { widget }
— it planted the repair and named it the
coincidence. That is why the conflation survived review, and re-deriving the arm
required authoring a coincidence that actually is one: consumer source
byte-identical across both sides, reaching the target through a blanket import,
target grows the name.

Both arms mutation-checked, opposite directions:

  • locally_authored_claim_added forced true → coincidence arm reds alone
  • forced false → authored arm reds alone
  • restored: 20 passed; 0 failed

cargo fmt --all --check clean.

…PoolCoincidenceResolution

The wave-admission wall (#9365) classified every binding whose candidate set went
from empty to one member as `NewPoolCoincidenceResolution`, refusing unless an
operator admission names it. `binding_disposition` compares candidate SETS only,
and its own header says that arm means "a name that began denoting something
WITHOUT ANYONE AUTHORING A REFERENCE — resolution arriving from a pool".

That is one of two states sharing the symbol, and they have opposite owners and
opposite repairs:

  - the TARGET grew a name this module was already reaching for — the coincidence
    the containment rule exists to remove, cause in another module;
  - this module's own author wrote the import that resolves a name it was already
    spelling — the exact repair the wall was built to want.

The wall was refusing the second while naming it the first. Found by gunbc#9485,
a one-line import repair (5 blocking diagnostics -> 0) that the wall would not let
merge, and it could not be admitted either: `NAMESPACE_TRANSITION_ADMISSIONS` is a
`const &[TransitionAdmission]` over a `DeltaSubject` carrying `String` fields, so a
row naming an actual module is E0015 — that half is escalated separately and is
not repaired here.

The discriminator is the module's own source, and it was already in hand: the
membership arm one function over consults `membership_supported`, which admitted
the membership edge of the very change whose bindings were refused.
`locally_authored_claim_added` answers it from the two `ModuleDeclarationRecord`s
alone — deliberately index-free, because consulting either index reintroduces the
conflation (a blanket import whose target grew the leaf would read as authorship).
False is the fail-closed answer: it leaves the delta on the refusing arm.

The new disposition auto-admits, amending the 2026-08-26 operator partition on
`gunbc.compiler_frontend_program_interlock` per the 2026-08-27 ruling relayed
through swift-badger-524. The `.dag` coproduct is the authority and the host enum
is one realization; the vocabulary-join tests (host <-> ruling, both directions)
gate the pair and pass.

EXECUTED EVIDENCE. The test file asserted `NewPoolCoincidenceResolution` over a
head that authored `import probe.home { widget }` — it planted the repair and
named it the coincidence, which is why the conflation survived review. That
fixture is re-derived as the authored arm, and a real coincidence is authored for
the other: consumer source byte-identical across sides, reaching the target
through a blanket import, target grows the name. Both arms mutation-checked:
forcing `locally_authored_claim_added` true reds the coincidence arm alone,
forcing it false reds the authored arm alone. 20/20 green restored.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TrqmnrTJvHxHxJuJFBED8k
@gunbai-bot gunbai-bot Bot changed the title Five BLOCKING diagnostics sit on main in extdeps/container/oci/manifest.dag: it uses three symbols from media_types.dag without importing that module -- a one-line fix, and a live specimen of the DESIGN row declaring this population uncounted and unbounded A 0 -> 1 binding is two states: split AuthoredReferenceResolution out of NewPoolCoincidenceResolution Aug 27, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 27, 2026 18:06
gunbai-bot Bot pushed a commit that referenced this pull request Aug 27, 2026
…port was laundering a pool coincidence

Review 56882 on this PR, before it merged. `locally_authored_claim_added`'s
member-list and self-declaration arms name the leaf in the source and were scoped
to it; the blanket-import arm names no leaf at all, and the first revision admitted
authorship whenever ANY blanket target was new. So an unrelated new blanket import
elsewhere in the same module auto-admitted a genuine pool coincidence beside it —
a fail-open widening, in the one direction this function must never move, and
directly opposite the docstring's own "false is the fail-closed answer".

THE ARM IS NOW A CONJUNCTION AND THE ORDER OF ITS HALVES IS THE POINT: the claim
must be NEW IN THIS MODULE'S SOURCE **and** the head target must actually supply
the leaf. Asking the second alone is exactly the conflation this function exists to
discriminate — an unchanged blanket import whose target grew the leaf would read as
authorship. Gating it behind the first makes the index consultation safe rather
than forbidden: a claim the author did not write cannot reach the surface check,
whatever the target did. So the docstring's index-free claim is corrected rather
than restated; it was true of the leaf-named arms and never of this one. A target
absent from the index answers false.

EXECUTED EVIDENCE, both directions of the scoping:

  - an_unrelated_new_blanket_import_does_not_launder_a_pool_coincidence — the
    reviewer's scenario. `probe.home` grows `widget` with its blanket import
    UNCHANGED; the author adds a blanket `probe.other`, which does not supply
    `widget`. Must stay NewPoolCoincidenceResolution and must stay refused.
    Restoring the leaf-blind arm reds this test ALONE.
  - a_new_blanket_import_that_does_supply_the_leaf_is_an_authored_reference_resolution
    — so the scoping is not a narrowing to nothing: when the NEW blanket target is
    the one supplying the leaf, it auto-admits like any other authored reference.

22/22 green, fmt clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TrqmnrTJvHxHxJuJFBED8k
@gunbai-bot

gunbai-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Fixed in 49e58ea. Review 56882 is correct, and the fail-open direction is what makes it worth more than a scoping nit: the arm could only ever turn a refusal into an admission, which is the one direction this function must never move, and my own docstring asserted the opposite.

The arm is now a conjunction, and the order of its halves is the point: the blanket claim must be NEW IN THIS MODULE'S SOURCE and the head target must actually supply the leaf. Your parenthetical offered the alternative of accepting that this discriminator needs index consultation for blanket imports — that is what landed, but gated rather than accepted outright. Asking the surface question alone is exactly the conflation the function exists to discriminate (an unchanged blanket import whose target grew the leaf would read as authorship); asking it only after the claim is established as newly authored makes it safe, because a claim the author did not write cannot reach the surface check whatever the target did. A target absent from the index answers false.

So the docstring's index-free claim is corrected rather than restated — it was true of the leaf-named arms and never of this one.

Two tests, both directions of the scoping:

  • an_unrelated_new_blanket_import_does_not_launder_a_pool_coincidence — your scenario, authored exactly: probe.home grows widget with its blanket import UNCHANGED, while the author adds a blanket probe.other that does not supply widget. Must stay NewPoolCoincidenceResolution and must stay refused. Restoring the leaf-blind arm reds this test alone — measured, not asserted.
  • a_new_blanket_import_that_does_supply_the_leaf_is_an_authored_reference_resolution — so the scoping is not a narrowing to nothing: when the NEW blanket target is the one supplying the leaf, it auto-admits like any other authored reference.

22/22 green, fmt clean.

— sent from merry-lynx-302

…predicate split

Textual conflict only, in one hunk. #9490 renamed `membership_supported` to
`membership_bound_through` and added `membership_declared` above it; my
`locally_authored_claim_added` had been inserted at exactly that anchor, so the two
edits landed on the same lines. Both survive: #9490 splits the MEMBERSHIP channel's
add and removal directions, this branch splits the BINDING channel's `0 -> 1`, and
neither predicate is called by the other.

ONE THING THE MERGE ALMOST TOOK WITH IT: `/// Whether any name this module authors
reaches into `target`'s surface.` is `membership_bound_through`'s doc line, and the
conflict left it sitting above MY function, where it would have read as a
description of authorship-claim detection. Moved back to the function it describes.

23/23 green (main's `membership_declared_by_an_import_whose_names_appear_only_in_pattern_arms`
included), fmt clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TrqmnrTJvHxHxJuJFBED8k
@gunbai-bot

gunbai-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

CI investigated on 01ede37. There is no fix for this PR to push — the failure is main's, and this run carries the positive receipt that the change works.

The phase this PR is about PASSED, on the live tree:

required-ci: namespace-wave-admission base=9538523a3c head=58bbc70c88 modules_compared=4196
required-ci: namespace-wave-admission ADMITTED — every delta is auto-admitted or named by a transition admission

That is the whole point of the change, executed against the real corpus rather than a fixture: before it, the wall refused authored-import resolutions and had no authorable admission roster to relieve them.

The two failing phases are dag/product/fabric/contention.dag, and nothing else. Every .dag error in the run is one of four, all from one removal:

  • 23:19 name 'grant_duration_seconds' not found in module 'product.fabric.supply'
  • 280:3 non-exhaustive match: missing variant(s) UnobservedGrantDuration
  • 421:3 non-exhaustive match: missing variant(s) QuoteNotPriceableWithoutDuration
  • 463:30 and 469:43 function 'grant_duration_seconds' not found in scope

This branch touches src/v1/stage0/src/namespace_wave_admission.rs, its test file, and dag/gunbc/compiler_frontend_program_interlock.dag. It cannot produce any of those.

Fixed by #9488, which is open and whose declarations phase already passes. One correction worth recording, because the dashboard renders it as a red: #9488's floor job did not fail — its log ends ##[error]The operation was canceled after a clean compile.emit, so it was superseded, not refused. A cancelled check is not a failed one and not a passed one.

The srv3_wiring_with_a_duplicated_header duplicate declaration I reported on the earlier run is gone — fixed on main since.

This PR goes green when #9488 lands and this branch takes a run on top of it. Nothing here to rework.

— sent from merry-lynx-302

…r imported (#9485)

`accept_image_manifest` reads `oci_image_schema_version`,
`media_type_oci_image_manifest_v1` and `media_type_oci_image_config_v1`, all
declared in `extdeps.container.oci.media_types`, with no import of that module —
five BLOCKING name-resolution diagnostics standing on main. Adds the one import.

This is a live specimen of the DESIGN row declaring the blocking-diagnostic
population uncounted and unbounded: no required phase emits over a closure
reaching this module, so nothing refused.


Claude-Session: https://claude.ai/code/session_01TrqmnrTJvHxHxJuJFBED8k

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@briansrls
briansrls merged commit 48d5967 into main Aug 27, 2026
2 checks passed
@briansrls
briansrls deleted the session/merry-lynx-302-wave-classifier branch August 27, 2026 21:14
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