Skip to content

checkSubmissionFreshness silently trusts a PR with a missing authorLogin, contradicting its own documented fail-closed contract #7794

Description

@JSONbored

Context

submission-freshness-check.ts's own header comment states the module's contract explicitly: "FAIL CLOSED: an unreachable/failed live-state fetch is treated as stale (aborts), never as 'no evidence of staleness, so proceed'." But the final author-comparison check (packages/loopover-miner/lib/submission-freshness-check.ts:143-148) does the opposite for a referencing PR whose authorLogin is missing/non-string (e.g. GitHub returns user: null for a deleted account):

const minerLoginKey = minerLogin.toLowerCase();
const addressedByAnotherAuthor = referencingPrs.some(
  (pr) => typeof pr.authorLogin === "string" && pr.authorLogin.trim().toLowerCase() !== minerLoginKey && (pr.state === "merged" || pr.state === "open"),
);

If pr.authorLogin isn't a string, the typeof === "string" guard short-circuits the predicate to false — a merged/open PR from an author GitHub can't identify is treated as NOT evidence of "already addressed," so the miner proceeds to open a duplicate PR.

Contrast with claim-conflict-resolver.ts's assembleCompetingClaims (packages/loopover-miner/lib/claim-conflict-resolver.ts:60-64), which handles the identical "is this PR someone else's" question for the identical reason but with the opposite, safer bias:

.filter((pr) => typeof pr.authorLogin !== "string" || pr.authorLogin.trim().toLowerCase() !== minerLoginKey)

Here, a missing authorLogin is treated as "can't rule out it's someone else" and is kept as a competing claim — the correct, fail-closed behavior.

Verified empirically (extracted the exact predicate and ran it in Node): with a merged PR whose authorLogin is missing, addressedByAnotherAuthor evaluates to false, so checkSubmissionFreshness returns {fresh: true} and proceeds to open_pr — directly contradicting the module's own documented guarantee.

Failure scenario: an issue is already fixed and merged by a since-deleted GitHub account. checkSubmissionFreshness — the last gate before open_pr — returns {fresh: true} instead of aborting with already_addressed, so the miner opens a duplicate PR on an already-resolved issue.

Requirements

Align submission-freshness-check.ts's predicate with claim-conflict-resolver.ts's already-correct, safer bias for the identical data shape — a PR with a missing/non-string authorLogin (merged or open) should count as evidence the issue may already be addressed by another author, not be silently excluded from consideration.

Deliverables

  • checkSubmissionFreshness in packages/loopover-miner/lib/submission-freshness-check.ts treats a referencing merged/open PR with a missing/non-string authorLogin as potential evidence of "addressed by another author," matching claim-conflict-resolver.ts's existing bias for the same data shape.
  • A regression test covering a referencing PR with a missing authorLogin, asserting checkSubmissionFreshness no longer silently treats it as fresh/unaddressed.

Test Coverage Requirements

This file is under src/ via the packages/loopover-miner workspace - confirm current coverage.include scoping before assuming the top-level 99% patch gate applies exactly as src/** does; the new branch and its test must both be covered.

Expected Outcome

A referencing PR whose author GitHub can't identify (e.g. a deleted account) is treated as possible evidence the issue is already addressed, matching this module's own documented fail-closed contract, instead of being silently ignored.

Links & Resources

packages/loopover-miner/lib/submission-freshness-check.ts:143-148 (the bug, and the module's own fail-closed contract in its header comment), packages/loopover-miner/lib/claim-conflict-resolver.ts:60-64 (the correct sibling pattern to mirror)

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:bugGittensor-scored bug fix — scores a 0.05x multiplier.help wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions