Skip to content

Check a miner's own prior-rejection history on a repo (rejectionSignaled's second documented trigger) #5655

Description

@JSONbored

Context

iterate-policy.ts's own doc comment defines rejectionSignaled as true when "the target repo (or this contributor's history with it) has signaled it does not want automated contributions -- an explicit AI-usage-policy ban, OR a prior submission from this same miner was closed/rejected on this exact repo." rejection-signal.js's resolveRejectionSignaled only resolves the FIRST trigger (the live AI-USAGE.md/CONTRIBUTING.md ban). The file's own header explicitly documents the second trigger as a known, deliberate gap — "not fabricated as 'no rejection history'" — and names exactly what's needed to close it: governor-state.js's listRecentOwnSubmissions (already tracks this miner's own recorded submissions, filterable by repo) and rejection-state-machine.js's resolveRejection (already classifies a fetched PR payload's terminal outcome into a rejection reason). Both already exist, are already tested, and are simply not wired together for this use.

Dependencies

None — independently shippable. Consumes two already-shipped modules (listRecentOwnSubmissions #5134, resolveRejection #4278) without modifying either.

Requirements

  1. Add a function (e.g. resolveOwnRejectionHistory(repoFullName, options)) that: calls listRecentOwnSubmissions({ repoFullName }) to get this miner's own prior submissions on the target repo; for each with a real pullRequestNumber, fetches its current GET /pulls/{n} state (reusing the existing GitHub-fetch conventions this package already uses elsewhere, e.g. live-issue-snapshot.js's auth/timeout/user-agent handling); runs the payload through resolveRejection (no signal — gate/duplicate context isn't available or needed here, just "was it closed without merge"); returns true if ANY prior submission on this repo was rejected (closed without merge).
  2. Bound the number of PR-status fetches per call (e.g. the N most recent submissions on that repo) so a miner with a long history on one repo doesn't trigger an unbounded fan-out of API calls on every single attempt.
  3. Fail-open on any fetch/parse failure for an individual PR (consistent with resolveRejectionSignaled's own existing fail-open behavior for the policy-doc trigger) — one unreachable PR must never block resolution of the others, and a wholesale fetch failure resolves to false (not fabricated as a rejection, and not silently treated as "definitely no rejection" either — log/surface the degraded check).
  4. resolveRejectionSignaled (or its caller in attempt-cli.js) combines both triggers: true if EITHER the live policy-doc ban OR the new own-rejection-history check fires.
  5. Out of scope: any change to rejection-state-machine.js's classification logic itself, or to governor-state.js's own submission-recording — this issue only wires the two together for a new caller.

Deliverables / Acceptance Criteria

  • A real own-rejection-history check exists, backed by real GitHub PR state, not fabricated
  • Bounded fetch count per call
  • Fails open (never blocks/crashes) on individual or wholesale fetch failure
  • rejectionSignaled now reflects BOTH documented triggers, matching iterate-policy.ts's own doc comment for the first time since it was written
  • No change to rejection-state-machine.js or governor-state.js's own logic

Test Coverage Requirements

This PR must ship with full test coverage for every changed line and branch — the repo's Codecov patch gate requires 99%+ coverage and the house standard is to aim for 100%, including both sides of every conditional/nullish-coalescing branch introduced. Required: (1) a real-rejection-detected test (a prior submission on the repo that resolves to a closed-without-merge PR flips the signal true); (2) a no-prior-submissions-on-this-repo test (signal stays false, no fetch attempted); (3) a bounded-fetch-count test (more prior submissions than the cap exist; only the cap's worth are fetched); (4) a fail-open test for both an individual PR fetch failure (other submissions still checked) and a wholesale failure (resolves false, not thrown); (5) a combined-trigger test proving either trigger alone is sufficient (policy-doc ban with clean history, OR clean policy doc with a real rejection, both resolve true).

Expected Outcome

rejectionSignaled finally means what its own doc comment has said since it was written — a miner won't keep re-attempting a repo that has already rejected its work, closing a real behavioral gap before Wave 5 puts this on a multi-tenant, reputation-sensitive footing.

Links & Resources

  • packages/gittensory-miner/lib/rejection-signal.js (the file's own documented gap)
  • packages/gittensory-miner/lib/governor-state.js's listRecentOwnSubmissions
  • packages/gittensory-miner/lib/rejection-state-machine.js's resolveRejection
  • packages/gittensory-engine/src/portfolio/iterate-policy.ts (the doc comment defining both triggers)
  • Theme: AMS hardening / Wave 5 prerequisite

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:featureGittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.gittensor:priorityMaintainer-selected Gittensor priority — scores a 1.5x multiplier.

    Projects

    Status
    In Progress

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions