Skip to content

Repair main: a stranded import and a body-scope annotation, both admitted by the hollow floor - #11945

Closed
gunbai-bot[bot] wants to merge 4 commits into
mainfrom
repair/main-parse-11902
Closed

gunbai-bot[bot] wants to merge 4 commits into
mainfrom
repair/main-parse-11902

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

main does not resolve. Two defects landed tonight, each with four green checks. I merged one of the two PRs, so this is my breakage to repair.

1. A stranded import across two PRs

#11845 deleted gunbc.runner_host_file_converge classify_host_file_presence — correctly, because test -e exit 1 is stat(path) == 0 failing, so EACCES on an ancestor, ELOOP, ENOTDIR and EIO all answered "absent" with empty stderr.

#11902 imports and calls that symbol. Neither PR could see the other: each was green against a base that did not yet carry the other's change. That is the cross-PR stranding no single-diff review catches.

Repaired by consuming the landed replacement, not restoring the deleted function — the stat metadata read decides presence, and when it failed, a parent listing decides whether nothing is there or nobody could look. The module's own parent-listing idiom is reused, and the Optional protocol is preserved so the call site is unchanged.

2. A body-scope annotation

#11902 left a // block indented inside a declaration body; DESIGN §4c models module-item grain only. Seven parse FAILs. Hoisted above the declaration it describes, losing none of its reasoning.

Why neither was caught — worth more than the repair

The floor check reports SUCCESS while its own log says phases_run=2 phases_failed=2, and the run refuses with ArmSetConsumerPlanningUnavailable having selected no witness at all. That is witnesses.yml:67 downgrading structural to none because claim_executor exits 0 over its own typed refusal.

So the hollow gate did not merely hide these — it admitted them, exactly as it admitted #11731's unparseable file. The parse class that reached a zero census today was reopened within hours by two PRs that CI called green.

One note for anyone reading that job log: every class= line in it is echoed step script, so grepping the log for a class is not a reading. The one real line is the required-ci: summary.

Evidence, at its real level

The corpus resolves and typechecks clean with both repairs — the run reaches evaluation and fails only on a deliberately fake entry function. Witness execution is not available from this container, so please read the floor on this head rather than my typecheck — with the caveat above that a green floor is currently not evidence.

🤖 Generated with Claude Code

briansrls and others added 2 commits September 21, 2026 06:01
…en by the floor

MAIN DOES NOT RESOLVE, and both defects landed tonight with four green checks
each. I merged one of the two PRs, so this is my breakage to repair.

1. STRANDED IMPORT ACROSS TWO PRs. #11845 deleted
   gunbc.runner_host_file_converge classify_host_file_presence -- correctly,
   because `test -e` exit 1 is stat(path) == 0 failing, so EACCES on an
   ancestor, ELOOP, ENOTDIR and EIO all answered "absent" with empty stderr.
   #11902 imports AND CALLS that symbol. Neither PR could see the other: each
   was green against a base that did not yet carry the other's change, which
   is the cross-PR stranding no single diff review can catch.

   Repaired by consuming the landed replacement rather than restoring the
   deleted function: the stat metadata read decides presence, and when it
   FAILED, a parent listing decides whether nothing is there or nobody could
   look. The module's own parent-listing idiom is reused, and the Optional
   protocol is preserved so the call site is unchanged -- Present is a settled
   standing, Absent means "go compare content".

2. BODY-SCOPE ANNOTATION. #11902 left a // block indented inside a declaration
   body; DESIGN 4c models module-item grain only. Seven parse FAILs. Hoisted
   above the declaration it describes, losing none of its reasoning.

WHY NEITHER WAS CAUGHT, which is the finding worth more than the repair. The
floor check reports SUCCESS while its own log says phases_run=2
phases_failed=2 and the run refuses with ArmSetConsumerPlanningUnavailable
having selected NO witness. That is witnesses.yml:67 downgrading structural to
none because claim_executor exits 0 over its own refusal. So the hollow gate
did not merely hide these -- it ADMITTED them, exactly as it admitted #11731's
unparseable file. The parse class I watched go to a zero census today was
reopened within hours by two PRs that CI called green.

Note for anyone reading that log: every class= line in it is echoed step
script, so grepping the job log for a class is not a reading. The one real
line is the required-ci summary.

EVIDENCE: the corpus resolves and typechecks clean with both repairs -- the
run reaches evaluation and fails only on a deliberately fake entry function.
Witness execution is not available from this container.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ng them

The finding is correct and the sharpest evidence is in my own commit message:
it claimed the repair "consumes the landed replacement rather than restoring
the deleted function", and it did not. It hand-wrote the metadata-unread ->
parent -> standing decision that classify_host_file_path and
runner_host_file_settled_standing already own, down to the VERBATIM message
text "the containing directory holds this entry and ". Copied prose is the
fork made visible (DESIGN 3; 2's "net concepts must not grow by re-invention").

The reviewer's separation is the right one: only the EntryPresence PRODUCER is
transport-bound. The classification is pure and transport-agnostic. So this
function now produces ONLY the EntryPresence over the elevated leg and hands it
to the landed classifiers; the Optional protocol and the call site are
unchanged.

THE REMAINING DIFFERENCE IS NOW STATED RATHER THAN HIDDEN, and the review was
right that the copy had already drifted: member_observe entry_presence
escalates an indeterminate parent by walking ancestors, and this producer reads
ONE level. That is a weaker reading, never a wrong one -- an unreadable parent
yields EntryPresenceIndeterminate, which classify_host_file_path maps to
HostFilePathUnreadable and never to absence, so the false-absence class the
deletion closed stays closed. Consuming the escalation needs an ObservationArm
over the elevated leg, which this module has no carrier for; the annotation
names that carrier as what would end the difference.

EVIDENCE: resolves and typechecks clean; the copied message text is gone from
the module. Witness execution is not available from this container.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

Review 69503's finding accepted and fixed in 23fd0c9424. The sharpest evidence is my own commit message, which claimed the repair "consumes the landed replacement rather than restoring the deleted function" — and it didn't. It hand-wrote the metadata-unread → parent → standing decision that classify_host_file_path and runner_host_file_settled_standing already own, down to the verbatim message text "the containing directory holds this entry and ". Copied prose is the fork made visible, and I wrote a §3 justification over a §3 violation.

Your separation is the right one and it is what I missed: only the EntryPresence producer is transport-bound; the classification is pure. So the function now produces only the EntryPresence over the elevated leg and hands it to the landed classifiers. The Optional protocol and the call site are unchanged, and the copied text is gone from the module.

You were also right that the copy had already drifted, which is the part I want on the record because it is the argument for the rule rather than an appeal to it: entry_presence escalates an indeterminate parent by walking ancestors, and my copy read one level. A fork one hour old had already lost a behaviour.

That difference now survives in the producer, and is stated rather than hidden: this producer reads one level, which is a weaker reading and never a wrong one — an unreadable parent yields EntryPresenceIndeterminate, which classify_host_file_path maps to HostFilePathUnreadable and never to absence, so the false-absence class the deletion closed stays closed. Consuming the escalation needs an ObservationArm over the elevated leg, which this module has no carrier for; the annotation names that carrier as what would end the difference.

Standing caveat unchanged, and it is why this PR exists: resolves and typechecks clean, but witness execution is not available from this container — and on this repo right now a green floor is not evidence either. The floor reports SUCCESS over phases_failed=2 having selected zero witnesses, which is precisely what admitted the two defects this PR repairs.

— sent from sunny-ant-606

Correct, and it is the SAME fork one layer over: the previous commit routed the
CLASSIFICATION to the landed authority and then re-minted the ARGV inline, in a
call to the very module that owns it. gunbc.runner_host_file_converge already
declares runner_host_file_metadata_probe_argv, consumed by its own probe and
PINNED BY A WITNESS -- so two sources answered "what argv reads this file's
type", and a change to the probe would have desynchronized this elevated leg
from the witnessed one silently.

Consuming it also deletes both extdeps imports the inline expression forced, so
the repair is subtractive: one import line replaces two.

The pattern across three reviews on this PR is worth stating plainly, because
it is the finding and not the diff. Each fix consumed one authority and left
the next one beside it un-consumed: first the standing classification, then the
parent-presence rule, now the probe argv. Routing one fact to its home does not
establish that the neighbouring facts are routed; each is its own claim.

EVIDENCE: resolves and typechecks clean. Witness execution is not available
from this container.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

Review 69508 accepted and fixed in 5f3059fd31. Correct, and it is the same fork one layer over: the previous commit routed the classification to the landed authority and then re-minted the argv inline — in a call to the very module that owns it. runner_host_file_metadata_probe_argv is declared there, consumed by its own probe, and pinned by a witness, so two sources answered "what argv reads this file's type" and a change to the probe would have desynchronized this elevated leg from the witnessed one silently.

Consuming it is subtractive: one import line replaces two, since both extdeps.* imports existed only to support the inline expression.

The pattern across the three reviews on this PR is the finding, more than any of the diffs. Each fix consumed one authority and left the next one sitting beside it un-consumed — first the standing classification, then the parent-presence rule, now the probe argv. Routing one fact to its home does not establish that the neighbouring facts are routed; each is its own claim, and I treated the first repair as if it had settled the class. Three reviewers found three layers of one habit.

It is also the same shape as the defect this PR exists to repair, which is what makes it worth recording rather than just fixing: a fact with a home, answered somewhere else, where nothing executing would notice the divergence.

Standing caveats unchanged: resolves and typechecks clean; witnesses have not run from this container, and a green floor on this repo is currently not evidence.

— sent from sunny-ant-606

@briansrls
briansrls added this pull request to the merge queue Sep 21, 2026
gunbai-bot Bot pushed a commit that referenced this pull request Sep 21, 2026
These were all PRE-EXISTING on main and invisible: the parse phase aborted
first, so the declarations phase never ran. #11945 took parse to zero FAILs and
1978 modules resolved, and the phase behind it reported six defects on its
first execution. An early abort makes "no diagnostic" and "no check" identical.

1. IMPORT-MEMBER-ABSENT. test.claim.jade_first_contact_model_witness imported
   Nat from std.types, which declares no such name; Nat is std.nat. Imported
   from its declaring module, as its two sibling witnesses already do.

2. LENS-AUTHORSHIP-ABSENT. v2.lens.reference_derived_residency_reading declared
   no construction_justification. Classified WallAfterGrounding rather than
   copying a sibling's row: both questions the lens answers are decidable off
   the producer's type declaration, so it is not outside the modeled guarantee;
   what is missing is the single authority that would make the qualification a
   PROJECTION of the declaration, at which point the lens has nothing to check.

3-6. CITED-DECLARATION-ABSENT x2 and CITATION-DEBT-ROW-STALE x2, which are ONE
   defect. #11625 moved both dispositions from gunbc.ci_floor_measurement to
   gunbc.host_memory_observation and left the PRE_EXISTING_CITATION_DEBT rows
   naming the old subject module: the old rows went stale (their subject no
   longer exists there) and the citations at the new home fell out of coverage.
   Re-pointed the rows' SUBJECT module; the roster does not grow.

   NOT repaired by making the citations resolve, which is the tempting and
   wrong move. The rows' own annotation records an earlier author making it and
   correcting it: v2.lens.disposition_redundancy counts a violation when a bind
   target is PRESENT, so an absent successor is the normal state of outstanding
   debt, and binding these to rows that exist would convert two pieces of honest
   debt into two false claims that it was paid.

7. DeclaredNotRostered. fabric_purpose_handover_registration_unobserved_stall
   was declared and absent from all_guarantee_stalls, so every wall over that
   roster ranged over one row fewer than it claims -- the exact class the
   roster's own annotation documents from the last time four went missing.

8. TWO TYPE ERRORS. field_at returned String while lines.skip(n).first()
   answers String?. Propagated the Optional rather than defaulting to "": an
   empty string is indistinguishable from a field that was present and blank,
   which is the widen DESIGN section 5 refuses. All five call sites already
   return Optionals and already length-guard, so absence stays answerable and
   nothing is fabricated.

EVIDENCE: resolves and typechecks clean. Witness execution is not available
from this container, so the declarations phase itself is owed against CI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Sep 21, 2026
@gunbai-bot

gunbai-bot Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

Closing as fully superseded — this branch's diff against main is now empty.

Both repairs landed independently while this sat in the queue:

  • the stranded classify_host_file_presence import, repaired on main with the same shape this PR used — runner_host_file_metadata_probe_argv + classify_host_file_metadata consumed rather than re-minted
  • the §4c body-scope annotation hoist

That is the right outcome, and the PR did its job before it was superseded. Its CI run is what took parse from failing to 0 FAILs / 1978 modules resolved, and that is what let the declarations phase execute for the first time and report six previously-invisible defects. Three lanes then converged on those within one window. The proof is in the run, not in this diff.

Recorded for whoever reads the history: the reason two lanes repaired the same file is that main did not resolve and the floor was reporting SUCCESS over it — phases_failed=2 with zero witnesses selected, because witnesses.yml:67 downgrades structural to none when claim_executor exits 0 over its own refusal. Duplicated repair effort is the cheap symptom of that; the expensive one was #11731 landing an unparseable file.

The remaining unfixed work is in #11953.

— sent from sunny-ant-606

@gunbai-bot gunbai-bot Bot closed this Sep 21, 2026
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