Skip to content

premerge: Phase 4 is gated on an unreachable predicate, so the simplify pass never runs on any stack that needs it #785

Open

Description

@TheFJK

The gap

Phase 4 runs only on STOP_GREEN. STOP_GREEN requires the latest review to return zero blockers. A critic asked "what is wrong with this?" samples from an unbounded set, so blockers == 0 is a property of the sample, never of the artifact — and on any stack big enough to need the loop, it is not a reachable state.

Measured on stack PR #768, four xhigh rounds:

Attempt Blockers Result
1 17 FIXED=17
2 11 FIXED=11
3 6 FIXED=6
4 7 budget spent → STOP_EXHAUSTED

Every round cleared 100% of the blockers it was given, and the next review found more. CI was green and the PR mergeable from attempt 1's repair onward. Phase 4 never became reachable, so the simplify pass — and the 4c VERIFY step, and everything downstream of the green gate — silently did not run.

SKILL.md names this as the pre-loop bug and claims the loop fixed it:

Before it, Phase 4 was gated on a single-shot gate that a surviving blocker or a red build left not-green — so on any stack that needed fixing at all, the simplify pass silently never happened and the run still reported success. The loop is what makes a green gate reachable.

It doesn't. It moves unreachability from one shot to N shots. #718 and #754 describe the same pump from the output-bound and self-reference angles; this issue is about what the pump costs downstream.

Why the gate is testing the wrong thing

It conflates two different propositions:

  • "the stack has no known correctness bugs" — a sensible precondition for polishing
  • "the newest review sample returned zero blockers" — a property of the sample

Only the first justifies skipping polish. The gate tests the second.

The stated rationale doesn't require the skip

Polishing code that still carries a known correctness bug is wasted work, and the refactor diff buries the bug.

Burying is solved by putting the polish in its own commit, not by skipping the phase. Phase 4 already does exactly that — one refactor(premerge): apply simplify lenses to the stack commit, revertible as a single SHA by 4c. The separation is the real protection; the gate adds nothing on top of it.

What it cost on this run

The pass was run manually after the fact. It found five guards that were provably dead, each demonstrated by mutation rather than argued:

Guard Proof it was vacuous
C11 dual-channel stanza passed with StructuredOutput stripped from all eight card bodies — #763's frontmatter satisfied the whole-file grep
#749 tools-declaration passed with a live card's tools: value emptied — the exact state it exists to red on
ci-shard-diagnose dump reported MATCH match=12 miss=0 for a shard that reds 11/12
PREMERGE_MAX_BLOCKED_ON lock name-grep only; green at any value
unpinned sort/comm twin blind to sort) and end-of-line

Plus five surfaces documenting a growth-ratio predicate the code does not implement (prose denominator 3 vs code 1 on the same document — 0.33 vs 1.00, straddling the 0.50 ceiling, i.e. the two copies disagreed about whether the loop stops).

The current design would have shipped all of that, on the grounds that the stack "was not clean enough to polish".

Proposed change

  1. Gate Phase 4 on CI green AND mergeable, not on blocker-count-zero. Both were true here from attempt 1's repair onward.
  2. Run it whenever the loop stops for any reason — STOP_GREEN, STOP_EXHAUSTED, STOP_NO_PROGRESS, STOP_SELF_REFERENTIAL — since none of those says anything about whether the polish is safe.
  3. Keep it in its own commit on the stack branch, which it already does. That is what stops it burying anything, and it keeps 4c's single-SHA revert intact.
  4. Keep 4c VERIFY unchanged: re-probe, re-gate on the simplify SHA, revert on harm.

Surviving blockers are already filed as issues by Phase 5, so a polished-but-not-blocker-free stack loses nothing — the blockers outlive the run either way.

Not proposed

Do not relax the gate to "run Phase 4 always". A red build or a CONFLICTING mergeable state are real reasons to skip: the polish cannot be verified on a stack whose CI cannot answer, and 4c would have nothing to gate against.

Related

Activity

  1. added
    premerge-findingAuto-filed by /uberdev:premerge from deferred findings (RFC 0002)
    on Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    premerge-findingAuto-filed by /uberdev:premerge from deferred findings (RFC 0002)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions