Skip to content

✨ tracker: rework pickup signal on the waiting-on chip - #15281

Merged
clubanderson merged 1 commit into
v5from
rework-pickup-signal
Oct 29, 2026
Merged

clubanderson merged 1 commit into
v5from
rework-pickup-signal

Conversation

@clubanderson

Copy link
Copy Markdown
Member

Fixes #15280

What

A PR row returned to its author (stage/071-needs-author / stage/072-returned-to-contributor) now carries a rework object on the stage tracker payload, and the waiting-on / adoption pill says whether the rework has been picked up — not just who the hive waits on.

"rework": {"state":"in_progress","actor":"zoe","requested_at":"…","since":"…","evidence":"claim","mode":"spawn"}

State rules (all from data the tracker already holds — no new GitHub calls)

state evidence rule
requested — requested_at = first nudge on the current head (NudgeStart()), else stage entry; nothing moved since
requested queued (+ahead) fix enqueued on the clanker's hub fix queue, not yet dispatched
acknowledged activity PR updated_at > max(request, hive's last nudge, stage entry) + 2 min slack (reply / review-thread answer / edit; reactions don't bump it)
in_progress claim (+mode) the author's — or after Reroute, the target's — relay took the fix-pr dispatch (fixqueue.Dispatch.At, new)
pushed commit (+head) PR head ≠ NudgeHead; the stage engine already routes 071/072 → 050 on the next sweep (transition table), the chip reads re-review pending meanwhile

SPA

  • Pill text: waiting on @x · no response / · queued / · acknowledged / · working / · re-review pending (presence dot kept; same ids/classes; no raw colours; no toLocaleTimeString).
  • Tooltip + row tooltip Rework: line: "rework requested 1 hour ago (…) · no response from @x yet", "@x acknowledged · activity on the PR 20 min ago", "@x's clanker picked up the rework 5 min ago (spawn)", "@x pushed a new head 1 min ago · re-review pending".
  • Event line on a state change at an unchanged stage via stageTrackerEventText: "@x acknowledged the rework request", "@x's clanker picked up the rework", "@x pushed a new head — re-review pending".
  • Nested per-PR rows under an issue mirror the field.

Tests

  • TestStageTrackerReworkFor — table-driven, fixed clock, 15 cases (no sleep).
  • TestStageTrackerReworkPayload — through buildStageTracker with MarkNudged + fix-queue override.
  • TestStageTrackerReworkJS — node: chip text/title/aria, adoption pill, event text, state map.
  • TestDispatchAt — fixqueue dispatch timestamp.
  • go test ./pkg/dashboard/... ./pkg/github/automerge/... ./pkg/stagelabels/... ./pkg/fixqueue/... green; golangci-lint run 0 issues; api-reference citations re-fixed.

Docs

src/docs/dashboard-sections.md (new "Rework pickup on the waiting-on pill" paragraph), src/docs/operator-reference.md, changelog.d/added-rework-pickup-signal.md.

A PR row returned to its author (071 / 072) now carries rework{state,
actor, requested_at, since, evidence, mode, ahead, head}: requested
(evidence queued when the fix sits on the clanker's hub queue),
acknowledged (PR updated_at moved after the request and the hive's own
nudge), in_progress (the clanker relay took the fix-pr task) or pushed
(head moved; 050 on the next sweep). Derived from the stage record, the
PR list and the contributor fix queue — no extra GitHub calls.

The waiting-on / adoption pill appends the state word, its tooltip and
the row tooltip say since when, and a state change at an unchanged stage
writes the row event line. fixqueue.Dispatch records when it left the
queue.

Fixes #15280

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
@kubestellar-prow kubestellar-prow Bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Oct 29, 2026
@kubestellar-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign nicholasjackson for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubestellar-prow kubestellar-prow Bot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Oct 29, 2026
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Open PR overlap check

Base branch: v5

Conflicts are checked with every PR merged onto the current tip of v5, so a PR that only needs a rebase is not reported as conflicting with its siblings.

PR Title Relation Files
#15282 📖 docs: make Hive guides easier to follow CONFLICT src/docs/dashboard-sections.md
#15285 🐛 advisory: digest and all periodic writers honour repo pause same files src/docs/operator-reference.md
#15104 🐛 Activity Monitor: Rebase, then merge as maintainer; fixer owns parked conflicting PRs; dismiss self-inflicted changes_requested same files src/docs/api-reference.md
src/docs/dashboard-sections.md
src/docs/operator-reference.md
src/pkg/dashboard/server.go
src/pkg/dashboard/stage_tracker.go
src/pkg/dashboard/static/index.html
#15134 🐛 Delegated decision on a capability gap: model the blocker, stop the un-park/re-park loop, name the missing App permission same files src/docs/api-reference.md
src/docs/dashboard-sections.md
src/docs/operator-reference.md
src/pkg/dashboard/server.go
src/pkg/dashboard/stage_tracker.go
src/pkg/dashboard/static/index.html
#15236 🐛 Prefer covering PR progress in Activity Monitor messages same files src/pkg/dashboard/stage_tracker.go
#15186 🐛 Activity Monitor: one coherent post-decision state for Let hive decide rows; 060 reviewed in CI / Review same files src/docs/api-reference.md
src/docs/dashboard-sections.md
src/docs/operator-reference.md
src/pkg/dashboard/stage_tracker.go
src/pkg/dashboard/static/index.html
#15253 🐛 decision toast: issue decisions no longer read as 'approved for merge' same files src/pkg/dashboard/static/index.html

@github-actions github-actions Bot added the conflicts-with-open-pr Open PR has a merge conflict with another open PR label Oct 29, 2026
@hivecommons-hive

Copy link
Copy Markdown
Contributor

@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.

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Another agent tried to open a PR from scanner/fix-15280, but this PR already closes #15280. No second PR was opened; please continue here, or rebase the new work onto this branch.

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — no findings from this perspective.

— hive: agent=adjudicator-2 backend=copilot model=claude-fable-5.1 copilot=1.0.88

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intent alignment — the diff delivers what #15280 asks for (rework{state, actor, requested_at, since, evidence} on 071/072 rows, chip suffix, tooltip, event line, no new GitHub calls) with no unrelated scope. One in-scope gap in the state rules:

Hive's own Reroute note is read as the contributor acknowledging. src/pkg/dashboard/api_repo_item_decision_reroute.go:235-236 records the reroute (store.NoteReroute(...), which sets RerouteAt) and then posts the <!-- hive:rerouted … --> comment, which bumps the PR's updated_at. src/pkg/dashboard/stage_tracker_rework.go:160-166 builds the activity floor from requested, rec.LastNudgeAt and rec.EnteredAt only — rec.RerouteAt is not in it. When the reroute lands as queued (relay busy / refused, so FixWorkFor returns Queued, not InFlight), the queued evidence set at :152-157 is then overwritten at :166-169 once updated_at passes the floor + 2 min: the pill reads waiting on @target · acknowledged and the tooltip says "@target acknowledged · activity on the PR" when the only activity was the hive's own note. That is exactly the (a)-vs-(b) confusion the issue asks to remove. Dispatched reroutes are unaffected (InFlight returns early at :141-147).

		floor := requested
		if rec.LastNudgeAt.After(floor) {
			floor = rec.LastNudgeAt
		}
		if rec.EnteredAt.After(floor) {
			floor = rec.EnteredAt
		}
		if rec.RerouteAt.After(floor) {
			floor = rec.RerouteAt
		}

Worth a 16th case in TestStageTrackerReworkFor: RerouteTo set, RerouteAt = requested+30m, fix queued for the target, UpdatedAt = RerouteAt+30s → expect requested/queued, not acknowledged.

— hive: agent=adjudicator-3 backend=copilot model=claude-fable-5.1 copilot=1.0.88

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correctness review (read at head 16914ca; stage_tracker_rework.go, stagelabels/store.go, automerge_stage_labels.go, fixqueue.go).

1. acknowledged is derived from PR updated_at, which the hive's own writes bump — a 24h-stalled row will read as "acknowledged"

src/pkg/dashboard/stage_tracker_rework.go:165-179 sets acknowledged/activity when it.UpdatedAt > max(requested, LastNudgeAt, EnteredAt) + 2min. Only the hive's initial writes are excluded by that floor. Every later hive-side write on the PR also bumps updated_at: the stage/stalled label after the 24h dwell (stagelabels.go:272-273, :138), needs-rebase / ci-failing modifier flips, label healing, takeover/reroute comments, operator holds. The stalled label is literally "nobody is working it" (stagelabels.go:24), and this code turns it into waiting on @x · acknowledged and an event line "@x acknowledged the rework request". Maintainer review comments produce the same false positive.

The record the tracker already holds solves this: Record.LastActivityAt (store.go:277-282) is "when somebody other than the hive last touched the item … Stalled measures quiet time from here, never from the PR's updated_at (which the hive's own writes bump)" (#12534). It is refreshed every reconcile cycle for every PR, including 071/072 (automerge_stage_labels.go:1058-1067, store.go:646-690; own comments are netted out via OwnComments).

Suggested fix — use LastActivityAt and fall back to updated_at only for records that predate it:

--- a/src/pkg/dashboard/stage_tracker_rework.go
+++ b/src/pkg/dashboard/stage_tracker_rework.go
@@ -162,20 +162,30 @@ func stageTrackerReworkFor(...) *StageTrackerRework {
-	// Acknowledged: the PR moved after the request and after the hive's own
-	// last comment on it — somebody replied or edited.
-	if it.UpdatedAt != nil {
+	// Acknowledged: somebody other than the hive touched the PR after the
+	// request. The record's LastActivityAt already nets out the hive's own
+	// labels and comments (hivecommons/hive#12534); updated_at is only the
+	// fallback for records written before it existed, and the hive's later
+	// writes (stage/stalled, modifier flips) bump it too.
+	activity, slack := rec.LastActivityAt, time.Duration(0)
+	if activity.IsZero() && it.UpdatedAt != nil {
+		activity, slack = *it.UpdatedAt, reworkActivitySlack
+	}
+	if !activity.IsZero() {
 		floor := requested
 		if rec.LastNudgeAt.After(floor) {
 			floor = rec.LastNudgeAt
 		}
 		if rec.EnteredAt.After(floor) {
 			floor = rec.EnteredAt
 		}
-		if u := *it.UpdatedAt; u.After(floor.Add(reworkActivitySlack)) && !u.After(now.Add(reworkActivitySlack)) {
+		if u := activity; u.After(floor.Add(slack)) && !u.After(now.Add(reworkActivitySlack)) {
 			out.State, out.Evidence, out.Mode, out.Ahead = reworkStateAcknowledged, reworkEvidenceActivity, "", 0
 			out.Since = &u
 			return out
 		}
 	}

Please add a TestStageTrackerReworkFor case for it: rec.LastActivityAt = requested−1m, UpdatedAt = requested+3h (hive label write) → expect requested, not acknowledged. None of the 15 current cases exercise a hive write after the nudge (stage_tracker_rework_test.go:60-98).

2. (advisory) pushed cannot be detected on a 071 row that was never nudged

stage_tracker_rework.go:128 requires rec.NudgeHead != "". A 071 row dated from EnteredAt (the "071 without a nudge" case, :107-113) has no head to compare against, so a new push falls through to acknowledged via activity rather than pushed. Not blocking — the stage engine still routes to 050 next sweep — but the chip will say "acknowledged" for a push, and the PR body's state table does not mention the gap. Worth a note in dashboard-sections.md or a Head captured at stage entry in a follow-up.

— hive: agent=adjudicator backend=copilot model=claude-fable-5.1 copilot=1.0.88

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Hive filed review findings that do not block this PR as backlog items:

Cap: 10 backlog item(s) per PR per day.

@hivecommons-hive hivecommons-hive Bot added stage/071-needs-author Human-authored PR: CI red, changes requested or conflicting; diagnosis posted, the author must act and removed stage/050-review-pending Review swarm requested; awaiting a verdict for the current head labels Oct 29, 2026
@hivecommons-hive

Copy link
Copy Markdown
Contributor

@clubanderson this PR is held at stage/071-needs-author and the hive will not merge it yet.

Why:

  • the review swarm requested changes

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.

@clubanderson
clubanderson merged commit 8785546 into v5 Oct 29, 2026
87 of 92 checks passed
@kubestellar-prow
kubestellar-prow Bot deleted the rework-pickup-signal branch October 29, 2026 04:04
@github-actions

Copy link
Copy Markdown
Contributor

Thank you for your contribution! Your PR has been merged.

We'd love to hear how your experience was: share feedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author/human A person pushed this PR themselves conflicts-with-open-pr Open PR has a merge conflict with another open PR dco All commits are DCO signed-off dco-signoff: yes Indicates the PR's author has signed the DCO. role/trusted Author is trusted for unattended merge (trusted-author role or registry/claim tier in require_tiers) size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. stage/071-needs-author Human-authored PR: CI red, changes requested or conflicting; diagnosis posted, the author must act

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stage tracker: no signal whether the author or clanker has picked up a requested rework

1 participant