Skip to content

perf(lanes): measure work-resolve-issue's idle time to a transient re-fire, 7 days before and after #12804 #13073

Open

Description

@kyle-sexton

Refs: #12635

Problem

#12804 (merged 2026-11-03T16:07Z) shortened work-unblock's stranded re-fire backoff to 1 hour for the transient causes (no-run, failed-mint, kill-switch) and kept 3 hours for the rest (docs/conventions/pr-pipeline.yaml:1085-1090). #12635's last done-when item asks for the measured effect; #12635 closed with its other items delivered and this one carried here. It is a measurement over time, which an unattended lane run cannot perform, so it is host work.

Done when

  • On or after 2026-11-10T16:07Z: the median idle time from a transient failure to the re-fire is measured for 7 days before and after, and posted here.

The after window runs from 2026-11-03T16:07Z, so this cannot finish before 2026-11-10T16:07Z.

Filed by Issue Triage. This was generated by AI.

Activity

  1. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    host-runNeeds an unattended run on a host; the host runner takes it, not a person or the issue lane.
    on Nov 4, 2026
  2. github-actions commented on Nov 4, 2026

    @github-actions
    Contributor

    Proposed work class: work-class: read-only
    Basis: automated intake triage; the lanes App applied this class.

    Size: Small
    Complexity: Low
    Uncertainty: Known
    Flags: none
    Blocked by: none

    Understood: this asks for the median idle time from a transient failure to the re-fire, measured over 7 days before and 7 days after #12804 merged, with the result posted here. It is a measurement over time, so it is host work. The after-window cannot finish before 2026-11-10T16:07Z. The scope is clear and nothing is missing. #13073 is related to #12804's follow-up work but is not a duplicate of any open issue.

    Automated triage, applied by the lanes App.

  3. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    work-class: read-onlyAudits, research, reports. No repository mutation; tracker and queue writes only.
    on Nov 4, 2026
  4. added
    status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.
    and removed
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    on Nov 4, 2026
  5. melodic-automation-lanes commented on Nov 4, 2026

    @melodic-automation-lanes
    Contributor

    Not admitted to the issue lane: its done-when asks for what an unattended lane run cannot perform: item 1 (tracker-output: "The median idle time from a transient failure to the re-fire is measured for ..."); no done-when item is left for the lane, so it goes to the host queue (host-run); it carries host-run. Admission takes the issue once each of those is met, when intake triages it again (.github/actions/resolve-config/admission-rules.json).

  6. melodic-automation-lanes commented on Nov 4, 2026

    @melodic-automation-lanes
    Contributor

    The latest triage verdict holds nothing: admission moved the issue to status: confirmed; its comment says why.

  7. kyle-sexton commented on Nov 4, 2026

    @kyle-sexton
    MemberAuthor

    Claimed by poteto (desk session 789d5794). The 7-day BEFORE and an interim AFTER (from the change's merge until now) get posted here today, with the method and the script path, so the final AFTER is the same command run over the full window once it closes. That final AFTER, and this issue's close, can't come before the 7-day after window ends.

  8. kyle-sexton commented on Nov 4, 2026

    @kyle-sexton
    MemberAuthor

    Before measurement and interim after: idle time from a stranded failure to work-unblock's re-fire

    The changed paths almost never fired. In the 7 days before #12804, and in the 23 hours since, the paths whose wait #12804 shortened fired zero times: the no-run first re-fire, the kill-switch backoff after trip 4, and the no-run and failed-mint backoff re-fires. Every transient re-fire measured went through the kill-switch clamp path, and #12804 did not change that path. So far the change has nothing to act on. A before/after delta on the pooled "transient" group would come from other changes, not from #12804.

    Method

    Script: .work/gh-monitor/trends/13073-measure.py <from> <to> (hub-local, run with python3 -I). Line numbers below are on origin/main at e5554b8.

    • Config under test: docs/conventions/pr-pipeline.yaml:1082-1094 (stranded-backoff-hours: no-run 1, no-report 3, failed-again 3, failed-mint 1, kill-switch 1). git log -G shows perf(lanes): configure work-unblock's stranded re-fire backoff per cause and shorten it for transient causes #12804 (ea71ee1) is the only commit since 2026-10-26 to touch stranded-backoff-hours, reset-clamp-min or limit-stops-per-issue.
    • Which re-fires perf(lanes): configure work-unblock's stranded re-fire backoff per cause and shorten it for transient causes #12804 changes:
      • no-run first re-fire: waits hoursFor["no-run"] (.github/scripts/work-unblock/label-unblocked.mjs:1763-1782), 3 h before, 1 h after.
      • kill-switch: hoursFor["kill-switch"] applies only from trip limit-stops-per-issue + 1 = 4. Trips 1-3 wait ended + clamp, where clamp is 0 at the broker check and otherwise reset-clamp-min = 1 h (label-unblocked.mjs:1817-1818, .github/scripts/work-resolve-issue/limits.mjs:11,17). That clamp path is unchanged.
      • failed-mint: the per-cause hours apply only to the backoff after 3 re-fires on one workflow key (label-unblocked.mjs:1836). A first failed mint is clamp-timed, and its record carries the generic failed-run text.
      • backoff re-fires: backoffDue doubles the cause's hours (label-unblocked.mjs:415, 1744-1758).
    • Re-fire event: a bot (melodic-automation-lanes) unlabel then relabel of agent-ready no more than 120 s apart (label-unblocked.mjs:2070-2095 posts or edits the record, removes the label, then adds it back). Each pair is attributed by the bot comment created or edited in the 180 s before it:
      • <!-- work-unblock refired KEY breaker --> is kill-switch (label-unblocked.mjs:1284, report-outcome.mjs:862).
      • <!-- work-unblock refired KEY --> with a strandedCause text is no-run, no-report or failed-again (label-unblocked.mjs:1273-1277). With the generic FAILED_CAUSE text it is a first failed run or a first failed mint; the text cannot tell these two apart.
      • <!-- work-unblock infrastructure KEY -->, created or edited (userContentEdits), is a backoff re-fire, with its cause taken from its text (MINT_CAUSE at label-unblocked.mjs:1279).
      • The workflow-stale text (report-outcome.mjs:866) is the run re-firing itself straight away. It is out of scope and reported apart.
      • A relabel after an outcome= marker (a limit-stop restart) or a recurrence relabel is out of scope.
    • Clock start:
      • kill-switch: the refused run's end, as the record states it ("that run ended at ...").
      • no-run: the last agent-ready add before the pair.
      • every other cause: the end of the issue's newest completed work-resolve-issue run (event=issues, title ending #N) created after that add and ended before the re-fire.
    • Inclusion: a re-fire counts in a window when its clock start is in [from, to) and the re-fire is before to. Re-fires that straddle a window edge are dropped and counted.
    • Incident: re-fires whose clock-to-re-fire interval overlaps the GitHub incident of 2026-11-04T09:54Z to 11:44Z are excluded, and counted.
    • Reads: GraphQL search repo:… is:issue "to start a fresh run" updated:>=<from − 30 h>, then each issue's timeline (comments, labeled and unlabeled events) since from − 30 h. Lane runs are listed per UTC day, only for the days the run-clock rows need.
    • Statistics: median, and p90 by nearest rank, of idle hours.

    BEFORE: 2026-10-27T16:07Z to 2026-11-03T16:07Z

    group path median idle h p90 idle h n
    transient no-run, first re-fire (changed 3 h -> 1 h) - - 0
    transient kill-switch, clamp path (trip 1-3, unchanged) 1.27 4.98 206
    transient kill-switch, backoff path (trip 4+, changed) - - 0
    transient backoff re-fire: no-run (changed) - - 0
    transient backoff re-fire: failed-mint (changed) - - 0
    control no-report, first re-fire (3 h) 3.27 5.25 8
    control failed-again, first re-fire (3 h) - - 0
    control backoff re-fire: no-report / failed-again (3 h) - - 0
    control generic first failed run or first failed mint (clamp) 1.71 4.67 74
    out of scope workflow-stale immediate re-fire 0.28 0.64 14
    transient pooled 1.27 4.98 206
    control pooled 1.81 4.67 82

    Issues read: 311. Excluded: 31 that straddle a window edge, 36 limit-stop restarts or recurrence relabels, and 4 relabel pairs with no record. Of the counted rows, 8 have no matching lane run, so their clock is the label add.

    Interim AFTER: 2026-11-03T16:07Z to 2026-11-04T15:15Z (interim, about 23 h of 7 days)

    group path median idle h p90 idle h n
    transient no-run, first re-fire (changed 3 h -> 1 h) - - 0
    transient kill-switch, clamp path (trip 1-3, unchanged) 0.26 1.16 22
    transient kill-switch, backoff path (trip 4+, changed) - - 0
    transient backoff re-fire: no-run (changed) - - 0
    transient backoff re-fire: failed-mint (changed) - - 0
    control no-report, first re-fire (3 h) - - 0
    control failed-again, first re-fire (3 h) - - 0
    control backoff re-fire: no-report / failed-again (3 h) - - 0
    control generic first failed run or first failed mint (clamp) 0.29 0.32 3
    out of scope workflow-stale immediate re-fire 0.72 1.35 23
    transient pooled 0.26 1.16 22
    control pooled 0.29 0.32 3

    Interim n = 25 in scope (22 transient, 3 control). Excluded: 15 that straddle a window edge, 1 that overlaps the incident, and 2 limit-stop restarts. The interim window is right-censored: a failure from the last hours that has not been re-fired yet is missing, which biases it low. The 18 rows with no matching lane run are the workflow-stale rows, whose run ends after its own re-fire.

    Reading

    Final AFTER (after 2026-11-10T16:07Z)

    python3 -I .work/gh-monitor/trends/13073-measure.py 2026-11-03T16:07:00Z 2026-11-10T16:07:00Z
    

    Run it with no --cache, so it reads fresh. Expected cost: about 20 GraphQL calls and about 30 run-listing calls.

    UNVERIFIED

    • "Listed human" for the kill-switch trip floor is approximated: any non-bot account that added agent-ready, or any outcome= marker, within the 30 h lookback. With no floor inside the lookback, every breaker record in the lookback counts. That can only push a re-fire toward the trip 4+ path, and none landed there.
    • The cause of a backoff re-fire comes from the infrastructure comment's current text, not from the text of the edit made at that re-fire. No backoff re-fires occurred, so this did not affect these numbers.
    • The 4 BEFORE relabel pairs with no record were not inspected one by one.
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

    host-runNeeds an unattended run on a host; the host runner takes it, not a person or the issue lane.priority: mediumReal value, no hard deadline; normal backlog flow.status: confirmedA maintainer confirmed the item is real and in scope; ready to be worked.work-class: read-onlyAudits, research, reports. No repository mutation; tracker and queue writes only.

    Type

    Fields

    Work status

    confirmed

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions