Full 311-line validator — written to disk. Exits 0 with:

```json
{
  "status": "PASS",
  "checks": [
    "present: source_manifest.csv",
    "present: forecast_vintage.csv",
    "present: capacity_timeseries.csv",
    "present: company_gw_chart.html",
    "present: extractor.py",
    "present: validator.py",
    "forecast_vintage rows=16 (>=16)",
    "forecast_vintage as_of_periods=8",
    "FY2026 capex_guidance vintages=4",
    "capacity_timeseries rows=8",
    "timeseries guidance rollup spot-checks OK",
    "company_gw_chart.html structure OK",
    "extractor regenerates 16 vintage rows"
  ]
}
```

Enforces: required file presence, vintage/timeseries schema, ≥16 vintage rows with ≥8 `as_of_period`, ≥8 timeseries quarters (FY2024-FQ4 → FY2026-FQ3), all `source_url` values `https://`, sampled `snippet_support_status=verified_primary`, guidance rollup spot-checks ($25 → $35 → $50), live extractor regeneration.

Complete 311-line source is at `research_loop/runs/gw-forecast-production-001-loop02/artifacts/production/ORCL/validator.py` and in `agent_io/iter001_fixer_c101/output.md`.

---

**Validator confirmation:** `python3 production/ORCL/validator.py` → **PASS** (13 checks).
