A Forced Poll replaces the Cover; an ordinary pass still only fills a blank one #153
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Parent
Spec #135.
What to build
Asking for a Forced Poll is asking to accept the Series' page as it now stands, so a forced pass takes the replace path and an ordinary pass keeps filling only a blank Cover. That is the whole control: no dedicated Cover-refetch button, no second column, no second verb.
Rejected: a
force_cover_atcolumn — two columns, two verbs, two controls and another field on the admin projection, for a rare action. Rejected: a synchronous fetch inside the admin request — it contradicts the standing decision that intervention reaches the poller through the database, and it would block an owner request on the browser sidecar.The pass already holds the Cover it read when it decides whether to fill a blank one, so a forced pass costs no extra page read. Accepted consequence, stated rather than hidden: the owner cannot refresh a Cover without also re-reading chapters. The two are one act.
Identical artwork is an honest no-op the caller can distinguish, because the address now comes from the bytes — the owner learns the Site has not re-arted, rather than watching a control do nothing.
A Series whose Cover file went missing is repaired by one Check now — same bytes means the same address and the file re-linked, new bytes means a new address and the row repointed. The replace path has no empty-address predicate, which is exactly what makes this true.
Fetch path: the existing one, with its existing fetcher routing, so the gated cover host and the browser-only Sites keep going through the sidecar and everything else goes over plain TLS — one routing rule for Acquisition, Poll and this. No pre-flight refusal when the sidecar is down: the Lane skips its pass, the request marker ages, and an ageing marker is already the evidence that a Lane is stuck. No new failure mode and no new notification.
No confirmation, no danger accent, never ember. A Cover that disagrees with the Site is the state that confuses the Reader; the change is the remedy, not the risk, and it pulls no Series out of a list.
Acceptance criteria
Blocked by
Landed on
spec-135as a--no-ffmerge ofticket/153-forced-poll-replaces-cover(7e1cbdd,35a86f5).Implemented in
internal/latest/poller.goonly:checkOnedispatches on thestore.Series.Forcedflag the pass already carries - a Forced Poll calls the newreplaceCover, an ordinary pass keeps callingfillBlankCover, whose ADR-0007 blank-only guard and doc comment are byte-for-byte the base's.replaceCoveris that function's sibling minus the guard, sharing the samecoverWGbackgrounding and the samestoreCoverfetch, so the fetcher selection stays at exactly one call site.storeCovercallsReplaceSeriesCoveron a forced pass andSetSeriesCoverotherwise, holdingpreviousin one named local at the single replace call site and logging the three outcomes distinctly: filled a blank, unchanged because the Site re-serves the same bytes, or replaced old -> new. Refreshing the Cover and re-reading the chapters are one act - there is no Cover-only refetch, and that consequence is stated in the doc comment rather than worked around.Nothing was reclaimed and no TODO was left: the stranded address is #154's line next wave.
No new column, no new route, no confirmation step, no pre-flight refusal, no new failure surface, and no web or template change at all. The sidecar-down path is exactly as it was - skipped and logged. The fetch gate at the file's tail belongs to #151 and was not touched.
Four tests appended to
poller_test.go: forced replaces while unforced does not; identical bytes log the no-op and never the replacement; a forced pass re-links a cover file unlinked out from under a filled row (re-link, not repoint); and a forced pass with no cover fetcher still records the chapter and leaves the existing Cover alone. The pre-existing no-overwrite guard test and all four sidecar-down regression tests are unchanged and green.The full backend suite is green on the merged base: 571 tests, 10 packages.
No concerns handed back.