Skip to content

claw: the issue-shape gate judges a stale payload -- #10644 stayed closed 1246 s with a passing body #10662

Closed

Description

@gHashTag

What happened

.github/workflows/needs-boundary.yml judges an issue from the event payload: BODY: ${{ github.event.issue.body }}, REFUSED: contains(labels, 'shape-refused'), STATE: ${{ github.event.issue.state }}. GitHub fixes that payload when the event is created. On 2026-10-18 the job waited about twenty minutes for a runner, so the gate judged bodies and labels that were no longer true.

#10644, times from the run and job API (UTC):

Event created Body Job ran What the gate did
20:28:09 opened (run 39163431991) no sections, fails 20:47:55 closed it, labelled shape-refused
20:29:36 edit by tri-claw (run 39163543210) passes cancelled by the next event in the group nothing
20:44:17 edit (run 39164669059) passes 21:03:54 read REFUSED: false, STATE: open from the payload and did nothing; the issue stayed closed
20:56:27 edit (run 39165588024) passes 21:08:41 reopened it

The issue sat closed for 1246 s with a passing body, and only a third edit undid it. Five other lane issues were closed the same night (#10630, #10645, #10600, #10617, #10608). Each needed a manual reopen or another edit, and every edit queues another gate run.

specs/claw/shape_race.t27 replays a gate timeline under two readings. The payload reading is what the gate does today. The live reading reads the body, labels and state when the job runs. With the #10644 fixture, the payload reading leaves the issue wrong after 2 of 3 jobs. The live reading leaves it wrong after none. Without the 20:56 edit, the payload reading ends stuck (closed with a passing body). Mergify, bors and Kodiak make the same choice: they re-read live state when they act, not the event that woke them.

Proposed fix (owner's decision; this lane does not edit workflow files)

In the shape job, before judging, read the live issue: gh issue view "$N" --json body,labels,state. Then judge that body, and decide close or reopen from those labels and that state. Keep the payload only for the issue number.

User Scenarios

  • Given an issue opened with a failing body and edited to a passing body before its first gate job runs, when the gate jobs run, then the issue ends open without the shape-refused label.
  • Given an issue the gate closed, when an edit's job runs whose payload predates the close, then the gate still sees the live shape-refused label and reopens the issue if the live body passes.
  • Given the claw: the merger waits about an hour for a runner -- 34 merge runs queued behind PR jobs (measured 2026-10-18) #10644 timeline as rows created TAB ran TAB ok, when race_plan in specs/claw/shape_race.t27 replays it, then it prints F shape-race race, with the payload reading wrong after 2 jobs and the live reading wrong after 0.

Requirements

  • FR-001: The shape job MUST judge the issue body as it is when the job runs, not as the event payload carried it.
  • FR-002: The shape job MUST decide close or reopen from the live labels and state.
  • FR-003: specs/claw/shape_race.t27 MUST replay a timeline under both readings, and MUST read unknown when any row is unreadable.

Success Criteria

  • t27c test-report specs/claw/shape_race.t27 --specs-dir specs reports 16 of 16 passing with 0 vacuous passes, and t27b test specs/claw/shape_race.t27 exits 0.
  • t27c seal specs/claw/shape_race.t27 --verify exits 0.
  • After the workflow change: an issue opened with a failing body and edited to pass within one minute ends open, without shape-refused, once both gate jobs have run.

Boundary

  • .github/workflows/needs-boundary.yml
  • specs/claw/shape_race.t27
  • .trinity/seals/claw_ClawShapeRace.json
  • docs/claw/README.md
  • docs/reports/t27b_expectations.json

🤖 Generated with Claude Code

Activity

  1. gHashTag commented on Oct 19, 2026

    @gHashTag
    OwnerAuthor

    Implemented by #11008 (merged 2026-10-19 11:18Z), which is the fix proposed above: the shape job reads gh issue view "$N" --json body,state,labels when it runs and judges that, the payload only names the issue. I found the same defect independently (issue #11007: #10897 was closed by a run queued 38 min and never reopened after tri-claw's edit) and did not see this issue until now; the replay in specs/claw/shape_race.t27 (#10663) is the better evidence and stays.

    Since the merge every run of needs-boundary.yml has completed in about 14 s and succeeded (for example the run on #11053 at 13:34:41Z).

    Side effect cleaned up in #11007: 128 of the 185 issues the gate had closed since 2026-10-18 passed their current body; 88 were closed as completed (a merged PR names them) and 40 reopened with a comment.

    Not shown live: the open-then-edit-within-a-minute scenario of the Success Criteria needs a gate queue to recur. Closing as completed; reopen if that scenario should be forced first.

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions