Skip to content

Calibrate the reference-occurrence census before the corpus run: its coverage is not unproven, it is refuted - #10256

Merged
gunbai-bot[bot] merged 20 commits into
mainfrom
work/step0-census-calibration
Sep 4, 2026
Merged

gunbai-bot[bot] merged 20 commits into
mainfrom
work/step0-census-calibration

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

The candidate reference-occurrence producer's coverage of the family roster was recorded as
unestablished. It is now refuted, by execution, on a hand-authored two-module subject.

Two claims this PR made in an earlier revision are refuted by its own later measurements

Recorded first rather than quietly edited out, because a stepping-stone PR carrying known-false
current claims is a false evidence authority, and a later PR cannot retroactively make it truthful.

  1. "type annotation and generic type argument both emit TypeOccurrence, converged" — false. A
    type named as a generic argument emits no occurrence at all. The row that made it look
    observed came from somewhere else in the fixture entirely (below).
  2. "a name inside an import statement's brace list produces no reference occurrence" — false. The
    first name in the list is emitted as a reference occurrence; every later name carries no role.

Both were established the same wrong way — by reading a count — and both were caught the same
right way, by a control over a spelling nothing else in the subject can stand in for. That is the
fixture law this PR now carries: a calibration spelling must be unique AND free of every construct
that re-mentions a name
, because an import list re-mentions every name it imports.

What was measured

step0_calibration_probe runs tools.reference_occurrence_binding_census over a fixture manifest and
renders one line per observed occurrence. Re-derive it with:

gunbc run --source-root dag --source-root src/v2 \
  --entry dag/test/claim/namespace_step0_census_calibration_witness_test.dag \
  --function step0_calibration_probe
authored family what the instrument emits
type annotation TypeOccurrence
top-level value, function value, nullary constructor, variant expression LexicalValueOccurrence — converged, four ways
ordinary call CallableOccurrence — discriminated
qualified container.member two occurrences — the head as a lexical value, the member as a FieldOccurrence, neither a namespace segment. Split, not discriminated (below)
generic type argument no denominator row at all
payload constructor in expression position no denominator row at all
variant in match-pattern position no denominator row at all

In the other direction, two things that reference nothing are emitted as reference occurrences: the
label of a named argument — the n in cal_called(n: 1) — stamped CallableOccurrence, and the
head of an import list, stamped as whatever category its spelling would carry. The population is
short real occurrences and long invented ones simultaneously; the errors are over different
populations and cannot cancel.

The counts behind that table are not transcribed here. step0_family_observation is the authority and
the controls join against it, so a wrong row goes red rather than standing in prose — and the earlier
version of this section named "two blind families" while the table had grown to three, which is
exactly the rot a transcribed count produces. The denominator-defect roster now derives its
omission rows from step0_unobserved_families() for the same reason.

ConstructorOccurrence and NamespaceSegmentOccurrence are uninhabited in this subject — not
dead. The fixture is small and hand-authored; an arm with no inhabitants here may have them in the
corpus. What is established is that no construction written here reached them.

"I found no row" and "there is no row" are different sentences

Only the second is a finding, and the difference is a perturbation control. A second subject
removes every appearance of one variant — its declaration, its import-list entry, and its match arm —
and the observed occurrence count changes by zero. Both counts are nonzero, so this is not two
silences agreeing. That is removing_a_variant_entirely_does_not_change_the_occurrence_count.

The positive control does the matching work in the other direction: one spelling, twice in one
file at one revision, comes back CallableOccurrence in call-head position and
LexicalValueOccurrence as a bare value. So the instrument discriminates rather than being
uniformly coarse — an instrument coarse everywhere could be excused as a lower bound; this one sees
this and not that, and cannot.

A cardinality assertion is blind to substitution, at every layer it appeared

This is the single stated rule of the PR, because it caught four separate defects in this lane:

  • the family-roster contract check compared a count of families, so it would have passed over any
    substitution in the roster — replaced with set inclusion over the family, law and receipt-field
    names;
  • the import-list measurement above read a count that did not move while the population did;
  • two of the four metamorphic invariants were first written over sizes, where one demanded that a
    real addition add nothing and another would have passed clean over the fabrication it exists to
    catch;
  • and every figure this census eventually publishes has the same exposure.

Completeness is an identity join, not a count equality (DESIGN §5). The four invariants are
therefore stated over the tag-and-category multiset — and that grain is declared honestly in the
source: cardinality rejected, tag-plus-category established (discriminating here only because
the fixture law makes every perturbed spelling unre-mentionable), exact authored-occurrence identity
not established by these controls, since the key is not an OccurrenceId and carries no
containment path or semantic slot.

Why no law we wrote would have caught it

The denominator and the observations come from one walk. Every conservation law balances by
construction
over whatever that walk produced, so a family it never emits is invisible to all of
them. The anti-join cannot reach it either: an anti-join needs a population to join against, and
those occurrences were never in one. The unobserved-derivation law was written against a denominator
derived from the diagnostic; the same disease sat one layer above it.

Three consequences, carried as typed rows

1. The removed-edge roster is owned by the strip — and the reason is now stronger, not weaker. The
imported-binding grain, one row per imported name, cannot be sourced from the occurrence walk. Not
because the walk is silent there, which is what this PR first claimed, but because what it emits is
fabricated and position-dependent: an import-list entry names a binding to introduce rather than
referring to a declaration from a use site, and only its first entry is admitted. A roster sourced
from the walk would have been neither empty nor right. The strip parses the statements and their
brace lists and is the only thing that knows what it removed, so the census has two producers by
construction, joined on identity.

2. The census unit is declared. The denominator is the reference occurrence; a reader hears
reference; for one family those are different numbers. "Every occurrence receives exactly one
outcome" holds perfectly while the census answers a different question than "every authored reference
is accounted for" — the laws balance and the figure is still wrong. One number carries both findings:
a blind family maps to zero occurrences per authored reference, an observed one to one, a
split one to two. A fold joins that mapping against the observation table, so two authored tables
about one instrument cannot drift apart.

3. Three ranks below coverage, not one. A converged family is counted in the wrong bucket; a
split family is counted twice with nothing in the row schema to say so; an unobserved family is
not counted anywhere. These are different claims and only the first can be reported as coverage at
any grain. A family the instrument splits is explicitly not discriminated: one authored reference
arriving as two occurrences is only discriminated if the rows can be joined back to the one authored
slot, and the row carries no parent occurrence and no semantic-slot identity — which this module's
own grain statement already admits about its comparison key. So FamilySplitAcrossUnjoinedOccurrences
is its own arm below discrimination, and the measured partition is three unobserved, four
converged, one split, two discriminated
. The discrimination count went down when this landed,
because the model got more truthful rather than because the instrument got worse. There is no arm of
step0_calibration_standing in which a partially blind roster renders as coverage, and the census's
rung is the minimum across its families.

The refusal arm is carried, not erased

The witness's subject accessors mapped a census refusal to the empty list and to zero. The
liveness control closed the false green that could produce, but a gate compensating for an erased
refusal is not the same thing as not erasing it — the refusal was destroyed and reconstructed
downstream as an observed population of size zero, which is the absorbing fallback DESIGN §5 names.
Every accessor now returns CalSubjectObserved { denominator_size, rows } | CalSubjectRefused { cause },
every control opens the carrier, and a refusal on either side of a two-subject invariant reds.
Liveness is now a property of the observed arm rather than a repair of a missing one, and
step0_calibration_probe is the located reader a red sends you to.

The roster becomes one axis

Step0ReferenceFamily had carried SameSpellingInTwoModules beside TypeReference and
OrdinaryFunctionCall. That is not a way of writing a reference but a shape of the name pool one
resolves against, and holding both on one axis made the roster unable to say that a homonym can occur
under any family. It moves to the binding-topology axis, where it composes with every family row
rather than standing beside six.

Two producer branches are declared unauthorable from source, with the harness that would reach
them, rather than covered by rows that never execute — a permanently green check gets cited as
evidence, which is worse than an absent one.

Not in this PR

No corpus run, no pre/post pairing, and no repair to the producer. The denominator was never
supposed to come from the observation walk, so patching that walk is not the fix. The mechanism behind
the fabrications is measured in a separate PR and repaired in a third, because the stamper is shared
and its blast radius — every node requested as a lexical-value declaration, which includes imports,
function and lambda parameters, type parameters and pattern binders — must be enumerated before it is
edited, not inside the measurement.

Deliberately not claimed: most rows in the first run came back Unresolved, including
cross-module spellings in a fixture where the provider is supplied and imported. Two explanations
predict that identical output and the discriminator has not been run, so it is an observation about
the probe, not a finding about the resolver.

The floor's cost refusals are a DECLARED RUNG DROP, not an open question

Cited so a reader lands on the trigger: gunbc.rung_drop floor_cost_claim_qualification_unavailable
— "Per-claim cost qualification is unavailable at the subject grain the gate consumes", declared
2026-09-01, projected in docs/design-rung-drops.md.

The rule is one reroll per exact head. Not "per head per signature" — that spelling parses as a
counter key, licensing many rerolls per distinct signature, and it is self-defeating on this row's
own claim: these arms vary across attempts of one unchanged tree, so a changed signature is the
expected outcome of a reroll rather than new information, and every reroll would license the next.
The signature is an eligibility predicate, never a budget. And eligibility is read off the run's
phase verdict
— phases_run, failed, the FAILED PHASE lines — never off this class's own
disposition counters, which enumerate cost dispositions and cannot report that another phase failed.

One reroll was taken on this branch, on head 0a3e0e8c2d, and it is appended to that row's INSTANCES
list with run id, head, floor job and both arms rather than tallied. Its first version justified
eligibility with claims_failed=0 — the repudiated inside-the-subject form — and the row now carries
the correction visibly, on the evidence that actually decides it: phases_run=3 phases_failed=1 with
a single FAILED PHASE floor line and no other.

It is not carried forward. f64177c424277542f549ca22f24a20a42e3d85ed and
200591eb6f2cebc0037501c3f104cb820beab95e each completed CI green on their first attempt with no
reroll, so the budget for those heads was never spent — a receipt belongs to the tree it was
established on, and reading a green as a settle without binding it to a revision is the same defect
this lane keeps finding one layer out.

The claims and margins are not transcribed here either. Re-derive with
claim_executor --required-ci --required-lane witnesses and read the [over-cost] and
INTERRUPTED-BEFORE-VERDICT lines; the instances list on the drop row carries the per-run readings.
No budget was widened here — widening a cost requirement to get a lane green is the escape hatch §5
forbids — and the deficit belongs to the owners of those witnesses, who should learn it from a receipt
rather than from an incident.

Two things I had to correct in my own reading, recorded because they are the kind of error this PR is
about. The 500ms deadline is not a check that reports something other than what it claims: it is a
valid observation of this execution attempt, and it stays REQUIRED as attempt-safety and
verdict-availability — removing it lets runaway evaluation consume the executor unbounded. What it
cannot do is qualify the claim as an isolated subject. And "the whole distribution translates with
load" was my inference, withdrawn; what I actually established is narrower — for the one pair I
compared, the shared-fill triggered_by and provenance were identical with only the milliseconds
moving, which refutes payer transfer for that pair and says nothing about cause.

The merge that neither side could win

Integrating main produced a four-way case worth naming, because it is the merge driver's refusal
doing exactly the job it exists for. Main deleted two bridge arms from the generated dispatch
file while this branch added a builtin arm. Taking this branch's bytes resurrects two arms main
removed — and the compiler says so, E0004 non-exhaustive, since main's merged interpreter no longer
matches them. Taking main's bytes drops the builtin and nothing builds at all. Neither side is
correct, which is why a low-level driver that answered true here would have silently dropped
authority-derived content.

The file was rebuilt from main's side plus this branch's three builtin lines only to bootstrap a
compiler able to run the regenerator, and then the regenerator adjudicated it:
claim_executor --required-regen reports first_generation_equal=true over planned=executed=156.
That is the check that matters — a successful build proves only that nothing contradicts, not that
the artifact is what the authority generates.

dag/gunbc/rung_drop.dag conflicted inside a single 52,000-character line, where git can show
nothing useful and neither side reads as an overlap. Main appended its verdict-grain section before
the row's closing paragraph; this branch's reroll instance appends after it. Resolved by hand and
verified by content that each side's material survives exactly once.

Main's addition carries a same-head control — run 33806159353, two attempts on runners srv4-14
and srv4-19 at one unchanged head, opposite verdicts — which is stronger evidence for that row's
redraw reading than any instance this branch cites, because it is established by construction rather
than by correlation across runs.

Review state

Four approving reviews stand, three of them at superseded heads, and they do not settle this PR:
an approve means no blocking defect found, not that the change is what was asked for. Codex review
59402 (request_changes, at b280e56b, six commits back) is unread, not cleared — its stdout
artifact is truncated by a 1 MiB server-side cap with the verdict past the end, and the dashboard
exposes no other artifact for it. Treated as unread rather than resolved.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd

Brian Searls and others added 8 commits September 3, 2026 16:45
…coverage is not unproven, it is refuted

THE CANDIDATE PRODUCER IS BLIND TO TWO FAMILIES AND EMITS A ROW FOR A THING THAT IS NOT A REFERENCE.
Measured, on a hand-authored two-module subject, by an instrument that re-derives the table:
a payload constructor applied in expression position produces no denominator row at all, and a
variant named in a match pattern produces none either -- while the label of a named argument
produces one, stamped CallableOccurrence, though it refers to no declaration. The population is
short real occurrences and long invented ones at the same time, over different populations, so the
errors cannot cancel.

WHY NO LAW WE WROTE WOULD HAVE CAUGHT THAT. The denominator and the observations come from ONE
walk, so every conservation law balances BY CONSTRUCTION over whatever that walk produced, and a
family it never emits is invisible to all of them. The anti-join cannot reach it either: an
anti-join needs a population to join against, and those occurrences were never in one. The
unobserved-derivation law was written against a denominator derived from the DIAGNOSTIC; the same
disease was sitting one layer above it.

FamilyEmitsNoOccurrence IS NOT A COARSE OBSERVATION AND MUST DOMINATE. A converged family is
counted in the wrong bucket; an unobserved family is not counted anywhere. Those are different
claims and only the first can be reported as coverage at any grain, so CalibrationBlindToFamilies
dominates CalibrationCappedByConvergence in the standing fold and never merges with it. The census's
rung is the minimum across its families, which is what a receipt quoting it inherits.

THE ROSTER BECOMES ONE AXIS. Step0ReferenceFamily carried SameSpellingInTwoModules beside
TypeReference and OrdinaryFunctionCall, and that row is not a way of WRITING a reference -- it is a
shape of the name pool one resolves against. Holding both on one axis made the roster unable to say
that a homonym can occur under ANY family. It moves to the binding-topology axis, where it composes
with all ten rows rather than standing beside six.

WHAT IS EXECUTED HERE, and it is the point rather than the packaging: seven controls run the
instrument over the fixture. A liveness control first, because every absence below is vacuous
without it. Then the two blind families, with CalMiddle authored ONLY in pattern position so its
absence cannot be explained by anything else in the subject. Then the positive control that makes
the absences mean something -- ONE spelling, in call-head and bare-value position in the same file,
comes back CallableOccurrence and LexicalValueOccurrence, so the walk does separate acquisition path
and the instrument is discriminating rather than uniformly coarse. Then the fabricated row, the
nullary constructor arriving as a lexical value, and the qualified reference splitting into two
occurrences under two categories with neither a namespace segment.

The two roster-totality folds are identity joins in both directions: a producer branch with no row
claiming it, or a family with no row authoring an occurrence of it, goes red. Two branches are
declared UNAUTHORABLE FROM SOURCE with the harness that would reach them, rather than covered by
rows that never execute -- a permanently green check gets cited as evidence, which is worse than an
absent one.

NOT IN THIS PR: any corpus run, any pre/post pairing, and any repair to the producer. The
denominator was never supposed to come from the observation walk, so patching that walk is not the
fix; the fix is an independent occurrence population, and which authority can supply one is the next
measurement rather than a design to improvise now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd
…ake the absence a perturbation control

THREE CONSEQUENCES OF THE MEASUREMENT, each now a typed carrier rather than a sentence in chat.

THE UNIT IS DECLARED, because the conservation laws cannot detect answering the wrong question. The
denominator is the reference OCCURRENCE and a reader hears 'reference', and for one family those are
different numbers: an authored container.member reference becomes TWO occurrences. 'Every occurrence
receives exactly one outcome' holds perfectly while the census answers a different question, so the
mapping between the units is carried explicitly. One number carries both findings at once -- a blind
family maps to zero occurrences per authored reference, an observed one to one, a split one to two --
which is why it is one function and not two, and a fold joins it against the observation table so the
two authored tables cannot drift.

THE REMOVED-EDGE ROSTER IS OWNED BY THE STRIP, settled by measurement. A name inside an import
statement's brace list produces no reference occurrence, so the imported-binding grain cannot be
sourced from the occurrence walk -- a roster that tried would have come back silently empty, the same
vacuity one layer further out. The strip parses the statements and their brace lists and is the only
thing that knows what it removed.

AND THE ABSENCE BECOMES A CONTROL RATHER THAN AN OBSERVATION. A second subject removes every
appearance of one variant -- declaration, import-list entry, match arm -- and the observed count
changes by zero. If a variant in pattern position or a name in an import list produced an occurrence,
that perturbation HAD to move the number. Both counts are nonzero, so this is not two silences
agreeing. 'I found no row' and 'there is no row' are different sentences and only the second is a
finding.

Two category arms are described as UNINHABITED IN THIS SUBJECT rather than dead: the fixture is small
and hand-authored, and an arm with no inhabitants here may have them in the corpus.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd
…_read_as_population

The census consumes module.occurrence_transport REFERENCES -- a role-filtered view built beside the
authored-occurrence population index.entries -- and emits one denominator row per member as though
that view were the population. This is the rostered class in its inherited form, where the view is
somebody ELSE'S and therefore looks like an authority.

What makes it worth the row rather than a local bug report: every conservation law over that
denominator balances BY CONSTRUCTION, because the denominator and the observations are walked from
the same view, and an anti-join cannot reach the missing members because an anti-join needs a
population to join against. The completeness machinery is not weak here, it is inapplicable.

The recognition rule gains the inherited-view form -- a name like references or declarations beside
an entries is the tell -- and the repair is stated as NOT switching views: a consumer declares its
own total eligibility disposition over the source population, every member either in the subject or
excluded by a named cause, which holds even where the two views agree today.
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review September 3, 2026 17:59
@gunbai-bot

gunbai-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

All twelve controls are green locally, each executed on the real acceptance path with a compiler
built from this branch. In the order that matters:

  • the_instrument_observed_this_subject_and_is_not_silent — first, because every absence below it
    is vacuous without it. An instrument that refused, or saw nothing, answers "no row for CalRight"
    exactly as a blind one does.
  • removing_a_variant_entirely_does_not_change_the_occurrence_count — the perturbation control.
    Deleting a variant's declaration, its import-list entry and its match arm moves the observed count
    by zero, with both counts nonzero. That is what makes this there is no row rather than I
    found no row
    ; only the second sentence is a finding.
  • a_call_head_and_a_bare_function_value_are_stamped_differently — the positive discriminator. One
    spelling, twice in one file, comes back CallableOccurrence and LexicalValueOccurrence. An
    instrument coarse everywhere could be excused as a lower bound; one that sees this and not that
    cannot.
  • Then the two blind families, the fabricated named-argument row, the nullary-constructor stamping,
    the qualified-reference split, both roster-totality identity joins, the unit-mapping join, and the
    standing fold returning the measured 2 unobserved / 6 converged / 2 discriminated.

Also filed here: this is the rostered selection_view_read_as_population class in its inherited
form, where the view is somebody else's and therefore reads as an authority. The census consumes
module.occurrence_transport.references — a role-filtered view built beside the authored-occurrence
population index.entries — as though it were the population. The receipt is appended to that row
rather than written as a novel finding, because an instance of a known class tells the next person
where else to look. Its recognition rule gains the inherited-view form: a references or
declarations sibling beside an entries is the tell.

The repair recorded there is deliberately not "switch views". A consumer must declare its own
total eligibility disposition over the source population — every member either in the subject or
excluded by a named cause — because silence from a view someone else built is exactly how a family
disappears with nobody deciding it should, and that holds even where two views agree today.

Next measurement, not in this PR: whether index.entries carries an entry for the payload
constructor that the references view drops, and if so with what role. Presence alone cannot separate
"the population lacks it" from "the classification is blind" from "the filter predicate is wrong" —
three answers with three different repairs — so the probe must report identity, role, and whether
the references view admitted it.

— sent from jolly-badger-374

🤖 Generated with Claude Code

https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd

Brian Searls and others added 9 commits September 3, 2026 19:28
Review 59402 found that the matrix claimed QualifiedContainmentReference
calibrates BranchDispositionBoundDefinerResolvable, a branch the instrument
selects only for an authored spelling carrying a dot -- and the qualified pair
reaches the census as two occurrences, neither of which carries one. Measuring
rather than re-reading widened it: FOUR branch claims are unexercised by this
subject, not one. Nothing joined the outcome column to a disposition the run
produced, so the column was unfalsifiable, which is rung inflation in the module
whose job is to detect it.

A row may now claim OutcomeObservedOnSubject only when its claimed branch IS the
disposition branch that outcome names and the run exercises it: three rows, not
seventeen. Two controls check it against the run -- the specific one the review
asked for, and its general form so the next overstated row goes red without a
reviewer finding it.

THE FIXTURE LAW, and it cost two wrong claims of mine to state. A calibration
fixture must use a spelling nothing else in the subject can stand in for. I read
a listing, concluded a generic argument produces no occurrence, and authored the
retraction; the control the law demands went RED and I withdrew it unlanded; the
entries probe showed the row came from the IMPORT LIST, not the argument; and a
spelling declared in the consumer module produces no row, so the retraction
stands. Unique in spelling AND free of every construct that re-mentions the name.

A SECOND FABRICATED ROW, found by perturbation. The first name in an import list
is emitted as a reference occurrence and every later name carries no role. The
denominator SIZE does not move under a reordering -- only which name holds the
row -- so a count-only invariant would have missed it entirely. Four metamorphic
invariants are enrolled; this one is asserted in its broken form with an explicit
inversion trigger rather than parked as a permanent CI red.

The canary's roster check was a count over literals: it fires when a family is
ADDED, which is safe, and passes when one is SWAPPED, which is the silent drop it
was written to prevent. Replaced with set inclusion over identities.

All twenty controls green by execution. Every claim is about THIS SUBJECT: the
perturbation controls license the absences and nothing licenses a universal.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd
A CARDINALITY ASSERTION IS BLIND TO SUBSTITUTION, WHEREVER IT APPEARS. It fails
on a safe addition and passes on an unsafe swap. The contract's roster check and
these invariants were the same defect at two layers, and so is every figure this
census eventually publishes -- so the rule is stated in the file rather than left
to be re-derived from a third incident.

All four invariants are restated over identity sets, keyed by authored spelling
paired with stamped category: occurrence ids are graph-scoped and cannot be
joined across two compilations, and spans move under exactly the transformations
these invariants apply. Invariant A additionally pins that the denominator SIZE
is unchanged while the key sets disagree, so the control itself records that the
cardinality version would have passed clean over the fabrication it exists for.

INVARIANT D'S FIRST VERSION WAS WRONG -- THE CONTROL, NOT THE CENSUS. It demanded
that the keys mentioning neither added spelling agree exactly, which required a
real addition to add nothing: `List<CalLocalArg>` legitimately contributes `List`
and `Int` occurrences spelled with names the subject already used. That is this
file's own fixture law violated a third time, in a property statement rather than
an observation, which is why the law has to govern how invariants are PHRASED and
not only which spellings a fixture uses. The sound form needs no oracle: addition
is ADDITIVE -- every key present before is present after at least as often, so
growth passes while loss and substitution fail.

REVIEW 59447's fail-closed nit, taken on all three sites. Two were sentinels. The
third was not minor: `unwrap_or_default()` on the consumer module's import list
yields an EMPTY list, which makes `listed` false, which stamps the row
PoolCoincidence -- a fabricated semantic disposition produced by a failed lookup,
indistinguishable in the output from an observed one, in exactly the field this
census reports about. All three now refuse with a typed cause naming the
occurrence.

Each claim now compiles each subject ONCE. The comparison helpers take rows a
claim already holds rather than an entry source; the repeated demand had one
shared-state ancestor and was authored duplication (DESIGN section 2).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd
…ibration

# Conflicts:
#	docs/design-failure-modes.md
…ibration

# Conflicts:
#	dag/gunbc/recurring_failure_mode.dag
#	docs/design-failure-modes.md
…oster, and correct two claims this PR refuted itself

Three defects in this PR's own head, two of them refuted by its own later
measurements and one a fail-closed violation DESIGN section 5 makes a hard
reject at the PR that ships it.

THE REFUSAL ARM WAS DESTROYED AND RECONSTRUCTED AS AN EMPTY POPULATION.
cal_rows_of, cal_observations and the denominator helpers mapped a census
refusal to [] and to 0, so a refused subject was indistinguishable in every
control from an instrument that ran and saw nothing. The liveness control closed
the false green that could produce, but a gate compensating for an erased
refusal is not the same thing as not erasing it -- that is the absorbing
fallback. Every accessor now returns
CalSubjectObserved { denominator_size, rows } | CalSubjectRefused { cause },
every control opens the carrier, and a refusal on EITHER side of a two-subject
invariant reds. Liveness is now a property of the observed arm.

THE OMISSION ROSTER HAD ALREADY DIVERGED FROM THE TABLE IT DESCRIBES. The
observation table grew a third blind family -- the generic type argument --
while step0_denominator_defects still carried two hand-written omission rows.
Adding the third by hand only resets the clock, so the omission arm is now
derived from step0_unobserved_families() and only the defects the family axis
cannot express are authored.

TWO PROSE CLAIMS WERE REFUTED BY THIS LANE'S OWN LATER WORK, and are corrected
rather than dropped: a type named as a generic argument emits NO occurrence (the
row that made it look observed was the import-list head), and a name inside an
import statement's brace list DOES produce one -- the first name does, and every
later name carries none. Both were established by reading a COUNT, and a
cardinality assertion is blind to substitution.

THE COMPARISON KEY'S GRAIN IS NOW STATED HONESTLY. (authored_name, category) is
not an identity set: cardinality is REJECTED, tag-plus-category is ESTABLISHED
and discriminating here only because the fixture law makes every perturbed
spelling unre-mentionable, and exact authored-occurrence identity is NOT
ESTABLISHED by these controls -- the key is no OccurrenceId and carries no
containment path or semantic slot. Two controls are renamed off the word
"identity" accordingly.

AND THE FLOOR REROLL IS CITED WHERE THE ROW LIVES. The one reroll taken on this
branch is appended to gunbc.rung_drop floor_cost_claim_qualification_unavailable's
INSTANCES list by run id, head, floor job and both arms' counts -- bound to head
0a3e0e8 and explicitly not carried forward, because the current head passed
on its first attempt and a receipt belongs to the tree it was established on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd
… control to what it actually discriminates

Ruling D removed "identity set" from the comparison key and left it standing in
the three surfaces a skimming reader takes the grain from. The file contradicted
itself within six lines: the block header said the invariants are stated over the
tag-and-category multiset "not over identities, a grain these controls do not
reach", and the next three headers said INVARIANT A ... the identity set must not
move, INVARIANT B, OVER IDENTITIES, INVARIANT C, OVER IDENTITIES. The bodies were
already right, which is what makes this a prose defect and not a modelling one --
B and C both describe the key multiset correctly. Only the labels claimed the
grain the file had just finished disowning, and the label is what carries at a
glance.

AND ONE THE ENUMERATION DID NOT NAME, FOUND BY READING. The perturbation
control's comment still carried this PR's own refuted claim -- that deleting
every appearance of one variant establishes that a variant in pattern position
AND A NAME IN AN IMPORT LIST produce no occurrence. The import-list half is
false, and the instrument is wrong for it besides: the control reads a COUNT, and
a count is blind to substitution, so removing a name from the list hands the
fabricated head row to whichever name is now first while the number holds. The
comment now scopes the control to pattern position, states why a count cannot
reach the import list, and names the two controls that do -- both of which
compare populations rather than sizes.

The roster-totality controls keep the word: they join branch and family NAMES,
where identity is exactly what is being compared. That distinction is the point
of stating a grain rather than banning a word.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd
THE GENERATED DISPATCH FILE IS A CASE WHERE NEITHER SIDE'S BYTES ARE CORRECT, which is the four-way
condition the generated-artifact merge driver exists to refuse rather than answer. Main DELETED two
bridge arms from src/v1/stage0/src/v1_interpreter_dispatch_generated.rs -- v4_bridge
fn_arrow_decl_substrate_is_whole_tree and the corpus_dependency_view lens arm -- while this branch
ADDED the compile_dag_reference_occurrence_binding_census builtin arm. Taking this side resurrects
two arms main removed, and the compiler proves it: E0004, non-exhaustive patterns, because main's
merged v1_interpreter.rs no longer carries a match arm for the resurrected bridge. Taking main's side
drops the builtin and nothing builds at all. Only the union is right, and only the authority can say
what the union is.

So the file was rebuilt from main's side plus this branch's three builtin lines purely to BOOTSTRAP a
compiler capable of running the regenerator, and then the regenerator adjudicated it:
`claim_executor --required-regen` reports first_generation_equal=true over planned=executed=156, so
the emitted bytes equal the tree's -- the hand-assembly was correct rather than merely compilable.
That is the check that matters; a build that succeeds proves only that nothing contradicts, not that
the artifact is what the authority generates.

dag/gunbc/rung_drop.dag conflicted INSIDE a single 52,000-character line, where git can show nothing
useful and neither side reads as an overlap. Main appended its verdict-grain section immediately
before the row's closing paragraph; this branch's reroll instance appends after it. Resolved by hand
and verified by content that each side's material survives EXACTLY ONCE, which is the only available
check at that grain.

Main's addition carries a SAME-HEAD CONTROL -- run 33806159353, attempts on runners srv4-14 and
srv4-19 at one unchanged head 07f81df, opposite verdicts -- which is stronger evidence for this
row's redraw reading than any instance this branch cites, because it is established by construction
rather than by correlation across runs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd
Takes main's main_wet_verified gate function and its CI spec. CI at 5959b60
failed heal-generated-artifacts with NoSuchFunction { name: "main_wet_verified" }
-- base/head skew, not content: d6fb9d6 (#10302) added that function to the
gate module, the CI spec and the workflow after this branch merged c1ca34c, and
a pull_request run executes the workflow from the merge with the CURRENT base. So
main's newer YAML was asking this tree's older gate module for a function it does
not define.

MERGEABLE IS NOT THE WHOLE ADMISSION TEST, and this is the second half of a rule
this branch has now paid for twice. A branch can carry no textual conflict at all
and still fail CI because the base moved a workflow, a gate function or a required
phase underneath it. Mergeable means no conflict; it does not mean the base's
acceptance path can still run this tree, and those two properties come apart
precisely for long-lived branches.

docs/design-failure-modes.md conflicted and was REGENERATED rather than
side-picked. Verified by regenerator and not by build:
required-regen reports first_generation_equal=true over planned=executed=156.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REQUEST_CHANGES on exact head 520ca1f764715e52512756d552c9fe0f82140560.

The prior axes, qualified-two-row, ordinal, located-reader, and prose blockers are materially closed, and this SHA is fully green/CLEAN. Two source-level blockers remain; neither needs more measurement.

  1. The constructor-equality blocker is not closed throughout. step0_family_observation_key still serializes OccurrenceCategory constructors through step0_occurrence_category_label and compares the joined String; cal_rows_named_in_category likewise compares category labels. The executed outcome controls also classify binding source and disposition through cal_binding_source_of / cal_disposition_label strings, and the metamorphic key is a concatenated authored_name:category-label string. A duplicated or changed renderer label can therefore make a constructor substitution invisible—the shared-corruption case this round was meant to remove. Compare constructors directly (or use a typed { authored_name, category } key and typed predicates); keep labels only for rendering. The PR body should then say constructor inclusion, not inclusion over names.

  2. The standing can still claim full discrimination while a split family remains. After unobserved becomes empty, step0_calibration_standing branches only on first(converged). If convergence is repaired while step0_split_families() remains nonempty, the Absent arm returns CalibrationDiscriminatesEveryFamily, despite FamilySplitAcrossUnjoinedOccurrences explicitly meaning that family is not discriminated. Add a split-capped arm or require split == 0 before the full-discrimination constructor is reachable.

Keep the operator’s no-more-measurement ruling intact: these are structural corrections to the carrier and selectors, not requests for another probe or corpus run.

Brian Searls and others added 3 commits September 4, 2026 08:33
…ibration

# Conflicts:
#	dag/gunbc/rung_drop.dag
#	docs/design-failure-modes.md
#	docs/design-rung-drops.md
… longer claim full discrimination

BLOCKER 1: CONSTRUCTOR EQUALITY IS NOW THROUGHOUT, NOT JUST IN THE ROSTERS. Four
semantic selectors still used RENDERED STRINGS as identity, so one renderer
defect corrupted BOTH SIDES of every comparison at once -- a shared corruption a
comparison cannot detect. If two OccurrenceCategory constructors ever rendered to
one label, the constructors stayed distinct while the sharing fold reported FALSE
CONVERGENCE, the row selectors conflated them, and the tag multiset lost the
category distinction.

  family-observation sharing: the joined label string is gone; the typed category
  lists are compared directly. An unobserved family is now false against
  EVERYTHING INCLUDING ANOTHER UNOBSERVED ONE, so blind families can never read
  as a convergence set -- the exact misreading this module exists to prevent.

  cal_rows_named_in_category: row.category == category.

  the outcome controls: cal_is_unresolved / cal_is_ambiguous /
  cal_is_bound_via(required_source:), all constructor matches.

  the metamorphic key: a typed CalRowTag { authored_name, category } replacing
  concat(authored_name, ":", category_label).

cal_binding_source_of served only those string comparisons and is DELETED rather
than left as an unused second answer. Labels survive in cal_row_line and the
other renderers, and nowhere else.

THE TYPED TAG IMMEDIATELY EARNED ITSELF. Converting it turned up two defects the
string key had been hiding. The multiset helpers still DECLARED List<String>
while carrying a Record, which failed at runtime rather than at the boundary; and
the call sites passed "c:" and "scrutinee:" WITH THE KEY'S OWN SEPARATOR BAKED
IN, because string_contains needed the `name:` prefix to anchor a substring match
to the name field. That coupling is the whole argument for the carrier: the
caller had to know the key's internal syntax to ask about one of its fields, and
any spelling that was a substring of another would have counted as the renamed
identity -- so the invariant could report agreement it had not established. The
check is now exact equality on the tag's own field.

BLOCKER 2: THE CAP IS A CONSTRUCTOR, BECAUSE A MISSING CONJUNCT IS HOW THE
OVERCLAIM GOT IN. step0_calibration_standing branched only on whether the
convergence set was empty and never required the split set to be empty, so the
reachable state unobserved=[] converged=[] split=[one family] returned
CalibrationDiscriminatesEveryFamily -- full discrimination claimed over a family
this module ITSELF classifies as undiscriminated, because a split family's rows
cannot be joined back to the one authored reference that produced them.

IT WAS NEVER A BUG IN ANYTHING THAT RAN. It was a state machine permitting a
false claim, held shut by an INCIDENTAL fact about today's corpus -- four
families happen to converge, so the convergence arm fires first -- and it would
have fired the day convergence was repaired, which is a repair we want.
"Unreachable today" is the same argument as "n is small here": a guard that
depends on a measurement is not a guard.

CalibrationCappedBySplit is now its own arm, with precedence matching the
declared ranking: blindness > split across unjoined occurrences > convergence >
fully discriminated. A cap that is a constructor cannot be skipped.

AND THE PARTITION IS AN ARGUMENT SO THE CAP'S RED IS AUTHORABLE. The minimum
repair would have left the control undiscriminating: the offending state is not
expressible against the live rosters, so a control over the live standing is
PERMANENTLY GREEN on the very point it claims to check -- a decoration that then
gets cited as coverage (DESIGN 4b). step0_standing_over_partition takes the
partition; step0_calibration_standing is that fold applied to today's rosters.
The forbidden state is then authorable in a fixture, which is where a compiler's
regression probes belong.

  a_split_family_can_never_reach_full_discrimination -- the exact state above,
  plus the split-and-converged pair.
  the_cap_fires_only_when_a_family_is_actually_split -- the positive control, so
  the cap cannot be satisfied by a fold that answers CalibrationCappedBySplit
  unconditionally: empty split reaches full discrimination, a converged family
  stops one rung below, and blindness still outranks split.

All 22 controls in the witness green by execution, verified against a binary
rebuilt for this branch after a cargo build returned exit 0 having done nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd
The merge driver left both paths UNMERGED with the ours side in the worktree and
no conflict markers, because both sides changed them since the merge base -- so
neither parent's bytes were the projection of the MERGED authorities. They were
staged provisional through the merge commit and are now DERIVED: this is
generated_artifact_gate main_wet's output over the merged tree, not a hand pick
of either side and not a hand edit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd
@gunbai-bot
gunbai-bot Bot merged commit 0db19fb into main Sep 4, 2026
7 checks passed
@gunbai-bot
gunbai-bot Bot deleted the work/step0-census-calibration branch September 4, 2026 12:00
briansrls pushed a commit that referenced this pull request Sep 4, 2026
…the import-authority scoping record

TWO SUBJECTS, BOTH FALLOUT OF #10256.

ONE -- THE NESTED-COMPILE BUILTIN I ADDED WAS NOT ON THE SURFACE. #10256 landed
compile_dag_reference_occurrence_binding_census, which runs the frontend over
supplied sources. That is unbounded host work of exactly the class
compile_dag_rust_emit_check is on the surface for, and
compile_dag_multi_module_fixture was ALREADY two rows above it in the same
roster. It appeared in ZERO rows. So a claim reaching it would report
CooperativelyPollable while doing unbounded work -- the same defect main repaired
one commit earlier, where the surface was spelled with free_call. identities
while the recorder compared bare spellings and 3602 of 3602 claims read benign.

VERIFIED BY THE CHECK THAT DISCRIMINATES, not by the ones that do not.
opaque_host_call_surface_is_grounded returns true, which is what proves
roster_arms_for_identity RESOLVES the new identity to an authored spelling rather
than leaving it in the unresolved list. A row that fails to resolve is precisely
the decoration that reads as coverage, and 7/7 green on the reach-control and
preemption witnesses does not substitute for it.

TWO -- THE SCOPING RECORD FOR THE IMPORT-AUTHORITY CUT, registered so the work
that cites it can name a stable slug rather than a PR body. It states TWO layers
with citations (selective_func_env_view folding only over the listed names, so
specific_names IS the population; and the two TypeEnv maps plus
author_named_visibility), records the WRONG three-layer claim as a recorded error
rather than silently replacing it, and states the parent_index order-dependence
as a PRECONDITION of the population repoint rather than a ticket beside it --
it is latent today only because every resolution-path access is
map_get(parent_index, imp.module_path), and it arms the moment lookups stop being
keyed by import path.

THE DOC-GRAPH GATES ARE RED AND THAT IS NOT THIS CHANGE. Measured against a
stashed baseline rather than assumed: doc_graph_has_no_orphan_docs is false on
main WITHOUT these files, and the population is dispositioned in
gunbc.guarantee_stall.doc_graph_orphan_population_stall with a declared trigger.
Those identities sit on floor_expected_red_roster, which means RUN EVERY PR AND
HOLD THE RED -- so the hazard is an UNEXPECTED GREEN, not the red. All three are
still red here, so no dissolution signal fires and the stall row stands.

AND THE PLAN-ROOTS PROBE WAS CHECKED IN BOTH DIRECTIONS, because "it was already
red" stops being an explanation once the change touches its subject. Registering
a plan root is that subject. Measured: baseline total=215 admitted=72; with this
change total=216 admitted=73. Both +1, so the new root IS admitted and the gap of
143 is untouched. The probe stays red for its pre-existing reason and this change
adds no new one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd
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