Repository navigation
🐛 fix(automerge): sign-off stall notes name the squash gate only where it runs; log the stall at INFO - #14481
Conversation
…e it runs; log the stall at INFO
The adopted-PR stall escalation ("adopted PR sits with nothing the hive
can push") is designed, but it was logged at WARN, so the slog feed counted
three projectbluefin parks toward an unclassified_error_repeated fleet
self-report (hivecommons#14466). It is now logged at INFO, the same line as hivecommons#14480 on
v5.
The adoption stall note and the maintainer sign-off note said the
`Sign-off survives the squash` gate stays red. That check is
dco-squash-attribution.yml, which only some repositories carry; elsewhere
the hive's own commit check holds the head. noteStageDCOGate now records
whether the head's required or reported checks include it, and the notes
say the hive will not squash-merge the head, naming the check only when it
is there.
Refs hivecommons#14466
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BQYnPGFJx81c8JXR3o1sg1
Signed-off-by: Danathar <Danathar@users.noreply.github.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 |
|
@Danathar this PR is back in your court ( Failing checks:
Reply here or push a new head to this branch (same sign-off); CI and the review swarm re-run automatically and the PR returns to the normal path. Your relay session received this as a |
There was a problem hiding this comment.
Looks correct to me. Two notes for the maintainer.
The red checks are not this PR's. test (agent 4/5) (job 121943222780) fails TestPollTmuxOutputForAgent_WiresThrashBreaker 3/3 at src/pkg/agent/thrash_poller_wiring_test.go:110; coverage and test are the roll-ups of that shard. This PR touches nothing under pkg/agent. That is the v6 half of incident #14406, and #14494 forward-ports the #14415 fix. Once #14494 lands, a re-run here should be green.
The change itself, read against v6:
squashSignoffGateNote(automerge_merge_commit.go:157-163) returns the check mention only whenDetail.SquashSignoffGateis set andDCOGateHeadis the observed head. The flag is set innoteStageDCOGate(automerge_stage_labels.go:563-575) from the same required/observed sets asDCOGate, andStageTracker.drain(:296) only copies it inside the existingDCOGateHead == o.HeadSHAguard, so the per-head semantics hold on both paths andTestSquashSignoffGateNoteIsPerHeadpins them.c.infoexists on v6 (automerge_sweep.go:3213) andslogfeed.minLevel = slog.LevelWarn(slogfeed.go:31), so the INFO line genuinely drops out of the self-report feed;TestAdoptionStallEscalationLogsAtInfodrives the real handler rather than mocking it.- Both call sites that carried the old "gate stays red" wording (
adoptionBlockerTextatautomerge_contributor_adopt.go:455andSignoffAttributionDecisionCommentatautomerge_merge_commit.go:182) are updated; no other non-test occurrence remains on the head. - The log-level change at
automerge_contributor_adopt.go:1179is the same one-line edit as #14480 on v5, as the body says, so the forward-merge meets the same line on both sides.
— hive: agent=reviewer-2 backend=copilot model=claude-fable-5.1
|
hive/shared-ci: the 🐝 Hive Agent: — hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88 |
|
stage 060-reviewed → 050-review-pending: shared-ci-incident:14506 |
…14415) (#14494) Port 3540e2a from v5 to the v6 path src/pkg/agent/. Give the thrash-breaker wiring test its own tmux socket and a plain shell so co-sharded tests cannot change its server options or tear down its session; emit the blocked glyph with single octal escapes; cancel and drain the poller during cleanup. Unblocks the test (agent 4/5) shard on v6 fork PRs (#14454, #14481). Signed-off-by: scanner <280983584+hivecommons-hive[bot]@users.noreply.github.com> Co-authored-by: scanner <280983584+hivecommons-hive[bot]@users.noreply.github.com>
Open PR overlap checkBase branch: Conflicts are checked with every PR merged onto the current tip of No conflicting open PRs or same-file overlaps were found. |
|
Shared-CI incident #14506 is resolved: the 🐝 Hive Agent: — hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88 |
|
hive/awaiting-ci: branch synced with v6 (picks up #14494, which fixed the 🐝 Hive Agent: — hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88 |
|
@Danathar this PR is back in your court ( Failing checks:
Reply here or push a new head to this branch (same sign-off); CI and the review swarm re-run automatically and the PR returns to the normal path. Your relay session received this as a |
There was a problem hiding this comment.
Read automerge_merge_commit.go, automerge_contributor_adopt.go, automerge_stage_labels.go and prstage/types.go at 101417b; this looks correct to me.
SquashSignoffGateis written innoteStageDCOGate(automerge_stage_labels.go:573) together withDCOGateHead, anddrain()(:294-297) only copies it under the same head guard asDCOGate, so a stale value cannot carry across heads.squashSignoffGateNote(automerge_merge_commit.go:157-163) repeats that guard. Both note sites now use it; no non-test note text still hardcodes the gate name.warn→infoatautomerge_contributor_adopt.go:1179is a log-level change only.
CI: test (agent 1/5) is red on TestSendKick_RestartsCrashedCLIThenDelivers and TestRestart_CancelsPendingAsyncKick in pkg/agent, which this diff does not touch; coverage fails only because that shard failed ("Coverage requires successful test shards … agent=failure"). That looks like an unrelated flake rather than something for this PR to fix. go build ./pkg/github/automerge/ ./pkg/stageengine/... passes locally.
— hive: agent=reviewer-2 backend=copilot model=claude-fable-5.1 copilot=1.0.88
There was a problem hiding this comment.
Read the diff against the v6 tree. Looks correct to me.
.github/workflows/dco-squash-attribution.yml:34— job name is exactlySign-off survives the squash, matchingsquashSignoffCheck(automerge_merge_commit.go:147);isSquashSignoffCheckcompares case-insensitively.automerge_stage_labels.go:557-573—noteStageDCOGateis called unconditionally from the sweep for every PR (automerge_sweep.go:2961) over bothrequiredandst.Observed, soSquashSignoffGateis populated whereverDCOGateis;drain()(line 294-296) copies it only under the same head match, so a stale head reads as "not present" and the note falls back to the plain wording.escapeStalledAdoptionWARN→INFO (automerge_contributor_adopt.go:1179) matches the v5 line in #14480, as the body says.- Builds clean at 101417b.
The red test (agent 1/5) / coverage on run 40478131307 are pkg/agent tmux restart tests (kick_cancel_test.go:299, kick_restart_recovery_test.go:132), unrelated to this diff.
— hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88
|
hive/check-report (head 101417b): the 🐝 Hive Agent: — hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88 |
There was a problem hiding this comment.
Reviewed (correctness) — no blocking findings at 101417b. Two advisory notes:
-
The check can be missed on a repo that runs it (conservative miss, but permanent per head).
SquashSignoffGateis only set fromcommitGreenForPRWith(src/pkg/github/automerge/automerge_sweep.go:2961), and the tracker clearst.detailsevery drain (src/pkg/github/automerge/automerge_stage_labels.go:304). If the cycle in whichescapeStalledAdoptionfirst fires bails before CI evaluation (behind/conflicting/missing-head paths atautomerge_sweep.go:1690-1703), the one-per-head note atautomerge_contributor_adopt.go:1183is written without the mention and is never rewritten. Same cycle-scoped behaviour as the pre-existingDCOGate, and omitting the mention is the safe direction, so advisory only — but the body's "name the check only when the head's … checks include it" is really "when they were observed in the escalating cycle". -
The INFO demotion covers every stall reason.
c.infoatautomerge_contributor_adopt.go:1179runs for whateveradoptionStalledReasonreturns, not onlyhive-signoff-attribution. That matches #14480 on v5 and the PR body's description of "the line", so no change requested; just noting the scope is broader than the title suggests.
Verified: Observed holds check-run names (src/pkg/github/commit_ci.go:102) and the workflow's job name is Sign-off survives the squash (.github/workflows/dco-squash-attribution.yml:34), so isSquashSignoffCheck matches in production. The facts round-trip (src/pkg/stageengine/derive_pr.go:151-157) drops SquashSignoffGate, but observationsFrom is test-only, so notes are unaffected.
— hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88
There was a problem hiding this comment.
Read the diff against the tree at 101417b, including the callers. Looks correct to me.
noteStageDCOGateis fed fromautomerge_sweep.go:2961withst.Observed, whichcommit_ci.go:437fills with every status-context/check-run name on the head — soisSquashSignoffCheckwill seeSign-off survives the squashexactly when the workflow (.github/workflows/dco-squash-attribution.yml:34,name: Sign-off survives the squash) actually reported on this head.StageTracker.drain(automerge_stage_labels.go:293-296) copiesSquashSignoffGateunder the existingDCOGateHead == o.HeadSHAguard, andsquashSignoffGateNotere-checks the head, so a gate seen on an earlier head is not named on the new one.- Sweep order holds:
SweepContributorLaneAutoMerges(CI evaluation) runs beforeApplyStageLabelsatautomerge_sweep.go:1533, matching the order the new tests set up. go build ./pkg/github/automerge/ ./pkg/stageengine/...is clean at this head; CI is green (Sign-off survives the squashpassed on the latest run; the three CANCELLED entries are superseded runs).
Body matches the diff: the only behaviour changes are the WARN→INFO level at automerge_contributor_adopt.go:1179 and the two note strings.
— hive: agent=reviewer-2 backend=copilot model=claude-fable-5.1 copilot=1.0.88
Summary
Follow-up to the triage on #14466. The hive parked three adopted contributor PRs on the projectbluefin hive at
stage/085asadoption-stalled:hive-signoff-attribution, right after its own fix commit:The park itself is designed (#13800, #13803). Two things around it were wrong, and this changes only those:
unclassified_error_repeatedfleet self-report ([selfreport] unclassified_error_repeated: stage labels: adopted PR sits with nothing the hive can push; escalating to nee… #14466). It is now logged at INFO, as the triage suggested.Sign-off survives the squashgate "stays red". That check is.github/workflows/dco-squash-attribution.yml, which only some repositories carry. None of the three repos above runs it; the hive's own commit check is what held them. The notes now say the hive will not squash-merge the head, and name the check only when the head's required or reported checks include it.The log-level line is byte-identical to #14480, which the hive's scanner opened against v5. This PR carries it to v6 with a regression test, so the v5→v6 forward-merge meets the same line on both sides.
Cause
At 392df48:
automerge_contributor_adopt.go:1179logs the escalation withc.warn.slogfeed.go:31observes WARN and above.automerge_contributor_adopt.go:455(the adoption stall note) andautomerge_merge_commit.go:161(the maintainer sign-off note) always say the gate stays red. The hold comes from the stage pass's own commit check (automerge_stage_dco.go:67), on every managed repository.Change
c.info. The escalation, its note and its stage are unchanged.noteStageDCOGatealready reads the head's required and reported check names for thedcocontext. It now also recordsSquashSignoffGatewhen one of them isSign-off survives the squash, for the same head asDCOGateHead. The tracker copies it with the DCO gate, under the same head guard.Sign-off survives the squashcheck stays red)" only when that check was seen on this head (squashSignoffGateNote). The maintainer asks and the merge-commit route are unchanged.src/docs/labels-and-control-signals.mdsaid the required check "is red there" for every such head. It now says the hive will not squash-merge the head, that the check is red too only where a repository runs the workflow, and that the notes name the check only then.Testing
From
src/under/var/tmp,-count=1:go test ./pkg/github/... ./pkg/stageengine/... ./pkg/stagelabels/... ./pkg/fleetreport/... ./pkg/review/...: allok.go build ./pkg/... ./cmd/...succeeds;go vet ./pkg/github/automerge ./pkg/stageengine/...andgofmtare clean.check-docs-links.pyandcheck-docs-citations.pypass onsrc/docs;check-changelog-fragment.sh v6passes.New and changed tests:
TestSignoffStallNoteNamesSquashGateOnlyWhereItRunsnoteStageDCOGateand the tracker.TestSignoffAttributionDecisionNoteNamesSquashGateOnlyWhereItRunsTestSquashSignoffGateNoteIsPerHeadTestAdoptionStallEscalationLogsAtInfoslogfeedhandler observes nothing for it.TestAdoptedInPlaceSquashUnsafeHiveCommitStallsWithoutSupersedeMutation checks
Each part was broken in turn and restored from a backup:
noteStageDCOGate: the existing stall test and both wording tests fail.Not verified
stage/074, which stops the review fixer on the hive's own head) is raised on [selfreport] unclassified_error_repeated: stage labels: adopted PR sits with nothing the hive can push; escalating to nee… #14466 as a proposal, not changed here.Contributor checklist
changelog.d/fixed-signoff-stall-note-and-log-level.md.v6.src/docs/labels-and-control-signals.md).🤖 Generated with Claude Code
https://claude.ai/code/session_01BQYnPGFJx81c8JXR3o1sg1