Cross-reference lnwChapterRe from the function doc instead of restating
its rationale, drop the redundant '; skipping' from the fail-closed log
to match the package's bare verb:detail form, and reword the truncation
comment so the logged body length is not described as a code-made
distinction.
The Poll scoped the lightnovelworld scan to the slug derived from the
stored address, so a Series publishing chapters under more than one
Chapter Slug froze its Latest Chapter. The branch now matches any
chapter-shaped address on the host (lnwChapterRe) and scans only the
body before the wpdiscuz thread marker (wpd-threads); a body without
the marker is skipped and logged with its length, never scanned whole.
The size-cap comment now states the measured ~3.5x headroom.
A row keyed under the Chapter Slug its address was built from, while the
page pointer names a different Series, is stale. Rewrite its key, identity
and address in the cache, the retry-queue entry (if any) and the per-device
last-checked map together, then sync through the queue-backed path so an
offline repair parks and replays. Pure transform exported for the harness;
wired before render() at both detect() call sites. A row already under the
repaired key merges, keeping the farther-ahead progress, favourite OR'd and
the stronger lifecycle bucket.
- Share one lnw host regex between matches and the pointer validator so
the two cannot drift apart.
- Resolve the pointer href against the page address before validating,
so a relative pointer still yields its Series instead of silently
resolving to type other.
- Pin pointer/breadcrumb agreement on the divergent page and pin that a
pointer off-host or not /novel/<slug>/ resolves to other.
Review follow-up: the parenthetical about the research note's ~1.18 MB
bound is not locatable from code and would rot. Keep the size disclosure,
drop the cross-reference.
The a-will-eternal fixture carried a hand-written cross-series anchor
(overgeared-chapter-9999) that no real series page produces. Replace it
with text trimmed from a real, wholly-fetched
all-jobs-and-classes-i-just-wanted-one-skill-not-them-all page (2026-08-11,
~307 KB decoded): chapter anchors under both Chapter Slugs (1-99 at
...-not, 100-423 at ...-not-them-all, page order, boundary numbers and max
423), the wpd-threads marker exactly once, and after it a real wpdiscuz
comment block from the-sword-illuminates-the-great-wilderness (the pinned
page serves zero comments; same Site, same theme) carrying the one composed
element - a bare <a href> to a real overgeared chapter (2059, HTTP 200).
Scan expectation moves 1317 -> 423, the no-trailing-slash and challenge
cases move to the new novel, lnwCoverFixture moves to the new novel's real
og:image, and the poller's cover-fill case follows. sites.go and fetch.go
are byte-for-byte unchanged.
The lightnovelworld chapter branch no longer derives the Series address by
string-manipulating the chapter path: on ~7% of novels the Chapter Slug
diverges from the Series slug and the derived address 404s on every Poll.
The identity now comes from the page's own a[aria-label='All Chapter']
pointer (breadcrumb's second crumb as fallback), validated as a
lightnovelworld.net /novel/<slug>/ address; no pointer resolves to
type: other. The Chapter Slug rides on the detected page object only
(chapterSlug; null on a series page) and is written to no store, for the
stale-row repair in #90.
Harness: document.querySelector now answers attribute selectors with an
element exposing getAttribute (attrEls table, cleared by reset()).
AGENTS.md records that the Series address is discovered, not derived.