# Phase 2: Seeder Day-Boundary Backfill - Context

**Gathered:** 2026-03-25
**Status:** Ready for planning
**Mode:** Auto-generated (infrastructure phase)

<domain>
## Phase Boundary

After midnight UTC, the seeder checks yesterday's Parquet file and backfills any missing trades up to `crossover_tid - 1`. Uses the shared `get_crossover_tid(symbol, date)` from Phase 1.

</domain>

<decisions>
## Implementation Decisions

### Claude's Discretion

Key facts:

- Seeder runs every 5 min via systemd timer (`opendeviationbar-seeder.timer`)
- Main seeder script: `scripts/tick_cache_seeder.py`
- After midnight, "today" becomes the new day — yesterday's Parquet file is frozen
- The seeder should detect it's past midnight, check yesterday's file completeness, and backfill if needed
- Use `get_crossover_tid(symbol, yesterday)` to determine the expected last TID
- Use `TickStorage` to read yesterday's Parquet max TID and append missing trades
- Only runs once per day transition (not every 5 min) — use a state file or timestamp check

</decisions>

<canonical_refs>

## Canonical References

- `scripts/tick_cache_seeder.py` — main seeder script
- `python/opendeviationbar/crossover.py` — shared `get_crossover_tid()` (Phase 1)
- `python/opendeviationbar/storage/parquet.py` — `TickStorage` for Parquet read/write
- `scripts/CLAUDE.md` §"Exness Forex Tick Cache Seeder" — seeder architecture
  </canonical_refs>

<code_context>

## Existing Code Insights

- Seeder writes daily Parquet files: `~/.cache/opendeviationbar/ticks/{SYMBOL}/YYYY-MM-DD.parquet`
- `TickStorage.write_ticks()` can append to existing files
- `fetch_aggtrades_rest(symbol, from_id, limit)` — Rust binding for fetching trades by ID range
- Crossover TID gives the boundary: yesterday's file should have max TID = crossover_tid - 1
  </code_context>

<specifics>
No specific requirements.
</specifics>

<deferred>
None.
</deferred>

---

_Phase: 02-seeder-day-boundary-backfill_
_Context gathered: 2026-03-25_
