RelayCTX Creative MAINTENANCE.md
RelayCTX Creative · Document

Creative Index — Maintenance Guide

1,607 words · 7 min View raw Source History

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.

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

TypeURL patternExample
Area index/{area}//concepts/, /brand/
Current pageClean, no version/concepts/app, /concepts/console
Archived pageVersion-suffixed/concepts/app-v32, /concepts/console-v34
ExplorationNamespaced/marketing/web/explore/minimal, /concepts/explore/journey
ReferenceClean 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:

StatusTag markupReads as
Canonicalcard-tag is-canonSolid teal chip — the ratified, current-truth page for its surface. At most one per surface.
Freshcard-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.
Currentcard-tag is-newFull-weight teal-tinted chip — live, current work.
Archivedcard-tag is-archived + is-archived-card on the cardDimmed, 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.

AreaSections
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:

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:

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):


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