# Creative Index — Maintenance Guide

*How to keep creative.relayctx.com current as new work ships.*

> **Deploying / branches?** This file is about the *content* of the indexes.
> For how the site is **hosted, built, and shipped** — Cloudflare Pages, no
> build step, `main` = production — see [`GUIDE.deploy.md`](GUIDE.deploy.md).

**Design-system canon (v3.5):** token values in `brand/relay-tokens-v35.css`; direction in
`briefs/BRIEF.interface-v35.md` (**v3.5-a**, product UI); interactive guide
`brand/relay-brand-guide.html`. `briefs/SPEC.design-v35.md` is **v3.5-b** (marketing bold
concept) — a separate track.

---

## Index structure — hub + areas

The root `index.html` is the **hub**: one card per area, the specs & docs
bridge, and reference pages. It should stay a *domain overview* — individual
pages never get cards on the hub.

Each area (`concepts/`, `marketing/`, `brand/`, `email/`, `mcp/`) has its own
`index.html` card index and a curated `CHANGELOG.md`. All indexes are
**static, hand-maintained files** (no build step; nothing scans the repo to
regenerate them). A card goes live when its PR merges to `main`. Always edit
the area index on the same branch as the page so the card travels with it.

**Every page lands as a bundle:** the file, its card in the area index, its
`_redirects` entry (if a clean URL is involved), and a line in the area
`CHANGELOG.md` — same PR. If the page changes what's canonical, the master
`MANIFEST.md` row updates in the same PR too.

---

## URL conventions

| Type | URL pattern | Example |
|---|---|---|
| Area index | `/{area}/` | `/concepts/`, `/brand/` |
| Current page | Clean, no version | `/concepts/app`, `/concepts/console` |
| Archived page | Version-suffixed | `/concepts/app-v32`, `/concepts/console-v34` |
| Exploration | Namespaced | `/marketing/web/explore/minimal`, `/concepts/explore/journey` |
| Reference | Clean or namespaced | `/mcp/relay-card-display`, `/brand/type-specimen` |

**Clean URL redirects** live in `_redirects` (first match wins — keep new rules
above the legacy `/web/*` splat). When a page becomes canonical, add or retarget
its clean rule:
```
/concepts/[name]    /concepts/[name-version]    302
```
**Never point a clean URL at its own `.html`.** Pages serves clean URLs and
**301s `/x.html` → `/x`** on its own, so a rule like `/concepts/foo → /concepts/foo.html`
fights that and produces `ERR_TOO_MANY_REDIRECTS` — the page becomes unreachable
by *either* form. Rules target the clean path (`/concepts/map → /concepts/map-v35`);
only cross-directory targets carry `.html` (`/concepts/support-form →
/concepts/public/support-form-v1.html`). **A page that Pages already serves needs
no rule at all** — the only rule you add is the un-versioned alias. Broke production
this way on 2026-08-04 with `files-v2`; it took v1 down with it.

Convention: **302** for clean-URL-to-current-version rules (they retarget as
canon moves), **301** for permanent legacy-path migrations.

---

## Labels — canonical / fresh / archived

Three explicit statuses, one implicit:

| Status | Tag markup | Reads as |
|---|---|---|
| **Canonical** | `card-tag is-canon` | Solid teal chip — the ratified, current-truth page for its surface. At most one per surface. |
| **Fresh** | `card-tag is-fresh` + `is-fresh-card` on the card, with `<span class="fresh-dot"></span>` | Indigo, breathing dot — the current front line, freshly updated. Keep scarce (usually one card per section); demote to `is-new` when newer work lands. |
| Current | `card-tag is-new` | Full-weight teal-tinted chip — live, current work. |
| **Archived** | `card-tag is-archived` + `is-archived-card` on the card | Dimmed, collapsed per section behind the "▸ N archived" toggle. |

Cards with none of these dim to 45% (explorations, stable references). The
per-section archive collapse and the live-page count are automatic — the
scripts ship in every index.

## When a new page ships

1. **Build the file** at a versioned path in its area: `concepts/app-v36.html`
2. **Add a card** to the area's `index.html` in the relevant section — tag it
   `is-fresh` if it's the newest/active work, `is-canon` if it's ratified
   canon, otherwise `is-new`
3. **Update `_redirects`** to point the clean URL at the new version
4. **Update the old card** — retag `is-archived` + `is-archived-card`, move it
   to the section's archived tail (or the area's Archive section)
5. **Add a changelog line** to the area's `CHANGELOG.md` (newest first)

**CI backstop:** `scripts/check_index_cards.py` (the "Content checks" workflow)
fails a PR if a page under an area folder isn't linked from *anywhere* in the
repo — a card, an inline cross-link from a sibling page, or a doc mention
(MANIFEST.md-style). It's deliberately looser than "must have a grid card" —
that's still the convention above, but the CI gate only catches the failure
mode that actually happened here: a page landing with zero references at all,
unreachable and unfindable. A `<!-- index-check ignore: pattern -->` comment
in an area's `index.html` exempts a path with a reason, for cases that are
legitimately not wired up yet.

**Vocabulary backstop:** `scripts/check_vocab.py` (same workflow) fails a PR that
introduces a retired term — `PIN` for **Code**, `Relay Code`, `RelayContext`,
`relaycontext.com`, `Little Rocket` for the entity. `_vocab/_VOCAB.md` is the source
of truth; the script enforces only the unambiguous subset of its `Don't say:` lines
and self-validates against them, so it cannot drift from the vocabulary silently.

It compares against `scripts/vocab-baseline.txt`, which records the ~150 pre-existing
uses found when the check was introduced — so it only fails on drift *you* add.
Removing baselined uses always passes; run `--update-baseline` afterwards to lock the
win. That file is a burn-down backlog, not an accepted state.

Two escapes, both requiring a reason: a line that names a retired term in order to
forbid or map it ("never PIN", `PIN → Code`) is auto-exempt, and any line can carry a
`vocab-ok` comment. Judgment-call terms (*send*, *pass*, *thread*, *memory*) are
deliberately **not** enforced — they're retired only in a specific sense, and scanning
for them literally would bury the signal.

## When a page is superseded

1. Retag its card `is-archived` (+ `is-archived-card`) — never remove cards
2. Retarget the clean URL in `_redirects` to the new version
3. Don't delete old files — they stay reachable at their versioned URL
4. Note the supersession in the area `CHANGELOG.md`

---

## Sections and their rules

**Hub:** Areas · Specs & Docs · Reference — that's it.

| Area | Sections |
|---|---|
| `concepts/` | v3.5-a Direction (canonical) · Console · Easter Eggs · Team & Collaborator Onboarding · Product & App · Mobile · Errors & States |
| `marketing/` | Stealth · Marketing site (choosing) · Decks & concepts · Direction Explorations |
| `brand/` | Emblem & headlines · Creative Gallery · Design System |
| `email/` | Notifications & Email |
| `mcp/` | MCP |

Add a section to an area when a genuine new family of work appears; prefer
extending an existing one. A section that's all-archived can collapse into the
area's archive tail.

**`concepts/` — Team & Collaborator Onboarding vs. v3.5-a Direction's onboarding
cards:** the two are easy to conflate but are a genuinely different family —
v3.5-a's "Onboarding Flows" / "Sequential Onboarding" are the *product's own*
new-user activation/onboarding UX; "Team & Collaborator Onboarding" is the
*internal* welcome experience for people joining the company (contractors,
hires), built and gated separately in `relay-resources`. Keep new cards in the
section that matches which "onboarding" they mean.

---

## Boundary — creative vs the docs environment

Two estates, two purposes, **zero overlap**:

- **This site** (`creative.relayctx.com`) is the *visual* estate — clickable
  concepts, the brand system, marketing, rendered email, MCP visuals, and the
  briefs that drive them.
- **The MkDocs environment** (the documentation repos) is the *reading* estate
  — user-facing and internal documentation, runbooks, contracts.

Content lives in exactly one of them. Nothing is mirrored: creative pages are
never republished into MkDocs, and docs-repo content is never re-rendered
here. **This repo's own markdown** (briefs, changelogs, manifests) renders
on-site in the branded reader — an edge middleware (`functions/_middleware.js`)
wraps any `*.md` URL in the v3.5 shell (`?raw=1` for the plain file), so cards
can link local markdown directly. Cross-repo specs still link out to their
GitHub / MkDocs home. The two are **aware of each other and guide people across**: the hub's
Specs & Docs section links out where a contract lives in a docs repo, and docs
pages link to `creative.relayctx.com` where a visual reference exists. Rule of
thumb when placing something new: if it's *looked at*, it's creative; if it's
*read as reference*, it's docs.

**Three layers, never duplicated:**
- Spec files (`relay-platform/docs/`, `briefs/`) — contract, rules, params
- Site pages (`creative.relayctx.com`) — visual reference
- Relay transfers — team handoffs and working context

The spec references the site URL; the page references the spec path.

---

## Vocabulary

All new copy must use locked vocabulary (V&V Session 0, relay `KD8684`):
- `Code` not PIN / Relay Code / relay ID
- `receive` / `received` not claim / claimed
- `relay` (user-facing object), `transfer` (API-facing)
- `Item` not contribution

---

## Version lineage & provenance

Archived pages are **moved, never deleted**. `git mv` preserves full file
history (`git log --follow` traces a page back through its pre-rename commits —
including across the 2026-07-19 `web/` → area restructure), old versions stay
reachable via `_redirects`, and their cards are retagged `is-archived` (never
removed). Per-area lineage tables live in each area's `CHANGELOG.md`.

**When a set is superseded:** `git mv` it to a version-suffixed path (`v32/`,
`v34-bold/`), add a `_redirects` entry, retag its card `is-archived`, and drop a
short `README.md` in the archived folder noting what superseded it and when.

**Root-level strays:** the root now holds only the hub, shared runtime assets
(`relay-agent-launcher.js`, `relay-toolbar.js`, `activation.css` — loaded
absolutely by pages in several areas; don't move them without a sweep), and
reference pages. Anything else retired goes to `_archive/` (the graveyard —
`git mv` + a `_redirects` entry; convention in `_archive/README.md`).

---

*Last updated: 2026-07-19 · relay-creative/MAINTENANCE.md*
