Skip to content

πŸ› dashboard: Let hive decide preview is one clear decision, not a wall of text - #15399

Merged
clubanderson merged 2 commits into
v5from
fix/decide-preview-dialog
Oct 29, 2026
Merged

clubanderson merged 2 commits into
v5from
fix/decide-preview-dialog

Conversation

@clubanderson

Copy link
Copy Markdown
Member

Fixes #15397

Operator feedback on the "Let hive decide β€” preview" dialog (seen on #15332): "yikes - this is a mess. different fonts, repeated wording, placement of text and buttons, explanation is confusing" β€” "this needs to be exceedingly simple to understand and act on."

What changed

Plan API (GET …/decide/delegated/plan, api_repo_item_decide_delegated_plan.go)

  • summary is one verb-first sentence with no Hive would: prefix (the prefix was composed on both sides β€” Go put it in summary, JS prepended it again β†’ "Hive would: Hive would:").
  • why is one plain line (≀ 12 words); consequences ≀ 2.
  • New fields: title, ladder (πŸ› Let hive decide: close already-fixed PRs instead of adopting themΒ #15301), mergeable_as_is. The decide:merge-now alternative is dropped unless the head is mergeable as it is (ladder rung mergeable-as-is, or head facts when the rule had no ladder), so the API and the UI can't disagree.

Dashboard (static-src/js/tracker-actions.js, static-src/css/tracker.css, regenerated static/index.html)

  • One renderer (stageTrackerDelegatePlanView β†’ stageTrackerDelegatePlanHtml) for PR, issue, batch and the adopt / close / return variants: title Β· subject line (repo#N Β· title…) Β· optional ⚠ Sentinel chip Β· Hive would sentence Β· Why Β· Then list Β· collapsed Details (rails, "Why not the others" ruled-out rungs, sentinel finding).
  • Exactly two buttons β€” Cancel Β· Let hive do that β€” right-aligned with the .hive-dialog-btn family; Approve & merge as-is only appears when mergeable_as_is (greyed with a reason if the caller lacks the merger role).
  • Tokens only, no new raw sizes/colours/inline styles.

Tests

Docs / changelog: src/docs/dashboard-sections.md (Preview before acting), src/docs/api-reference/packs-and-acmm.md, changelog.d/fixed-decide-preview-one-decision.md.

Before / after (#15332, headless)

Before After
the old preview: doubled Hive would, repo#number twice, rails footer, merge button offered on a red head the new preview: title, subject line, Sentinel chip, one bold sentence, Why, Then list, collapsed Details, two buttons
After β€” Details expanded, and a mergeable-as-is PR
Details open Mergeable as-is
Details disclosure open showing the sentinel finding, why-not-the-others ladder and rails mergeable-as-is preview with the third Approve & merge as-is button

…l of text

The delegated-decision preview showed the repo#number twice, composed
'Hive would:' twice (the plan API's summary already carried the prefix
and stageTrackerDelegatePlanText prepended it again), inlined the
consequences into a paragraph, drowned the decision under a rails
footer, and offered 'Approve & merge as-is' for a head the preview
itself called not mergeable.

The plan API now returns one verb-first sentence, a why line of at most
twelve words, at most two consequences, the ladder, and mergeable_as_is;
merge-now alternatives are dropped unless the head is mergeable as it
is. The dashboard renders every plan β€” PR, issue, adopt/close/return β€”
through one renderer: title, subject line, optional Sentinel chip,
'Hive would' sentence, Why, Then list, and a collapsed Details holding
the rails, the ruled-out rungs and the sentinel finding. Two buttons by
default; the merge button appears only when the ladder says
mergeable-as-is.

Fixes #15397

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

@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
#15402 πŸ› fix: show adopted PR provenance in the stage tracker same files src/pkg/dashboard/static/index.html
#15408 πŸ› tracker: merge outcomes always render in the Merge gate column; pending CI is not 'red' same files src/docs/dashboard-sections.md
src/pkg/dashboard/static-src/css/tracker.css
src/pkg/dashboard/static/index.html
#15406 πŸ› tracker: say it once, in plain words β€” simplify hovers, menus and captions same files src/docs/dashboard-sections.md
src/pkg/dashboard/stage_tracker_row_actions_test.go
src/pkg/dashboard/static-src/css/tracker.css
src/pkg/dashboard/static-src/js/tracker-actions.js
src/pkg/dashboard/static/index.html
#15400 πŸ› fix: keep merge queue position visible during sweeps same files src/pkg/dashboard/static/index.html
#15407 ✨ tracker: show where an adopted PR came from CONFLICT src/pkg/dashboard/static-src/css/tracker.css
src/pkg/dashboard/static/index.html

TestStageTrackerCuesWiring scans the tracker CSS block for raw colours;
'#15332' in a comment tripped its '#1' probe.

Signed-off-by: Andrew Anderson <andy@clubanderson.com>

@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=ci-maintainer backend=copilot model=claude-fable-5.1 copilot=1.0.88

@hivecommons-hive

Copy link
Copy Markdown
Contributor

stage 080-awaiting-merge-admission β†’ 050-review-pending: required-check-pending:build-and-test

@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 (head 499bb51)

1. Direction sentence garbles / drops the reviewer's question (medium, in-scope) β€” src/pkg/dashboard/api_repo_item_decide_delegated_plan.go:233-252 (delegatedPlanInstruction). When the PR has a fix list and in.Question is set, the function falls back to delegatedPlanPlain(d.Text). For a person-authored PR decideReturnToAuthor builds d.Text as "@author: make CI green without widening scope on #N; then it merges β€” @author, the reviewer asked: <question>" (src/pkg/delegatedecision/policy.go:613-626), and delegatedPlanPlain cuts at the first "; " (plan.go:297-300). Result: "Send #N back to its author with one instruction: @author: make CI green without widening scope on #N." β€” the reviewer's question (the only reason this branch exists) is lost, the @author: prefix is duplicated into the sentence, and the "one instruction" wording is wrong. No test covers Question != "". Suggested fix:

 func delegatedPlanInstruction(in delegatedecision.Input, d delegatedecision.Decision) string {
 	var fix []string
 	if in.Conflicting {
 		fix = append(fix, "rebase onto the base branch")
 	}
 	if in.DCOMissing {
 		fix = append(fix, "add the sign-off")
 	}
 	if !in.CIGreen {
 		fix = append(fix, "make CI green")
 	}
-	if len(fix) == 0 || strings.TrimSpace(in.Question) != "" {
+	question := strings.TrimSuffix(strings.TrimSpace(in.Question), ".")
+	if len(fix) == 0 && question == "" {
 		if text := delegatedPlanPlain(d.Text); text != "" {
 			return text
 		}
+		return "address the review"
 	}
 	if len(fix) == 0 {
-		return "address the review"
+		return "answer the reviewer: " + question
 	}
+	if question != "" {
+		return strings.Join(fix, ", ") + ", and answer the reviewer: " + question
+	}
 	return strings.Join(fix, ", ") + ", nothing else"
 }

plus a case in TestDelegatedPlanWordingDirectionIsOneSentence with OwnerAuthor: false, TrustedAuthor: true, Question: "…".

2. mergeable_as_is fallback ignores policy holds the ladder would have ruled out (low, in-scope, advisory) β€” plan.go:306-315: when the ladder does not land (decideLadder returns ok=false for ReporterTrustHold/WorkflowPath, ladder.go:198-200), d.Ladder is nil and the fallback is head facts only, so a green head under a reporter-trust hold still gets mergeable_as_is: true and the merge button, even though rung 2 had skipped mergeable-as-is with "reporter-trust hold" (ladder.go:183, mergeBlockers ladder.go:288-293). If an as-is merge is meant as a deliberate maintainer override there, fine β€” but then the Details list won't show the ruled-out rung either. Consider && !in.ReporterTrustHold && !in.AdoptionStalled in the fallback to match rung 2.

Otherwise verified: in-place filter of plan.Alternatives is safe (options are freshly built per call, delegated_decision_human_merge.go:88); merge-now disabled reason merger role required is always present (:48,58); JS OffersMerge/Mergeable gating and the #15332 duplicate-prefix normalisation match the Go output.

β€” hive: agent=adjudicator 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.

Read the Go and JS against the tree; this looks correct to me.

  • The doubled prefix is fixed at both ends: delegatedPlanWording no longer emits Hive would: (api_repo_item_decide_delegated_plan.go:185-230) and stageTrackerPlanSentence strips any stale (hive would:\s*)+ from an older server (tracker-actions.js:1216), so a mixed-version spoke still renders one eyebrow.
  • The API and the dialog cannot disagree on the merge button: the server drops decide:merge-now unless MergeableAsIs (:156-166), and stageTrackerDelegatePlanOffersMerge additionally requires mergeable_as_is === true (tracker-actions.js:1300). A non-merger still gets the option with enabled=false from delegatedHumanMergeOptions (delegated_decision_human_merge.go:48), so the greyed-with-reason path in the body is real.
  • The 090 shortcut (delegatedHumanMergeOutcome) builds a Decision with no Ladder, so MergeableAsIs falls back to head facts there β€” a green 090 head keeps the as-is button, a red one loses it. Sensible.
  • stageTrackerDelegatePlanText has no remaining callers outside the regenerated index.html; static-src and static/index.html are in sync (CI test (rest) green).

One open question, not a defect: with a Ladder present, mergeable_as_is is d.Ladder.Decision == RuleMergeableAsIs (:313). Rung 2 is skipped for a green, conflict-free, signed head when ReporterTrustHold or AdoptionStalled is set (delegatedecision/ladder.go:183), and the ladder then lands on rung 4/5 with a Ladder attached β€” so a merger loses Approve & merge as-is on a head that is technically mergeable, where the old dialog offered it. If that narrowing is intended (the ladder's judgement outranks the head facts), fine; if not, the fallback at :315 could also apply when the ladder's RuledOut entry for mergeable-as-is names only a trust/stall hold.

β€” hive: agent=reviewer 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.

Read the Go change against v5 and ran the generator check on 499bb51; looks correct to me.

  • Alternatives filter (api_repo_item_decide_delegated_plan.go, the kept := plan.Alternatives[:0] loop): decide:merge-now is dropped only when MergeableAsIs is false, and delegatedPlanMergeableAsIs defers to the ladder rung when a ladder ran and to !Conflicting && CIGreen && !DCOMissing otherwise. Both branches are asserted (TestDelegatedDecisionPlanMergeableAsIsOffersMerge offers it; the contributor-offline case asserts it is absent). The 090 shortcut path still gets its own alternatives first and then goes through the same filter, so the two paths cannot disagree β€” which is the point of the change.
  • Why/Direction wording: delegatedPlanWhy now suppresses the "untrusted / clanker offline" clauses for VerdictDirection and uses delegatedPlanBlockers instead, so a send-back no longer explains itself with trust facts that did not decide it. Consistent with the delegatedPlanInstruction fix list.
  • Source layout: static-src/js/tracker-actions.js, static-src/css/tracker.css and the regenerated static/index.html all move together; go run ./pkg/dashboard/webstatic/gen … -check exits 0 on this head, so TestIndexHTMLIsGenerated will pass.

One open question, not a defect: delegatedPlanPlain truncates at the first "; " and strips any (…#N) parenthetical. A rule rationale whose first clause is the less informative half would lose the useful part in the preview; the full text still rides ladder under Details, so this only matters if a rationale is written clause-second. Worth keeping in mind when adding rules.

β€” hive: agent=reviewer-2 backend=copilot model=claude-fable-5.1 copilot=1.0.88

@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
@clubanderson
clubanderson merged commit 4fe6eb4 into v5 Oct 29, 2026
77 of 78 checks passed
@kubestellar-prow
kubestellar-prow Bot deleted the fix/decide-preview-dialog branch October 29, 2026 15:33
@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

conflicts-with-open-pr Open PR has a merge conflict with another open PR dco-signoff: yes Indicates the PR's author has signed the DCO. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dashboard: "Let hive decide β€” preview" is a wall of text (doubled "Hive would", contradictory merge button, no hierarchy)

1 participant