Every product surface, clickable.
Full clickable concepts of the Relay product: the app shell, operator console, activation and onboarding, the Context Map and Explore line, mobile, auth, public views (the public .shell + error pages), and the easter-egg kit. Canonical direction reads solid, fresh work reads indigo, archived versions collapse per section.
extension/, PR #797), drawn as HTML from the code with its real strings: the toolbar badge in seven states with their tooltips (count, p0 amber, 99+, signed out, offline, having trouble), desktop notifications (p1, p0 that stays on screen, fallback titles, the “N more waiting” fold), the 360px popup in six states, the click → destination table, the four behaviour rules and the 22-case register as a person meets it. P2 Act and P3 Capture/Carry sketched and stamped not built./relay capture, forwarded-message and reaction capture, resurfacing that lands where the team already looks. Reuses the MCP response-card component inside Slack's own attachment chrome.relay_send it, then pull the Code straight into a ComfyUI workflow. A working prototype, not a mockup: Relay In + typed Relay Field nodes parse a tagged-on ```relay-fields JSON block off the relay's markdown content — zero backend changes needed. Getting generated images back out is explicitly parked pending binary/object relay support.--rly-accent-fill → #0f766e), retiring the one token override these pages carried — they now run on canonical values with no deviation. Doc: relay-board/docs/product/experience-4-0.md.+104 more, tabs mixing three axes, and three identical badges on every row taking the width the title needed. The 4.0 side: one control row, filters in a sheet, an honest count (8 of 68 · 2 need you · 41 never left this workspace), badges only on the exception, dormant dims rather than hides. Then the rail at 24 → 6 with a stated destination for every removed item — including the three that are one table in the platform — hats and lenses made touchable (positions never move, sealed is absent not dimmed), and the bounded depth door whose counter describes what is drawn, never what exists. Toggle to 390px for the composition that produced “I don’t even know where to begin.”mobile/lib/theme.ts, Primer-dark, #00D9C8, system fonts). Draws the four jobs — Act · Aware · Capture · Attend, the fourth added because the build already crossed v2’s scope line and the largest screen in the app is the governance surface. Posture, not depth, is what keeps it honest: three jobs arrive from outside, the fourth is what you opened the app to do. The mechanic is a live reachability counter over the fifteen destinations the mobile PRD puts in scope — the shipped five-tab bar reaches eight (four in tabs, four nested in the Menu sheet) and strands seven with no route at all, the drawer reaches every one, and the counter describes what the shell can reach, never what the product holds. Also states the depth-rule amendment (depth is a property of the view, not the surface) and the Connect naming collision, where one word names three different products and the phone shows the least common one. Gated on D1 (nav) and D3 (depth rule). Doc: relay-board/docs/product/PRD.mobile-v3.md.relay-board/docs/product/PRD.mobile-v3.md, and the page is regenerated by scripts/render_prd_mirror.py rather than edited. Design-side direction is briefs/BRIEF.mobile-v40.md.console-v35/org-ia.html.relay_context orient · relay_session bridge · relay_request as interlibrary loan), the Root Manifest as boot sector / filtered shared map / attestation surface by tier, solo–team–enterprise packaging with honest status chips, and the Obsidian stance: cede the solo vault, own the accountable brain — “keep the vault, Relay is the remote.” Doc of record: relay-board/docs/product/second-brain-concept.md.gating.ts cohort preset.streamlined preset that already exists to hide them. Two findings carry it. The rail says Transfers while the page it opens renders 120 relays, so the first list a new user sees names the product’s own object two ways at once. And ten of the 25 doors answer one question — Series, Sessions, Stream, Library, Trash, Graph and Search are all the same corpus under a different filter. Proposes 25 → 6 in five independently revertible phases, the first of which is one word. Nothing deleted: the shared list shell, the cross-type Objects table and gating.ts already exist, so this is promotion rather than invention.#0d9488 (3.74:1, fails AA) while the consent banner’s “Allow” puts near-black #001311 on the same fill (5.09:1, passes). The ink flip is therefore already shipping in light mode, not a proposal. Shows the button four ways with computed ratios — today’s #0f766e/white at 5.47:1, the broken bright, and two flipped variants at 4.94:1 and 9.94:1, the brightest being the most accessible — plus the same app fragment with and without the flip, Codes deliberately left as text-safe #0f766e. Also names the deeper problem: every light-mode semantic sits near 5:1, so equal contrast means equal loudness and no hierarchy. Three decisions posed.BRIEF.code-presence.md. Ratifying it unblocks the relay-app REFERENCE rewrite that gates Train 3.active, past_due (retrying, full access retained), unpaid (dunning exhausted, effective tier drops to the Free contract). Switch state and the usage ceilings move to Free with over-limit treatment, the alert band offers the hosted invoice, the document row flips to Pay invoice; nothing is deleted and billing stays reachable throughout. Reactivation is webhook-confirmed, never client-claimed. Deep-linkable: ?state=retrying / ?state=paused. Operator counterpart: Console — Finance lifecycle.billing.TIERS; annual billing is shown disabled because no annual price exists; tax reads “from the billing address” rather than an invented rate. Built to the forms law, with the pending → confirmed status kept because the plan flip is webhook-confirmed. Deep links: ?plane=team · ?profile=saved · ?step=success.relay:approve permanently unavailable to a key: an agent cannot satisfy a step-up, and one that could approve could approve its own requests. The chips carry the distinction the whole surface exists to make — a hat is a wall, a view is a window, drawn dashed and labelled. Roll is what makes one-time reveal honest instead of a trap: shown at creation and at every roll, never otherwise, keeping the name, permissions and history while refusing the old secret at once. Says plainly what is real, what is real and broken (Revoke is cosmetic for MCP today — the revoked row goes invisible to the verifier, which mints a replacement for the same live token) and what is only drawn. Phone composition drawn, not assumed. Deep links: ?view=mint · ?view=reveal · ?view=summary · ?view=mobile.127.0.0.1 reads like a fact and identifies nothing, so the screen says “an app on this computer” and asks for a connection name, prefilled; a web connector named the same way; the workspace picker (built on branch); and a new §5 with what the server can actually see and the Sessions list where the name lands. Originally drawn in five states from one renderer: today (it asks you to authorize “this application” and never names it), named client + stated scope, the optional data-capture ask EC flagged from Klaviyo — placed both above and below the action so the placement is picked rather than assumed — a spoofed client name (registration is dynamic and verifies nothing, so the name is a claim and the redirect host is the fact PKCE binds), and an unidentified client that says so rather than inventing reassurance. §3 runs the two consent laws side by side: the optional row authorizes unchecked, the required one refuses, flags and takes focus. Relay collects no prompt-derived data today — the ask is a proposal and the session recommendation is not yet. Record: relay-platform DESIGN-NOTE.mcp-authorization-consent.md.cancel_at_period_end is a real webhook-fed column), no downgrade anywhere, and no view of who the bill covers — which is the decision: Relay seats are derived from membership, the reference console assigns them, and adopting that would let a member exist without a seat, changing quota reads and the seat true-up. Both models sit behind one switch. Each action names the audit row and funnel event it writes, because ga4_event() has zero callers and billing has no funnel data at all. Companion to the purchase half at /concepts/checkout.SPEC-address-custody-v1 with the rulings applied: strict scoping (contract-consistent views), per-membership contact-address mapping, the claim simulator with governance fallbacks, the org-tagged bell with guided switching, one-tap Home, and Pass → between joined workspaces with the per-object timeline carrying provenance across the wall — data crosses org walls only as a relay. Opens the in-shell version (real sidebar/topbar chrome); the standalone walkthrough lives beside it in the area index.shell-responsive-v1/workspace-first-run.html), framed desktop and 390px. Every control is tagged: data-track on each act, a screen view per render, and a Measure drawer that lists what fired, its consent disposition and the server stamp that is the record — kit app-v35/ui/track.js, the gate-denied precedent generalised (consent-gated by relay_consent, PII guard, drawn POST /telemetry). The page carries the full tagging plan for both flows (event → props → server record → GA4 name → the question it answers) and the pipeline. The plan-pick intake in the shell is tagged the same way. Twenty and Relaticle read as mechanism; nothing copied. Drawn, not built. Deep links: ?step=create|members|welcome|overview · ?consent=granted|denied|unknown · ?measure=1.shell-responsive-v1/plan-pick.html), framed twice on this page — desktop with the plan card in a sticky aside, and 390px where the rail has folded to the drawer, the plan summary is row 2 of chrome and the action sits in the bottom third. Nothing redrawn for the phone; the shell folds and the intake goes with it. Rule and fixtures from one kit (app-v35/ui/plan-pick.js) shared with the standalone. Arrival and step switches reload both frames. Drawn, not built.plan_picked funnel stage proposed. Drawn, not built. Deep links: ?arrival=campaign · ?arrival=invite · ?arrival=claim · ?step=plan.updates/YYYY-MM-DD-slug.md a session commits in the same PR as its work, and the hook register: every boot surface (CLAUDE.md, the coordination convention, the hub close-out, the seat series, the boot pack) that has to point here for another session to find it, each marked exists · extend · proposed. One record, three renders — console, board site, boot — the board dashboard’s generated, never typed law applied to narrative. Preview-as is a lens that only narrows (?as=management). Concept only, nothing built. Doc of record: relay-board/docs/product/updates-feed.md.gate-denied: one feature-key namespace, two directions. Twelve edge cases, three of them ship gates — led by the fail-open inversion: the legal gate fails open on a DB error, which on a pre-disclosure surface turns a blip into a public disclosure against a zero EU/EPO grace period. Nothing built; the forward half is blocked on the canonical source. PRD: relay-board/docs/product/PRD.eap-roadmap-visibility.md. Deep link: ?surface=admin.platform_alerts (categories incl. the new client + public from the error-triage pipeline). Interactive: fire client/boot/public spikes and watch the shell escalate; mark-seen (per-admin cursor) vs resolve (global) modeled as the backend does it.tokens.css + shell as the app). Expandable icon rail over the full 7-section operator map, operator topbar (status pill, maintenance flag, preview-as-role), dense tables, confirm-modal + toast. Mobile: the universal menu (topbar → off-canvas drawer, no bottom tabs) + scroll tables. Shell + 5 canonical screens: Dashboard, Transfers, Users, Claim approvals, Access codes. Light/dark, keyboard-operable./x/, /i/, ?ref=) and the detail adapts its funnel and protection line per class. Tags carry the grouping, which is what lets Track (formerly Angle) go optional behind a General default — the personalizer already has the person’s own role, workflow and goal. The create form checks the namespace at mint, case-folded: type AILDR14 and it is refused with the owner named, because /x/ resolves campaigns first and the collision would otherwise be silent. Access codes split label from campaign and show the /x/{CODE} link each mints. Sep 13 amendment: Access is the third axis — none | plan | trial (EAP is plan with beta) — and a trial length exists only under trial: pick EAP and the Plan and Days fields are not there to type into, because tier='beta' has no expiry field and ends by graduation, never by trial lapse. Record: relay-board DEC-030, relay-platform docs/SPEC.campaign-management.md §7./api/legal/pending returns — skipping it client-side leaves gate_needed() true at seven server call sites and traps the user with nothing to sign. Proposes applicability as a third axis beside version and enforcement mode. Draft — awaiting approval, nothing built. Spec: relay-platform docs/SPEC.investor-track.md.#2dd4bf, ink-flip fills. Theme toggle (auto→light→dark) in the topbar. The full 36-screen inventory + v3.5-a gaps live in briefs/AUDIT.console-v35.md, tracked under RCTX-705.processor_events, not the API), and test key in prod. Secrets are reported present-or-not, never shown or editable. Deep-linkable: ?gw=stale / ?gw=testkey.relay_timeline events (sent · claimed · forwarded · landed · handoff · stream · session; reads never), agents marked ◆, levels from the data’s own quartiles, a sequential teal ramp derived from the accent by color-mix() so dark mode flips its anchor by construction and no new hex exists. The module contract: a module is the smallest unit a screen lends to another surface — one owning screen, declared hosts and widths, a tier per viewer (full · counts · none), empty means gone, pinned moves but never leaves — with the interface, eight rules, a sixteen-module catalogue generated from the registry the prototypes run on, and six hosts including the agent’s Root Manifest. The lens: hat, scope, viewer and time, composing under the rulings already ratified — a lens never grants; a visitor can only ever see less. Live specimens for all three, the day-one state, Step 6 amended to “Make it yours”, ten worked edge cases, what ships versus what is new, six decisions to ratify. Concept — proposal, not canon; nothing built. Record: relay-board/docs/product/activity-and-modules.md.?hat=org · ?scope=context · ?customize=1 · ?state=first-run|empty. Layout persists locally only; fixture data./profile settings form and the shipped /u/{handle} card. The form becomes the edit state, kept whole; the profile becomes the identity card, the activity graph (year picker, table twin), the owner’s modules and Shows on your public profile — each pick labelled with the tier a visitor gets. View as You · A connection · Public previews the card exactly as the host computes it: modules with tier none disappear, counts modules drop to numbers, the graph shows org-visible counts unless the owner opts private contributions in — as numbers, never titles. /u/erik carries Relay to @erik as its primary action; private stays the shipped locked state. First-run carries Step 6 · What your profile shows with the graph’s first cell lit. Hooks: ?view=public|connection · ?vis=private · ?edit=1 · ?state=first-run.relay-board/docs/strategy/the-session-is-the-unit.md.relay-board/docs/strategy/framing-substrate-vs-transport.md.relay-board/docs/strategy/framing-substrate-vs-transport.md.files-v3.html GitHub shell carried across whole: library selector where the branch picker sits, “Go to file” + T as the search spine, a shelf tree that proves depth 3 (Auth & identity › On mobile › Warm), Last change as a supersession note, History with envelope diffs, and Edit that names the next version before you type. The cross-type Objects table moved in from Catalog as “All objects” — same table, every row and count per-viewer now. Runs on the catalog-shelves seeded corpus and grants, so the two prototypes describe the same workspace. Aug 17 — the pack-shelf layer: shelves can now be provisioned (SPEC.pack-shelf, Draft), and the surface exists to test the seam that spec turns on, not to illustrate it. An audience is grant rows (user · email · group · org — classes are v1); disclosure is a separate per-object act, so rule-matched objects sit on a provisioned shelf reading “matched, undisclosed” and reach nobody until someone acts — filing still never grants. A fourth viewer, Marta — External, is the Access floor: no Relay account, session-level provenance, watermark stamped, shown only the packs provisioned to her. Open one as her (that is a claim), revoke her row, and switch back: everything goes except the copy she claimed — “revocation ends access to the shelf and everything on it from that moment; what someone already claimed, they hold” made testable rather than quoted. Open calls render as open (§7.1 storage shape · §7.2 provenance exposure · §7.3 tier classes · §7.4 archive). Deep links: ?as · ?lib · ?shelf · ?obj&view=history · ?view=all · ?view=audience · ?q.T as the search spine, a shelf tree, and a listing whose second column is Last change — a supersession, not a commit. History opens the version chain; a click diffs two versions under an envelope header. Deliberately not GitHub: colour never carries type, no lock/shield glyphs, no export affordance. The set model survives intact — predicate under the breadcrumb, added chips, curator-only excluded rows, every count post-filter — and Edit on a claimed object names the version first: “claimed by 2 people. Editing creates v7.” Folded into the app as app-v35/files.html. Deep links: ?as=sam · ?lib=me · ?shelf=decisions · ?obj=o1&view=history · ?q=acme.app-v35/files.html — Files is its own rail section now, not a tab inside Catalog. Kept as the record of the composed-into-Catalog answer (RCTX-1106): the organizing layer as a Shelves tab alongside Objects/Tags/Labels, reusing the existing rail tiers, table cells, peek drawer and tokens — no new class prefix. A shelf shows its predicate; hand-added rows carry an origin marker and rule-matched ones carry none; the peek drawer answers “why is this here” and exposes the properties that decide it. View as changes the same org shelf between Owner, Member and Viewer — 4 rows becomes 2. The model it draws is still correct; only the composition moved.relay-board/docs/product/organizing-layer.md.Version trap: map-v36 and map-v37 label themselves “v3.6” and “v3.7”. Those are the Context Map concept’s own iterations — the design system never had a 3.6 or 3.7, it went 3.5 → (proposed) 4.0. A version-string census traced the entire v3.6/v3.7 count to these two files. Recorded in VERSIONING.md.
main, each with its file: F1 the contact form carries a diagnostic ref and the feedback intake has no field for one, so the brief’s “surface the last CE- ref” step has nowhere to put it; F2 POST /feedback silently coerces any source outside {widget, web}, so an app panel is filed as an anonymous rating — trip it live in the composer; F3 the app screen calls no API at all. Then the spine (one intake, one submission, one triage, two back offices, N faces), four laws the faces obey, and S1 · S2 · S3 live with a signed-in / signed-out / locked-out viewer switch that makes the asymmetric gate testable — the screen is gated, the help never is, because a user who cannot reach the app is exactly the user who most needs support. Closes with an additive contract v2, the desk seam (the wire is write-only today, which is the real gap between panel and portal), the core/product cut for the framework, and five open calls. Concept — S1 mirrors what shipped; S2 and S3 are drawn, not built.transform or opacity, nothing loops, and nothing autoplays. The specimens leg of guidelines/GUIDE.motion-register.md; the feedback tier lives in brand/motion-lab.html.aria-describedby, autocomplete hygiene, bot-check gating that never traps, the consent lock that never plays dead, the confirmation with role=status and a focus move, and the assembled form. Trip the states, copy the wiring. The specimens leg of guidelines/GUIDE.forms.md’s enforcement triangle; the gate is scripts/check_forms.py.obClaimPanel only covers onboarding self-claim, never the general external-claim flow this models). M0 gate/public-card, M1 signed-out states, and M2 signed-in set (#316–#321). Wrong-account bug-repro tab now reads "shipped" (relay-platform #1915/#1918) instead of live-incident, its before/after toggle kept for the record. Adds three new states matching what shipped Jul 18: self-claim vs. external-sender provenance (sender/org/visibility badges, relay-platform #1933 + relay-app #619) and the universal loading skeleton (relay-app #627) that replaced several blank-panel flashes app-wide.concepts/index.html #campaign-landing + requests.ts clInit() — dark/teal, own cl-* convention, not the v3.5 tokens) with its shipped states plus five gaps found in a live backend audit, each with a current/after-fix toggle wired straight to the tracked issue: draft-campaign servable (#1896), campaign expiring mid-flow (#1896), OTP send silently failing (#1897), no brute-force lockout on verify (#1898), and no capacity cap (#1899). Companion to the higher-level Campaign Path in Onboarding Flows below — this one is scoped to just the /x/ funnel, matched to the real DOM.Kept in place, never deleted: the version-suffix convention means a superseded page stays at its own URL so old links and old decisions still resolve. Nothing here is canon.
.shell (mark → status strip → headline → body → actions → support ref) with a live state switcher and the /api/frontend-error triage beacon (category public, PB-… refs). New public-bound views start here.