# Design note — named activity streams

**Dated 2026-08-05. Written before the code, per the provenance practice in
[ROADMAP.md](../../ROADMAP.md#proving-independence).**

---

## The job to be done

`/activity` is one chronological list of posts with a forum dropdown. That
answers "what happened here recently", which is a real question but not the one
anybody asks daily.

The daily questions are:

- **What have I not read?** — the one somebody opens the site to answer.
- **What happened in the threads I started?**
- **What happened in the threads I replied to?**

Each is a destination somebody navigates *to*, not a value they set in a
filter. Burying them behind a dropdown means they are never found, and a member
who cannot find "what's new" concludes the forum is quiet and stops coming.

## Decision 1 — destinations with URLs, not filter state

Four addresses under one page:

| URL | Answers |
|---|---|
| `/activity` | what happened here recently — works for guests |
| `/activity/unread` | what have I not read |
| `/activity/started` | the threads I started |
| `/activity/posted-in` | the threads I replied to |

A URL means it can be bookmarked, linked from a nav item, and returned to. A
dropdown value cannot. The tab bar across the top is how somebody discovers the
other three, and it is present on all four so no stream is a dead end.

## Decision 2 — the personal streams are lists of topics; All Activity stays posts

They answer different questions and want different shapes.

"What have I not read" wants **threads**: one row per conversation, with the
unread marker and the jump to where you stopped. A list of forty individual
posts is not something anybody can act on.

"What happened recently" genuinely wants **posts**, because the point is the
chronology. That page keeps working as it does.

So the three new streams reuse the topic row from the forum listing — the same
markup, the same unread marker, the same first-unread link — and gain the forum
name, because a stream spans forums and a bare title is ambiguous.

## Decision 3 — "Unread" is its own nav item, and it is an ordinary menu item

It is the thing somebody opens the site to look at, so it belongs in the
navigation rather than one level down inside Activity.

`/activity` keeps meaning "everything, chronologically" for everybody. A URL
whose meaning changes depending on who is looking is a URL nobody can share, so
signing in does **not** silently redirect it somewhere else.

The nav is admin-managed, so this is **seeded as a normal menu item** rather
than hard-coded — an administrator can rename it, move it or remove it. Menu
items have no per-group visibility, so a guest who clicks it is asked to sign
in. That is the honest outcome: "unread" is meaningless without an account, and
the sign-in page explains why better than an empty list would.

## Decision 4 — unread means the same thing here as everywhere else

The unread stream is the read-state rules applied across every forum instead of
one: the three marks, and the thirty-day recency cutoff.

That cutoff is load-bearing here rather than merely tidy. Without it, somebody
returning after six months away lands on a page of four thousand threads, which
is indistinguishable from a broken page and produces exactly the same reaction.

The stream is capped at a page like everything else, and ordered newest activity
first, so the top of it is the useful part.

## Decision 5 — "you are all caught up" is a real state worth designing

An empty unread stream is the *good* outcome, and it should read like one rather
than like an error or a blank page. It gets a proper empty state, and it offers
somewhere to go next.

Same for the other two: "you have not started anything yet" is a prompt, not a
failure.

## Decision 6 — the streams do not invent their own permission rules

A stream shows what the member could already see by browsing. It is a different
route to the same content, and any stream that could surface a topic somebody
cannot open would be a permission bypass wearing a convenience feature's
clothes.

## What this does not do

- **No saved custom streams.** "Everything tagged X, in these three forums, by
  these people" is a real Invision feature and a genuinely bigger one: it needs
  stored definitions, an editor, and a sharing story. The four fixed streams are
  what people actually use daily.
- **No condensed/expanded toggle.** One presentation per stream, chosen to suit
  the question it answers.
- **No unread count in the nav.** Counting unread topics on every page render to
  put a number in a badge is work out of proportion to what the number tells
  anybody. The stream itself says how much there is.
- **No "content I follow" stream.** Following already produces notifications
  and email; a third channel for the same thing is a settings page nobody
  finishes reading.
