Moves FRONT_DOOR from /showcase to /latest. Showcase is a random
TABLESAMPLE — lean-back, and it can never tell you anything is wrong.
The feed is the only view where a failing source surfaces on its own,
as a creator who has gone quiet. The per-artist "new since last visit"
badges (#597) were a workaround for this view not being the door.
Showcase is demoted to a nav entry, not removed. Nothing is being
replaced, so rule 22's delete-the-legacy-path does not apply.
Deviation from the filed plan, deliberate: the step said write a new
LatestView.vue. Rejected — PostsView is ALREADY a self-contained feed
(own container, own store, infinite scroll, filters, deep-link
anchoring, empty state), and Browse only ever wrapped it in a tab
strip. A new view would have duplicated 231 working lines to gain
nothing. Mounting PostsView directly at its own route IS the whole
difference the promotion was after: a door you arrive at, not a hub
you navigate out of. Rule 28.
Backend untouched, as scoped — PostFeedService.scroll already does
cursor-paginated newest-first.
Two things this shook loose:
PostsView's deep-link "All posts" button was a hard `{ name: 'posts' }`,
which redirects into Browse. Correct while the view only ever rendered
inside Browse's tab; from the front door it would have yanked the
operator sideways into a different surface. Now returns to the current
route minus post_id, so Browse keeps its tab and any active scope.
The README claimed "A Showcase front page". That block is the SOURCE
the release notes quote (scripts/release_notes.py product_overview),
not a generated copy, so it is fixed here — a document contradicting
the code is the characteristic defect of the public-surface area.
No stickyChrome on the route: unlike Browse/Gallery/Settings this view
has no sticky sub-header for the nav to butt against.
The router spec pinned FRONT_DOOR to /showcase and now pins /latest,
plus that Showcase stayed reachable and in the nav — the demotion is
asserted, not assumed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LNXXULQDjVZmbuNa2G9mD9
The surface shipped at /system with no nav entry, reachable only by
clicking the health dot beside the brand — a target you have to already
suspect something is wrong to go looking for. Operator-flagged: it needs
a path someone can walk to.
Settings is where you go to ask the instance about itself, so the view
becomes a tab there, beside Activity — Activity answers "what is the
queue doing", System answers "is anything left to do it".
- SystemView.vue moves to components/settings/SystemHealthTab.vue; the
content is unchanged apart from shedding its own container and h1.
- SettingsView adopts useTabQuery (the composable Browse and
Subscriptions already use) so a tab can be linked TO. The health dot
now points at ?tab=system, and /system redirects there so the previous
build's link and any bookmark still land.
- The tab drops its own 10s poll. v-window keeps a visited item mounted
rather than destroyed, so that timer would have gone on firing behind
Maintenance — and TopNav already polls the same store every 15s for
the dot.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTjbZZ6JirCMSaJzQV1RhA
Posts, Artists, and Tags are the three 'browse the library by an axis'
surfaces; Subscriptions stays purely management (operator-asked 2026-06-09).
New BrowseView renders them as tabs (?tab=posts|artists|tags); only the active
tab mounts. The old standalone paths become redirects into the matching tab,
preserving deep-link query (/posts?post_id=N → /browse?tab=posts&post_id=N) and
keeping the route names so existing { name: 'posts'|'artists'|'tags' } links and
path pushes still resolve. Nav now reads Showcase · Gallery · Browse · Series ·
Subscriptions, with Settings pinned right.
Test: /browse resolves; /tags and /artists redirect into their tabs; a posts
deep link survives the redirect.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>