Repository navigation
🐛 Activity Monitor: name the PR a blocked issue waits on; keep hive's own unblock live - #14957
Conversation
…wn unblock live
Two Activity Monitor bugs on the reviewer review-backlog spin-off issues:
1. The grey blocked pill never said what blocked the issue although the
body carried <!-- hive:blocked-on pr=owner/repo#N --> and the
enumeration already filed the reason "blocked on owner/repo#N". The
tracker now parses the marker (body, else reason) into
blocked_on_pr {repo, number, url, state}; state is resolved from the
status snapshot's open PRs, the ForgeState cache and the recent-merge
ring only, never a GitHub call. The SPA renders the pill as
"blocked on #N" linking the PR, with a tooltip saying what lifts the
block; the caption reads "Blocked on PR #N" instead of "No stage
recorded yet" and the row title carries it.
2. Rows stayed blocked ~an hour after the hive itself removed the label.
A reconcile enumeration that started before the unblock was stored
with lastActionable.Store, overwriting the webhook re-read that had
patched the cached snapshot; cached cycles then rebuilt status from
the pre-unblock copy. The governor now remembers applied webhook
re-reads on the snapshot and replays those newer than a pass's start
onto its result before publishing (compare-and-swap). Every hive-side
blocked removal also fires a github.ItemRefreshHook that drops the
tracker cache and queues the same targeted re-read an inbound label
webhook gets.
Fixes #14952
Signed-off-by: Andrew Anderson <andy@clubanderson.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Changelog: this PR changes code but carries no changelog entry If it is user-visible — a feature, a fix an operator would notice, a This is a reminder, not a gate; it never blocks a merge. |
Open PR overlap checkBase branch: Conflicts are checked with every PR merged onto the current tip of
|
|
@clubanderson is auto-promoted for contributor-lane merging on this PR: the last 5 merged PRs by this author in this hive's repositories have no revert or sentinel-alert evidence. CI, reviewer verdict, diff fences, soak, holds and branch protection still apply. |
|
@clubanderson this PR is held at Failing checks:
Next: the hive does not push to your branch. Push a new head (or reply here); CI and the review swarm re-run automatically and the PR returns to the normal path. |
Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Signed-off-by: Andrew Anderson <andy@clubanderson.com>
There was a problem hiding this comment.
Conflicts with #14965 (scanner's PR for the same issue #14952): both add StageTrackerItem.BlockedOnPR with the same blocked_on_pr JSON shape, the same caption/pill text, and the same CompareAndSwap rewrite of snapshotPatcher.apply plus a replay-before-publish helper at the two lastActionable.Store sites. Both cannot merge; I have recommended on #14965 that it be closed in favour of this one, since this PR is a superset (ItemRefreshHook + unblockIssue, closed state via ForgeState, docs, JS test).
What I read here and found correct: finish() sets the blocked modifier before stageTrackerBlockedOnPR is called (stage_tracker.go hunk @1571), so the slices.Contains(it.Modifiers, modBlocked) guard sees the label; resp.RecentlyMerged is populated at stage_tracker.go:1328 ahead of stageTrackerPRStateResolver capturing it; publishEnumeratedSnapshot re-runs ReplayWebhookPatches on each CAS retry, which is safe because listedUpdatedAt refuses to move an already-patched copy backwards. I did not read the 966-line diff exhaustively — this is a targeted read of the two fix paths, not a full sign-off.
— hive: agent=reviewer-2 backend=copilot model=claude-fable-5.1 copilot=1.0.88
|
Thank you for your contribution! Your PR has been merged. We'd love to hear how your experience was: share feedback |
…als out of the merge gate (#15011) * Close superseded hive PRs automatically and re-stage adopted originals out of the merge gate A hive-authored PR whose closing targets are all closed, one of them by a different merged PR, and whose head conflicts with the base (or whose files that PR already covers) is now closed by the hive itself as hive/superseded with a notice naming the superseding PR: in the self-authored auto-merge lane before any review is dispatched, in the supersession sweep when the rebase is refused for a conflict, and in close-on-merge of the superseding PR. New knob governor.auto_close_superseded (default on); human-authored PRs are never auto-closed. A contributor PR adopted in supersede mode leaves stage/085-needs-decision in the adopting pass when the park was only the review swarm's requires_human verdict, renders in the CI/Review column with an 'Adopted -> #N' pill, and the duplicate-fix sweep no longer closes the superseding App PR as a duplicate of the PR it supersedes. Evidence: #14965 (closed by #14957 for #14952), #14975 -> #14980, Signed-off-by: Andrew Anderson <andy@clubanderson.com> #14947 -> #14977. * Move changelog fragment to repo-root changelog.d Signed-off-by: Andrew Anderson <andy@clubanderson.com> --------- Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Fixes #14952
Observed 2026-10-28 13:18Z on hive's hive for the reviewer "Review backlog" spin-off issues (#14863 / #14867 / #14868 / #14869 / #14926).
Bug 1 —
blockedpill never names the blockerThe issue body carries
<!-- hive:blocked-on pr=owner/repo#N -->and the enumeration files reasonblocked on owner/repo#N, but the row showed a bare greyblocked, "Open · blocked · since 7h", caption "No stage recorded yet".pkg/github/issue_blocked.go:ParseBlockedOnReason/BlockedOnTarget(body marker, else the filtered reason, so sidelined rows that carry only the reason are covered).pkg/dashboard/stage_tracker.go: newblocked_on_pr: {repo, number, url, state}(theblocked_onname was already taken by the GitHub "blocked by" list from 🐛 stage tracker: issues withheld for open GitHub blockers show as plain Actionable #14765). State comes from caches only — status snapshot open PRs → ForgeState → recent-merge audit ring →""— never a GitHub call. Caption becomesBlocked on PR #N — lifts when it merges(ormerged; the blocked sweep lifts the label next/closed unmerged; the blocked sweep re-triages it next); actorPR #N.index.html: pill readsblocked on #Nas a link to the PR,title/aria-labelBlocked on PR owner/repo#N (open) — lifts when it merges; re-triage if closed unmerged; the chevron tip and the row tooltip carry it.Bug 2 — stale
blockedafter hive's own unblockThe block sweep removed the label at 12:41Z and the webhook re-read patched the governor's cached snapshot within seconds (pod logs: issues 7→10). A reconcile enumeration that had started at 12:38Z finished at ~12:42Z and was published with
lastActionable.Store(actionable), overwriting the patch with its pre-unblock copy (logsnapshot_age21m → 4m). Cached cycles then rebuilt status from it; once the dashboard's 30-min webhook replay window lapsed the rows reverted toblockeduntil the next pass (~66 min).pkg/github/webhook_item_patch.go:ActionableResult.WebhookPatches(process-local, bounded 4096, copied byClone) remembers applied re-reads;ReplayWebhookPatches(prev)replays onto a fresh result those withFetchedAtafter itsGeneratedAt, only when the result lists the item with an olderupdated_at(never moves an item backwards behind a newer listing; never resurrects an item the listing dropped).cmd/hive/eval_cycle_source.go:publishEnumeratedSnapshot(CAS loop) replaces bothStoresites (main.go,repos_rescan.go);snapshotPatcher.applyalso uses CAS so neither side can overwrite the other.pkg/github/item_refresh_hook.go:ItemRefreshHook+(*Client).unblockIssue, used at all 5 hive-sideblockedremovals (review_backlog_blocks.go,issue_blocked.go).main.goregistersdashSrv.RefreshSelfEditedItem, which drops the tracker cache and queues the same targeted re-read an inbound label webhook gets (ItemPatchesdeliveryself:edit), patching the status row and the governor snapshot.forgeWriteThroughviaremoveLabelObserved), so no change at that level.Tests
pkg/github:TestParseBlockedOnReason,TestUnblockIssue_FiresItemRefreshHook,TestReplayWebhookPatches_*.cmd/hive:TestPublishEnumeratedSnapshotReplaysNewerWebhookReads.pkg/dashboard:TestStageTrackerBlockedOnPRFromMarker(payload + caption + state resolution + JSON shape),TestRefreshSelfEditedItemPatchesRowLikeAWebhook(end-to-end through the refresher with an httptest GitHub),TestStageTrackerRowsextended (rendered pill/link/tooltip), newstage_tracker_blocked_on.test.js.time.Sleepadded.go build ./...,go test ./pkg/dashboard/... ./pkg/github/... ./cmd/hive/...,node --test pkg/dashboard/*.test.js,check-api-reference-citations.shall green.Docs
docs/dashboard-sections.md(Activity Monitor: Blocked pill, Hive's own unblock is live),docs/labels-and-control-signals.md(blockedrow),changelog.d/fixed-14952-tracker-blocked-on-pill.md.