Skip to content

fix(miner-governor): disambiguate self-plagiarism ties#5104

Merged
JSONbored merged 1 commit into
mainfrom
codex/propose-fix-for-self-plagiarism-vulnerability
Jul 12, 2026
Merged

fix(miner-governor): disambiguate self-plagiarism ties#5104
JSONbored merged 1 commit into
mainfrom
codex/propose-fix-for-self-plagiarism-vulnerability

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Motivation

  • The self-plagiarism election previously reused a same-repo duplicate-winner helper that only compared PR/issue numbers, which are repository-scoped and may collide across repositories when timestamps tie, allowing multiple survivors; the goal is to make the election deterministic and safe across repos.

Description

  • Replace the duplicate-winner reuse with a cross-repo election that orders by submittedAt, then by repo-scoped PR/issue number, and finally by normalized repoFullName as a deterministic tie-breaker, and fail-closed when tie-breaker data is ambiguous (packages/gittensory-engine/src/governor/self-plagiarism.ts).
  • Add helpers submissionNumber, repoTieBreaker, submissionPrecedesSibling, isSelfPlagiarismClusterWinner, and resolveSelfPlagiarismWinner and wire selfPlagiarismCheck to use them instead of the same-repo helper.
  • Add regression tests covering equal-time / equal-number cross-repo ties and ambiguous missing-repo cases, and adjust existing expectations to match the new winner semantics (test/unit/self-plagiarism.test.ts).
  • Regenerate Cloudflare Worker type bindings so cf-typegen/typegen checks remain current (worker-configuration.d.ts).

Testing

  • Ran npx vitest run test/unit/self-plagiarism.test.ts and the unit suite for that file passed (all tests in that file succeeded).
  • Ran npm run typecheck which completed successfully with no TypeScript errors.
  • Ran npm run cf-typegen:check and npm run test --workspace @jsonbored/gittensory-engine, both of which completed successfully.
  • Attempted the full local gate with npm run test:ci; the broader workspace run was exercised but the run was not completed end-to-end here due to unrelated failures in other test shards (queue-5 reported failures) and the coverage job was terminated during debugging.
  • npm audit --audit-level=moderate was attempted and failed due to the registry audit endpoint returning 403 Forbidden (environmental, not related to the change).

Codex Task

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 11, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
gittensory-ui 4b6e495 Commit Preview URL

Branch Preview URL
Jul 12 2026, 08:35 AM

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.34%. Comparing base (b1ab5c2) to head (4b6e495).
⚠️ Report is 4 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5104   +/-   ##
=======================================
  Coverage   94.34%   94.34%           
=======================================
  Files         473      473           
  Lines       39928    39949   +21     
  Branches    14557    14564    +7     
=======================================
+ Hits        37670    37691   +21     
  Misses       1583     1583           
  Partials      675      675           
Flag Coverage Δ
shard-1 46.34% <100.00%> (+<0.01%) ⬆️
shard-2 34.65% <2.94%> (-0.02%) ⬇️
shard-3 32.14% <2.94%> (+0.10%) ⬆️
shard-4 31.82% <2.94%> (-0.14%) ⬇️
shard-5 33.75% <32.35%> (-0.01%) ⬇️
shard-6 44.86% <2.94%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
.../gittensory-engine/src/governor/self-plagiarism.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gittensory-orb gittensory-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 11, 2026
@gittensory-orb

gittensory-orb Bot commented Jul 11, 2026

Copy link
Copy Markdown

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-12 08:40:17 UTC

2 files · 1 AI reviewer · 2 blockers · readiness 93/100 · CI green · unstable

⏸️ Suggested Action - Manual Review

  • No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.
  • Maintainer requires a linked issue — Link the relevant issue (for example Closes #123) before opening the PR.

Review summary
This PR replaces the cross-module duplicate-winner reuse (repo-scoped PR/issue number only) with a self-contained cross-repo election in self-plagiarism.ts that orders by submittedAt, then repo-scoped number, then normalized repoFullName, failing closed (falling through to the matched-prior throttle path) when both numbers and repo names tie or a repo name is empty. The election logic (submissionPrecedesSibling / isSelfPlagiarismClusterWinner / resolveSelfPlagiarismWinner) is traced end-to-end against the new tests and produces the expected deterministic results, including the ambiguous-tie and missing-repo-name cases. The most notable leftover issue is the file's header doc comment, which still describes the old behavior of reusing `isDuplicateClusterWinnerByClaim` from duplicate-winner.ts even though that import and reuse have been removed.

Nits — 5 non-blocking
  • packages/gittensory-engine/src/governor/self-plagiarism.ts:5-7 — the module doc comment still says the election 'reuses isDuplicateClusterWinnerByClaim's claim-time / earliest-wins ordering' and points at src/signals/duplicate-winner.ts, but that import/reuse was deleted in this diff; update the comment to describe the new local election helpers.
  • packages/gittensory-engine/src/governor/self-plagiarism.ts resolveSelfPlagiarismWinner (post-diff line ~145) — it re-checks isSelfPlagiarismClusterWinner(candidate, nearDuplicates) even though selfPlagiarismCheck already confirmed that's false before calling it, which is harmless but a redundant recomputation worth trimming for clarity.
  • The test at test/unit/self-plagiarism.test.ts titled 'denies ambiguous equal-time and equal-number cross-repo ties when a repo name is missing' actually asserts eventType 'throttled', not 'denied' — consider renaming to avoid confusing 'fail closed' (not-a-winner) with the 'denied' eventType reserved for missing/invalid input.
  • Consider verifying packages/gittensory-engine/test/self-plagiarism.test.ts (a separate pre-existing dist-based test file referencing the old duplicate-winner-style ordering) still passes against the new election logic, since it isn't part of this diff but exercises overlapping behavior.
  • Update the file-header comment in self-plagiarism.ts to reflect the new local election (submittedAt → repo-scoped number → normalized repoFullName) instead of referencing the removed duplicate-winner.ts reuse.

Concerns raised — review before merging

  • No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.
  • Maintainer requires a linked issue — Link the relevant issue (for example Closes #123) before opening the PR.
Signal Result Evidence
Code review ❌ 2 blockers 1 reviewer
Linked issue ⚠️ Missing No linked issue or no-issue rationale found.
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (no linked issue context).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 45 registered-repo PR(s), 37 merged, 411 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 45 PR(s), 411 issue(s).
Gate result ❌ Blocking Repo-configured hard blocker found.
Improvement ✅ Minor risk: clean · value: minor — Code changes are accompanied by test evidence.
Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 45 PR(s), 411 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
  • Explain no-issue PR.
  • Link the issue being solved, or explicitly explain why this is a no-issue PR.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
[BETA] Chat with Gittensory

Ask 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.

  • @gittensory ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @gittensory chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @gittensory mention with a real question is routed to the closest matching read-only command automatically -- no exact syntax required.

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 Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

Replaces reuse of the same-repo duplicate-winner.ts helper (compares
repo-scoped PR/issue numbers only) with a self-contained cross-repo
election ordered by submittedAt, then repo-scoped number, then
normalized repoFullName as a final deterministic tiebreaker -- PR/issue
numbers collide across repos, so the old helper could produce multiple
winners on a timestamp tie.

Also drops resolveSelfPlagiarismWinner's redundant leading outright-winner
check: its only call site (selfPlagiarismCheck) already performs that
same check and only calls this helper when it returned false, so the
check was unreachable.
@JSONbored JSONbored force-pushed the codex/propose-fix-for-self-plagiarism-vulnerability branch from e9ec9c7 to 4b6e495 Compare July 12, 2026 08:34
@JSONbored JSONbored merged commit d88d6d4 into main Jul 12, 2026
20 checks passed
@JSONbored JSONbored deleted the codex/propose-fix-for-self-plagiarism-vulnerability branch July 12, 2026 08:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

aardvark codex gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Projects

Development

Successfully merging this pull request may close these issues.

1 participant