Smart sync planner
The planner builds a sync plan before each job runs. It fuses three signals:
1. Time window
The lookback shrinks to the gap since your last sync, capped between 12 h minimum and the window you set (default 2 days, max 30). If the gap is bigger than your saved window, the gap wins.
Example: saved window = 2 days, but cron last ran 6 h ago → this run scans the last 12 h (min). Last ran 5 days ago → this run scans the full 5 days of news.
2. Recency-skip
For each candidate company, we look at its most recent signal. If it landed less than half the window ago, the company is skipped — likely no new LinkedIn posts yet. Saves credits without missing news.
Hard ceiling: companies idle for ≥ 7 days are always included regardless of recency.
3. Budget filter
We pull your live linkdapi balance. After a 10-credit safety floor, we include companies sorted by (priority high→low, oldest signal first) until the budget runs out. Excess gets skipped with reason = "budget" and surfaced in a warning bar.
Same-URL dedup (during ingest)
If LinkedIn + Google News + a custom link all return the same URL for one company, we keep the highest-priority source (linkdapi > custom > others) and drop the duplicates before calling Claude — saves classify cost.
Plan preview
The card in Sync Now → Smart sync plan shows you everything before you commit: companies, skips, credits, tokens, $, duration estimate.