Skip to content

The blocked-issue sweep only checks issues that already carry the label, so 5 declared blockers are invisible to it #3142

Description

@devantler

🤖 Generated by the Agentic Engineer

Evidence

blocked-label-blocker-line.sh enumerates its population with

search/issues?q=org:${ORG}+is:issue+state:open+label:blocked+archived:false

so it can only ever check issues that already carry the label. It answers "does a
blocked-labelled issue have a conforming line?"
and reports that as "all N open
blocked-labelled issue(s) carry a conforming **Blocker:** line"
— which is true, and is not the
question a run needs answered. The question a run needs answered is "is this issue blocked?", and
the check is structurally blind to every issue that is blocked without carrying the label.

Measured 2026-09-01 over all 771 in-scope open issues, reading bodies directly rather than
through the label filter. The org-wide search returns 802; the 31-issue difference is
data-product (27 — archived, which AGENTS.md requires omitting from every census) plus
fleet-gitops (3) and maintenance (1), neither of which is in the Portfolio map. A per-repo REST
enumeration over the Portfolio map's repositories independently returns 772, agreeing within one
issue of the filtered search — the two enumerations differ in method, so their agreement is a real
control rather than the same query run twice. None of the five findings below is in an excluded
repository
, so the correction moves the denominator and not the finding:

Class Count Visible to the sweep?
blocked label and a conforming line 32 yes — reports 32/32 CONFORMS
A real **Blocker:** line, no label 5 no
**Blocker:** none — agent-actionable, no label 2 n/a — correctly unlabelled
Blocked in fact, neither label nor line ≥2 known no, and not mechanically detectable

The five: ksail#5150, platform#3251, platform#3252, platform#3253, platform#3381. Each names a real
blocker — homebrew/cask notability policy, a Cloudflare account action, two chained on those, and
a maintainer decision on a third-party upstream contribution.

The two Blocker: none cases (actions#1025, actions#1028) are the reason this needs the body read
rather than a bare "line without label" match: they declare no blocker and are correctly
unlabelled. A naive check would report 7 and be wrong about 2 of them.

Who this affects and what it costs

Every run, in every lane, and the cost compounds because the two failure directions are both bad:

  • Unlabelled but blocked — the issue reads as ordinary actionable work. AGENTS.md's skip test
    keys clause (b) on a named, live-verified dependency, so a run must re-derive the blocker from the
    body or from live state before it can pass over the issue. With three lanes on an hourly cadence
    that is the same derivation repeatedly, for issues whose status has not changed in weeks.
  • The reported number is reassuring and incomplete. 32/32 CONFORMS is what a run sees, and it
    reads as the blocked set is in good order when 5 members of that set were never examined.

This is the Epic's pattern exactly: a measurement counting something other than what it claims to,
in the direction that corrupts a decision.

Two live cases found while working the Security queue today

Both were at the top of rung 2, both cost a full derivation, and neither was detectable by the sweep:

  • platform#3255 — every acceptance criterion had been met by #3264 twelve days earlier, which
    closed its duplicate #3258 and left this one open. Verified and closed today.
  • platform#3263 — substantively delivered by #3267 (which used Part of, not Fixes), with its
    three remaining criteria blocked on #3269. It carried neither label nor line. Repaired today,
    which is what moved the sweep from 31 to 32.

Expected behaviour

The check answers "is this issue's blocked-ness recorded consistently?", in both directions — a
label without a conforming line (today's finding), and a declared blocker without the label.

Acceptance criteria

  • The check enumerates open issues independently of the blocked label, and reports a
    declared blocker carrying no label as its own finding class, distinct from MISSING/MALFORMED.
  • **Blocker:** none is not reported — the two actions cases above are the fixture, and a
    RED ablation proves the check would otherwise flag them.
  • The wider enumeration keeps the existing UNKNOWN discipline: a failed or truncated read exits
    2, never a clean report. An empty result stays a claim about the query.
  • The five listed issues are labelled, each after its blocker is re-verified — a stale line
    whose dependency has shipped must be unblocked, not labelled. Adding the label to an issue
    that is no longer blocked is the more expensive error, since a label never expires.
  • The existing 32/32 behaviour is unchanged for issues that already carry both.

Not in scope

The "neither label nor line" class (platform#3196, platform#3223) cannot be detected from issue
content — nothing distinguishes it from an ordinary open issue. It is named here so the residue is
recorded rather than implied to be covered.

Rough size: small — one enumeration change plus a finding class, against a script that already
has the body-parsing, soft-wrap joining and UNKNOWN handling this needs.

Activity

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

    Type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions