A single report tells you about one run. The cross-run layer answers “how did this run compare to last week?” — trend, drift, and regression detection over a stored history of reports.
ReportHistory
ReportHistory is an append-only store of AnalysisReports, keyed by (analysis_name, dataset, run_id). It defaults to JSONL (a reports log is the natural fit) with SQLite optional — both stdlib, no new dependencies.
Regression detection
Regression flags are direction-aware and per-metric. The baseline is a strategy, not just “the previous value”:
rolling_median (default) — the median of the last window runs; immune to one noisy night, where previous would alternately flag and un-flag.
previous / last_known_good — the most recent historical value.
- a pinned
run_id.
Thresholds come from a RegressionPolicy and respect each metric’s direction: a higher_better metric (recall) flags only on a drop, a lower_better metric (finding counts) only on a rise, neutral either way.
The worked example: a per-metric 2% gate on match.recall_safe_bound catches a 0.97 → 0.89 recall drop that a global 10% gate would miss — exactly the kind of quiet quality regression a nightly pipeline should alert on.
Narrative
build_narrative(report, regressions) produces a deterministic, ASCII-clean one-paragraph summary: it names the largest-magnitude flagged regression, lists co-moving metrics across analyzers, and surfaces the most common quality finding. Because root cause is often only visible by crossing analyzers, the narrative sees the full metric set.
CLI
--fail-on-regression makes GoldenAnalysis a drop-in nightly-pipeline gate: store a report after each run, then fail the job when a direction-aware, per-metric threshold trips.
TypeScript
The cross-run layer is ported to TypeScript too. The decision logic (detectRegressions, buildTrend, buildNarrative) is edge-safe in goldenanalysis/core; the file-backed ReportHistory (JSONL) lives in goldenanalysis/node.