Skip to content

calibration: backfill the corpus from the 10k+ historical review ledger (labels + firings; raw context phase 2) #8157

Description

@JSONbored

Problem

The calibration corpus (#8101/#8104 fired events + human overrides) only accumulates from the moment those writers shipped — audit_events had 0 calibration.* rows and a young signal history on 2026-07-22, while the ledger holds 10k+ historical reviews whose decisions and human outcomes are already durably recorded (review_targets/review_audit, orb_pr_outcomes, agent.action.close/agent.action.merge events, reversal_reopened/reversal_reverted events). Backfilling turns the backtest/trend system from "starts learning today" into "starts with years of ground truth."

What is honestly reconstructable (verified against the live schema, 2026-07-23)

Corpus ingredient Backfillable? Source
Human verdict labels (confirmed/reversed) Yes terminal PR outcomes + the reversal events recordReversalSignals already writes; a decision later reversed ⇒ reversed, a terminal decision left standing ⇒ confirmed
Rule firings per blocker code Mostly review_audit/decision_json blocker lists where recorded; coverage varies by era of the ledger schema
metadata.confidence Partial present where decision_json carried per-finding confidence (AI-review-era rows); absent for older deterministic-only rows
Raw prompt context (issueText/prTitle/prBody/diff) Re-fetchable (phase 2) the PRs/issues still exist on GitHub for public repos — a bounded, rate-limit-aware re-fetch job can reconstruct them
modelResponseText No — permanently never stored before the #8139 capture; not reproducible (no deterministic model output)

Net effect: threshold backtests (#8138) and the precision/accuracy trends (#8113/#8140) gain instant deep history; logic-replay backtests (#8139) can only accumulate forward — no backfill can manufacture the model responses.

Requirements

⚠️ Required pattern. Pure-core/thin-IO split exactly like scripts/backtest-corpus-export-core.ts / backtest-corpus-export.ts. The transform (ledger rows → synthesized RuleFiredEvent/HumanOverrideEvent pairs) is the tested pure core; the CLI does the D1 reads/writes.

  • Synthesized events must be idempotent and distinguishable: dedupe on (eventType, targetKey, provenance) and tag metadata.backfilled: true so trend/backtest consumers can include or exclude them explicitly, and re-runs never double-write.
  • Dry-run mode is the default (--apply opts in), printing per-rule counts of what would be written.
  • Never fabricate what isn't there: a row without a recorded blocker list yields NO fired events (skip + count), never a guess. modelResponseText is never synthesized.
  • Phase 2 (separate flag, separate PR if large): the GitHub re-fetch of raw context for public-repo rows, bounded and resumable.

Deliverables

  • scripts/backfill-calibration-corpus-core.ts (pure transform + dedupe/provenance logic, fully unit-tested)
  • scripts/backfill-calibration-corpus.ts (thin IO: D1 read of the ledger eras, dry-run/apply, summary output)
  • A dry-run report from the real DB pasted into this issue before any --apply

Test Coverage Requirements

scripts/** sits outside coverage.include, so Codecov does not gate this patch — the pure core still requires full unit tests per house convention (both label directions, reversal precedence, dedupe/idempotency, the skip-don't-guess paths).

Links & Resources

Boundaries

Backfilled events are additive, tagged, and reversible (deletable by the backfilled tag). No GitHub re-fetch in phase 1. modelResponseText is out of scope permanently.

maintainer-only — one-shot data migration against the production ledger.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.roadmapOn the Wave-2 agent-layer roadmap board (project 9)

Projects

Status
Done
Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions