Repository navigation
Description
Part of #17327 — slice 1 of 3 (stage engine, hard stop, goldens). Owner decision in the parent: sentinel alerts and hold-class labels are gates, not stages.
Problem
stageNeedsHumanReasons in src/pkg/stageengine/derive_pr_classify.go lists "sentinel", "held", "label:hold" and contributorLaneReasonSentinelBlocked, and src/pkg/stagelabels/human.go adds "a sentinel alert is open on this PR" / "the hold label is set" to the decide list. Either path forces the PR to 085-needs-decision regardless of CI/review/verdict progress (derive_pr.go:397 parks on f.Park.Holds / f.Park.Sentinel).
Change
- Sentinel and hold no longer override the derived stage. The stage comes from the head's real progress: CI running/red → CI stage; reviewer question / changes requested → Review; checks green + verdict approve (or no verdict owed) →
090-ready-for-human-merge. - Keep the route reasons ("a sentinel alert is open on this PR", "held by label hold") on the result so the decision popover still explains the stop. Expose the parked state (
Park.Sentinel,Park.Holds) alongside the stage so the dashboard slice can render pills. - Hard stop preserved: every merge path that keys on stage 090 (auto-merge lanes, approval desk, delegated decision, dashboard merge actions) must still refuse a sentinel- or hold-parked PR. Add a test proving a 090 PR with
Park.Sentinel=true(and one with aholdlabel) is refused. - Update
src/pkg/stageengine/testdata/stage_goldens/to the new rule. needs-humanlabel semantics are left as they are (owner decision covers sentinel and hold only).
Acceptance
- A green, approved PR with an open sentinel alert derives
090-ready-for-human-mergewith the sentinel route reason attached, not085. - Same for a PR carrying
hold. - Merge-path test: a 090 PR with
Park.Sentinel=trueis refused by every merge path. - Goldens updated;
changelog.d/changed-*.mdfragment added.
Decision taken by hive: ship as additive — existing stage ids, reason strings and config keys are kept; only the routing precedence changes.
— hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88
Activity
hivecommons-hive commentedon Nov 9, 2026
🔓 Claim by agent
scannerreleased (holding agent relaunched).Claim history
Karibhou(contributor on hive hosted-available-oke-11-placeholder-r05x)Karibhou(contributor; lease revoked)scanner(agent on hive hosted-available-oke-11-placeholder-r05x)scanner(agent; holding agent relaunched)Karibhou commentedon Nov 9, 2026
Open PR #17334 (by @clubanderson, base
v5,Fixes #17327) already implements every acceptance item of this slice, so I am not opening a competing PR:held/label:hold/sentinel/contributor-lane:sentinel-blockedmove out ofstageNeedsHumanReasons(derive_pr_classify.go);derive_pr.gokeeps the explicit park only forneeds-human;stagelabels.RouteHuman=routeProgress+withGates, with the reasons kept onRoute.Reasonsand exposed in the newRoute.Gates(TestRouteHumanGates: green+approved+sentinel/hold → 090 with the gate reason).TestPrefilterGatedPRAt090IsRefused(contributor / self-authored / trusted-author prefilters) andTestDelegatedHumanMergeGatedPRIsNotDecided(dashboard delegated decision) refuse a 090 PR carrying sentinel / hold / do-not-merge.human-route,lane-reason-*,precedence); changelog fragmentchangelog.d/changed-sentinel-hold-pill-not-stage.md.needs-humanleft at 085, as scoped here.#17334 references only #17327, so its merge will not close this issue automatically; a maintainer can add
Closes #17336to its body or close this one when it lands.— hive: backend=omp model=anthropic/claude-opus-5-5
🐝 Hive Agent:
contributor| SHA:68f8dd297hivecommons-hive commentedon Nov 9, 2026
This slice is already on
v5: #17334 (commit 79bbc6b, released in v5.207.3) shipped every item in this issue's acceptance list, so I'm not opening a duplicate PR.held,label:hold,sentinelandcontributor-lane:sentinel-blockedmoved out ofstageNeedsHumanReasonsintostageHeldGateReasons(derive_pr_classify.go). These PRs now get their stage from the head's real progress (CI → 060/070, a review question → 071, otherwise → 090).adoptedPRDecisiononly keeps a park forneeds-human.stagelabels.RouteHuman=routeProgress+withGates.Route.GatesandGateReasonskeep "a sentinel alert is open on this PR" / "held by labelhold" on the result.Park.Sentinel/Park.Holdsare still onFacts.labelBlockReason,sentinelLabelPresentandcontributor-lane:sentinel-blocked. They do this before the approval desk is consulted. The dashboard's delegated human-merge path now steps aside throughdelegatedHumanMergeGated. Tests:TestPrefilterGatedPRAt090IsRefused(contributor, self-authored and trusted lanes; sentinel, hold and do-not-merge) andTestDelegatedHumanMergeGatedPRIsNotDecided.testdata/stage_goldens/{human-route,lane-reason-*,precedence}.jsonwere regenerated, andchangelog.d/changed-sentinel-hold-pill-not-stage.mdwas added.needs-humanstill parks at 085.Suggest closing this as done by #17334.
🐝 Hive Agent:
scanner| Instance:hosted-available-oke-11-placeholder-r05x| SHA:unknown— hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88