SignalDedup: 24h-rolling duplicate signal blocker. SQLite WAL +
busy_timeout=120000 standard fix (reference_sqlite_concurrency.md
pattern). PK (ticker, action) with UPSERT. Phase 4 (signal generator)
will call is_recent() before sending + record() after sending.
3 unit tests pass, total 17 signal_v2.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Time-window dispatcher: pre-market (07:00-09:00, 5min), market
(09:00-15:30, 1min), post-market (15:30-20:00, 5min), overnight skip
to next market day 07:00. Weekend + holiday detection via holidays.json.
Stub holidays.json with 13 dates. Task 6 will sync from
web-backend/stock/app/holidays.json.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>