Skip to content

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

Description

@JSONbored

packages/gittensory-miner/lib/event-ledger.js (#2290) is a general, append-only local event ledger with an open type vocabulary — any string type plus a JSON payload (event-ledger.js:41-46,76-90). manage-status.js already shows the established pattern for layering a specific, typed event on top of it: it defines its own event type constant (MANAGE_PR_UPDATE_EVENT = "manage_pr_update", manage-status.js:5) plus a payload normalizer (normalizeManageUpdatePayload, manage-status.js:28-39) and a thin writer (recordManagePollSnapshot in manage-poll.js:114-160) that calls the ledger's generic appendEvent. There is no equivalent for PR outcomes yet — pr_outcome does not appear anywhere under packages/gittensory-miner/.

Note this is a different layer from the server-side pr_outcome concept: src/review/outcomes-wire.ts:285 (recordPrOutcome) already writes pr_outcome rows to the HOSTED backend's D1 review_audit/audit_events tables on a pull_request.closed webhook. That's the gittensory server recording ground truth for every contributor's PRs, from the App's own webhook stream. This issue is the miner's own local record of the outcomes of its own PRs, written to the miner's local SQLite via event-ledger.js — same concept name, different codebase layer, no shared code (a laptop-mode miner may not have a webhook relay at all). Pick a distinct local constant name (e.g. MINER_PR_OUTCOME_EVENT) to avoid implying it's the same code path as recordPrOutcome.

Deliverables

  • packages/gittensory-miner/lib/pr-outcome.js exporting an event-type constant (e.g. MINER_PR_OUTCOME_EVENT = "pr_outcome") and a payload normalizer, mirroring manage-status.js's MANAGE_PR_UPDATE_EVENT pattern
  • recordPrOutcomeSnapshot(input, options) — a thin writer taking { repoFullName, prNumber, decision: "merged"|"closed", closedAt } plus an optional reason bucket (reuse REJECTION_REASONS from rejection-templates.js:19 when the PR was closed-not-merged, so this writer and the rejection-state-machine sibling issue share one vocabulary), that calls eventLedger.appendEvent(...) — same dependency-injection shape as recordManagePollSnapshot (manage-poll.js:114-160) so it's unit-testable without a real ledger file
  • readPrOutcomes(eventLedger, filter) — read-side helper mirroring indexLatestManageUpdates (manage-status.js:42-53) to reconstruct current-outcome-per-PR from the ledger's append-only event stream
  • Unit tests in test/unit/miner-pr-outcome.test.ts for the writer (both merged and closed decisions), the payload normalizer's validation, and the read-side reduction over a multi-event history
  • CLAUDE.md/README note distinguishing this from the server-side recordPrOutcome (src/review/outcomes-wire.ts:285) so future contributors don't conflate the two

References

  • packages/gittensory-miner/lib/event-ledger.js:41-46,76-90,148-166 (normalizeEventType, serializePayload, appendEvent — the generic primitive this builds on)
  • packages/gittensory-miner/lib/manage-status.js:4-6,28-53 (MANAGE_PR_UPDATE_EVENT, normalizeManageUpdatePayload, indexLatestManageUpdates — the pattern to mirror)
  • packages/gittensory-miner/lib/manage-poll.js:114-160 (recordManagePollSnapshot — the thin-writer-over-ledger shape to mirror)
  • packages/gittensory-miner/lib/rejection-templates.js:19 (REJECTION_REASONS — reusable reason-bucket vocabulary)
  • src/review/outcomes-wire.ts:285-344 (recordPrOutcome — the server-side namesake this must NOT be confused with)

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:featureGittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.help wantedExtra attention is needed

    Projects

    Status
    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions