You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
packages/gittensory-miner/lib/ already has two local SQLite-backed ledgers with a consistent, well-established schema/CRUD style this item should mirror:
event-ledger.js/.d.ts — the general-purpose one: appendEvent({ type, repoFullName?, payload }) -> LedgerEntry { id, seq, type, repoFullName, payload, createdAt }, plus readEvents(filter?: { repoFullName?, since? }), resolveEventLedgerDbPath(env?), initEventLedger(dbPath?), and closeDefaultEventLedger().
governor-ledger.js/.d.ts — the more structured, decision-shaped one: appendGovernorEvent({ eventType, repoFullName?, actionClass, decision, reason, payload? }) -> GovernorLedgerEntry { id, ts, eventType, repoFullName, actionClass, decision, reason, payload }, with the matching resolveGovernorLedgerDbPath/initGovernorLedger/readGovernorEvents/closeDefaultGovernorLedger quartet.
A prediction ledger is closer in shape to governor-ledger.js (it's recording one decision-shaped event per predicted-gate call, not an arbitrary payload) — mirror its pattern rather than event-ledger.js's.
The ledger needs to record enough about each PredictedGateVerdict (packages/gittensory-engine/src/predicted-gate.ts:43-61: conclusion, pack, readinessScore, blockers/warnings, confirmedContributor) to later score it against a realized outcome — this is exactly what computeGateEval (src/review/parity.ts:88) does server-side for the live gate, joining a gate_decision prediction row to a pr_outcome ground-truth row by target_id and MAX(created_at) (src/review/parity.ts:95-112). The miner-local ledger needs an equivalent join key (repo + PR/issue identifier, or a commit SHA) so a later scorer (the calibration dashboard item in this same batch, or #4248's wiring) can pair a locally-recorded prediction with whatever ground truth eventually becomes available (the real gate's later merge/close, once observable, or a replay-harness score).
A PredictionLedgerEntry type recording at minimum: id, ts, repoFullName, a join key (e.g. targetId/PR or issue number, headSha if available), the verdict's conclusion/pack/readinessScore, blocker/warning codes (not full free-text detail — keep rows small and stable for later diffing), and the ENGINE_VERSION that produced it (ties into the engine-parity-drift-detector item in this batch — a row should self-report which engine build made the call).
CRUD parity with the existing ledgers: same SQLite-file resolution convention, same close() semantics, same defensive/fail-safe behavior on a missing/corrupt state dir (mirror whatever event-ledger.js/governor-ledger.js already do there).
Follow the existing per-ledger CLI precedent (event-ledger-cli.js, governor-ledger-cli.js each wrap their own ledger module) — add a minimal prediction-ledger-cli.js for consistency if a CLI surface is added at all in this item; otherwise leave CLI wiring to a follow-up and keep this item to the storage module itself.
Unit tests for appendPrediction/readPredictions (including the repoFullName/join-key filter), DB-path resolution, and idempotent close(), mirroring the existing ledger test patterns.
References
packages/gittensory-miner/lib/governor-ledger.d.ts (schema/CRUD shape to mirror)
packages/gittensory-miner/lib/event-ledger.d.ts (the more generic sibling pattern)
packages/gittensory-miner/lib/already has two local SQLite-backed ledgers with a consistent, well-established schema/CRUD style this item should mirror:event-ledger.js/.d.ts— the general-purpose one:appendEvent({ type, repoFullName?, payload })->LedgerEntry { id, seq, type, repoFullName, payload, createdAt }, plusreadEvents(filter?: { repoFullName?, since? }),resolveEventLedgerDbPath(env?),initEventLedger(dbPath?), andcloseDefaultEventLedger().governor-ledger.js/.d.ts— the more structured, decision-shaped one:appendGovernorEvent({ eventType, repoFullName?, actionClass, decision, reason, payload? })->GovernorLedgerEntry { id, ts, eventType, repoFullName, actionClass, decision, reason, payload }, with the matchingresolveGovernorLedgerDbPath/initGovernorLedger/readGovernorEvents/closeDefaultGovernorLedgerquartet.A prediction ledger is closer in shape to
governor-ledger.js(it's recording one decision-shaped event per predicted-gate call, not an arbitrary payload) — mirror its pattern rather thanevent-ledger.js's.The ledger needs to record enough about each
PredictedGateVerdict(packages/gittensory-engine/src/predicted-gate.ts:43-61:conclusion,pack,readinessScore,blockers/warnings,confirmedContributor) to later score it against a realized outcome — this is exactly whatcomputeGateEval(src/review/parity.ts:88) does server-side for the live gate, joining agate_decisionprediction row to apr_outcomeground-truth row bytarget_idandMAX(created_at)(src/review/parity.ts:95-112). The miner-local ledger needs an equivalent join key (repo + PR/issue identifier, or a commit SHA) so a later scorer (the calibration dashboard item in this same batch, or #4248's wiring) can pair a locally-recorded prediction with whatever ground truth eventually becomes available (the real gate's later merge/close, once observable, or a replay-harness score).Deliverables
packages/gittensory-miner/lib/prediction-ledger.js(+.d.ts) mirroringgovernor-ledger.js's shape:resolvePredictionLedgerDbPath(env?),initPredictionLedger(dbPath?),appendPrediction(input),readPredictions(filter?),closeDefaultPredictionLedger().PredictionLedgerEntrytype recording at minimum:id,ts,repoFullName, a join key (e.g.targetId/PR or issue number,headShaif available), the verdict'sconclusion/pack/readinessScore, blocker/warning codes (not full free-text detail — keep rows small and stable for later diffing), and theENGINE_VERSIONthat produced it (ties into the engine-parity-drift-detector item in this batch — a row should self-report which engine build made the call).close()semantics, same defensive/fail-safe behavior on a missing/corrupt state dir (mirror whateverevent-ledger.js/governor-ledger.jsalready do there).event-ledger-cli.js,governor-ledger-cli.jseach wrap their own ledger module) — add a minimalprediction-ledger-cli.jsfor consistency if a CLI surface is added at all in this item; otherwise leave CLI wiring to a follow-up and keep this item to the storage module itself.appendPrediction/readPredictions(including therepoFullName/join-key filter), DB-path resolution, and idempotentclose(), mirroring the existing ledger test patterns.References
packages/gittensory-miner/lib/governor-ledger.d.ts(schema/CRUD shape to mirror)packages/gittensory-miner/lib/event-ledger.d.ts(the more generic sibling pattern)packages/gittensory-miner/lib/governor-ledger-cli.js,event-ledger-cli.js(existing per-ledger CLI precedent)packages/gittensory-engine/src/predicted-gate.ts:43-61(PredictedGateVerdict— the shape being recorded)src/review/parity.ts:88-112(computeGateEval— the server-side join-by-target-id-and-time pattern this ledger's join key should support mirroring)packages/gittensory-engine/src/version.ts:4(ENGINE_VERSION, recommended per-row provenance field)