fix(review): stop the surface lane from auto-closing clean registry submissions - #2586
Conversation
…ubmissions Two bugs in the registry surface-review lane were closing structurally clean registry submissions: 1. classifyRegistryPrScope already approves a genuine debut-provider companion file riding alongside an entry submission (isAllowed matches providerFilePattern), but runSurfaceReview threw that away and routed any companion file straight to manual review. It now validates the companion via the spec's assessProviderEntry and combines it with the entry's own assessment: merge only when both sides are clean, close if either is invalid. artifactPattern companions (generated build output) are still allowed as-is with no validation attempted. The entry/base/companion fetches run concurrently instead of sequentially. 2. A duplicate_pr_risk finding (severity "warning") escalated into a hard blocker by duplicatePrGateMode: "block" was able to singlehandedly override a clean, deterministic surface-lane merge and force the whole PR closed via applySurfaceGate's unconditional union. It now downgrades to a neutral hold instead, mirroring the existing AI-judgment-only carve-out, and the held check-run's title/summary name the actual reason. This is scoped to exactly duplicate_pr_risk (not every warning-severity finding), since missing_linked_issue / self_authored_linked_issue / manifest_linked_issue_required / manifest_missing_tests are also warning-severity but block-mode-escalatable via their own independent maintainer-configured gate and must still close outright when a maintainer opts into that. Both were confirmed live against JSONbored/metagraphed: PR #2654 (an entry + debut-provider companion) and PR #2680 (a provider-only resubmission sharing #2654's linked issue) now resolve to merge and a held-for-review neutral hold respectively, instead of reject/close.
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-02 11:01:23 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 6 non-blocking
Review context
Contributor next steps
Signal definitions
🟩 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 Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2586 +/- ##
=======================================
Coverage 95.98% 95.99%
=======================================
Files 229 229
Lines 25810 25837 +27
Branches 9389 9400 +11
=======================================
+ Hits 24774 24801 +27
Misses 425 425
Partials 611 611
🚀 New features to boost your workflow:
|
…merging it classifyRegistryPrScope identifies a companion by file path alone (providerFilePattern), which only proves the file is shaped like a provider submission, not that it's a genuine debut (a brand-new provider, not an edit to one already registered). runSurfaceReview now also fetches the companion's base content and only runs it through the debut-provider merge/close flow when base is absent; a companion that already exists at base routes to manual instead, since editing an existing, unrelated provider record alongside an entry submission is a more sensitive shape that needs a human. The entry and both companion refs are still fetched in one concurrent round-trip.
|
Pushed a follow-up fix: the companion-provider path was proving a companion is a provider-shaped file (path pattern match) but not that it's actually a debut (a brand-new provider, not an edit to one already registered).
|
Summary
Two bugs in the registry surface-review lane were closing (or routing to manual review) structurally clean registry submissions:
Bug 1 — a genuine debut-provider companion was rejected even though the scope classifier already approved it.
classifyRegistryPrScope(src/review/content-lane/registry-logic.ts) already computes that a companion file matchingproviderFilePatternis a legitimate part of an "entry + its first provider in the same PR" submission — butrunSurfaceReview(src/review/content-lane/orchestrator.ts) threw that away and routed any companion file straight to manual review, never invoking the already-validated standalone-provider path for it.RegistryScopeResultnow carries aproviderCompanionFilefield; when present, the orchestrator loads and validates it via the spec'sassessProviderEntryand combines that with the entry's own aggregate assessment — merge only when both sides are clean, close if either is invalid.artifactPatterncompanions (generated build output) remain allowed as-is with no validation attempted. The entry head/base fetch and the companion fetch now run concurrently (Promise.all) instead of three sequential round-trips.Bug 2 — a warning-severity finding could singlehandedly force a hard close.
duplicate_pr_risk(a same-linked-issue overlap finding) is always pushed atseverity: "warning", butduplicatePrGateMode: "block"(the deliberate, twice-reaffirmed default — see#488and#644) escalates it into a hard blocker in the generic gate.applySurfaceGate(src/review/content-lane-wire.ts) then unconditionally unioned that blocker into the final conclusion, even when the surface lane's own deterministic verdict for that PR was a clean merge — a same-linked-issue lead is not proof of a defect in the PR's own content. There's already a purpose-built escape hatch for the legitimate "sequenced, non-competing" case (isDuplicateClusterWinnerByClaim+GITTENSORY_DUPLICATE_WINNER), but it doesn't help every PR in a cluster — only the earliest claimant. A newisDuplicateOnlyFailurecheck (mirroring the existingisAiJudgmentOnlyFailurecarve-out) now downgrades aduplicate_pr_risk-only generic failure to a neutral hold instead of a close when the surface lane merges cleanly, with the held check-run's title/summary naming the actual reason and the finding staying visible inwarnings. This is scoped to exactlyduplicate_pr_riskvia a code allowlist, not every warning-severity finding —missing_linked_issue,self_authored_linked_issue,manifest_linked_issue_required, andmanifest_missing_testsare also severity "warning" but are block-mode-escalatable via their own independent maintainer-configured gate, and that explicit opt-in must still close a PR outright. (An earlier draft of this fix used a blanket severity check instead of a code allowlist; an adversarial review caught that it would have silently defeated those other four gates, so it was replaced before this PR was opened.)Both fixes are fully generic — no repo name, installation ID, or PR number is hardcoded into the engine.
Live evidence (JSONbored/metagraphed, read-only — not touched by this PR)
feat(registry): enrich SN28 gm) adds two clean surfaces toregistry/subnets/gm.jsonand a genuine debutregistry/providers/gm.jsonin the same PR — exactly Bug 1's shape. Before this fix it was rejected with "surface contributions must only append to one existing registry/subnets/<slug>.json manifest and must not add provider files." Traced against the actual current diff, it now resolves to merge.registry(providers): register gm provider) is a clean, single-file debut-provider submission whose own surface-lane review found zero real blockers, but it references the same linked issue (feat(enrichment): deep-nesting / arrow-anti-pattern heuristic analyzer #2030) as feat(signals): flag open-vs-open PR file-path collisions #2654 and was closed solely for "Linked issue overlaps another open PR (feat(signals): flag open-vs-open PR file-path collisions #2654)." Traced against the actual current diff, it now resolves to a neutral hold for review (not merge, since it isn't the earliest claimant of the shared issue — but no longer an auto-close either) instead of reject/close.Operator note —
GITTENSORY_DUPLICATE_WINNERThis PR does not flip
GITTENSORY_DUPLICATE_WINNERon in the deployed environment. That flag (already fully implemented and already covered by pre-existing tests intest/unit/rules.test.tsandtest/unit/queue.test.ts) is a global toggle affecting every installed repo, not something to change from inside a code PR — it needs an explicit deploy-time decision from whoever owns the deployment config. New tests in this PR (test/unit/rules.test.ts,test/unit/content-lane-wire.test.ts) exercise both the flag-on suppression path and the new neutral-hold path so the interaction is verified end to end regardless of when/whether the flag is enabled.Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally — the four changedsrc/**files (registry-logic.ts,orchestrator.ts,content-lane-wire.ts,advisory.ts) are 100% line-covered, and every uncovered branch reported for them is a pre-existing, untouched line (verified individually againstgit diff), not part of this diff.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateSafety
ui:openapi:checkconfirms no drift.UI Evidencesection below with screenshots. — N/A, backend-only change, no UI evidence needed.Notes
GITTENSORY_DUPLICATE_WINNER.