docs: replace evasion framing with honest onboarding-prioritisation rationale
'Try now' and the newest-first batch implement onboarding prioritisation: foreground (user-clicked 'Try now') summarises a chosen video on demand; background batch summarises newest-first; both honour the shared rate gate. Remove any prior framing that described 'Try now' as making traffic 'look organic to YouTube' or as rate-limit evasion — that was not the rationale and contradicts ADR-014's explicit account-safety constraint. Correct statement: rate limiting is respected, not evaded. TAPIR_FETCH_RATE and TAPIR_FETCH_BACKOFF are honest rate controls; they govern how fast Tapir fetches captions, not how the requests appear to YouTube. Architecture: add two-path model table (foreground/background, both through globalFetchGate) and newest-first batch ordering doc (three-phase RunOnce, before/after example). ui-spec: add 'Try now' row with correct rationale; add pipeline stats bar row; update Summarized-only filter row to mention sort-to-top.
This commit is contained in:
@@ -208,6 +208,35 @@ This is the precondition that makes scheduled auto-summarize safe: without the g
|
||||
multi-user scheduler pass could fire many concurrent timedtext requests from the same IP
|
||||
within seconds, triggering 429s for all users.
|
||||
|
||||
### Two-path summarisation model
|
||||
|
||||
Both paths share `globalFetchGate` — rate limiting is **respected in both**, not routed around.
|
||||
|
||||
| Path | Trigger | Order | Rationale |
|
||||
|------|---------|-------|-----------|
|
||||
| **Foreground** | User clicks "Try now" on a rate-limited card (`POST /v/{id}/retry-now`) | Single chosen video | On-demand value: user picks a specific video to read now |
|
||||
| **Background batch** | Scheduled discovery pass every `TAPIR_DISCOVERY_INTERVAL` | **Newest-first across all channels** (see below) | Onboarding prioritisation: most recent, relevant videos surface first |
|
||||
|
||||
The rationale for both paths is **onboarding prioritisation** — a new user should get summaries
|
||||
of their most recent, relevant videos quickly while the older back-catalogue fills in behind,
|
||||
all within the honest shared rate limit.
|
||||
|
||||
### Newest-first batch ordering (ADR-018)
|
||||
|
||||
Within each scheduled pass, `RunOnce` uses a three-phase structure:
|
||||
|
||||
1. **Discover + persist**: walk all channels, `UpsertVideo` every candidate (so it appears in
|
||||
the list), apply pre-filters (seen/manual/backoff), collect surviving candidates.
|
||||
2. **Sort**: order candidates `published_at DESC, NULLS LAST, discovery_pos ASC`. Videos with
|
||||
no publish date (schema 001: nullable) sort after all dated content. The sort is in-memory
|
||||
(`slices.SortStableFunc`) — at current scale this is fine.
|
||||
3. **Process**: feed candidates to the engine in sorted order through `globalFetchGate`.
|
||||
|
||||
Before (per-channel inline): `[chanA-old, chanA-mid, chanB-new, chanB-null]`
|
||||
After (newest-first): `[chanB-new, chanA-mid, chanA-old, chanB-null]`
|
||||
|
||||
The set of processed videos is identical; only the order within a pass changes.
|
||||
|
||||
---
|
||||
|
||||
## Sequence — core use case: new video summarized
|
||||
|
||||
Reference in New Issue
Block a user