Skip to content

feat(miner-manage): local pr_outcome record writer (#4274) - #4450

Merged
JSONbored merged 1 commit into
JSONbored:mainfrom
davion-knight:feat/gittensory-miner-pr-outcome
Jul 9, 2026
Merged

feat(miner-manage): local pr_outcome record writer (#4274)#4450
JSONbored merged 1 commit into
JSONbored:mainfrom
davion-knight:feat/gittensory-miner-pr-outcome

Conversation

@davion-knight

Copy link
Copy Markdown
Contributor

Adds packages/gittensory-miner/lib/pr-outcome.js — the miner's own local record of the outcomes of its own PRs (merged / closed), layered on the generic append-only event-ledger.js exactly like manage-status.js layers MANAGE_PR_UPDATE_EVENT.

API (mirrors the manage-status pattern)

  • MINER_PR_OUTCOME_EVENT + normalizePrOutcomePayload — a distinct local event type and a tolerant payload normalizer (returns null on any malformed shape). A closed decision may carry a reason bucket reused from rejection-templates.js's REJECTION_REASONS (one shared vocabulary with the rejection-state-machine sibling); a merged decision — or an unrecognized reason — normalizes the reason to null.
  • recordPrOutcomeSnapshot(input, { eventLedger }) — a thin writer over an injected ledger (same DI shape as recordManagePollSnapshot, so it's unit-testable without a real SQLite file). Fail-soft: a missing repo or invalid payload returns null; only an unusable ledger throws.
  • readPrOutcomes(eventLedger, filter) — reduces the append-only stream to the latest outcome per repo/PR, mirroring indexLatestManageUpdates.

Distinct from the server-side namesake

This is not src/review/outcomes-wire.ts's recordPrOutcome (which writes hosted-backend audit rows from the GitHub App's webhook stream). Same concept name, different codebase layer, no shared code — a laptop-mode miner may have no webhook relay at all. Uses a distinct MINER_PR_OUTCOME_EVENT constant, adds the hand-written .d.ts, and records the distinction in the package README.

Tests

test/unit/miner-pr-outcome.test.ts: normalizer validation (non-object / bad prNumber / unknown decision / merged-drops-reason / closed-keeps-recognized-reason / null-non-string-whitespace coercion), the writer (unusable-ledger throw, fail-soft null, valid append), and the reader (latest-per-PR reduction, foreign-type / blank-repo / bad-payload skips, unreadable-ledger). 100% branch coverage on the new module; typecheck clean; miner-package skeleton suite green.

Closes #4274

Add packages/gittensory-miner/lib/pr-outcome.js: the miner's OWN local record of
the outcomes of its OWN PRs (merged / closed), layered on the generic append-only
event-ledger.js exactly like manage-status.js layers MANAGE_PR_UPDATE_EVENT.

- MINER_PR_OUTCOME_EVENT + normalizePrOutcomePayload: a distinct local event type
  and a tolerant payload normalizer (returns null on a malformed shape). A closed
  decision may carry a reason bucket reused from rejection-templates.js's
  REJECTION_REASONS (shared vocabulary with the rejection-state-machine sibling); a
  merged decision or an unrecognized reason normalizes the reason to null.
- recordPrOutcomeSnapshot(input, { eventLedger }): a thin writer over an injected
  ledger (same DI shape as recordManagePollSnapshot, unit-testable without a real
  file). Fail-soft: a missing repo or invalid payload returns null; only an unusable
  ledger throws.
- readPrOutcomes(eventLedger, filter): reduces the append-only stream to the latest
  outcome per repo/PR, mirroring indexLatestManageUpdates.

Distinct from the SERVER-side pr_outcome path (recordPrOutcome, src/review/
outcomes-wire.ts): same concept name, different codebase layer, no shared code (a
laptop-mode miner may have no webhook relay). Adds the hand-written .d.ts and a
README note recording that distinction.

Closes JSONbored#4274
@davion-knight
davion-knight requested a review from JSONbored as a code owner July 9, 2026 19:10
@superagent-security

Copy link
Copy Markdown
Contributor

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

1 similar comment
@superagent-security

Copy link
Copy Markdown
Contributor

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

@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.97%. Comparing base (4daceaa) to head (84331ac).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4450   +/-   ##
=======================================
  Coverage   93.97%   93.97%           
=======================================
  Files         414      414           
  Lines       37317    37317           
  Branches    13636    13636           
=======================================
  Hits        35068    35068           
  Misses       1594     1594           
  Partials      655      655           
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 9, 2026
@loopover-orb

loopover-orb Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Tip

🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩

✅ Gittensory review result - approve/merge recommended

Review updated: 2026-07-09 19:24:02 UTC

4 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
Adds a miner-local pr_outcome event writer/reader (pr-outcome.js) layered on the existing generic event-ledger.js, deliberately mirroring manage-status.js's normalize/write/read pattern and reusing REJECTION_REASONS from rejection-templates.js for the closed-reason vocabulary. The normalizer, fail-soft writer (invalid ledger throws, bad payload/repo returns null), and latest-per-repo/PR reducer are all straightforward and internally consistent with the diff shown, and the accompanying test file exercises every branch (bad shapes, decision/reason coupling, closedAt coercion, writer throw/fail-soft/append, reader latest-wins/skip paths). The PR is narrowly scoped to one new local capability tied to issue #4274, with no schema/migration impact since it rides the pre-existing event-ledger table.

Nits — 5 non-blocking
  • packages/gittensory-miner/lib/pr-outcome.js:38 — repoFullName is only trimmed, not format-validated (e.g. against `owner/repo`) the way prediction-ledger.js's `normalizeRepoFullName` does; a malformed value like `"acme"` or `"a/b/c"` will silently write/key a garbage repoFullName instead of failing fast.
  • Cannot verify from this diff that `REJECTION_REASONS` in rejection-templates.js is actually an array of plain strings matching what `new Set(REJECTION_REASONS)` expects — worth a quick confirm since the whole closed-reason bucket depends on that shape.
  • packages/gittensory-miner/lib/pr-outcome.js:70 — `readPrOutcomes` keys latest-wins by `${event.repoFullName}:${normalized.prNumber}` using the raw (non-trimmed) `event.repoFullName` from the stored event; fine today since the writer always trims before storing, but it's an implicit coupling worth a one-line comment.
  • Consider reusing prediction-ledger.js's `normalizeRepoFullName` (or exporting a shared helper) instead of a bare `.trim()` in recordPrOutcomeSnapshot, for consistency with the other ledger writers in this package.
  • The three-paragraph banner comment distinguishing this from `src/review/outcomes-wire.ts` is helpful but duplicated near-verbatim in the file header, JSDoc, and README — could collapse to one canonical spot to avoid drift if the distinction is ever refined.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #4274
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 (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 83 registered-repo PR(s), 48 merged, 3 issue(s).
Contributor context ✅ Confirmed Gittensor contributor davion-knight; Gittensor profile; 83 PR(s), 3 issue(s).
Gate result ✅ Passing No configured blocker found.
Linked issue satisfaction

Addressed
The PR adds pr-outcome.js with MINER_PR_OUTCOME_EVENT, a normalizer reusing REJECTION_REASONS for closed-decision reasons, a DI-based recordPrOutcomeSnapshot mirroring recordManagePollSnapshot, and readPrOutcomes mirroring indexLatestManageUpdates, plus unit tests covering the normalizer, writer, and reader, and a README note distinguishing this from the server-side recordPrOutcome — covering ever

Review context
  • Author: davion-knight
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Rust
  • Official Gittensor activity: 83 PR(s), 3 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
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.

🟩 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

@JSONbored
JSONbored merged commit aa95930 into JSONbored:main Jul 9, 2026
10 checks passed
@loopover-orb loopover-orb Bot added gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. and removed gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. labels Jul 9, 2026
@JSONbored JSONbored added gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. and removed gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. labels Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. manual-review Gittensor contributor context

Development

Successfully merging this pull request may close these issues.

feat(miner-manage): local pr_outcome record writer

2 participants