refactor(queue): extract the public-comment merge-facts derivation from maybePublishPrPublicSurface#5787
Conversation
…om maybePublishPrPublicSurface (JSONbored#4607) `maybePublishPrPublicSurface` is 2,600+ lines, and JSONbored#4607's stated cost is that "most cross-cutting review-pipeline concerns live as unnamed inline blocks in one function rather than named, independently-testable steps". This lifts one such block into a named step. `derivePublicCommentMergeFacts` derives the five merge/disposition values the public PR comment renders -- ciState, mergeStateLabel, mergeReadiness, heldForReview, neverClosed -- from the live CI aggregate, the live merge-state refresh, the repo settings and the changed files. Its output IS buildUnifiedCommentBody's input contract for those fields, so the seam is a real step rather than an arbitrary cut. It is pure: the `incr()` metrics emit that sat in the middle of the block stays at the call site, since it reads the gate conclusion the derivation never sees. These flags exist so the COMMENT agrees with the ACTION the disposition planner takes -- heldForReview for a guardrail-touching diff (#guarded-hold-comment), neverClosed for an owner/protected-automation author (JSONbored#8/JSONbored#9). Until now they were only reachable by standing up a whole webhook delivery: the renderer's own suite passes them in as hand-written literals, and the queue suites exercise them transitively. They now have direct table tests, including the empty-changed-file-list fail-safe (an unresolved file list HOLDS for review rather than claiming safe-to-merge), which had no test at all. No behavior change: the 882 tests in the existing queue suites pass unchanged.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5787 +/- ##
=======================================
Coverage 95.06% 95.07%
=======================================
Files 580 580
Lines 46156 46152 -4
Branches 14804 14800 -4
=======================================
Hits 43880 43880
Misses 1516 1516
+ Partials 760 756 -4
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-14 15:52:35 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 4 non-blocking
Linked issue satisfactionPartially addressed Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk Gittensory a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
Closes #4607
Summary
maybePublishPrPublicSurfaceis 2,600+ lines, and #4607's stated cost is precise: "most cross-cutting review-pipeline concerns live as unnamed inline blocks in one function rather than named, independently-testable steps." This PR lifts one such block out as a named step, in the same incremental-slice style as the merged #4688 / #4695 / #4728 / #4752 / #5066.New:
derivePublicCommentMergeFacts(src/queue/processors.ts) — derives the five merge/disposition values the public PR comment renders (ciState,mergeStateLabel,mergeReadiness,heldForReview,neverClosed) from the live CI aggregate, the live merge-state refresh, the repo settings, and the changed files.The seam is real rather than arbitrary: this function's return shape is
buildUnifiedCommentBody's input contract for exactly those five fields. It is pure — theincr("loopover_gate_decisions_total", …)metrics emit that sat in the middle of the original block stays at the call site, because it reads the gate conclusion the derivation never sees.Why these two flags matter
They exist so the comment agrees with the action the disposition planner will take:
heldForReview— a clean, green PR whose diff touches a hard-guardrail path is held for owner review byplanAgentMaintenanceActions, never auto-merged, so the comment must not headline "safe to merge" (#guarded-hold-comment). It uses the same sharedisGuardrailHitthe planner uses, not a second copy.neverClosed— the disposition never auto-closes a repo-owner or protected-automation PR, so a gate "close" verdict on one must headline "held", not "Closed" (#8/#9).The testability win
This is the part that makes the block worth extracting. Today those five values are:
test/unit/unified-comment-bridge.test.ts:506hand-writesconst mergeReadiness: MergeReadiness = { ciState: "passed", mergeStateLabel: "clean" }rather than deriving it; andThat same test file notes at
:1205that testingmaybePublishPrPublicSurfaceend-to-end "is net-new and entangled". After this change the derivation is directly table-testable.One behavior had no test at all and is now pinned: an empty changed-file list holds for review rather than claiming safe-to-merge.
isGuardrailHittreats "no known changed paths" as a hit — the file list may simply not have resolved, and a false "safe to merge" is the dangerous direction. I asserted the opposite first, and the code corrected me; the fail-safe is intentional and is now locked down.Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run typechecknpm run test:coveragelocally;codecov/patchrequires >=99% coverage of the lines AND branches changednpm run engine-parity:drift-checknpm run docs:drift-checknpm run ui:openapi:checknpm audit --audit-level=moderatePatch coverage: 100% (13/13 executable changed lines, zero partial branches), measured by intersecting the lcov report against this diff's added lines.
No behavior change: the 882 tests in the existing queue suites (
queue,queue-2…queue-5,queue-lifecycle-guards) pass unchanged. New suitetest/unit/processors-public-comment-merge-facts.test.ts(13 tests) covers every branch of the extracted step: live-vs-stored merge-state fallback and the both-absent case;passed/failed/elseciStatecollapse; the failing-check projection with and withoutsummary/detailsUrl(absent optionals must be omitted, never rendered asundefined); non-required red checks staying visible without turning the PR red; guardrail hit / miss / mixed / override-away; the empty-file-list fail-safe; andneverClosedfor owner (case-insensitively), protected bot, ordinary contributor, missing login, and an owner-lessrepoFullName(the"" === ""trap that would otherwise make an author-less PR un-closable).If any required check was skipped, explain why:
Safety
UI Evidencesection. Not applicable here.UI Evidence
Not applicable — no UI, frontend, docs, or extension surface is touched. The diff is one backend file plus one new unit-test file.
Notes
pr.mergeableState/pr.authorLoginbecome explicit arguments), so this is a no-op at runtime.settingsparameter is narrowed to the two fields the derivation actually reads, so the step can be tested without constructing a wholeRepositorySettings.