v0.4.0 — ### Added
- **T-004** Delta ingestion + ingestion ledger (`ingest/delta.py`): `ingest_report` writes `reports` / `fights` / `combatants` and the ledger row in one transaction. Cache-first p…
- T-004 Delta ingestion + ingestion ledger (
ingest/delta.py):ingest_reportwritesreports/fights/combatantsand the ledger row in one transaction. Cache-first per PLAN §3 Invariant 1 — acompleteledger short-circuits before any network call;openreruns only insert fight IDs not already infights_ingested. - Status auto-flips to
completewhenreport.endTimeis older than 6h (configurable).mark_report_complete()to force the flag. - Combatants seeded from
masterData.actors(Player-typed only); per (new fight, player).statsdeferred to T-005. - 7 unit tests covering first ingest, complete-rerun no-op (proves zero GraphQL calls), open-rerun delta, auto-complete heuristic, missing report, idempotent rerun. 25 tests total.
scripts/verify_delta.pylive AC harness: discovers a public report and exercises first-ingest → rerun → force-complete → rerun on real FFLogs.