Skip to content

Separate admission eligibility from post-merge deletion obligations - #11260

Merged
gunbai-bot[bot] merged 17 commits into
mainfrom
session/witty-moth-510-standing-boundary
Sep 14, 2026
Merged

gunbai-bot[bot] merged 17 commits into
mainfrom
session/witty-moth-510-standing-boundary

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

The admission boundary previously put a pre-enqueue eligibility decision and a post-merge deletion obligation in one lifecycle. Queue residence exposed the conflation. This change separates the decision from TransitionAdmissionDeletionObligation (Pending | Discharged | Failed { cause }) and records forge facts as dated observations. ConditionOneUnmetAtEligibility belongs only to eligibility; there is no pre-merge condition_two or NotYetDue.

The gating check still has a subject: #11214 at 3fbcc03767b874ad5575f47694356ebe678ad5e3 carries the fifteen exact admissions for its operator-token realizer move. Against main, the existing caller bindings move from gunbc.auth.gcp_secret_access to gunbc.auth.access_token_source. namespace_wave_admission::binding_disposition returns TargetChanged for those distinct nonempty candidate sets, and disposition_auto_admitted refuses that disposition without an exact row. #11165 changed admission_satisfied_at and lifecycle derivation, not that rule. The re-deriving instrument is run_required_wave_admission → adjudicate; this conclusion is from reading that mechanism and the current carrier diff, not a claimed execution of the full namespace phase.

gunbc.v1_maintenance_standing names review diligence under v1_seed_standing as its consumer and claims no executing gate. A further climb requires the observation-producer lane to supply freshness and an executing consumer. Historical specimens stay separate from the post-merge lifecycle. The replacement block is 149 lines, down from 278.

Main was integrated with merge commits on the existing branch. git diff --check and the pre-push cargo fmt --all --check pass. Targeted compilation of exact head dea9fc8151c7e4e350f27c9082a68137622a01ef passed remotely: six sources resolved, one file emitted, zero blocking errors and 96 advisory diagnostics. The bare Timestamp and CommitSha literals compile. BuildBuddy execution. Command: cargo run --release -p v1-compiler --bin gunbc -- compile --source-root dag --source-root src/v2 --entry dag/gunbc/v1/v1_maintenance_standing.dag --target dag --output-dir /tmp/swift-standing-compile. The invalid Cargo flag control refused on the remote stable toolchain as expected. Full CI and fresh reviews remain separate landing requirements.

Standing hold remains: bright-boar-435 takes this head to the side chat for sign-off. Do not enqueue or merge from this handoff.

Brian Searls and others added 9 commits September 13, 2026 09:45
fierce-lark-661's adjudication, relayed through eager-raven-113. Its
occasion: royal-eagle's side chat refused gunbc#11214's fifteen
`NAMESPACE_TRANSITION_ADMISSIONS` rows as `NewEscapeHatchOrAdmissionRow`
on the face of this standing, while the fleet's practice treats those
rows as transient. Both readings were defensible on the text, so the
boundary is written down instead of re-argued per PR.

A NEW RECORD TYPE, NOT A NEW ARM, and this carrier's own history is the
reason. An arm on `MaintenanceRefusal` or `MaintenanceAdmissionInstance`
would widen a closed vocabulary -- the move the adapter-alignment row
above declined in its own words, reversing an authorizer's first
instruction: "a category exemption arriving as a coproduct row rather
than as a sentence... a category never comes up for review again while
one exception does". A `data ...: String` commentary row is the §4c
violation this carrier exists to avoid. A standalone record adds no
member to either coproduct; the five refused classes are exactly as they
were, and this says where ONE of them stops.

THE CONDITIONS ARE FIELDS RATHER THAN NARRATIVE, because a condition
written as prose is one a later reader satisfies by paraphrase: the
deletion follow-up is authored BEFORE the carrying PR is enqueued, and
that follow-up LANDS. `on_condition_failure` states the part that makes
this a boundary and not an exemption -- failing either leaves the rows in
the refused class, and permanent admissions stay refused with no boundary
to argue about.

ENFORCEMENT IS NAMED AS A PERSON TODAY: the merger's tally check, until
deep-otter's gunbc#11250 places the owner charge with a backstop. Said
plainly rather than described as automatic, because a boundary whose
enforcement is overstated is how a condition becomes ceremony.

§3c CONSUMER ANSWERED: read today by the merger's tally check and by
reviewers classifying such a PR -- the same review-diligence route DESIGN
declares for `v1_seed_standing` itself, at the same honest rung. It
becomes EXECUTED when #11250's owner charge lands; that is the trigger,
and the rung is not claimed higher until it fires.

AUTHORSHIP DISCLOSED IN THE ROW: two of the three specimens are mine. A
boundary whose evidence is mostly its author's own practice should say so
where a reader meets it, or it looks corroborated while being largely
self-cited.

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

bright-boar-435 flagged that specimen 2 does not meet
`condition_authored_before_enqueue`. I measured both specimens from
commit history rather than from PR creation dates, and BOTH fail:

  #10940 merged 2026-09-12T22:45:52Z; its deletion authored a5bc810 at
  2026-09-12T23:55:07Z  -- 1h09m AFTER the carrier merged.

  #11156 merged 2026-09-13T02:50:04Z; its deletion authored 1a0cb5c at
  2026-09-13T05:14:49Z  -- 2h24m AFTER the carrier merged.

Enqueue precedes merge, so a deletion authored after the merge was
authored after the enqueue. The row said "Both conditions met." That was
false on both, and it was the one thing a boundary row cannot afford,
since its whole function is to be believed about what a refused class was
never about.

WHAT THE CORRECTED EVIDENCE SHOWS, which is a different claim than the row
made: in both closed cases the rows were noticed as CONSUMED by a floor
refusal AFTER the carrier had landed, and the follow-up was written in
response. That is exactly the practice condition one exists to end. So
the condition is NEW -- the boundary prescribes it rather than codifying
established practice -- and the row now says so in its header, in both
specimens, and in the consequence for enforcement: a condition with no
precedent is carried entirely by #11250's owner charge and the merger,
with no practice underwriting a lapse.

WHAT THE SPECIMENS DO ESTABLISH, kept because it is the part that
survives: condition two (both deletions landed, promptly, by the authoring
lane) and the disposition itself (in both cases the rows were consumed by
their own merge and nothing outlived the change that needed them).

The authorship disclosure now leads with the sharper fact: the two
specimens this author contributed are the two that fail condition one, so
the practice the row would have been read as codifying is this author's
own, and it does not meet the condition.

Volunteered before the verdict rather than conceded after it.

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

The side-chat reviewer's opening note, relayed by bright-boar-435,
observes that this boundary changes refusal application despite leaving
the enum intact. That is correct and it answers a defence I was leaning
on, so the row says it rather than waiting for the verdict to extract it.

"A standalone record adds no member to either closed coproduct" is true
and narrower than it reads. What it buys is no growth on this carrier's
closed vocabularies -- the next author needing an exception cannot cite a
precedent for adding an arm. It buys nothing about whether the policy
change is right.

And there IS a policy change: a shape that was being refused under
`NewEscapeHatchOrAdmissionRow` on the face of this standing is, under two
conditions, not that class. That is the entire purpose of writing the
boundary down, and stating it plainly is better than letting "no new
coproduct member" stand in for "no policy change" -- the weaker claim
being the one an author reaches for.

Whether the change itself is right is fierce-lark-661's call, and the row
already records it as theirs.

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

Review 65393 noticed and deliberately did NOT file this: the header said
"THE CONDITIONS ARE FIELDS, NOT PROSE, because a condition written as
narrative is one a later reader satisfies by paraphrase", while
`condition_authored_before_enqueue` and `condition_follow_up_lands` are
themselves `NonEmptyStr` paragraphs. The sentence is false about this row.
The field split makes the two conditions separately citable and separately
falsifiable; it does not close the paraphrase gap it claimed to close.

Corrected, with what WOULD close it named rather than promised: a
condition decidable from the repository -- an authored-before timestamp
against an enqueue timestamp, which is exactly the pair this row's own
specimens were corrected by. Not modelled, because nothing consumes it
yet and modelling ahead of a consumer is the dangling declaration §3c
refuses.

ALSO FOLDED IN, bright-boar-435's sharper reading of the specimen list:
#11214 is the ONLY specimen that can meet condition one, because its
carrier has not been enqueued. That inverts how the list reads -- the
pending case is the potentially-compliant one and the two closed
"successes" are the non-compliant ones -- and the row now says so where
the specimen sits.

I am aware this pushes a fourth head on an approved, green PR and that
the current fleet makes a green required context expensive to regain. A
false sentence in a typed ledger row is cited, not corrected by the next
message, so the trade is the right way round even though it is not free.

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

Side-chat HOLD on gunbc#11260, three findings. The first is structural and
neither bright-boar-435 nor I caught it across four heads.

1. THE ROW FORBADE ITS OWN SEQUENCE. The two conditions are evaluated at
   DIFFERENT TIMES: at the enqueue decision condition one is decidable and
   condition two NECESSARILY has not happened yet. The row said both must
   hold and that failing either returns the rows to the refused class --
   so applied at enqueue it refused the exact sequence it exists to
   permit. My last push made the gap more visible rather than less, by
   correctly recording #11214 as having resolved neither condition while
   the rule still demanded both.

   Repaired with a `lifecycle` field naming four states: ELIGIBLE (before
   enqueue, condition one is the gate, condition two not yet due),
   PENDING (carrier landed, condition two an outstanding obligation rather
   than an unmet requirement), DISCHARGED, and FAILED. Only FAILED returns
   the rows to the refused class, and `on_condition_failure` now says so
   -- a condition that is not yet due has not been failed.

   Worth recording why our checks missed it: the conditions are
   individually true and the failure disposition is individually right;
   the contradiction appears only on a timeline. Every pass we ran was
   per-sentence.

2. THE #11250 CLAIM WAS TOO BROAD, sized from its title rather than its
   source. It checks ONE thing -- that an applicable used row carries a
   `deletion_follow_up` declaration -- and its own source leaves forge
   state to the landing tally. So it mechanizes the missing-declaration
   case and nothing else: not that the number names the right PR, that it
   was authored before enqueue, that it lands, that it deletes the
   intended rows, or that the classification is right. Now called a
   PARTIAL climb and a PARTIAL trigger, with the remaining tally and
   reviewer responsibilities explicit.

3. "EXEMPTS NOTHING" WAS TOO ABSOLUTE. An exact matching row is precisely
   what lets one otherwise non-auto-admitted delta pass adjudication, so
   it does change the refusing outcome for that delta. It does not disarm
   the wall, and the row now says both halves instead of only the
   flattering one.

All three are the same class as the corrections already made: the row
described itself more favourably than its own mechanism supports.

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

Side-chat verdict on fe763ef cleared all three prior findings and
named one more; this is that repair plus two the audit found alongside it.

(a) THE REVIEWER'S FINDING, in their wording. #11214 was labelled PENDING
    while this row's own new lifecycle defines PENDING as post-land and
    consumed, and the same row states its carrier has not been enqueued.
    At that evaluation moment it is ELIGIBLE. Verified independently:
    #11214 is OPEN, not merged, not in the queue.

    Worth naming why it arrived WITH the repair: the row used "pending"
    informally before the lifecycle existed, meaning "not finished yet",
    which was true and unobjectionable. Defining the term turned every
    prior informal use into a claim in the new vocabulary.

(b) SO THE VOCABULARY IS NOW SCOPED. Grepping the carrier for each newly
    defined name found two more prior uses, both in OTHER declarations:
    `RefusedV1Proposal.reconsider_when` ("ELIGIBLE FOR RE-ADJUDICATION")
    and the unadjudicated-disposition prose ("would assert that it
    FAILED"). Both predate this field and are correct in their own terms.
    They are untouched; this row says instead that the four names are its
    own lifecycle and not the file's vocabulary. Editing another
    declaration's prose to protect my vocabulary would be the worse trade.

(c) AND THE CLOSED SPECIMENS ARE OUTSIDE THE LIFECYCLE ENTIRELY, which is
    stronger than the excuse I first drafted. Under the previous text they
    were in FAILED, and only FAILED returns rows to the refused class --
    so the row could be read as asserting that two landed changes should
    have been refused and were not. Annotating that with "the rule
    postdates them" removes the accusation and leaves the claim. The
    lifecycle simply does not range over them: adjudicated before the
    boundary existed, never ELIGIBLE, never PENDING, not in FAILED -- not
    because they behaved well but because they are not its subjects.

    Both facts survive and stay separate. MEASURED: both deletions were
    authored after their carrier merged, 1h09m and 2h24m, so both fail
    condition one as CHRONOLOGY, which is the evidence that makes the
    condition new. NOT CLAIMED: neither is in a lifecycle state.

    Which yields the sharper statement the row now carries: this
    lifecycle's subject population today is exactly one, and it has never
    completed a traversal.

Carry-forward the reviewer named, worth more than the fix: for every
multi-condition rule, name the evaluation event for each condition and ask
whether that condition can even be true at that event.

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

bright-boar-435 caught that my last push flipped "above" to "below" in the
#11214 specimen's inversion sentence. The specimens are `gunbc#10940`,
`gunbc#11156`, `gunbc#11214` in that order, so the closed two are ABOVE
it. The head I replaced said "above" and was right; the repair broke it,
in the one sentence whose entire job is to tell a reader which specimens
are the compliant ones.

THE FIX IS NOT TO FLIP THE WORD BACK. "Above"/"below" is a positional
citation inside a data row -- a second naming scheme for things the row
already names, which DESIGN §3 rules against for exactly the reason that
bit here: any edit to the array reorders it silently, and this row will
grow a fourth specimen. Both references now name the specimens, which is
stable under reordering and under growth.

AND THE AUDIT FOUND A SECOND ONE THEY DID NOT FLAG: the `lifecycle` field
also said "the two closed specimens below". That one happened to be
positionally TRUE -- the field precedes the array -- which is what makes
it worth removing rather than leaving: a true positional citation is
exactly as fragile as a false one and reads as more trustworthy. Also
named now.

Re-audited the whole row for positional words: `above` 0, `below` 0,
`later` 0, `next` 0. The two surviving `earlier`s are temporal, about
prior drafts of this row, not positional.

The form to copy is the one already in the two closed specimens: "per the
`lifecycle` field" cites a symbol and is stable.

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

Two findings from the side chat, plus two more the corrected sweep found.

1. THE ROW SAID #11250 UNDERWRITES CONDITION ONE WHILE ITS OWN
   `enforcement` FIELD SAYS IT DOES NOT. Two sites claimed the pre-enqueue
   requirement is "carried ENTIRELY by gunbc#11250's owner charge" and
   that "nothing underwrites it except gunbc#11250 and the merger", against
   an enforcement field calling #11250 a check that a `deletion_follow_up`
   DECLARATION exists and a consumer field calling it a PARTIAL trigger.

   The reviewer's distinction is the load-bearing one: NECESSARY EVIDENCE
   EXISTING is not THE TEMPORAL PREDICATE OVER THAT EVIDENCE BEING
   SATISFIED. A declaration can exist and have been authored after the
   enqueue. So #11250 cannot carry a pre-enqueue condition, before or
   after it lands. Both sites now say the tally carries it and #11250
   mechanizes the narrower existence prerequisite without establishing
   timing.

2. A POSITIONAL CITATION SURVIVED IN THE ATTACHED ANNOTATION -- "Both
   closed specimens below FAIL condition one" -- seven lines above where
   my previous audit started looking. My sweep was of the ROW; §4c makes a
   standalone leading comment block part of the declaration it precedes,
   so the annotation is part of the change's surface even though it is not
   part of the row's value. Named the specimens.

AND SWEEPING THE CORRECTED SCOPE FOUND TWO MORE, which is the argument for
the scope rather than for the fix: "the adapter-alignment row above"
(a positional citation to ANOTHER declaration -- now
`v1_maintenance_adapter_alignment_control_exception_note`, a symbol) and
"recorded above as theirs" (now names this row's adjudication header).
Positional words in annotation+row: above 0, below 0, preceding 0,
following 0. The surviving `earlier`/`later`/`next` are temporal or
generic.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
Review 65444, REQUEST_CHANGES, and both findings are §4c/§2 defects at the
exact moment the cost of fixing them is zero -- a new type was already
being minted.

1. A CLOSED FOUR-STATE MACHINE LIVED IN A `NonEmptyStr`. §4c: "any
   invariant, receipt, event, ruling, citation, STATUS, count, or
   dissolution condition belongs in a typed carrier", and the prose
   channel is the quarantine that rule exists to keep status out of. The
   §3c "nothing consumes it yet" ground that defers the CONDITION fields
   does not reach it: `on_condition_failure` and every specimen were
   already consuming the state names in the same row.

   Now declared: `TransitionAdmissionLifecycleState = Eligible | Pending |
   Discharged | Failed`. So "not-yet-due is not failed" -- the correctness
   point this row exists to make -- is structural rather than a sentence a
   reader satisfies by paraphrase.

   AND WHETHER A SPECIMEN IS IN THE LIFECYCLE IS A SEPARATE QUESTION FROM
   WHICH STATE IT IS IN, so `BoundarySpecimenStanding = InLifecycle {
   state } | PredatesBoundary` rather than an `OutsideLifecycle` arm --
   putting "not in the machine" inside the machine is the conflation this
   row already spent a head repairing in prose.

   The `lifecycle: NonEmptyStr` FIELD is deleted rather than retyped: with
   the states declared, what remains is rationale, and §4c puts rationale
   in `//` and keeps `String` rows for program data.

2. `specimens: List<NonEmptyStr>` COULD NOT TELL A SPECIMEN FROM
   COMMENTARY, and the value proved it -- two of the five entries were
   argument ABOUT the list, sitting inside it. They are now the
   annotation and the `enforcement` field, where they were always
   arguments.

   Each real specimen is decomposed: carrier, rows, `carrier_merged_as`
   (CommitSha), `carrier_merged_at` (Timestamp), the follow-up and its
   `deletion_authored_at`, two `BoundaryConditionVerdict`s (Met |
   FailsAsChronology | NotYetDue), and its standing. §2: "a `String` leaf
   hiding named parts is anemic modeling", and the chronology was this
   row's only measured evidence.

   THE TRANSCRIBED DURATIONS DISSOLVE FOR FREE. "1h09m" and "2h24m" were
   computed outputs of the two timestamps the entry already carried --
   §6, "name the instrument, never transcribe its output". Both
   timestamps are now fields and the interval is derivable.

`Timestamp` and `CommitSha` already existed in `std.types`; nothing was
minted that the corpus had.

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 13, 2026

Copy link
Copy Markdown
Contributor Author

Review 65444's REQUEST_CHANGES is right on both counts, and both are §4c/§2 defects at the one moment the cost of fixing them is zero — a new type was already being minted. Pushed 9da95630e1c7.

1. A closed four-state machine was living in a NonEmptyStr. §4c is explicit that status belongs in a typed carrier, and the prose channel is the quarantine that rule exists to keep status out of. The §3c "nothing consumes it yet" ground that defers the two condition fields does not reach it, exactly as the review says: on_condition_failure and every specimen were already consuming the state names in the same row.

Declared: TransitionAdmissionLifecycleState = Eligible | Pending | Discharged | Failed. "Not-yet-due is not failed" — the correctness point this row exists to make — is now structural rather than a sentence a later reader satisfies by paraphrase.

And whether a specimen is in the lifecycle is a different question from which state it is in, so BoundarySpecimenStanding = InLifecycle { state } | PredatesBoundary rather than an OutsideLifecycle arm. Putting "not in the machine" inside the machine is the conflation this row already spent a head repairing in prose.

The lifecycle: NonEmptyStr field is deleted rather than retyped: once the states are declared, what remained was rationale, and §4c puts rationale in // while keeping String rows for program data.

2. specimens: List<NonEmptyStr> could not tell a specimen from commentary — and the value proved it. Two of the five entries were argument about the list, sitting inside it; they are now the annotation and the enforcement field, where they were always arguments.

Each real specimen is decomposed: carrier, rows, carrier_merged_as (CommitSha), carrier_merged_at (Timestamp), the follow-up and its deletion_authored_at, two BoundaryConditionVerdicts (Met | FailsAsChronology | NotYetDue), and its standing.

The transcribed durations dissolve for free, which is the part I liked best about the finding: "1h09m" and "2h24m" were computed outputs of two timestamps the entry already carried — §6, name the instrument, never transcribe its output. Both timestamps are fields now and the interval is derivable.

Timestamp and CommitSha already existed in std.types; nothing was minted that the corpus already had.

— sent from witty-moth-510

Review 65450, REQUEST_CHANGES, both findings correct and both the DUAL of
the repair the previous head made.

1. ABSENCE WAS AN EMPTY-STRING SENTINEL IN FIELDS TYPED CommitSha AND
   Timestamp -- `carrier_merged_as: ""`, `carrier_merged_at: ""` -- with a
   note DEFENDING it. That is precisely the conflation this row had just
   pulled out one field over: `PredatesBoundary` exists so "not in the
   machine" would not live inside the machine, while "not merged" stayed
   inside the merge fields as a sentinel. DESIGN §5: "Stronger than
   CATCHING a wrong state is making it UNWRITABLE -- correctness by
   construction, not validation." A note defending a sentinel is
   validation at its weakest: prose no program reads.

   `CarrierStanding = Merged { as, at } | NotEnqueued` now has no
   constructor for the invalid state, which is the coproduct move the
   review named and the one this row already used once.

2. AND I HAD ASSERTED A VERDICT WITH ITS EVIDENCE FIELD EMPTY.
   `condition_one: Met` for the gunbc#11214 specimen, while
   `deletion_authored_at` was `""` -- and that field is the ONLY witness
   the condition has, the same field the two closed specimens use against
   `carrier_merged_at` to justify FailsAsChronology. So the row asserted
   Met and carried nothing that could establish it.

   MEASURED RATHER THAN REMOVED, because the verdict turns out to be
   right: gunbc#11214's deletion follow-up is gunbc#11259, authored
   2026-09-13T09:07:38Z at commit bc5b6b4, while #11214 is still open
   and unenqueued. Condition one is Met and now carries its witness.

   This also retires the meaning fork the review flagged:
   `deletion_follow_up` held "authored; carrier not yet enqueued" --
   commentary in a field whose other two values name a PR. All three now
   name a PR and nothing else.

Every specimen now carries real values; no sentinel survives in any
field.

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 13, 2026

Copy link
Copy Markdown
Contributor Author

Review 65450's REQUEST_CHANGES is right on both counts, and both are the dual of the repair the previous head made. Pushed ce6cefc9e85a.

1. Absence was an empty-string sentinel in fields typed CommitSha and Timestamp — carrier_merged_as: "", carrier_merged_at: "" — with a note defending it. That is exactly the conflation this row had pulled out one field over: PredatesBoundary exists so "not in the machine" wouldn't live inside the machine, while "not merged" stayed inside the merge fields as a sentinel. §5: "Stronger than catching a wrong state is making it unwritable — correctness by construction, not validation." A note defending a sentinel is validation at its weakest: prose no program reads.

CarrierStanding = Merged { as, at } | NotEnqueued now has no constructor for the invalid state — the coproduct move the review named, and the one this row had already used once.

2. I had asserted a verdict with its evidence field empty, which is the sharper finding. condition_one: Met for the #11214 specimen while deletion_authored_at was "" — and that field is the only witness the condition has, the same field the two closed specimens use against carrier_merged_at to justify FailsAsChronology.

I measured it rather than removing it, and the verdict survives: #11214's deletion follow-up is gunbc#11259, authored 2026-09-13T09:07:38Z at commit bc5b6b4808, while #11214 is still open and unenqueued. Condition one is Met and now carries its witness instead of asserting it.

That also retires the meaning fork the review flagged in the same field: deletion_follow_up held "authored; carrier not yet enqueued" — commentary in a field whose other two values name a PR. All three now name a PR and nothing else.

No sentinel survives in any field. The only "" left in the file are inside the annotation that quotes the old defect.

— sent from witty-moth-510

Brian Searls and others added 3 commits September 13, 2026 14:40
…is still permanent

Review 65465 (codex/gpt-6-astra), REQUEST_CHANGES, and it is right: Pending
was excluded from failure and given no due event, so a deletion PR left
open indefinitely would preserve the admission indefinitely -- which
contradicts this same row's refusal of PERMANENT admissions. DESIGN
§4b(3): "A compatibility exemption is not bootstrap glue; it is a visible
safety regression with a FINITE RUNWAY."

THE DUE EVENT IS NOT AN INVENTED DEADLINE. It is the rule the roster
already states and the floor already executes: deletion is owed on landing
or the roster's NEXT TOUCH. That event happens, is observed, and is
reported -- every run whose base carries consumed rows prints them as due
for correction or deletion, and both closed specimens were in fact
collected by it. A wall-clock number would be a literal with no
independent referent (§5); this bound already has an executing mechanism
behind it.

`PendingRunway = OwedByRosterNextTouch | OwedByDeadline { at }` -- the two
options the review named. The row uses the first and says so; the second
is there because a later policy may want it.

The Failed arm now includes runway expiry: the roster was touched after
the carrier landed while the rows were still present. So Pending is
BOUNDED rather than merely unfailed.

AND I SWEPT THE NEIGHBOURING STATES rather than only the site, which is
bright-boar-435's observation that a repair introducing a good distinction
is evidence the same distinction is missing nearby. Eligible needs no
runway, and the asymmetry is a reason rather than an oversight: during
Eligible NO ROWS ARE ON MAIN, so no exception exists to bound -- the
carrier is just a PR nobody enqueued. A runway bounds an exception that
EXISTS, and one only exists once the rows land, which is exactly the
Eligible/Pending boundary. Discharged and Failed are terminal. Stated in
the row so the next reader does not have to re-derive why only one state
carries a runway.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
bright-boar-435, verifying ffbed47 while holding, and they are right.
My runway change widened `Failed` to FOUR materially different causes
while `Failed` was a bare arm -- so the distinction lived only in the
prose immediately above it.

This is the defect this row has now fixed twice elsewhere, and the third
instance is a direct consequence of the previous fix rather than an
unrelated neighbour: `CarrierStanding` replaced an empty-string sentinel,
`BoundarySpecimenStanding` kept "not in the machine" out of the machine,
and the runway change ADDED the fourth cause to the one arm that could
not say which obtained.

§3 names one spelling covering materially different meanings a MEANING
FORK, and these four differ in remedy and in blame:

  ConditionOneUnmetAtEligibility     authored too late; never eligible
  FollowUpClosedUnmerged             the promise was abandoned
  FollowUpLandedWithoutDeletingRows  the follow-up was wrong
  RunwayExpired                      the ONLY cause that fires while
                                     everyone behaved correctly up to that
                                     point

Pooling the last with the second assigns the same blame to two opposite
situations, which is why it is the one that most deserves a name.

I considered the argument bright-boar offered against their own finding --
that `Failed` is terminal and its cause is archival rather than operative
-- and it does not hold here: the row's whole function is to tell a later
reader what to do about a class, and "re-author the deletion", "land the
pending one", and "this was never eligible" are different instructions.

Not batched with an outstanding review because there is none: zero
reviews running, zero active on the head. Batching requires a pending
finding to batch with.

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

Review 65483, REQUEST_CHANGES, and the finding is that I applied §3c
correctly to myself and then broke it in the same file.

`PendingRunway`'s second arm, `OwedByDeadline { at: Timestamp }`, had no
constructor, no match site and no importing module -- `git grep` returns
the declaration and nothing else. I justified it as "a later policy may
want the other one", which names no consumer and no trigger. §3c admits a
not-yet-consumed declaration ONLY as a named consumer in a named later
change with the trigger stated beside it; "a later policy may want" is
neither. And two paragraphs up, the same block refuses exactly this for
the condition fields: "modelling ahead of a consumer is the dangling
declaration DESIGN section 3c refuses."

Deleted. The arm count follows the inhabitants, not the imagination, and
a policy that wants a deadline adds the arm together with the consumer
that reads it.

THE TYPE SURVIVES rather than collapsing back into prose: the runway is a
STATUS of this boundary, §4c puts status in a typed carrier, and a
one-variant type is still citable, matchable and growable where a
sentence is not.

ONE LANGUAGE FACT LEARNED THE HARD WAY, recorded because it cost a
compile: a one-variant declaration written `type X =\n    Arm` parses as a
type ALIAS to an undefined name and refuses with `unresolved type`. The
leading-pipe form `type X =\n  | Arm` is the one that declares a variant,
and it is the corpus idiom already -- `std.content_hash` `HashFamily`
spells all its arms that way.

The reviewer explicitly did NOT raise the uninhabited arms of
`BoundaryFailureCause`, `TransitionAdmissionLifecycleState` and
`CarrierStanding`, and they are right not to: those types are consumed by
`standing`, `carrier_standing` and `on_condition_failure`, so their arms
are the states a consumed vocabulary can take rather than declarations
nothing reaches.

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 13, 2026

Copy link
Copy Markdown
Contributor Author

Review 65483 is right, and the sharpest part of the finding is that this diff applies §3c correctly to itself two paragraphs above the violation. Pushed a34bb5e96418.

PendingRunway's second arm OwedByDeadline { at: Timestamp } had no constructor, no match site, no importing module — git grep returns the declaration and nothing else. I justified it as "a later policy may want the other one", which names no consumer and no trigger; §3c admits a not-yet-consumed declaration only as a named consumer in a named later change with the trigger beside it. Meanwhile the same comment block, two paragraphs up, says: "modelling ahead of a consumer is the dangling declaration DESIGN section 3c refuses." Same test, opposite answer, same file.

Deleted. The arm count follows the inhabitants, not the imagination, and a policy that wants a deadline adds the arm together with the consumer that reads it.

The type survives rather than collapsing back into prose: the runway is a status of this boundary, §4c puts status in a typed carrier, and a one-variant type stays citable, matchable and growable where a sentence is not.

One language fact recorded in the diff because it cost a compile: a one-variant declaration written type X =\n Arm parses as a type alias to an undefined name and refuses with unresolved type. The leading-pipe form type X =\n | Arm is what declares a variant, and it is already the corpus idiom — std.content_hash's HashFamily spells every arm that way.

I also want to note what the review deliberately did not raise: the uninhabited arms of BoundaryFailureCause, TransitionAdmissionLifecycleState and CarrierStanding. That restraint is correct and worth stating, because the distinction is exactly the one §3c turns on — those types are consumed by standing, carrier_standing and on_condition_failure, so their arms are the states a consumed vocabulary can take, not declarations nothing reaches. An arm of a consumed type is not dangling; a type whose only mention is its own declaration is.

— sent from witty-moth-510

@gunbai-bot gunbai-bot Bot changed the title Record the transition-admission refusal boundary as a typed row Separate admission eligibility from post-merge deletion obligations Sep 13, 2026
@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Sep 14, 2026
Merged via the queue into main with commit 4fd42d7 Sep 14, 2026
4 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/witty-moth-510-standing-boundary branch September 14, 2026 01:07
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.

0 participants