Skip to content

Qualify the extdeps.tools bare-name reads by their declaring module - #11137

Merged
briansrls merged 3 commits into
mainfrom
session/witty-moth-510
Sep 12, 2026
Merged

briansrls merged 3 commits into
mainfrom
session/witty-moth-510

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

Stage 1 of the bare-name-ambiguity campaign, first batch. The census instrument landed in #11078; this is the first of several batches that dissolve the population it named.

What the census says

[floor-bare-name-ambiguity-reads] read_name_module_pairs=105 read_names_distinct=5 — 105 (name, referring module) value-position reads that fall through to the shared name slot, over five names. 23 of them sit under extdeps.tools, which is this PR.

The other half of that line, qualified_name_module_pairs=305, is the mechanism: 305 sites corpus-wide already resolve an otherwise-ambiguous name through an explicit import naming its declaring module. The 105 are the residue that never got it. Nothing here is new machinery — it is the corpus's normal state applied to the sites that lack it.

The three names, and why each import names the module it names

String — declared by std.string_type, not std.types. Ten of these files carried import std.types { String }. That line answers nothing: std.types neither declares String nor imports it, so the name was travelling through the shared slot while the import implied otherwise. The census is unambiguous about the claimants — name=String claimants=std.string_type:other,v2.std.text:other — and std.types is not among them. The bogus name is dropped from the std.types list and import std.string_type { String } added, so the citation names the declaration rather than a module that merely mentions it (§3: cite the symbol, not the position, and not a re-exporter).

Unit — genuinely declared by std.types (type Unit, dag/std/types.dag), so it joins the existing import list. This is exactly the form the single proof site landed in #11078 demonstrates: extdeps.tools.hostname already reads [floor-bare-name-ambiguity-bound] name=Unit referring_module=extdeps.tools.hostname resolves_to=std.types. (That same file is still in the String population, which is the trap above in one file: the Unit half of its import line named the declaring module and qualified; the String half named a re-exporter and did not.)

Filesystem at extdeps.tools.sha256sum is the one judgment site here, and the site's own text decides it. The call is Filesystem.Write(path: …, content: …). extdeps.filesystem.filesystem_io declares service Filesystem with operation Write { input { path: String, content: String } } — an exact match. The rival claimant std.resources declares a resource Filesystem whose capability is lowercase write and which has no Write operation at all, so it could not have served this call. The file already imported extdeps.filesystem.filesystem_io bare; it now names { Filesystem }, the form 82 other files in the corpus already use.

Scope

No renames. Neither declaring side is touched. Every edit is an import line in the referring file.

Deliberately left alone: extdeps.tools.jq and extdeps.tools.sha512sum both carry String in a std.types import list, but the census does not list them in the String read population — their scopes settle the name inside the authored region. Qualifying them would be a sweep over sites this campaign's population does not contain, so the misleading import lines there stay for whoever measures that separately.

Evidence

  • [floor-bare-name-ambiguity-read] rows for these 23 (name, module) pairs should be gone from the floor log.
  • [floor-bare-name-ambiguity-bound] should name the chosen module for each — std.string_type for String, std.types for Unit, extdeps.filesystem.filesystem_io for Filesystem — which is the claim that matters, since a row merely leaving the ambiguous census only proves the site stopped falling through, not that it now reaches the declaration its author named.
  • qualified_name_module_pairs should rise by 23 as read_name_module_pairs falls by 23.
  • Every touched module still typechecks and its claims still pass (the floor lane runs them).

🤖 Generated with Claude Code

https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT

23 of the 105 value-position reads the bare-name-ambiguity census names
(`[floor-bare-name-ambiguity-read]`, landed #11078) sit under
`extdeps.tools`. Each was resolved by whichever claimant scope precedence
happened to rank first; this binds each to the authority its own module
means, through the file's own import, so the read no longer falls through
the shared name slot.

Three names, three declaring authorities, each named rather than inherited:

- `String` is declared by `std.string_type`, NOT by `std.types`. Ten of
  these files carried `import std.types { String }`, which answers
  nothing -- `std.types` neither declares `String` nor imports it, so the
  name was travelling through the shared slot while the import line
  implied otherwise. The bogus name is dropped from the `std.types` list
  and `import std.string_type { String }` added, so the citation now
  names the declaration (§3: cite the symbol, not a re-exporter).
- `Unit` IS declared by `std.types` (`type Unit`), so it joins the
  existing list. This is the form the proof site landed in #11078 already
  demonstrates: `extdeps.tools.hostname` reads
  `[floor-bare-name-ambiguity-bound] name=Unit resolves_to=std.types`.
- `Filesystem` at `extdeps.tools.sha256sum` is the one judgment site in
  this batch and it is not close: the call is `Filesystem.Write(path:,
  content:)`, matching `service Filesystem { operation Write }` in
  `extdeps.filesystem.filesystem_io`. The other claimant, `std.resources`,
  declares a `resource Filesystem` whose capability is lowercase `write`
  and which has no `Write` operation at all. The file already imported
  `extdeps.filesystem.filesystem_io` bare; it now names `{ Filesystem }`,
  which is the form 82 other files in the corpus already use.

No renames, and neither declaring side is touched -- this is the
qualification mechanism 305 sites corpus-wide already resolve through,
applied to the residue that never got it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
The required floor on this branch is CLEAN -- `verdict=FloorClean
unexpected_failures=0` over planned=3757 executed=3757 claims_failed=0 --
and the census moved exactly as the change intended:
`read_name_module_pairs` 105 -> 82, `qualified_name_module_pairs`
305 -> 334, with all 23 `[floor-bare-name-ambiguity-bound]` rows naming
the authority this PR chose (10 `String` -> std.string_type, 12 `Unit` ->
std.types, 1 `Filesystem` -> extdeps.filesystem.filesystem_io).

What blocked the lane was a different phase: `FAILED PHASE
namespace-wave-admission (1 unadjudicated delta)`.

THE DELTA, AND IT IS A REAL ONE -- a side effect on a name this PR never
set out to touch:

  TargetChanged binding
  extdeps.tools.sha256sum::extdeps_external_authority_anchor
  base {extdeps.filesystem.filesystem_io, extdeps.shell,
        extdeps.tools.sha256sum}
  head {extdeps.shell, extdeps.tools.sha256sum}

`extdeps.tools.sha256sum` imported `extdeps.filesystem.filesystem_io`
BARE. A bare module import drags the whole module into the candidate set
for every name it declares, so filesystem_io's copy of
`extdeps_external_authority_anchor` -- the per-module convention row some
315 modules each author -- was a candidate at this site. Naming
`{ Filesystem }` binds the one declaration the author meant and drops the
rest, which narrows the candidate set for that unrelated spelling too.

NO RESOLUTION CHANGES: sha256sum authors its own
`extdeps_external_authority_anchor`, and a module's own declaration wins
inside the authored region, so the site resolved to sha256sum's row
before and resolves to sha256sum's row after. The removed candidate could
not have won either way. What moved is the SET, three modules to two --
the resolution stopped depending on a module the author never named,
which is the qualification's whole purpose. That is admitted, not
silenced: the row states it out loud, which is what this wall exists for.

The ten `extdeps.tools.* -> std.string_type` membership additions needed
no row: the phase classified each `ExplicitlyEvaluatedZeroDelta ...
reached by a name this module authors`.

ALSO PAID HERE: the three `gunbc#11071 LinuxKernelRelease rehome` rows are
deleted. #11071 merged, so the base already binds those spellings to
`extdeps.linux.kernel` and the floor reported all three CONSUMED. A
consumed row's deletion comes due on this roster's OWN next touch; this
change is that touch, so the debt is paid rather than inherited by an
unrelated lane.

NOTE FOR THE LATER BATCHES: the Filesystem/Clock batch converts fourteen
more bare imports to named ones, so it should be expected to produce this
same class of delta per module rather than treated as a surprise.

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

Three of the four findings were right and are fixed here.

TRANSCRIBED INSTRUMENT OUTPUT (valid). The roster doc carried
`verdict=FloorClean unexpected_failures=0` and the planned/executed/
claims_failed counts as prose. DESIGN §6 is explicit that a measurement
is cited by naming the producer that re-derives it, never by copying its
numbers, because a transcribed number rots without anyone touching either
end. The counts are gone; the claim now names the `claim_executor`
invocation and the verdict line to read it off.

TWO FILES LEFT ON THE OTHER SPELLING (valid). `extdeps.tools.jq` and
`extdeps.tools.sha512sum` were edited on exactly the line that carries
`String` and kept it on `std.types`, which left them inconsistent with
their nine siblings after a change whose stated purpose is to qualify
reads by their declaring module. They were excluded because the census
does not list them -- their reads are settled inside the authored region
-- but "not in the measured population" is a reason to not CHASE a site,
not a reason to leave a wrong citation on a line already being edited.
Both now name `std.string_type`. All thirteen touched files are
consistent: none carries `String` on a `std.types` import.

THE ROSTER DID NOT SPEAK TO THE `String` REQUALIFICATION (valid as a gap
in the writing). The doc said "NO RESOLUTION CHANGES" about the sha256sum
anchor and a reader could take it as covering the whole diff. It now
states why `String` needs no row, and states it as the wave phase's
measurement rather than as this author's assertion.

THE FOURTH FINDING IS NOT ACCURATE and nothing is changed for it. It
reads the `String` requalification as retargeting the spelling to "a
second authority" and forking it across nine modules. `std.types`
declares no `String` -- the finding says so itself -- so it was never an
authority for that name, and `import std.types { String }` bound nothing.
The two real claimants are `std.string_type` and `v2.std.text`, which the
census names as the self-host migration double and explicitly scopes out.
Naming one of the two existing declarations creates no third.

That it is measured rather than argued is the part that matters: the
wave phase compares the binding table on both sides, and on this head it
reported exactly ONE `TargetChanged binding` delta over 814,621 binding
rows compared -- the sha256sum anchor -- and NONE for `String`. The ten
`String` sites are reported as `ExplicitlyEvaluatedZeroDelta membership
... reached by a name this module authors`: evaluated, zero. So the read
resolved to `std.string_type` before and after; what changed is its
authorization, from an accident of scope precedence to something the
author wrote.

The finding's live observation -- that ~1951 modules carry
`import std.types { String }` -- is real and is a corpus-wide defect this
campaign does not fix: those lines name a module that does not declare
the name they list. They are harmless only while those modules' reads are
not ambiguous. Correcting them is its own change with its own
adjudication, not a drive-by in a PR scoped to 23 measured reads.

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

gunbai-bot Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 64326. Three of the four findings were right and are fixed in 0675dea; one is not accurate and I've left the code alone rather than change it to match.

Fixed — transcribed instrument output. Correct, and a clean §6 catch. The roster doc carried verdict=FloorClean unexpected_failures=0 plus the planned/executed/claims_failed counts as prose. The counts are gone; the claim now names the claim_executor invocation and the verdict line to read it off.

Fixed — jq and sha512sum left on the other spelling. Also correct. I had excluded them because the census does not list them (their reads are settled inside the authored region), and the first review read that as a deliberate out-of-population deferral. But "not in the measured population" is a reason not to chase a site, not a reason to leave a wrong citation on a line the diff is already editing. Both now name std.string_type, and all thirteen touched files are consistent — none carries String on a std.types import.

Fixed — the roster did not speak to the String requalification. Fair as a gap in the writing: "NO RESOLUTION CHANGES" was about the sha256sum anchor and could be read as covering the whole diff. The doc now says why String needs no row, as the wave phase's measurement rather than my assertion.

Not accurate — the String retarget as a second authority. I don't think this one holds, and the disagreement is factual rather than interpretive, so here is the evidence.

std.types declares no String — the finding establishes this itself. So it was never an authority for that name, and import std.types { String } bound nothing. The two real claimants are std.string_type and v2.std.text, which the census names as the self-host migration double (channel=value_position_only not_covered=type_position_name_collisions owner=v2_self_host_replacement_migration) and explicitly scopes out. Naming one of two existing declarations does not create a third, so there is no fork for §3's replacement-migration rule to bite on.

The decisive part is measured rather than argued. The wave phase compares the binding table on both sides. On this head it reported exactly one TargetChanged binding delta over 814,621 binding rows compared — the sha256sum anchor — and none for String. The ten String sites appear instead as ExplicitlyEvaluatedZeroDelta membership <module> -> std.string_type ... reached by a name this module authors: explicitly evaluated, zero delta. So the read resolved to std.string_type before and after; what changed is its authorization, from an accident of scope precedence to something the author wrote. That is the campaign's whole purpose — the census moved these sites from [floor-bare-name-ambiguity-read] to [floor-bare-name-ambiguity-bound] ... resolves_to=std.string_type.

The finding's live observation is real and I want it on the record, because it is the better half of it: ~1951 modules carry import std.types { String }, a line naming a module that does not declare the name it lists. That is a corpus-wide defect this campaign does not fix. It is harmless only while those modules' reads are not ambiguous — which is exactly the condition that stops holding as the v2.std double resolves. Correcting it is its own change with its own adjudication, not a drive-by in a PR scoped to 23 measured reads.

— sent from witty-moth-510

gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
…sume

Review 64402 found a real defect and it is mine. A bare
`import extdeps.filesystem.filesystem_io` is an import-ALL: it binds every
name the module declares. Narrowing it to `{ Filesystem }` binds one and
DROPS THE REST, and three of the seventeen files were still consuming
names that went with them:

  dag/gunbc/roadmap/roadmap_publication_helper.dag
    filesystem_listing_names_entry                          (:307)
  src/v2/lens/complexity_accumulator_copy/roster_gate.dag
    filesystem_read_outcome, FilesystemReadSucceeded,
    FilesystemReadRefused                                   (:110-113)
  src/v2/lens/identity_captured_navigation/roster_gate.dag
    the same three                                          (:120-123)

Each braced list now names what its file actually consumes.

WHY I MISSED IT, because the shape is worth keeping: I reasoned carefully
about one consequence of narrowing a bare import -- that it shrinks the
CANDIDATE SET for unrelated spellings, which is what produced #11137's
admission delta and what this PR's body predicted for this batch -- and
did not carry the same reasoning to its sibling, that it also REMOVES
BINDINGS the file was relying on. Same edit, two consequences, one of
them anticipated in writing and the other not looked for at all.

SWEPT RATHER THAN SPOT-CHECKED. The review says the other fourteen look
correctly narrowed; that is not something to take on trust when the
failure is silent, so every one of the seventeen was joined against the
declarations of `extdeps.filesystem.filesystem_io` and `extdeps.clock`.
The sweep returns exactly these three before the fix and zero after.

It first flagged a FOURTH file, `gunbc.roadmap_belt_actuate`, for
`FilesystemEstablishedAbsence` -- a false positive: the name occurs there
only inside a comment, which the first pass did not strip. Worth saying
because reporting it would have sent a reader looking for a defect that
is not there.

ATTRIBUTION OF THE REMAINING BLOCKING ERRORS, established by control
rather than assumed. Compiling
`src/v2/lens/identity_captured_navigation/roster_gate.dag` as an entry
reports 3 blocking errors -- `unresolved type 'ConstructionJustification'`
and `'WallAfterGrounding'` in the PARENT module
`v2.lens.identity_captured_navigation`, which this change does not touch.
The pre-change file from the merge base was compiled the same way and
produces the IDENTICAL three errors, same lines and the same 1375
advisories, so they are pre-existing: the narrower-closure class
`test.claim.undeclared_bare_type_reference_class_witness` exists for,
where a bare type reference resolves only because some unrelated import
dragged its definer into the pool.

A NOTE ON THE CHECK ITSELF: `gunbc compile` EXITS 0 while reporting
blocking errors, so an exit-code test reads them as success. The
trustworthy signal is the `N blocking error(s)` line, which reads 0 for
the other two repaired files.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
@briansrls
briansrls merged commit 34d2a8d into main Sep 12, 2026
6 of 8 checks passed
@briansrls
briansrls deleted the session/witty-moth-510 branch September 12, 2026 06:35
briansrls pushed a commit that referenced this pull request Sep 12, 2026
…le (#11145)

Second batch of the bare-name-ambiguity campaign (census instrument:
#11078, first batch: #11137). 57 of the 105 value-position reads the
census names, across 29 extdeps modules outside `extdeps.tools`.

Same two names and the same two authorities as the first batch:

- `String` is declared by `std.string_type`. Twenty-six of these files
  carried `import std.types { String }`, which binds nothing: `std.types`
  neither declares `String` nor imports it, so the read was travelling
  through the shared slot while the import line implied it had been
  settled. The name is dropped from the `std.types` list and
  `import std.string_type { String }` added.
  Two files -- `extdeps.clock` and `extdeps.entropy` -- read `String`
  bare without importing it under any spelling at all, and simply gain
  the `std.string_type` line.
- `Unit` is declared by `std.types` (`type Unit`), so it joins the
  existing list, which is the form the #11078 proof site already shows
  binding to `resolves_to=std.types`.

`extdeps.github.pulls` reads only `String` and so takes only that half.

No renames, and neither declaring side is touched. Both this batch and
the first are the mechanism 305 sites corpus-wide already resolve
through, applied to the residue that never got it.


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

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Sep 12, 2026
…at are not (#11146)

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.


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

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
Pay the consumed #11137 wave-admission row on this roster touch; List stays an authored import so this head still admits nothing.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
Keep both live namespace-transition admissions (#10994 still open; #11137 from main) and take the merge-base generated rung-drops projection for heal to derive.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
The freeze repair must not drop the #11137 row that already lives on main; this head only omits the two gunbc#11082 admissions.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
The conflict is the one this branch's own commit predicted: #11137 and
this change both touch `NAMESPACE_TRANSITION_ADMISSIONS`, and both were
authored believing they owed the three `gunbc#11071` consumed-row
deletions.

RESOLUTION: KEEP BOTH COHORTS. They adjudicate unrelated deltas -- one
`TargetChanged` on `extdeps.tools.sha256sum`'s
`extdeps_external_authority_anchor` from #11137, and 37 on `string_eq`
from this change. Dropping either would leave its delta unadjudicated and
refuse the phase.

WHAT THE MERGE CORRECTED RATHER THAN CARRIED. This branch claimed the
THIRTY-FIFTH dissolution and the deletion of the three consumed rows.
#11137 reached the roster first and paid that debt, so by the time this
merges there is no debt left to pay and the claim would be false. The
note is renumbered THIRTY-SIXTH and says plainly that it dissolves
nothing: a ledger recording one deletion twice is worse than one
recording it once, and this file's whole value is that its history can be
read back.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
Both sides deleted the three #11071 rows -- main as its thirty-fifth dissolution
(#11137), this branch independently -- so main's text is taken, including its
numbering, which is the authority's count rather than my local one.

Main's #11137 row is then dissolved here, because its own trigger has fired:
"this row goes when #11137 merges", and #11137 is in origin/main with
`import extdeps.filesystem.filesystem_io { Filesystem }` at the base. The delta
it admitted has stopped being producible, so it is CONSUMED, and a consumed
row's deletion comes due on the roster's next touch. This change is that
touch. Verified rather than reasoned: the merge commit and the import line
were both read off origin/main before deleting.

The roster is empty again, which admits nothing: any delta no row names still
refuses as UNADJUDICATED.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NQnvBvFGNu9tNL544NJe2j
briansrls pushed a commit that referenced this pull request Sep 12, 2026
DELETES gunbc#11137's admission row, DELIBERATELY, and records it.

Two conflicts needing opposite treatment.

src/v1/stage0/src/namespace_wave_admission.rs is hand-maintained despite
living in the emitted stage0 tree -- .gitattributes line 70 carries an
explicit "!merge" against the line-53 glob, and git check-attr reports
"unspecified" where a control in the same directory reports
"generated-artifact". So it is hand-resolved, and it was resolved by
PROVENANCE rather than by rule.

The rule I nearly applied -- "rows arriving from main are consumed at my
base by construction" -- is a belief about main's content, not a
measurement, and applying it here would have silently reverted a landed
PR's adjudication narrative with no marker and no gate complaint. What
main's side actually is: exactly one commit, #11137 (34d2a8d), which
REPLACED #11071's record with its own.

Measured, the row IS consumed: #11137 landed after this branch's base, so
the base now authors the qualified import and the TargetChanged delta the
row admits is no longer producible. A consumed row's deletion comes due on
this roster's own next touch, and this merge is that touch -- the same
rule the thirty-fifth dissolution applied to #11071's rows, applied to the
change that applied it. So the row goes, and the deletion is recorded as a
THIRTY-SIXTH DISSOLUTION naming #11137 rather than left silent. The block
accumulates records (eighteenth through thirty-sixth all coexist) while
per-row accounts die with their rows, so main's thirty-fifth record is
kept verbatim.

docs/design-rung-drops.md is merge=generated-artifact and the driver
REFUSED, leaving ours-side bytes unmerged with no markers. Per its own
declared repair route the BASE side is taken verbatim and NOT regenerated
locally: heal-generated-artifacts derives it from the merged authorities
and the gate must agree with THAT derivation, which locally-produced bytes
would not be. Verified by set difference, not by count and not by marker
count: no row main carries went dark.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
The floor on this head is CLEAN -- `verdict=FloorClean`,
`claims_failed=0` -- and the namespace phase reports `0 unadjudicated
delta(s)`, so all 37 `string_eq` rows matched their deltas one-for-one.
What blocked it was the other column: `1 stale admission(s)`.

The stale row is `gunbc#11137 extdeps.tools.sha256sum names Filesystem
instead of reaching it`. #11137 merged, so the narrowed import is at the
base, the delta it admitted stopped being producible, and a row matching
no delta blocks the phase. Its own recorded trigger was "this row goes
when #11137 merges", and this change is the roster touch on which that
came due -- so it is deleted here rather than left to refuse the next
roster-touching PR.

That is the mechanism working exactly as designed, and it is worth
noticing that the row predicted its own retirement in the commit that
introduced it. The ledger's value is that this is checkable rather than
remembered.

ALSO RETRACTED: this change was authored believing it owed the three
`gunbc#11071` consumed-row deletions. #11137 reached the roster first and
paid them, so there was no debt left. The original text claimed the
deletion; the claim is retracted rather than carried, because a ledger
recording one deletion twice is worse than one recording it once.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
…e consumed ones

Required floor run 34678970776 refused with `1 stale admission(s), 0 consumed admission(s)`:

  STALE ADMISSION gunbc#11137 extdeps.tools.sha256sum names Filesystem instead of reaching it
    ... matches no delta in this run
  required-floor: verdict=FloorClean unexpected_failures=0

THIS IS NOT THE CONSUMED PATTERN REPEATING A FOURTH TIME, and I nearly filed it as one. The
dispositions are deliberately different and this file states the difference itself:
`consumed_admissions` is entered ONLY on the positive proof `admission_consumed_at_base`, never as
the else-arm of "did not match a delta", and a row provable against neither side stays an
UnmatchedAdmission in `stale_admissions`. Three previous rows left this roster because the wall
proved them satisfied at the base. This one leaves because it matched NOTHING.

The remedy is the roster's own stated rule rather than my inference from the pattern:
`stale_admissions` is per RUN, a pull_request build adjudicates the MERGE commit, so a row that
reached main is inherited by every open PR, and a PR that does not produce its delta can never match
it. The roster's own words: "the shrink is the fix, not housekeeping." This branch merged main, so
#11137's delta sits in the base on both sides and is not producible here.

Empty is still not permissive, which is what makes shrinking safe: with no rows a run carrying a
real delta refuses it as UNADJUDICATED rather than passing it.

Verified through the gated check written after the last merge's near-miss -- conflict markers first,
census only if that passes, nonzero before any success-shaped output. 40 rows, 31 + 9, zero markers.
cargo check -p v1-compiler --lib clean on the working tree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014NWm2sQUpponuEb8ERiBsw
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
The floor on this head enumerated eight namespace deltas. SIX WERE A
DEFECT AND ARE REPAIRED IN THE SOURCE; only two are transitions worth
admitting. The floor lane itself came back `floor_class=infra
signature=MemoryStallRefusedPageThrash`, which judges nothing, so it is
re-run rather than fixed.

THE SIX, AND THEY ARE THE SAME CLASS AS REVIEW 64402's FINDING, WIDER:

  gunbc.clock_read                 `Present`  {v2.std.optional} -> {}
  gunbc.fabric_event_log_host      `Present`  {v2.std.optional} -> {}
  v2.lens.complexity_accumulator_copy.roster_gate  `List`  {std.types} -> {}
  v2.lens.identity_captured_navigation.roster_gate `List`  {std.types} -> {}

`NewUnresolvedness` -- names going from resolved to UNRESOLVED. A bare
module import propagates reach BEYOND the importing module's own
declarations, so narrowing one can strand names belonging to modules the
file never mentions: `gunbc.clock_read` was receiving `Present` from
`v2.std.optional` through the bare `import extdeps.clock`, and the roster
gates were receiving `List` through the bare filesystem_io import.

WHY MY OWN SWEEP MISSED THEM. After review 64402 I joined every touched
file's body against the declarations of `extdeps.filesystem.filesystem_io`
and `extdeps.clock` and reported it as returning zero. That was true of
the class I checked and structurally incapable of finding this one: the
lost names are declared in OTHER modules, so no join against the narrowed
module could have surfaced them. "The sweep returns zero" was a narrower
claim than it sounded.

Each is repaired by naming the declaring module -- `v2.std.optional
{ Present }`, `std.types { List }` -- not by admitting it. An admission
row records an intended transition; a name losing its declaration is not
one, and admitting it would have written the defect into the ledger as
though it were a decision.

THE TWO REAL DELTAS get rows:

  extdeps.provisioning.ubuntu_seeded_install_media_remaster --
  TargetChanged on `extdeps_external_authority_anchor`, the same
  candidate-set narrowing #11137 recorded: the module authors its own
  anchor and a module's own declaration wins inside the authored region,
  so no resolution changes.

  gunbc.srv3_boot_once_cd -- AuthoredReferenceResolution on `Filesystem`,
  base {} -> head {extdeps.filesystem.filesystem_io}, and this one moves
  in the GOOD direction: the module called `Filesystem.Write` while
  importing the declaring module under no spelling at all, so the name
  reached its declaration only through pool membership. It now names it,
  which is what the file's own modeled `DeclarationRef` already asserted.

ALSO: the `gunbc#11137` row is deleted, stale since #11137 merged, on the
trigger it recorded for itself.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
Run 34679326830 refused with 1 stale admission: unmatched rows refuse on every PR. This roster touch pays that deletion; List stays an authored import so no #11082 admission is added.

Co-authored-by: Cursor <cursoragent@cursor.com>
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
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
The required floor on d6466da printed STALE ADMISSION for the sha256sum Filesystem row: that delta is already on main, so this PR produces none. The #10994 sizing rows stay.

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls pushed a commit that referenced this pull request Sep 12, 2026
WHY THIS MERGE, and it is not routine housekeeping: required-witnesses-floor
refused the previous head on `namespace-wave-admission 1 stale admission(s)`, and
the stale row is not this branch's. It is gunbc#11137's
(`extdeps.tools.sha256sum names Filesystem instead of reaching it`), which merged
into main at 06:35 today. CI's admission base is main's tip, so that relocation
sits on BOTH sides of the comparison and the row matches no delta -- exactly the
interval gunbc.rung_drop namespace_admission_consumed_row_deletion describes as
"RESIDENT on main ... from that merge until a human deletes it ... pure
liability", whose stated caveat is the merge-in case. This branch's own delta
adjudicated clean in the same run (ExplicitlyEvaluatedZeroDelta on the new
recurring_failure_mode row). Moving the merge base past #11137 is the sanctioned
response; the branch was 20 commits behind regardless.

THE DERIVED MIRROR WAS RESOLVED BY REGENERATION, NOT BY TAKING A SIDE. Only
src/v1/stage0/src/v1_compiler_emit_rust.rs came back unmerged -- the
generated-artifact driver refusing rather than answering, as designed, since both
sides changed it. src/v1/05_emit_rust.dag and cli_run.rs auto-merged cleanly, so
the authorities agree and only their projection needed deciding.

An ours-side bootstrap could not even compile: main added a `FileChanErrorKind`
variant to FileResultChannel that this branch's mirror predates (E0004). So the
seed was bootstrapped from MAIN's side of the mirror purely to get a compiling
compiler, then the mirror was regenerated from the MERGED authorities and
installed -- and the installed bytes carry BOTH sides, which is the property
neither --ours nor --theirs would have produced: 7 occurrences of this branch's
three arms AND main's FileChanErrorKind handling. Verified to a fixed point:
pass 1 drifted v1_compiler_emit_rust.rs, pass 2 reports
first_generation_equal=true. No ours-bootstrap bytes are review-visible, because
the regeneration lands in this same commit.

THE THREE ARMS RE-MEASURED ON THE MERGED TREE rather than assumed to have
survived: 17 `.args(..)` splices in extdeps_cargo_build, the empty-map turbofish
still `::<_, _>()`, 3 rc_list_concat and ZERO v1_rt::append in
extdeps_exec_command.

THE MERGED CLOSURE CARRIES NINE ERRORS THAT ARE NOT THIS BRANCH'S, and they are
reported rather than absorbed. Main widened this closure, which is the same
"accepted for as long as nobody emitted it" mechanism this branch's own work
documents. Both are already-rostered components of
gunbc.recurring_failure_mode.accepted_source_emits_uncompilable_target with their
own triggers, so neither is repaired here:

  - E0432 `unresolved import crate::std_types::Unit` at extdeps_cargo_build.rs:14.
    The emitted use-line gained `Unit` (pre-merge `{Bool, FilePath, NonEmptyStr}`,
    post-merge `{Bool, FilePath, NonEmptyStr, Unit}`) while emitted std_types
    exports no Unit. Component (viii), use-lines derived from SOURCE references
    rather than from the emitted reference set.
  - 8 x E0308 in std_string_type.rs, a file ABSENT from this closure before the
    merge and pulled in by it. `left = __tco_0;` assigns a String into the
    Rc<Vector<i64>> FreeMonoid<Char> carrier through the TCO rewrite. Component
    (iv), the std.string_type carrier-versus-primitive disagreement.

So the positive control is NOT green on the merged tree, and this commit does not
claim it is: the three classes this branch repairs are measured fixed, and the
closure carries nine pre-existing-class errors main introduced.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012xQnkeiJ1pnEpMgqh3dE1e
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
…t blocked everyone

gunbc#11137's transition-admission row admitted a TargetChanged binding on
extdeps.tools.sha256sum::extdeps_external_authority_anchor, created when a bare
import of extdeps.filesystem.filesystem_io became { Filesystem } and the
spelling's candidate set narrowed from three modules to two without changing
what it resolves to. Its stated trigger was "this row goes when #11137 merges".
#11137 merged at 06:35:25 today, so the base carries the named import, the delta
stopped being producible, and the deletion came due on this roster's next touch.
This is that touch. The roster is empty again, which the file already records as
its resting state.

DELETING A ROW WHOSE STATED TRIGGER HAS FIRED IS EXECUTING ITS DECLARATION, NOT
OVERRULING ITS OWNER. I asked rather than assumed, because it is another
program's roster; the ruling is bright-eagle-728's, on the measurement that four
unrelated lanes were each blocked by it and each reached the same deletion
independently.

AND IT DID NOT MERELY LINGER, which is the part worth leaving in the file. A
spent row matches no delta, so the wave phase reports it as an UnmatchedAdmission
refusal in stale_admissions -- correctly, since a row provable against neither
side is not evidence -- and that REFUSES the required floor for every pull
request whose base already carries the merge. Measured rather than inferred: PRs
based on 0c93af0 reported the stale row and a PR on an older base reported
none.

THE SHAPE TO FIX WHEN THIS ROSTER IS NEXT DESIGNED is recorded beside the empty
roster: a retirement condition written as a SENTENCE naming a merge does not
retire when that merge happens, because the trigger is readable by people and by
nothing else. The row outlives its own condition and the cost lands on whoever
opens the next pull request. Deriving retirement from the merge -- the positive
proof admission_consumed_at_base already performs for the consumed arm -- would
make the deletion structural rather than a debt passed between lanes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AQGTwRrSBe8r3bmR3epQsL
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
Keep NAMESPACE_TRANSITION_ADMISSIONS empty after #11137 retired on both sides.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
…#11137 wave row.

Media attach resolved `any` through MegaRAC's blanket import after that module started using algebra — a pool coincidence, not an authored reference. #11137 already merged, so its admission matched no delta on this run and refused as stale.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
… duplicate of it

Delete-versus-delete, resolved by keeping ONE record rather than two.

Both sides removed the `gunbc#11137` row and both wrote a dissolution
note for it. Main's landed first, so main's note is the one the ledger
keeps; this branch's copy is dropped. A ledger recording one deletion
twice is worse than one recording it once -- the same correction this
campaign already made on the string_eq branch, arrived at again from the
other direction.

The roster stays EMPTY, which is its resting state and is not permissive:
a run carrying any delta no row names still refuses it as unadjudicated.
This branch adds no rows, because the instrument and the resolution-tier
split left nothing here that produces a namespace delta.

That closes the #11137 row's story: four branches reached its retirement
independently, because a stale row refuses every PR carrying it, and the
deletion was owed exactly once.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
The floor measured clean on the previous head (FloorClean,
unexpected_failures=0, claims_failed=0, 3770/3770) and the only blocker was
a STALE ADMISSION left behind by gunbc#11137, whose own doc comment said
'this row goes when #11137 merges'. That row has now been deleted from main.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013YcKjgpfRzhjNJrjaNZjJG
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
Review 64521, three findings, all verified.

THE LEDGER OVERSTATED THE COLLAPSE. It said "the single declaration now
lives in `v2.std.text`". Nine homes survive this change, and the sentence
read as if none did. Measured rather than recalled, with the command in
the text so it can be re-derived: six exact `fn string_eq` declarations
plus three RENAMED byte-identical variants -- `floor_join_string_eq`,
`string_eq_native_routing`, `fn_index_string_eq`.

The renamed three matter more than their count. They are §3's NICKNAME --
a second name for one concept -- and they are the form `grep string_eq`
does not find, which is why they are named in the ledger rather than left
to the next reader's search. I had corrected this count in a PR comment
earlier; a PR comment is not readable from the code, which is the whole
reason the correction belongs here.

The residual is now a DECLARED FRONTIER (§3c) with a stated reason for
the scope and a trigger to close it, rather than silence: each further
consumer produces its own `TargetChanged` delta needing a row, and the
`dag/` files would be the first `dag/` modules importing `v2.std.text`
for this name -- a different reach question that deserves its own
evidence.

TWO PIECES OF MERGE RESIDUE, both mine:

  A stale `TRIGGER: this row goes when #11137 merges` was sitting inside
  the `gunbc#11138` cohort header, two lines after the text saying #11137
  had already landed. §4b(3) makes a row's trigger the whole check -- a
  cohort header carrying an already-satisfied trigger is how the wrong
  rows get retired on the next roster touch. Deleted.

  The `gunbc#11071` retraction paragraph appeared twice, near-verbatim,
  joined by a mid-sentence seam from the conflict resolution. One
  statement survives.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
…al one

Review 64522 is right and this is the worst of the prose defects in this
branch, because it cost a real receipt to buy a false one.

WHAT THE HUNK DID. It added a `THIRTY-SIXTH DISSOLUTION (gunbc#11143)`
paragraph saying "the `gunbc#11137 ...` row is deleted, leaving the
roster EMPTY". This PR deletes no row. The roster is ALREADY empty at the
base -- main carries `= &[];` and its own `RETIRED (2026-09-12): #11137
merged as 34d2a8d` -- and this branch's own merge commit says exactly
that. So the paragraph was a receipt for work performed elsewhere,
written in the first person of a change that did not perform it. §4b(1):
a reported rung must equal the rung established by executed evidence.
§4c: an annotation is never evidence that a machine claim holds.

AND IT WAS NOT FREE. The same hunk deleted the surviving
`THE gunbc#10671 ROWS DISSOLVED HERE (2026-09-06)` record -- a real
adjudication, carrying the three-direction join that established CONSUMED
for those four rows rather than asserting it. So the change was a net
LOSS of evidence: one genuine receipt removed, one fabricated receipt
added, in a file whose entire value is that its history can be read back.

The file is restored to main's version byte for byte. This branch has no
roster obligation and should touch this file not at all, which is now
what it does.

HOW IT HAPPENED, since the mechanism is the reusable part: the conflict
resolution on this branch replaced a region of the doc chain rather than
taking one side of it, and the replacement silently swallowed a paragraph
that neither side was in conflict about. Resolving by REGION is how you
lose text no one edited; resolving by SIDE is not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
The required floor reported that row STALE (matches no delta) after #11137 merged; the FAQ Minute import is ExplicitlyEvaluatedZeroDelta and does not replace it.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
…sion row.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
The required floor refused on a stale #11137 namespace-wave admission; main already retired that row in #11165.
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
Review 64537, three findings, all merge residue from patching this ledger
incrementally instead of cutting it once.

WHAT WAS WRONG. The `gunbc#11138` header carried #11137's adjudication --
the sha256sum candidate narrowing and the `String` -> `std.string_type`
zero-delta story -- attributing another change's `TargetChanged`
rationale to this cohort. §3 names that: a meaning fork gives one name
two materially different meanings, and a roster header is exactly where
that is load-bearing. The preamble was also present twice, which is §2
redundancy in a file whose value is that its history reads back.

AND IT CONTRADICTED ITSELF ABOUT THE CENSUS. Twenty lines after the
corrected frontier -- survivors remain, closes when the named `grep`
returns one declaration -- the header still asserted "THE POPULATION IS
COMPLETE AND MEASURED" via `grep -c '^fn string_eq' goes 9 -> 0`, and
that after merge the base authors `string_eq` "only in `v2.std.text`".
That re-inflated the narrow census the previous commit had just corrected
and would have been read as the stronger claim, because it is stated
later and more confidently. §4b(1): do not cite the strongest path while
another stays silent.

The block is now cut once rather than patched again: main's own #11137
retirement record is left untouched above, and this cohort's header
carries only what this change does -- the relocation, its classification,
the byte-identical adjudication, the instrument-named survivor frontier
with the four `v2.lens` nicknames it does not reach, and one trigger.

CHECKED THAT THE CUT ONLY ADDS: 439 insertions, 1 deletion, and ZERO of
main's doc lines removed. That check exists because the last conflict
resolution on this campaign silently deleted a real adjudication receipt
while adding a false one; verifying the subtraction side is now part of
touching this file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
gunbai-bot Bot added a commit that referenced this pull request Sep 12, 2026
* Type FS BOX FAQ trial and account-buffer durations as Minute.

The same change already used Minute for V4 battery endurance; leaving these as prose strings was a second representation of a published duration (review 64502 on the #11131 landing).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Delete the spent #11137 namespace-wave admission on this roster touch.

The required floor reported that row STALE (matches no delta) after #11137 merged; the FAQ Minute import is ExplicitlyEvaluatedZeroDelta and does not replace it.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls pushed a commit that referenced this pull request Sep 12, 2026
…mpty-map generics, argv word-list splice, append concat form (#11154)

* Three v2->Rust emitter arms the widened 00_compile closure exposed

#11011 widened the emitted closure to carry extdeps.rust.cargo_build and
extdeps.exec.command; the first srv2 execution of that route emitted a crate
rustc refused with 28 errors, all of them in those two newly-emitted modules.
Reproduced locally and repaired at the emitter, so any closure carrying the
shapes emits correctly. None of #10940's layer-inversion fix is here.

(1) EMPTY-MAP TURBOFISH, E0425. A module-scope `data ...: Map<String, String> =
empty_map()` emitted `v1_rt::rc_empty_map::<K, V>()`: the call resolved to the
v2.std.collection DECLARATION and the emitter wrote that declaration's own
formals into a module with no generic scope. The fold-init arm had already
learned to defer such a turbofish to the target's inference; the plain-call arm
had not. Both now read one authority, rust_empty_map_init_expr -- two sites
asking one question was the second representation DESIGN section 2 forbids.

(2) WORD LIST SPLICED INTO AN ARGV LITERAL, E0277, 17 sites. `Command::arg(list)`
handed one argument a run of words. emit_shell_call now asks the operation's own
input declaration -- the same authority optional_params beside it reads -- and
emits `.args(..)` for a List-typed element. argv[0] is deliberately untouched: a
word list there is already refused loudly on the same bound, and an emitted
refusal in its place is a red this route cannot adjudicate, since an emitted
panic compiles.

(3) THE CONCAT FORM OF append SPELLED AS THE SNOC BRIDGE, E0308, 9 sites. The
defect report named the `items:` keyword as the discriminator; measured against
the interpreter it is not. `append(xs, items: ys)` and `append(xs, ys)` BOTH
answer concat and `append(xs, items: x)` answers snoc -- method_call.concat asks
value_to_list_carrier of the argument and never reads the keyword. The
discriminator is the APPENDED ARGUMENT'S TYPE, so keying on the keyword would
have left the positional concat form still emitting snoc. All nine sites emit
through emit_rust_generic_method_call, not the plain-call seam, because nothing
in the corpus imports append and infer rewrites the bare form into a method
call; the plain-call seam therefore gets no reader, because its red is not
authorable anywhere a check could run it (section 4b).

EVIDENCE. Three fixtures under fixtures/fixture_closure_rustc/, each measured
RED against the pre-repair seed -- E0425 x4, E0277 x4, E0308 x5 -- and green
after, consumed by fixture_closure_rustc_verdict through three discrimination
pairs whose red arm is the route's own FIXTURE_RED_PATH. A pair per arm so a
regression is attributed to one emitter decision. Positive control: both real
modules emitted and cargo-built, 28 errors before and 0 after.

The argv fixture carries a note about a SEPARATE gap found while authoring it: a
single-output shell operation with no exit block emits an unwrapped value where
its own declared Result is expected. It is recorded, not repaired here -- a
fixture carrying two defects adjudicates neither.

gunbc.recurring_failure_mode.accepted_source_emits_uncompilable_target gains one
occurrence carrying all three, the keyword-discriminator correction, and an
honest rung: still mitigatable. The three pairs are #[ignore]d --lib tests and
repo_self_test_command is off the merge path, so nothing blocks a regression and
reporting rung 2 would be inflation. The trigger names the capability: a
required phase that emits a closure and compiles it over a population that
includes fixture-authored sources.

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

* File the shell projection arity class, and walk the mirror generation chain to its fixed point

TWO THINGS, and the second is the repair of my own error on the first push.

FIRST, THE ROW eager-raven-113 ASKED FOR. The separate finding the previous
commit recorded only as a note in the argv fixture is a newly discovered error
class, so under DESIGN 4b it gets its own row:
gunbc.recurring_failure_mode.shell_projection_return_convention_selected_by_arity.

THE MECHANISM WAS ISOLATED BEFORE IT WAS NAMED, because the fixture that exposed
it changed two things at once. Measured, each ruling out a plausible co-cause:
one field with NO exit block emits `output.status.success()` and is refused
E0308; one field WITH an exit block emits `0 => { output.status.success() }` and
is refused at the same grain, so the exit block is not load-bearing -- the exit
arm reaches the same projection; a lone `stdout` is refused exactly as a lone
`exit_success`, so the channel is not load-bearing; and TWO fields already emit
`Ok((output.status.success(), stdout.clone()))` and compile, so the boundary is
at one rather than at some larger shape. The arity is the whole mechanism.

SO IT IS A FORK, NOT A MISSING ARM: the Result convention is present and correct
at two fields and up, and an arity test chooses between two conventions where one
declaration should derive one. The trigger therefore names the capability -- the
return convention derived once, at the authority that also renders the signature
-- because "wrap the one-field case in Ok" would be satisfied by a second arity
branch, leaving the fork one arm wider.

THE SPECIMEN IS COMMITTED AS A RUNNABLE KNOWN-HOLE PAIR, which is the lesson its
sibling class records having learned twice: widening the argv fixture to the
output shape extdeps.rust.cargo_build actually declares had removed the only
instance from the tree. shell_single_field_projection_probe.dag (red, 1 x E0308)
and shell_multi_field_projection_probe.dag (control, compiles) differ in ONE
authored thing, so a green against a red locates the refusal at the arity.
Measured both directions. Per 4b(4) the red flips and is KEPT when the class
climbs. No repair here -- it was found by a different fixture being wrong, and
repairing it inside that subject would make one fixture carry two defects.

SECOND, THE CI FAILURE, WHICH WAS MINE. required-witnesses-build failed at
`generated-artifact stage0-mirrors FAIL generated surface drift: compiler_tests.rs`.
The stage0 mirrors are a GENERATION CHAIN: compiler_tests_rust.dag generates
v1_compiler_compiler_tests_rust.rs, and the binary built from THAT generates
compiler_tests.rs. Installing the first generation and stopping leaves the second
un-derived, so the drift appears only on the pass after the one I acted on. Local
regen said `first_generation_equal=false` twice and I read the named file list
instead of the flag -- a regen is a fixed-point iteration, and I stopped at one
pass.

WALKED TO THE FIXED POINT THIS TIME, one install and rebuild per generation:
pass 3 drifted v1_compiler_compiler_tests_rust.rs, pass 4 drifted
compiler_tests.rs (the file CI named), pass 5 reports
`first_generation_equal=true` with no FAIL line. All four generated
discrimination tests are present in compiler_tests.rs, and the three generated
mirrors are byte-identical to the candidate after cargo fmt, which touched only
the hand-authored host file.

cargo fmt --all --check clean; cargo clippy --all-targets -- -D warnings clean.

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

* Name the argv seam coupling and its trigger

Review 64440 on gunbc#11154 verified that the one-word argv arm's
emit_rust_dag_string_to_host_via_seam is the identity today and concluded the
word-list arm skipping it introduces no divergence. That is correct, and the more
useful half is what it implies: the two arms are now coupled through a function
only one of them calls.

They agree only while that seam is identity. If it becomes a real
dag-String-to-host-String conversion, every word spliced through the list arm
skips the conversion every word through the one-word arm receives -- silently,
because both arms still compile and the splice still yields the right NUMBER of
words. The coupling is invisible at the site that would break it: a lane changing
the seam has no reason to read the splice, and the splice never named the seam.
It does now, with the trigger stated beside it.

I said on the PR I would fold this in if another push became necessary rather
than spend a CI cycle on prose alone. It did, so this rides along.

MEASURED RATHER THAN ASSUMED, because DESIGN 4c's disjointness of annotation
capture from semantic emission is itself a claim and
gunbc.recurring_failure_mode.content_digest_makes_annotations_semantically_load_bearing
is a rostered class: required-regen over this annotation-only edit reports
first_generation_equal=true, so the emitted bytes are byte-identical with the new
block in place and no mirror needed reinstalling.

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

* Collapse the two word-list predicates onto one authority (review 64464)

review 64464 found this diff committing the defect its own headline arm exists to
repair: `is_list_typed_expr` and `shell_argv_param_is_word_list` were two
spellings of one question -- is this type an ordered run of elements -- authored
in the same change as `rust_empty_map_init_expr`, which exists because two sites
asking one question is the second representation DESIGN section 2 forbids. The
finding is correct and is fixed in code rather than argued with.

THE DIVERGENCE WAS A LATENT MISCLASSIFICATION, NOT A STYLE MATTER, which is why
consolidating repairs rather than tidies. The two conjunctions had ALREADY
diverged: `is_list_typed_expr` excluded a string carrier and the argv-parameter
reader did not. In this substrate `String` IS `FreeMonoid<Char>`, so a string
carrier spelled structurally satisfies node_is_element_collection -- and the argv
reader would then classify a shell input declared that way as a run of words and
splice it, when a string is ONE argv word.

THE EXCLUSION IS RIGHT FOR BOTH CONSUMERS, SO IT IS NOW DECIDED ONCE. For
`append`, a string second argument must be snoc and not concat, which is the
interpreter's own rule -- its concat arm tests Value::Str before asking
value_to_list_carrier. For an argv element, a string must be one word and never a
splice. Two consumers, one reason: a string is an atom to both even though its
carrier is a sequence. `type_node_is_ordered_element_run` carries the whole
conjunction and both readers project onto it.

NO EMISSION CHANGED, AND THAT IS MEASURED RATHER THAN ASSERTED, because it is the
evidence for WHY the divergence was latent rather than live: the ordinary spelling
`word: String` is a zero-child leaf excluded by ARITY alone, not by the string
test. Emitted extdeps_cargo_build.rs and extdeps_exec_command.rs are BYTE-IDENTICAL
before and after the consolidation. Had they differed, the explanation above would
have been wrong. The argv fixture still emits its four `.args(..)` splices and its
one `.arg(word)`, and its crate still builds. Regen at fixed point
(first_generation_equal=true).

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

* Thirty-sixth dissolution: delete gunbc#11137's consumed admission row

OPERATOR RULING A (eager-raven-113). required-witnesses-floor refused this branch
twice -- a0486fd and f991009 -- on `namespace-wave-admission 1 stale
admission(s)`, with the floor itself clean both times (verdict=FloorClean,
unexpected_failures=0) and this branch's own delta adjudicated clean
(ExplicitlyEvaluatedZeroDelta on the new recurring_failure_mode row). The single
blocker was gunbc#11137's row, whose own recorded trigger was "this row goes when
#11137 merges". #11137 merged as 34d2a8d, so the trigger fired; a consumed
row's deletion comes due on this roster's OWN next touch, and this change is that
touch. The roster returns to its resting state, empty, and nothing else in the
file changes.

MERGING MAIN DOES NOT CLEAR IT, WHICH I ASSERTED EARLIER AND WAS WRONG ABOUT.
gunbc.rung_drop namespace_admission_consumed_row_deletion says so in terms: the
row is RESIDENT on main "from that merge until a human deletes it", an interval
that "can never match a delta and is therefore pure liability". Human deletion is
the declared remedy and no push to this branch's own files could substitute.

THE EVIDENCE IS GIT IDENTITY, NOT A `CONSUMED ADMISSION` RECEIPT, and the
difference is recorded in the dissolution rather than glossed. Every dissolution
above this one cites the wall printing `CONSUMED ADMISSION ... already satisfied
at the base`. This one cannot: on this branch the wall printed `STALE ADMISSION
... matches no delta in this run` and failed the phase. So the fired trigger is
established by ancestry -- 34d2a8d is an ancestor of this run's base -- which
is exactly what the trigger sentence names.

THAT DISCREPANCY IS NOTED AS UNVERIFIED AND DELIBERATELY NOT CHASED HERE, per the
ruling. gunbc#9824 split ConsumedByMerge from UnmatchedAdmission precisely so a
row whose relocation the base already satisfies stops refusing unrelated pull
requests, and this row took the second arm where the first looks applicable.
Whether admission_consumed_at_base fails to recognise a TargetChanged binding
whose module and target are the same module, or whether the arm is right and my
reading is wrong, is UNVERIFIED: I read no code in that path, and nothing here may
be cited as a finding about it. It belongs to that mechanism's owner, because if
the hole is real then deleting one row treats a symptom while the mechanism keeps
producing them.

ONE MEASURED FACT WORTH CARRYING, recorded in the dissolution: main's own run of
this phase prints `NO SUBJECT -- the merge base against origin/main IS <tip>, so
this run has no diff to adjudicate`. main is therefore green on this phase
VACUOUSLY, and a resident row bills pull requests from a position where no push
run can observe it.

cargo fmt --all --check clean; cargo clippy --all-targets -- -D warnings clean
with the roster empty.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Sep 12, 2026
…red_quadratic_rejects red on main (dark long-lane row) (#11142)

* Repair the accumulator-copy analyzer: an argument capture is not the argument's value

v2.lens.complexity_accumulator_copy.analyze port_reading took its identifier
census with collect_value_identifiers over the WHOLE ^dag_surface_arg capture,
which for a named argument `left: acc` carries the LABEL as well as the value.
Measured on the specimen: the list_append call capture is found, it has two
ports, and port 0 reads PortComputedExpression with mentions = 2 containing both
^left and ^acc. So `idents == 1` was false, the arm that consults
arg_value_symbol and yields PortBareName { name: ^acc } was unreachable, and
classify_copied_port took ^copied_port_computed_argument -- the undecidable
residue, non-gating by design. No Poly2Suspect was minted and
accumulator_copy_compile_gate ACCEPTED the textbook quadratic.

It is none of the three candidates the brief offered: the shape matcher finds
the call, the carrier is bound (count_fold_sites bound_only > 0), and
list_append is rostered (copied_port_citation_list_append). Because every .dag
call uses named arguments, the bare-name arm was unreachable for the entire
corpus, which is why the lens has never minted a suspect on ingested source.

port_reading now reads the argument's VALUE subtree, the same
^dag_surface_primary_expr node arg_value_symbol already reads through, so the
census and the symbol read ask one authority what the argument IS. Nothing is
widened: the no-value-capture arm still reads the whole capture, so it stays an
over-approximation that degrades toward the refusal causes and never toward
clean.

Second latent red on main, same subject and the class gunbc#11025 already
fixed once: v2.test.long.accumulator_copy_fold_analysis findings_of passed the
sealed NormalizedTree where a Node is wanted (missing .root, dead since the
BL-1 seal in #10439), so all 21 of its witnesses were dark with
"no field 'kind' on type 'NormalizedTree'".

Evidence: all 7 witnesses of accumulator_copy_compile_gate_test now PASS,
including gate_red_quadratic_rejects, which FAILs on the same tree without the
lens change. The three diag_* controls that discriminated the failure are
enrolled beside gate_red/gate_green, in the census obligation's witness list
and in the witness_deferral_freeze identity join for that entry.

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

* Declare the four reds the .root repair makes visible, and file the fold fail-open

Un-darkening v2.test.long.accumulator_copy_fold_analysis puts 17 witnesses
dark-to-green and 4 dark-to-visibly-red. Attribution is measured, not assumed:
a control worktree carrying ONLY the .root repair, with the port_reading change
absent, fails all four identically, so they are pre-existing and unmasked rather
than introduced. A discriminating probe separates them into three defects, and
each is rostered at its own grain per the ruling from eager-raven-113.

let_alias_is_proven_suspect is NOT a lens fact and NOT a fixture typo: staged
probe shows tokenize ACCEPTS and v2.compiler.parse parse_module REJECTS the
specimen, so it never reaches normalize or the lens, and the witness's
`Absent => false` reports a stage refusal as a lens verdict. A six-cell ingest
matrix narrows the refusing shape: a let binding the fn literal's own parameter
standing immediately before a call statement. Renaming the binder still refuses;
an unbound RHS, a literal RHS, a second let, and the one-line spelling all parse.
Trigger: the grammar admits that statement shape.

let_fresh_binding_is_provably_clean is a false refusal that FAILS CLOSED -- the
lens over-refuses a provably fresh binding with ^copied_port_computed_argument,
which rides the non-gating Accepted channel, so no quadratic can be admitted
through it.

named_step_fold_refuses_accumulator_unread and report_counters_state_the_domain
are one silent fail-open (DESIGN section 5): for fold(xs, init: 0, f: step) the
normalized tree carries NO lowered Loop and NO surface fold call, count_fold_sites
returns 0, and the lens's own ^fold_accumulator_unread arm in fold_family_carrier
is unreachable -- a written, located refusal no input can trigger, which reads to
a reader as coverage. Filed as
gunbc.recurring_failure_mode.fold_shape_visible_to_no_lens: found at below the
floor, ceiling structurally guaranteed, trigger naming the capability with the
suspected home in v2.compiler.fold_lowering / body_lowering_fold rather than the
lens. Deliberately not repaired here -- that scope is unbounded inside a PR whose
subject is the port reading.

The four also leave the gunbc.witness_deferral_freeze FrozenPathDeferral row for
that entry: a witness leaves discovery for ONE reason, and carrying both an exact
admission and a path policy is the dual representation that module exists to
replace.

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

* Home the diag controls where they execute, instead of growing the frozen roster

Review 64325 is right and the gate behind it is real. The previous commit appended
three identities to gunbc.witness_deferral_freeze frozen_path_deferrals so the new
diag_* controls could sit beside the gate's red/green controls. That roster is
frozen against GROWTH by the cli_run collect_frozen_path_deferral_additions
monotonicity gate, which is a key set-difference against the diff baseline -- so a
net -4/+3 does not cancel, the three new keys refuse, and the push would have
redded CI. DESIGN section 3 says the same thing for a frozen X: no new rows on its
growth surfaces.

The deeper point is the one the module itself states: for a GREEN witness under an
offline home the only exact cadence available is QuarantineProbeExpectRed, which is
a declaration that a witness is RED and cannot be written truthfully about a green
one -- so the compliant move is not to author there. The brief said to enrol these
controls "beside" the existing ones; the authority docs say a green witness may not
live in a home that executes nothing, and the docs win.

So the three discriminators move to
src/v2/test/claim/complexity/accumulator_copy_compile_gate_diag_test.dag, which
per-PR discovery DOES execute (the complexity exclusion is the narrower
claim/complexity/accumulator_copy_roster_gate prefix, not the directory), the
freeze roster returns to its main content for that entry, and the census witness
rows repoint to the executing path and module.

Measured in the new home rather than assumed affordable: all three PASS at
cpu=851ms / 1022ms / 1051ms, wall <= 2003ms, against the 5000ms fast-lane
per-witness budget -- which is why these three fit per-PR while the gate's own
red/green controls, which they discriminate, do not.

The freeze roster's only remaining change is SHRINKAGE: the four witnesses that
gained exact known_red_probe admissions leave it, which is the migration that
module names for legacy rows.

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

* Withdraw the diag controls: no ingesting witness can be enrolled per-PR

CI on c382814 refused with nine blockers -- three per new witness:
interrupted_before_verdict, changed_witness_planned_without_terminal_verdict,
enrolment_censored_at_ceiling. The witnesses WERE planned, so the executing home
was right; what was wrong was the budget I checked them against.

I compared 851ms / 1022ms / 1051ms CPU to the 5000ms fast-lane eval deadline and
called the relocation affordable. That is the wrong line. The applicable ceilings
are v2.workflow.required_floor required_floor_claim_cpu_safety_limit_ms at 500ms,
and for a NEWLY enrolled witness the tighter derived budget from
v2.workflow.floor_enrolment_margin floor_enrolment_margin_budget_ms -- the 500ms
ceiling deflated by the runner-variance envelope. The measurement was right and
the comparison was wrong, which is worse than not measuring: it produced a
confident affordability claim on the PR.

The constraint is structural rather than a tuning gap. calm-crane-722 measured the
per-claim cost as a ~500ms FIXED front end -- dag_language_model plus
tokenize/parse/normalize, rebuilt in every claim's own evaluation frame, invariant
to the subject-specific work. A witness whose subject IS the ingest path therefore
cannot clear a 500ms ceiling with margin at any per-PR home, which is exactly why
the gate's own red/green controls live in the long home. And the long home cannot
take them either: its path roster refuses growth, and the only offline cadence that
executes is QuarantineProbeExpectRed, which declares a witness RED and cannot be
written truthfully about a green one.

So the three discriminators come out rather than being hidden behind a hand-built
tree that would assert a lowering shape I authored instead of one I observed -- my
own probing found the real shape surprising (a surface primary_expr inside a
lowered Loop, not a lowered Transform), so a synthetic fixture would go green while
the real path broke.

Brief item (2), "enrol the three diag_* controls as executing evidence", is
therefore UNMET, with the reason measured and the trigger named: the fixed
per-claim ingest front end has to come down, or a cadence has to exist that
executes a green witness too expensive for the fast lane. What the discriminators
established is not lost -- it is in gate_red_quadratic_rejects, in the four
known_red_probe reasons, and in
gunbc.recurring_failure_mode.fold_shape_visible_to_no_lens.

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

* Strip the argument label by navigation, not by search

Review 64393 is correct and the defect was mine, introduced by the previous
repair. Verified in the source before changing anything:
v2.extdeps.languages.dag parse_subtree_find_production_captured is a FIRST-MATCH
DFS that short-circuits on ParseSubtreeFound, and dag_surface_binary_expr /
dag_surface_unary_expr sit ABOVE dag_surface_primary_expr in the grammar. So
searching an argument for its first primary_expr returns only the LEFTMOST operand
of a compound argument, and the census became an UNDER-approximation of the
identifiers the argument names -- while the annotation I wrote beside it claimed
an over-approximation.

The consequence is the arm DESIGN section 5 forbids. `left: seed + acc` censused
as mentions [seed]: one identifier, so the bare-name arm fired; a BindsFresh
`seed` resolved through resolve_port_reading to PortPureLiteral; classify_copied_port
answered Absent; and a copied accumulator classified CLEAN with the carrier
invisible to any_port_carries_carrier as well, because it reads the same narrowed
list. A failure arm that widens into silence, and the same class this PR files at
gunbc.recurring_failure_mode.fold_shape_visible_to_no_lens -- which is why it is
recorded in the annotation rather than quietly corrected.

arg_value_node now walks the `name : value` spine instead of searching for a
production, and EVERY deviation from that exact shape falls back to the whole
capture: a positional argument has no label to strip, and a sequence whose
separator is an operator rather than ^dag_token_colon is not a labelled argument.
Both keep the whole-capture census, which over-approximates, so the reading
degrades toward the refusal arms and never toward clean -- what the annotation
claimed all along and now actually does.

MEASURED ON THE REAL TREE, both directions, since the previous claim here was a
confident assertion that did not hold:
  plain    `left: acc`        -> mentions [acc], label excluded, one identifier,
                                 PortBareName, suspect (unchanged)
  compound `left: seed + acc` -> mentions [seed, acc] -- BOTH operands, label
                                 excluded -- PortComputedExpression,
                                 ^copied_port_computed_argument, NOT clean, and
                                 no false suspect
Regression: 21/21 PASS across both accumulator-copy modules, 0 FAIL --
gate_red_quadratic_rejects included, and the 17 fold-analysis witnesses that are
not declared red.

The fixture gap review 64393 names is real and I cannot close it: a binary-expression
port fixture is a new witness, and a witness whose subject is the ingest path
cannot clear the 500ms per-claim floor ceiling at any per-PR home while the long
home's roster refuses growth. That is the capability gap already recorded as a
frontier with this PR as its specimen; the guard is verified by local probe and by
the unchanged existing witnesses, and that is weaker evidence than an enrolled
fixture would be.

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

* Re-point the accumulator-copy fixtures to the axis the cost authority now names

#11019 landed mid-flight and repointed list_append's copied-port citation from
the left operand to the right, because the concat realization copies the appended
side: v2.std.fn_index records that v1_rt::rc_list_concat make_muts the LEFT and
clones the RIGHT. So this PR's own fixtures asserted a retired cost shape. The
brief's textbook specimen, list_append(left: acc, right: x), copies only x per
step -- it is LINEAR under the current realization, and a correct lens must not
flag it. The quadratic is list_append(left: x, right: acc).

MEASURED, NOT INFERRED, and attributed before it was repaired. On the merged tree
quadratic_fold_has_suspect, real_branch_body_quadratic_is_caught and
let_transitive_alias_is_proven_suspect FAILED, and
noncarrier_name_in_copied_port_refuses_not_clean INVERTED -- its left: x, right:
acc snippet had become the suspect case. A control worktree on origin/main
carrying only the .root repair, with this PR's lens change absent, fails the same
four, so the inversion is #11019's and not this PR's.

THE DIRECTION COMES FROM THE AUTHORITY, AND NOTHING HERE ENCODES IT. The lens
reads v2.lens.cost.copied_port_citations copied_port_index_of, whose rows cite the
concat contract and carry their own dissolution to producer-ingested Arrow bodies;
that is why the verdicts moved on their own when the citation was repointed. Adding
a second left/right encoding in the lens to "fix" this would have been the section
3 fork review 64414 already caught once in this PR. Only the FIXTURES hard-coded
the axis, so only the fixtures move: every in-iteration list_append now carries its
subject on the copied (right) port. out_of_iteration_snippet is deliberately
untouched -- it has no carrier and asserts out-of-domain.

RED BEFORE, GREEN AFTER, both on the corrected fixtures:
  pre-fix seed (main + .root, lens change absent): gate_red_quadratic_rejects FAIL,
    all four fold witnesses FAIL, gate_green_identity_accepts_clean PASS
  this tree: gate module 4/4 PASS including gate_red_quadratic_rejects;
    fold module 17 PASS and 4 FAIL, the four being exactly the declared
    ExpectAssertionFalse rows. let_fresh_binding_is_provably_clean does NOT green
    under the flip, so its known-red row is not false on arrival.

Also in this push, from the merge: the known_red_probe row for
gate_red_quadratic_rejects is DELETED -- its trigger has fired, so the witness is an
ordinary permanent regression control again (DESIGN 4b(4)) -- and the census
annotation records that the trigger fired while the rung STAYS Mitigatable, because
4b(1) takes the minimum across paths and fold_shape_visible_to_no_lens establishes a
population where this gate's wall does not execute at all. gunbc.recurring_failure_mode
required_lens_red_control_never_executes_from_its_home gains a second specimen: the
same dark home is why #11019 could repoint the cost axis and leave these fixtures
stale, with nobody to run them.

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

* State the named-argument divergence, and file the collapsed-operand class

Operator ruling (eager-raven-113) on review 64414's fork finding, and it is a
better diagnosis than either remedy the review offered: the root is a defect in
the compiler's own decode rather than a question of which caller owns it.

(a) arg_value_node stays, and the divergence becomes STATED per DESIGN section 3b
instead of unstated. The annotation names v2.compiler.body_lowering_fold
body_lower_named_arg_value_optional as the authority it diverges from, gives the
reason by symbol -- body_lower_operand_ref_optional recurses into pair.left ALONE
on a sequence operand, so `left: seed + acc` returns the operand for `seed` and
drops `acc` -- and states the trigger: when that accessor preserves the full
sequence, arg_value_node DISSOLVES INTO IT and this annotation deletes with it.
Consuming the authority as it stands would reintroduce exactly the
under-approximation review 64393 caught, so the two functions answer different
questions today.

(b) gunbc.recurring_failure_mode.lowering_accessor_collapses_a_sequence_operand is
filed for the class: a lowering accessor that silently narrows a multi-element
operand to its first element, with no refusal and nothing counted. Specimen
`left: seed + acc`. Rung found at BELOW THE FLOOR because the loss is silent --
an operand replaced by a proper part of itself is neither refused nor recorded.
Ceiling structurally guaranteed and reachable: the narrowing has no constructor
once the accessor returns a shape that can represent a multi-element operand.
Trigger names that capability, and explicitly not a diagnostic, a counter, or a
second accessor beside it.

The receipt worth keeping is in the row: TWO INDEPENDENT IMPLEMENTATIONS of "the
argument's value" -- the compiler's operand reader and this lens's first-match DFS
-- converged on the same wrong answer, which is the evidence that the defect is in
the shared fact rather than in either caller. And no fixture in the suite could see
it, because every one used a single-identifier argument, where "first element" and
"whole operand" agree.

The compiler-side repair is its own lane: body_lowering_fold is a load-bearing
pipeline file, so it was raised rather than improvised here, and this row is its
brief. Gate module re-verified after the edit: 4/4 PASS.

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

* Attribute the gate's green to two edits, not one, and cite the cell that proves it

Review 64439 is correct. The receipt paragraph I added attributed
gate_red_quadratic_rejects's green entirely to the analyzer repair, but this PR
also re-points the discriminating specimen, and on the OLD specimen the carrier
sat on the NON-copied port -- gunbc#11019 moved list_append's copied port to the
right operand -- so the analyzer repair alone could not have minted a suspect. The
two edits are jointly, not severally, sufficient, and claiming otherwise is the
rung inflation DESIGN section 4b(1) forbids: a rung measured on a path the
evidence does not establish.

The deleted admission row named this exact hazard -- "deliberately NOT keyed on
this witness greening, since editing the specimen or the control would green the
witness without the capability" -- so the burden is to show the specimen edit is
not what greened it.

That evidence already existed in this PR and the annotation failed to state it,
which is the defect: the measurement was made, and the authority carrying the
claim did not carry the measurement. The annotation now names the three cells.
The one that matters is the corrected specimen on the PRE-FIX seed, origin/main
with only the .root repair and this PR's lens change absent: there
gate_red_quadratic_rejects FAILS, with gate_green_identity_accepts_clean passing
beside it as the control for planning. So editing the specimen alone does NOT
green the witness -- the route the row excluded is refuted by execution rather
than by assurance. Corrected specimen WITH the lens repair passes; old specimen
with the lens repair cannot, by the copied-port citation. The capability is what
closes the gap between the first cell and the second, which is the trigger
discharged on its own terms rather than by a fixture edit.

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

* Retire the consumed gunbc#11137 wave-admission row, clearing it for every branch

Operator ruling (eager-raven-113): delete main's stale gunbc#11137 admission row
in the same push. It is a permission standing over nothing, and the cost is
fleet-wide rather than local -- required-witnesses-floor refuses
namespace-wave-admission on every PR carrying it, and gunbc#11082, gunbc#11121,
gunbc#11154 and this branch each burned a floor on it.

THE ROW'S OWN TRIGGER IS WHAT FIRED, so this is the designed dissolution rather
than housekeeping on another lane's entry. Its doc comment recorded the condition
in advance -- "this row goes when #11137 merges. The base then carries the named
import, the delta stops being producible, and CONSUMED comes due on the roster's
next touch." #11137 merged at 06:35, and the roster's own rule charges the next
change that touches it, which is this one. The module states the same law twice:
"a row matching no delta refuses as stale, so the roster can only shrink toward"
its resting state, and "any absorbed or vanished delta makes required CI red until
that row is removed".

The deletion follows the file's own ledger convention rather than inventing one:
the THIRTY-FIFTH entry deleted three consumed rows "and their description with
them", so this appends a THIRTY-SIXTH entry naming the trigger that fired and the
branches that paid for it, and removes the row-specific rationale with the row.
NAMESPACE_TRANSITION_ADMISSIONS returns to the EMPTY enumeration that is its
resting state -- empty is not permissive, and a run with any delta no row names
still refuses it as UNADJUDICATED.

Nothing else in the file changes. Verified: cargo fmt --all --check clean, and
cargo check -p v1-compiler --lib Finished with no errors.

I had declined to make this deletion unilaterally when it first blocked this
branch: it is another lane's row in the v1 seed, and the obligation is specified
to come due on a roster-touching change rather than on any PR that happens to be
blocked by it. It is made here on an explicit ruling, with the fleet-level
evidence that it was blocking four branches.

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

* Enrol the discriminating red, re-point the planted control, name the binding trigger

Three findings from reviews 64460 and 64473, all correct, all mine.

1. THE REPAIR HAD NO ENROLLED RED (review 64460). Every re-pointed fixture is a
single-identifier or single-call value on the copied port -- the shapes where the
search census this repair replaced and the spine walk AGREE -- so reverting
arg_value_mentions to search left the whole suite green and restored the silent
fail-open. A fix whose mutation reds nothing is not enrolled evidence
(DESIGN section 5: a discriminating input that goes red when the behavior is wrong).

The cell is carried by the witness that already owns this subject rather than by a
new identity: a new test fn in this offline home would need roster growth, which
the monotonicity gate refuses, or a false expect-red admission. Witness count is
unchanged at 21.

MY FIRST ATTEMPT AT THAT CELL WAS DECORATION AND THE MUTATION CONTROL IS WHAT
CAUGHT IT. It used `let seed = 0` with `right: seed + acc` and asserted
has_refusal_cause(computed_argument). The CENSUS does differ -- measured on both
trees, port 1 reads [seed, acc] under navigation and [seed] under search, with the
carrier vanishing -- but another site in that snippet contributes
^copied_port_computed_argument anyway, so the assertion passed under BOTH readings.
A true claim asserted through a channel blind to it.

The shipped cell drops the binder: list_append(left: x, right: x + acc). The two
readings then disagree about WHICH CAUSE fires rather than whether anything fires
-- ^copied_port_name_may_alias under search, where the bare-name arm reads `x` and
`x` is no carrier, and ^copied_port_computed_argument under navigation, where both
operands are seen -- so asserting the presence AND the absence makes both conjuncts
flip. Measured: PASS on this tree, FAIL under a worktree reverting
arg_value_mentions to the search census, with the roster holding at 17 PASS and the
4 declared ExpectAssertionFalse rows.

2. A RED THAT COULD NOT FIRE (review 64473). I re-pointed the long-home fixtures to
the copied-right axis and left test/fixture_roots/complexity_accumulator_copy/
planted_copy.dag and the roster gate's planted_copy_snippet on `left: acc, right: x`
-- the axis gunbc#11019 retired. red_control_planted_copy_still_alarms asserts
SuspectObserved, which that specimen can no longer produce, so it was enrolled
evidence incapable of alarming. Both re-pointed, with the reason recorded beside the
snippet. Same defect class as finding 1, twice in one PR.

3. TRIGGER GRAIN MISMATCH (review 64473). The annotation claimed the restoration
condition was REPLACED by fold-domain totality while next_trigger still named only
affordability and the native door -- prose asserting one climb and the machine field
encoding another, which is how a rung later gets restored on the wrong evidence
(DESIGN 4b(3)). next_trigger now names fold-domain totality FIRST, as the binding
capability under 4b(1)'s minimum-across-paths, with the other two after it.

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

* Revert the roster-gate snippet re-point: touching that file plans an over-wall witness

CI on 396f026 refused with two blockers, both naming
v2.test.claim.complexity.accumulator_copy_roster_gate.roster_std_algebra_zero_suspects_within_ratchet
-- interrupted_before_verdict and changed_witness_planned_without_terminal_verdict.
Caused by my own fix for review 64473, and the mechanism is exact rather than
suspected.

WHY EDITING THAT FILE IS SELF-DEFEATING. floor_diff_edits_from_line_ranges
attributes changed lines to test declarations, so re-pointing the planted_copy_snippet
DATA row at line 47 attributed to the test declaration immediately above it, and
required_floor_disposition_with_changed_selection replaced that identity's withheld
disposition with PlannedAsChangedWitness. The witness then scans src/v2/std/algebra.dag,
a real corpus file, which is why its home carries the
claim/complexity/accumulator_copy_roster_gate exclusion in the first place. Its
identity IS in v2.workflow.floor_cost_debt floor_cost_debt_roster, so
changed_witness_cost_policy returns ChangedCostDebtVerdictOnly and the CPU deadline
becomes observed-only -- but as
gunbc.recurring_failure_mode.claim_edit_changes_execution_policy_outside_reported_cost_delta
states, WALL deadlines, semantic failures and missing cost observations still block.
The declared debt covers CPU, not wall, so the interrupt stands.

So the inline planted control cannot be re-pointed in this PR. Reverted to main's
spelling; the CORPUS fixture re-point
(test/fixture_roots/complexity_accumulator_copy/planted_copy.dag) is KEPT, because it
is a different file whose edit planned nothing -- the run's blockers named only the
roster-gate identity.

WHAT I DID NOT DO. I did not move the data row next to a cheaper witness to steer the
line-range attribution: that is editing around the mechanism rather than through it,
and the roster's own authority refuses exclusion patterns being "edited around". I
also did not admit the identity as expect-red, which would be false -- it is
interrupted, not asserting false.

The residue is real and is review 64473's finding standing unrepaired for the inline
snippet: red_control_planted_copy_still_alarms asserts SuspectObserved on the axis
gunbc#11019 retired, so it is a red that cannot fire, and it is also dark because its
home is excluded. Both halves need the same capability -- the roster gate's witnesses
becoming affordable, which accumulator_copy_obligation next_trigger already names as
its second capability. Reported rather than papered over.

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

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Sep 12, 2026
…11121)

* Wire map_insert/map_lookup to primitive delegates instead of an O(n) closure chain.

Keyed lookup is now the same HostRealizedSeam shape as empty_map, bound to the declared insert and lookup contracts, so native maps stay HAMT on both the interpreter and emitted-Rust paths.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Install the compile_stage0 candidate for std_primitive_projection.rs.

The build lane refused generated surface drift: the emitter orders primitive_lookup before empty_map, which the hand patch did not.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Invert the record-shaped map_insert control instead of deleting it.

The seam still refuses wrap-body fallthrough; insert on a non-native
carrier returns the carrier unchanged so lookup stays Absent, which is a
Bool verdict (a TypeError is RuntimeErrored and cannot stay enrolled).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fail-closed map_insert: TypeError on non-native carriers.

Keep the inverted record-shaped control as a Bool predicate over the
same Value::Map match; a throw cannot stay enrolled as a floor verdict.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Observe map_insert TypeError in the inverted record-shaped control.

The predicate now runs map_insert grounding instead of a parallel
Value::Map match, so restoring Ok(None) fallthrough turns the control red.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Keep map_insert TypeError and enroll a Rust inverted control.

A record-shaped insert refuses with InterpError::TypeError; n HAMT
inserts and sublinear first-key lookup steps witness the delegate vs wrap.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Keep grounded_shared_carrier_wrap_test enrolled beside the map_insert TypeError control.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Delete the stale #11137 namespace-wave admission row.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
Take main's namespace_wave_admission.rs (the #11121/#11137 prose dissolution) and restore the seventeen sizing Binding admissions on top. No rebase.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
…ents

Review 64588. The doc block above NAMESPACE_TRANSITION_ADMISSIONS carried a
second copy of main's RETIRED paragraph -- "the EMPTY DOES NOT MEAN PERMISSIVE
rule above makes this shrink fail-closed" -- sitting directly above this PR's own
sentence saying the roster now holds 181 rows. The annotation asserted the
opposite of the declaration's state.

THAT IS WORSE THAN ORDINARY STALE PROSE HERE. This roster is the disposition
record of a merge-blocking wall, and the argument the block makes -- that a row
retires by its trigger and not by the convenience of a green wall -- turns
entirely on a reader being able to tell which sentence describes which row. Two
sentences describing opposite states of the same declaration destroys that.

Deleted: the duplicated four-line RETIRED paragraph and the orphan sentence
("The old sentence predicted CONSUMED for a two-member result...") which
describes a sentence no longer in the block. Kept: "Lifecycle is derived by the
evaluator from the candidate set; no predicted STALE or CONSUMED outcome is
authored here" -- true of these rows, which author no predicted outcome -- and
everything from "THIS PR AUTHORS 181 ROWS" onward.

A SECOND DEFECT THE REVIEW DID NOT REACH, found by sweeping the rest of the
prose carried from main: TWO paragraphs both numbered THIRTY-SIXTH DISSOLUTION,
both recording the deletion of the same #11137 row -- main's, which cites the
floor run that reported it stale, and this branch's, which records why the
disposition was nearly the wrong one. Neither is droppable: one is the landed
record, the other is the reasoning that generalises. Resolved to ONE ordinal for
one event, main's paragraph keeping the number and this branch's continuing it
explicitly.

BOTH DEFECTS HAVE ONE CAUSE, AND IT IS MINE: resolving a conflict by taking a
side wholesale is a decision about content, not a neutral merge action, and I
treated it as the latter twice.

Verified by the acceptance test rather than by reading line numbers:
`diff <(git show origin/main:<path>) <path>` deletes exactly one line of main's
-- the empty `NAMESPACE_TRANSITION_ADMISSIONS = &[]` this PR replaces -- and
nothing else.

Annotation-only: no declaration, no mirror, no projection changes, so no regen is
implied.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013aZDLk2CxsCDznqn49Xhe8
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