Repository navigation
issue-triage applies needs-human-review as a blanket hold on every bug report — well-specified issues are parked until a human clears the label by hand #1778
Description
Summary
issue-triage applies needs-human-review to every bug report, and hold-gate.sh treats that
label as a fleet hold that blocks dev-lead, the initiative driver, and auto-release. So filing a
well-specified bug with written acceptance criteria silently parks it until a human notices and
removes the label by hand.
The triage rule is blanket (.github/workflows/issue-triage.md):
"Add
needs-human-reviewfor bugs and ambiguous reports that need human review."
In practice the "and ambiguous reports" qualifier does nothing — bug alone is sufficient, so
every issue labelled bug acquires a hold.
Observed, repeatedly
Five issues filed in this workstream, all with explicit acceptance criteria, all auto-held within
minutes of creation:
| Issue | Filed | Held at | Gap |
|---|---|---|---|
| #1734 | 11:38:15Z | 11:45:18Z | 7 min |
| #1698 | — | — | held |
| #1665 | — | — | held |
| #1775 | 02:4x | within minutes | held |
| #1776 | 02:4x | within minutes | held |
Each required a manual label removal before any agent would touch it. #1775 and #1776 were held
again immediately after being filed as splits of an already-triaged issue.
Why this is a defect and not a preference
The hold is load-bearing and correct — the application is what is wrong. #1595 deliberately made
needs-human-review gate the initiative driver after #1532 shipped with the hold still attached, and
scripts/lib/hold-gate.sh centralised the check so the hold set can never drift between callers.
That design is right. The problem is upstream: a hold that means "an agent must not proceed until a
human decides something" is being applied to items where nothing is awaiting a decision.
The label's own description disagrees with how triage uses it:
needs-human-review — "Flagged by automated PR review agent"
It is a PR-review escalation label — applied by the budget code in
scripts/lib/pr-automation-budget.sh when a PR exhausts its automation cycles. Triage reusing the
same label for "this is a bug report" overloads one label with two unrelated meanings, and the hold
semantics from the first leak onto the second.
It also degrades the signal. If every bug carries the hold, the label stops distinguishing items
that genuinely need a human. #1532 shipped with the hold attached precisely because the hold was
not meaningful at the release point.
Relationship to #1767 (closed)
#1767 fixed the visibility half — dev-lead now announces when it withholds action and names the
blocking label, so a held item no longer looks like a stalled agent. That was the right fix for the
symptom it addressed, and its evidence (PR #1742 sitting four days while three restart attempts were
made) is the same cost pattern seen here.
This issue is the upstream half: reducing the number of items that acquire a hold they never
needed. The two are complementary — #1767 makes holds legible, this makes them meaningful.
Acceptance Criteria
-
Triage stops applying a hold label to routine bug reports. Either:
- it applies
needs-human-reviewonly when the report is genuinely ambiguous or lacks enough
information to act on (make the qualifier operative, with stated criteria); or - it uses a distinct non-hold label for "triaged as a bug" and leaves
needs-human-reviewto the
PR-review escalation path that owns it per the label description.
State which path was taken and why.
- it applies
-
The chosen behaviour is verifiable, not just prompt wording: a test or fixture asserting that a
well-specified bug report does not acquire a hold label. Prompt-only rules drift. -
The hold semantics are not weakened.
hold-gate.shkeeps treatingneeds-human-reviewas a
hold wherever it is genuinely applied — needs-human-review does not gate the Initiative Driver — #1532 was auto-released and merged with the hold label still attached #1595's gating and conflict-integrity parser misses next-line-brace function definitions — latent blind spot in both the #1482 detector and the #1520 gate #1532's lesson stand. This issue changes
when the label is applied, never what it means. -
If the label keeps its dual role, the taxonomy documents both meanings explicitly
(standards/github-settings.mdlabel table) so the description no longer contradicts the usage. -
Existing wrongly-held open issues are swept once as part of the change, so the fix is not
prospective-only. Report which were cleared.
Dev Notes
- Do not fix this by removing
needs-human-reviewfromhold-gate.sh. That inverts the defect:
the hold would stop working where it is genuinely needed, which is exactly the conflict-integrity parser misses next-line-brace function definitions — latent blind spot in both the #1482 detector and the #1520 gate #1532 regression
needs-human-review does not gate the Initiative Driver — #1532 was auto-released and merged with the hold label still attached #1595 was filed to prevent. - Worth considering whether triage should apply any hold. Its own comment already asks the reporter
a clarifying question; the answer arriving is what should gate work, not the act of filing. - The pattern generalises beyond bugs: any agent that applies a label with hold semantics as a
classification will produce this. Whatever rule lands here is worth stating once in the label
taxonomy rather than per-agent.
References
.github/workflows/issue-triage.md— the labelling rulescripts/lib/hold-gate.sh— the centralised hold set (needs-human-review does not gate the Initiative Driver — #1532 was auto-released and merged with the hold label still attached #1595)scripts/lib/pr-automation-budget.sh— the escalation path that owns the labelstandards/github-settings.md— the label taxonomy- dev-lead silently skips held items — post a one-time notice naming the hold label and how to re-enable #1767 (closed) — the visibility half; needs-human-review does not gate the Initiative Driver — #1532 was auto-released and merged with the hold label still attached #1595, conflict-integrity parser misses next-line-brace function definitions — latent blind spot in both the #1482 detector and the #1520 gate #1532 — why the hold exists and must stay
- Observed on persona-runner: qa-lead advisory lost — DON_PETRY_BOT_GH_PAT gets HTTP 403 posting issue comments (regression from #1694) #1734, qa-lead over-escalates test flakiness at production tier — the one held-out case parity did NOT fix (HIGH/escalate where MEDIUM/no is correct) #1698, pr-review-sweep's stop condition mistakes a marker for a standing approval — a dismissed approval strands a green, auto-merge-armed PR indefinitely #1665, Preserve the advisory when the persona post fails — a 403 must cost a retry, not the work (split from #1734 AC #4) #1775, Authorization preflight: fail loudly when a persona credential authenticates but cannot write (split from #1734 AC #5) #1776
Activity
github-actions commentedon Sep 13, 2026
Thanks for filing such a thorough report — the evidence table, the label-description mismatch, and the explicit preservation of #1595's hold semantics make the problem very easy to reason about. This is clearly a defect in how the qualifier 'and ambiguous reports' is applied, and the fix has real design implications for the label taxonomy. The single most useful input before starting: do you have a preference between the two paths in AC1 — making the qualifier operative with explicit ambiguity criteria (so well-specified bugs bypass the hold inline), versus introducing a distinct non-hold label for 'triaged as bug' and reserving
needs-human-reviewexclusively for the PR-review escalation path the label description already describes? Either satisfies the acceptance criteria; knowing which direction fits the team's taxonomy philosophy would help scope the change correctly.don-petry commentedon Sep 13, 2026
Dev-Lead Implementation Plan
Issue: #1778 — issue-triage applies needs-human-review as a blanket hold on every bug report
Scope
Stop
issue-triagefrom applying theneeds-human-reviewhold label by removing it from triage'ssafe-outputs.add-labels.allowedset (AC #1 — Path B), so a well-specified bug is classified (bug) but never auto-held; the hold label reverts to its sole owner, the PR-review escalation path.Why Path B (option 2), not option 1
needs-human-review's own label description is "Flagged by automated PR review agent" — it is a PR-review escalation label (scripts/lib/pr-automation-budget.sh). Removing it from triage's allowed-set makes the fix enforced byaw.sh safe-output apply(the label is rejected even if the prompt wording later drifts), satisfying AC #2's "prompt-only rules drift" requirement. It also dissolves the dual-role overload, so AC #4's "if the label keeps its dual role" clause no longer applies.Implementation Checklist
.github/workflows/issue-triage.md— removeneeds-human-reviewfromsafe-outputs.add-labels.allowed; rewrite task step 2 so triage classifies but applies no hold (the clarifying comment solicits the reporter)tests/aw/issue-triage/scenarios.md— Scenario 1 expected labels becomebug(no hold)scripts/lib/hold-gate.sh— unchanged (AC Add @claude delegation, auto-merge, and rebase handling #3: hold semantics must not weaken; needs-human-review does not gate the Initiative Driver — #1532 was auto-released and merged with the hold label still attached #1595/conflict-integrity parser misses next-line-brace function definitions — latent blind spot in both the #1482 detector and the #1520 gate #1532)Tests to Write / Update
tests/aw/issue-triage/test_aw_run.sh: a triage result containingneeds-human-reviewis rejected bysafe-output apply(drift-proof — AC Go-live improvements for PR review agent #2)needs-human-reviewis absent fromissue-triage.mdallowed listneeds-human-review) to the new contractSweep (AC #5)
Of 18 open issues carrying
needs-human-review, 14 were bot-applied (triage classification holds) and 4 were human-applied (#1754, #1707, #1688, #1637 — genuine holds, preserved). Sweep the 14 bot-applied holds once and report which were cleared.Test Command
bash tests/aw/issue-triage/test_aw_run.shandbash .dev-lead/scripts/dev-lead-lint.shdon-petry commentedon Sep 13, 2026
Dev-Lead: Progress (in progress — not yet durable)
Approach — Path B (AC #1, option 2)
Removed
needs-human-reviewfromissue-triage.md'ssafe-outputs.add-labels.allowedset so triage classifies (bug/etc.) but never applies a hold. The label's own GitHub description is "Flagged by automated PR review agent" — it belongs to the PR-review escalation path (scripts/lib/pr-automation-budget.sh). Keeping it out of triage's allowed set makes the rule code-enforced byaw.sh safe-output apply(rejected even if the prompt drifts), which is the drift-proof property AC #2 asks for.scripts/lib/hold-gate.shis untouched (AC #3).Files touched (this workspace, not yet pushed)
.github/workflows/issue-triage.md: dropneeds-human-reviewfrom allowed labels; rewrite task step 2 to classification-only, no hold.tests/aw/issue-triage/test_aw_run.sh: Test 8 now asserts the label is absent from the allowed set; Test 11 now asserts safe-output rejects a triage result carrying it; Test 6 valid-case fixture isbugalone.tests/aw/issue-triage/scenarios.md: Scenario 1 expectsbugonly.Local check output (provisional — not the pushed run)
Sweep (AC #5 — live, already applied)
Of the open issues carrying
needs-human-review, the 14 bot/triage-applied holds were cleared:#1744 #1743 #1740 #1733 #1687 #1620 #1592 #1568 #1566 #1495 #1318 #1198 #1160 #865.3 human-applied holds were preserved as genuine (
#1707,#1688,#1637), keying the sweep on the lastlabeledevent's actor type (Bot vs User) so a deliberate human hold is never undone. Label removal is reversible if any needs re-holding.Notes
standards/github-settings.mdlives in the publicpetry-projects/.githubrepo, not here, so there is no local taxonomy table to amend.don-petry commentedon Sep 13, 2026
Dev-Lead: Implementation Complete — PR #1783
The implementation for issue #1778 is durable: commits are pushed and a pull request is open. This record is backed by verifiable artifacts you can confirm in one click.
f6cfd373b768874927c7995173f747daa06ec9f2Review happens on the PR. Acceptance criteria and test results are evidenced by the PR's diff and CI checks — not asserted here. If a later stage fails, this claim is retracted in place.
feat: implement issue #1778 — issue-triage applies needs-human-review…