Signed-in issue page with the Brief, downloads, index and colophon; article, World Briefing and Behind the paper pages under the login guard; the rating widget with its fetch enhancement; the admin-only POST /rate writing dashboard-attributed rating events; the HMAC confirmation page links to the site. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NHyYupFdBiR4VfoUM7NjSM
3.0 KiB
3.0 KiB
Step 2 handoff — full issues and ratings
Landed
- Signed-in
/and/issues/{date}now render the full issue: Brief, download links for artifacts that still exist, the section/article index with summaries andwhy, admin rating widgets, World/Behind links when their snapshot data is present, and colophon facts. - Added login-protected article, World Briefing, and Behind the paper pages. Article pages use the EPUB's ammonia cleaning path without XHTML conversion, retain remote images with lazy/no-referrer attributes, include rendered discussions, previous/next navigation, source links, and admin ratings.
- Replaced the Step 1
/ratestub with the admin-only form/JSON handler. Events are append-onlydashboardevents attributed to the viewer; missing issue dates uselatest_issue_date_for_article; clear events use the CLI's exactcleared/0.0representation; form redirects validatenextand carry a flash, while JSON returns the event id. - Added the no-JS rating partial and JavaScript enhancement, active-state updates, issue/article styling, and the signed-in private cache policy.
- The e-ink HMAC confirmation page now links to the corresponding site issue.
- Added router tests for full/fallback rendering, article discussions and image handling, World/Behind pages, 404s and login protection, artifact gating, both rating representations, role guards, attribution, fallback dates, validated redirects, clear values, admin widget state, and near-miss links.
Deviations and notes
- The pinned
axum-logindependency disables tower-sessions'axum-corefeature, so its re-exportedSessiondoes not implement an Axum extractor in this dependency graph. Handlers useExtension<Session>to read the exact session already installed by the auth layer; no second tower-sessions dependency was added. - The web form and JSON response use
down, as specified for the widget, while the persisted event label isnot_for_me, matchingcmd_ratingsand the existing learned-rating queries exactly. - No migration was needed. Step 3 can construct
RatingWidgetwithshow_note = truefor dashboard article variants.
Verification
cargo fmt: pass.cargo clippy --all-targets -- -D warnings: pass.- Focused
cargo test web:: -- --nocapture: 22 passed, 0 failed. cargo testwith the documented sandbox listener tests skipped: 395 passed, 0 failed, 15 filtered out. The filtered tests were the four Anthropic listener tests, three OpenAI fake-server listener tests noted in the Step 1 handoff review, the relative-URL listener test, fiveserver::testslistener tests, and bothtests/m7_server.rstests.
Orchestrator review (2026-09-03)
- Accepted as is.
Extension<Session>for flashes is fine (the auth layer's session manager inserts it); no second tower-sessions dependency. - Cosmetic follow-up for step 7: download buttons show raw byte counts; render them human-readable (KB/MB).
- Full suite outside the sandbox: 376 lib + all integration tests green.