# ADR-0011: Sightings — a Reader report defers a Poll where being wrong hurts only them Date: 2026-08-16 Status: accepted ## Decision A **Sighting** is what a userscript PUT already carries: the Latest Chapter the Reader's own browser read off the Series page. It is now allowed to stand in for a Poll, under one restriction and one ceiling: - **Solitary Series only.** A Sighting defers the Poll of a Series exactly one Bookmark points at. A Series two Readers share is Polled on schedule no matter how recently it was sighted. - **One rest of standing.** A Sighting postpones Polls for one Rest (`defaultRest`, an hour), not forever: a Series nobody visits again returns to the normal schedule by itself. - **Six-hour ceiling.** `sightingCeiling = 6 * defaultRest`. However many Sightings arrive, a Series unpolled for six hours is Polled. Both live in the due query's HAVING clause (`store.DueForLatestCheck`), beside the Rest cutoff — the same place the schedule has always been decided, so no timer and no second code path can disagree with it. Attribution and judgement: - `Store.RecordSighting` runs *before* the Upsert that stores the reported value, because the raise test needs the row as it stands. A report that raises the stored Latest Chapter names its Reader in `series.latest_raised_by`. - The Poll is the oracle. `Poller.checkOne` already compares what the Site publishes against what is stored, so judgement costs no extra request: a lower number contradicts the Sighting (`sighting_disagreements + 1`, both numbers and the Reader logged), the same number confirms it (`sighting_agreements + 1`), a **higher** number is the Site publishing and means nothing either way. - At `SightingDisagreementLimit` (3) that Reader's Sightings stop deferring anything. They still write the Latest Chapter — the penalty removes a privilege, it does not silence anyone. - `SightingAgreementsToClear` (20) consecutive confirmations forgive the disagreements. A disagreement resets the run to zero. - The owner clears marks from the administration page (issue #102, shipped first precisely so a false mark has a remedy the day the mechanism lands). ## Why Most of the backend's work was redundant. The userscript reads the Latest Chapter on every Series page visit and PUTs it; minutes later the Poll Lane fetches the same page for the same number. Deferring on a report converts a visit into a Poll saved, which is Lane capacity handed back to Series nobody is reading. The restriction is the whole safety argument, and it is about **blast radius**, not about trust arithmetic: - On a solitary Series, a wrong report can only mislead the Reader who made it. There is nobody else's ember to falsify. - On a shared Series it could mislead someone else, so a report never postpones anything there. The ceiling bounds the damage in time: a false value dies within six hours whatever happens, because the Poll that finds it is guaranteed. That is also what makes lying pointless — the six-hour audit is certain, not sampled, so a determined attacker buys at most three ceilings' worth of a wrong number on their own Series and then loses deferral entirely. The cost of recovery is deliberate. An agreement is only recorded when a later Poll confirms a Sighting, so twenty agreements are twenty Polls of Series that Reader bookmarks — hours to days of real time, not twenty page views. Waiting is therefore not a strategy, and credit cannot be banked in advance. ## Tradeoffs and rejections - **Trusting a Sighting on a shared Series** rejected: it is the only case where one Reader's mistake reaches another Reader's list, and no amount of reputation makes that recoverable within the six-hour window. - **Cross-Reader agreement, voting, weighting, consensus scoring** rejected: a single-source report cannot have its confidence evaluated by comparison, and with the typical two Readers a disagreement identifies nothing. The Poll is the only oracle in the system, so it is the only judge. - **A randomised audit** (Poll a fraction of deferred Series) rejected in favour of the fixed ceiling: a sampled audit makes the attacker's expected cost a probability, while a ceiling makes it a certainty, and a certainty is what makes the solitary-Series rule defensible in one sentence. - **Blocking a marked Reader's writes** rejected: the Latest Chapter they report is still the best available value, and their Sightings must keep being judged or they could never earn the privilege back. - **Per-Series flagging** rejected in favour of per-Reader marks: a Series is not the thing that can be wrong. Naming the Reader and logging both numbers is also what distinguishes a broken Site adapter (every Reader of that Site contradicted at once) from one bad actor. - **Timers or a background reputation job** rejected: deferral is decided from live facts every round — Bookmark count, sighting timestamp, the Reader's marks — so a Series that gains a second Bookmark stops deferring at once, with nothing to invalidate. ## Constraints preserved - A Sighting is not Progress: it may move the Latest Chapter and nothing else. `updated_at` never moves, so a report cannot reorder the list (ADR-0004). - The Latest Chapter is a Series-level fact (ADR-0003): a Sighting writes the shared row, so every Reader of a shared Series sees it immediately — deferral is the only thing the solitary rule withholds. - Ember means new chapter only (`docs/design-system.md`): a marked Reader renders no differently in their own list, and nothing about the trust model reaches the Series list's colour. - The Poll remains authoritative. Where a Sighting and a Poll disagree, the Poll's value is what gets stored.