Changelog — concepts/#
Product-surface concepts: app, console, activation & onboarding, Context Map / Explore, mobile, auth, errors, easter eggs. Newest first; entries are curated (one line per meaningful change), full detail in git log -- concepts/. Pre-2026-07-19 work lived under web/ and the repo root — git log --follow traces any file across the move.
2026-08-10 — Files becomes its own rail section: app-v35/files.html#
- New
app-v35/files.html— the v3 GitHub shell folded into the app per the day's direction calls (relay-board PRD.cloud-files §6.0): Files is its own rail section, not a tab inside Catalog. It sits directly after Overview (recommended placement — the rail call itself is still open) and owns the content area, drawing its own tree beside the persistent rail: library selector and lens switch in-surface, "Go to file" +T, a shelf tree that replaces the chips (chips die past ~6 shelves; the tree proves depth 3 — Auth & identity › On mobile › Warm), Last change / History / envelope diffs, and Edit naming 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, including the ⌘K palette's object results. - Runs on the catalog-shelves seeded corpus (mulberry32(42)) plus a second seeded supersession layer (mulberry32(7)) for version chains, so the two prototypes describe the same workspace. Chain rules AND correctly on nested shelves (the tab prototype's
Object.assignmerge silently dropped a parent's tag when the child also tested one — fixed in the new surface). app-v35/catalog-shelves.htmlbanner-superseded and kept as the record of the composed-into-Catalog answer; its rail group that listed the four lenses under the label "Shelves" now reads Lenses (the vocabulary bug flagged in the 2026-08-10 handoff — the group itself moves inside Files in the settled direction).files-v3.htmlgot its index card — it had shipped card-less on the branch, the exact miss the maintenance rules exist for. Clean URLs retargeted:/concepts/files→files-v3,/concepts/shelves→app-v35/files.- Verified in Chromium at 1320 and 500 over HTTP (tokens resolving): no page errors, zero horizontal overflow at both widths, view-as switching changes shelf contents per viewer, the depth-3 chain renders its full AND predicate, and the narrow topbar no longer clips the View-as control (caught by an element-edge probe; the scroll-width probe alone is blinded by
overflow-x:hidden). Sub-500 widths remain unverifiable in this container.
2026-08-10 — Files v3: the GitHub shell the brief actually asked for#
- New
files-v3.html. v1 drew Drive folders; v2 drew the set model correctly but as a four-pane inspector — it proved the semantics and lost the shell. v3 is the shell: library selector where the branch picker sits, "Go to file" +Tas the search spine, a shelf tree, and a listing whose second column is Last change — a supersession note, not a commit. The change bar,..row, breadcrumb-with-copy and History page carry GitHub's shape straight across; History opens the version chain and a click diffs two versions with an envelope header above the text. - What is deliberately not copied from GitHub: colour never carries type (no blue folders — v3.5 keeps type on glyphs, which also keeps the tree legible without colour vision), and there are no lock or shield glyphs. A shelf shows what your grants already reach; it never widens them.
- The set model survives the reshell intact: rule predicate under the breadcrumb,
addedchips on hand-pinned rows, struck-through excluded rows visible only to a curator, and every count post-filter — "3 items you can see", never a total. Switch View as (Erik → Dana → Sam) and the same shelf changes contents while its definition stays shared. - Editing a claimed object names the version before you type: "claimed by 2 people — editing creates v7". The brief's most important single moment, which v2 had dropped.
- Deep-linkable, same convention as the billing/gateway concepts:
?as=sam·?lib=me·?shelf=decisions·?obj=o1&view=history·?q=acme. Verified in Chromium at 1320 and 500 — no page errors, and a scroll-width probe finds zero horizontal overflow at 500. Sub-500 widths were NOT verifiable here (this headless build clamps the viewport to 500 minimum); the mobile rules below that are written but unproven — check on a device. - v1 and v2 are kept as the version record; neither is deleted.
2026-08-08 — Billing surfaces: app module + console gateway panel#
app-v35/billing.html— the member-facing half of the billing lifecycle on the shipped rail (Billing under Account): plan and seats, usage against the plan contract, invoices and receipts, payment method. Built on the three states the platform actually resolves —active,past_due(retrying, full access retained),unpaid(dunning exhausted, effective tier drops to the Free contract). Switching state moves the usage ceilings to Free with over-limit treatment and flips the open row to Pay invoice; nothing is deleted and billing stays reachable throughout. Reactivation copy holds the locked decision: webhook-confirmed, never client-claimed. Figures match the shipped tier contract and the billing-lifecycle email set, so app and email tell one story. Deep-linkable?state=retrying/?state=paused. Mirrors relay-platform RCTX-996/997/998; documents anticipate RCTX-993.console-v35/finance-lifecycle.html— new Gateway screen (RCTX-1055): connection health + console-managed config, framed adapter-shaped rather than Stripe-shaped so a Launchpad product on another processor inherits it (RCTX-1056). Three scenarios, all real failure modes: healthy, webhooks stale (the only check that catches an outage rather than a misconfiguration — it readsprocessor_events, no API call), and test key in prod. Secrets reported presence-only, never shown or settable, with the env-file boundary stated on the panel. Deep-linkable?gw=stale/?gw=testkey.
2026-08-08 — Hats & Lenses: the multi-hat framing made touchable#
- New
hats-and-lenses-v1.html. EC's framing observation — users wear multiple hats, work through different lenses, across various platforms and accounts — built as an interactive demonstration rather than prose. - The mechanic is the argument: node positions never move. A working week's context (20 objects across employer / two clients / personal) is laid out once; switching a hat seals or unseals, switching a lens emphasises or recedes. If a hat switch moved things it would be a filter, not a boundary.
- The money shot is the All hats view: four clusters, zero edges between them. Cross-hat edge count is computed from the data and shown in the readout, so the claim is asserted rather than drawn.
- "Reveal what's sealed" separates what the owner can see from what an agent in that hat can — an honest distinction the framing needs.
- Also states the precision ("ties it all together" means across tools and across time, never across identities), the argument against single-identity platform memory, and the single-point-of-trust objection answered by the zero-knowledge posture.
- Companion to the framing proposal in
relay-board/docs/strategy/framing-substrate-vs-transport.md. Clean URL/concepts/hats-lenses.
2026-08-08 — Organizing layer: the nouns are decided (Library · Shelf)#
- RCTX-1091 closed. A container is a Library, the rule-populated set at its root is a Shelf. Applied across
app-v35/catalog-shelves.html,console-v35/org-ia.htmlandshelves-mobile-v1.html— display strings only. - The RBAC constants deliberately do not follow: they stay
container.manage/slot.authorbecause each writes a permanentrbac_auditrow, and an audit trail must not change vocabulary partway through its own history. The console delegation card now says so on screen, so the mismatch reads as a decision rather than a miss. - Rationale: relay-board
organizing-layer.md§3.1; correction recorded in relay-platformSPEC.collections.md§6 (now ratified, schema landed).
2026-08-08 — Console Investor track: MSA → platform ToS (correction)#
- The MSA column and matrix row are gone. Erik: no MSA — the platform-side obligation is the Terms of Service, which every user already accepts at activation (
tos_accepted→registration_metadata, text atrelayctx.com/terms). NDA already applies to everyone, so the screen now shows NDA version + ToS acceptance date, and the lens matrix reads EAPA / NDA / ToS. - Lens & gate tab gains the reduced-scope note: no new document type is needed, and the whole change is EAPA becomes product-lens only.
- Two findings recorded on the same tab: the ToS is an unversioned checkbox (a terms change re-consents nobody; the signed text isn't recoverable from the record, unlike
legal_acceptances) — a real gap that belongs to the whole user base, not this screen; andBPAis labelled "Platform Agreement" inDOC_LABELSwhile being the retired Beta Participant Agreement that EAPA replaced, which now reads as the live platform terms.
2026-08-07 — Console: Investor track screen (draft, awaiting approval)#
- New screen in
console-v35/console.html— Investor track, in the Access group, tier-1 badged. Four tabs: Register (opaque 6-char pack IDs, lens badges, NDA/MSA status by version), Compliance (access-without-a-current- signature as a flagged live state, since a gate-mode version bump re-gates prior signers), Audit (grant/revoke with actor + timestamp), and Lens & gate. - The Lens & gate tab is the point of the screen: it carries the argument that EAPA cannot be made optional in the signing-gate component, because that component only renders what
GET /api/legal/pendingreturns. Skipping it client-side leavesgate_needed()returning true at seven server call sites (login, user API, MCP writes) — the user is blocked with nothing to sign. Proposes applicability as a third axis beside version and enforcement mode. - Revoke deliberately names what it does not reach: clearing the lens leaves the Cloudflare Access policy on that pack untouched, a manual step until the two systems are unified.
- Shell gains hash deep-linking (
console.html#screen-id) so the index cards can land directly on a screen. - Draft — nothing is built. Spec and rationale live in relay-platform (
docs/SPEC.investor-track.md,docs/DESIGN-NOTE.legal-gate-audience.md); both carry open questions, including one counsel question that blocks the NDA-tier unlock specifically.
2026-08-07 — Console board dashboard: tranche gates instrumented, roadmap dual-render#
- New:
console-v35/board-dashboard.html— a board-level console surface, gated tier-1/finance. Four screens in the v3.5-a console shell (sametokens.css, same shell vocabulary asfinance-lifecycle.html): Gate progress, Roadmap, Investor track, Sources & freshness. Clean URL/concepts/board. - The core move: instrument the tranche gates, don't build a metrics dashboard. Revenue and committed capital are both $0, so a metrics wall reads as failure and tells nobody anything. The gates (T1 Protect $120K → T2 Sustain $200K → T3 Team $680K, cumulative $1M = the round floor → T4 Scale $641K, cumulative $1,641,000 = target) are already the company's high-level goals, so those are what the screen renders.
- Five source states, deliberately not four. live · manual · stale · not instrumented · not computable. The last two exist because the concept refuses to collapse two pairs: measured-zero vs. never-wired (
repeat unprompted usehas no source at all), and zero vs. undefined (NRR with no paid cohort is a division by zero, not 0%). Every figure carries a provenance chip — source + as-of — and a stale manual input says so instead of showing an old value as current. - Roadmap is one source with two renders, live-toggleable in the page: board view keeps hard dates (fiduciary readers want slippage); the investor render drops every date at render time and removes rows touching protection still in progress — then reports its own withheld-row count, so a filtered pack is never mistaken for the whole plan. Not two roadmaps.
- Onboarding track screen — deliberately not a second investor register. The register, compliance view, grant/revoke audit and the legal-gate argument are owned by
console-v35/console.html#investor-trackandrelay-platform/docs/SPEC.investor-track.md; this screen adds only the column that surface doesn't carry — onboarding enrollment — and what it costs the gate signals. Reconciled on merge after the investor-track screen landed first; shipping two registers is the exact drift the rest of this concept argues against. It shows the two ways enrollment fails: an investor wrongly enrolled in the six-step First Relay sequence, and a principal holding access on a superseded agreement version. A dual-role row (investor and working user) is included on purpose: tracks are not exclusive, and suppressing that user's onboarding would break a real experience to satisfy a tidy model. - Money figures render the real current state ($0 committed, NRR not computable); platform-derived signals are sample. The preview bar says which is which. Nothing is wired.
- Companion docs: relay-platform
docs/SPEC.board-dashboard.md+docs/DESIGN-NOTE.onboarding-tracks.md; product shape and the edge-case register inrelay-board/docs/product/board-dashboard.md. Concept and docs only — the build is gated on approval and on settling the canonical source, which does not yet exist on a main line.
2026-07-30 — Catalog prototype: Objects tab, cross-type table (relay-app#458, scope-extended)#
- New:
app-v35/catalog.html— Catalog (relay-app#458, epic #449 /docs/DESIGN-NOTE.list-views-refresh.md). Built against EC's 2026-07-18 issue comment, which extended #458's scope beyond the original Labels/taxonomy convergence: Catalog becomes the rich object browser over the whole relay object base. Confirmed viamcp__github__issue_readbefore building — the comment text is reproduced verbatim in an HTML comment near the top of the file. The original Labels/taxonomy convergence (server-sidelabelstable,/api/user/v1/labels) already SHIPPED separately on 2026-07-18 and is NOT touched here — the realcatalog.ts/tags.tswere read to confirm Labels is already server-persisted, live, and consumed by the Transfers filter bar. - Tab bar: Tags and Labels are lightweight static stubs (per scope — this issue isn't about them) reproducing catalog.ts's real
.catalog-tabvisual pattern (one deliberate correction: active-tab color/border moved from the real code's literal--tealto the spec-correct--accent-textrole token, per the design note's "re-check against v3.5" requirement). Objects is the new third sibling tab and the prototype's default/active tab. - Objects tab — the actual deliverable: a real table (not cards) over ~90 seeded rows spanning Relay/Series/Session/Stream (36/14/20/20), each typed to its real field shape from
shared/src/types/{relay,transfer,stream}.ts(wire status vocab per type — relay: pending/claimed/expired/deleted; series & session: open/closed; stream: fresh/recent/stale/very-stale/unknown). Type facet with live counts (shape-alphabet icons matching the Graph canvas vocabulary: relay=rect · series=rounded-rect · session=diamond · stream=circle), a text+tag filter, a count line ("x–y of N (filtered from M)"), and click-to-sort column headers (Name/Title, Type, Status, Updated) per EC's comment. Pager is Transfers'.pager/.pgbtn/.rangecomponent and JS reused near-verbatim (range · numbered pages · page size 25/50/100). - Column strategy (design call, documented in-file): rather than a sparse table with many always-empty cells, shared columns (Name/Title, Type, Status, Tags, Updated) carry the table; type-specific fields (direction/weight/claims for Relay, relay+session counts for Series, agent+handoff for Session, item/unread/pinned for Stream) live in a row-click peek drawer instead of as dedicated columns. Tags column is genuinely empty ("—") for Series/Session since neither carries a
tagsfield on the real type — not a placeholder bug, an accurate reflection of the schema. - Row-click / #488 honesty finding: the brief's honesty constraint required either a real link or a clearly-labeled "#488 coming soon" stub per row. Checked production code (
relay-detail.ts,series.ts'sopenSeriesDetail,sessions.ts'sopenSessionDetail, andstream.ts) plus this repo's own sibling prototypes — all four in-scope object types already have a real, live per-type destination today (relay-app#488's unified cross-type object-detail page is what doesn't exist; the per-type flows do). So every row's peek drawer links out for real (target="_blank") to the matching sibling prototype — Relay→transfers.html, Series→series.html, Session→sessions.html, Stream→stream.html— zero rows are #488 stubs. Documented limitation stated in the drawer's own fine print and here: each sibling prototype seeds its own independent mock dataset, so the link lands on that object type's list/shell generally, not deep-linked to the specific row — a static multi-file demo constraint, not a fabricated destination. - Reusability for the epic's knock-ons (not built this round, per EC's comment): the filter/sort logic never hardcodes a "not deleted" assumption, so a future Trash variant (#607, deleted-only) or
/searchconvergence (#456) can reuse the same table without a rewrite — flagged in an HTML comment, not over-built. - Verified functionally (no headless Chromium available in this sandbox — the playwright browser download was blocked by the proxy) via a jsdom harness exercising the actual page script: type/tag/text filtering, click-to-sort (asc/desc, all 4 columns), pager (page size, next, numbered pages), all four drawer branches, tab switching, empty-state, and the ⌘K palette all run clean. Caught and fixed one real bug pre-publish: sort-header click handlers were being wired before the
<table>existed in the DOM (now rewired insiderenderObjects(), alongside row-click, on every re-render — matches Transfers' ownwireList()-after-innerHTML pattern). - Card index:
app-v35/index.htmlgets a Catalog card in the "App shell — as shipped" section, and the stale "Send / Catalog follow" note is updated now that both have landed.
2026-07-30 — Settings prototype: sectioned restructure, change-password removed#
- New:
app-v35/settings.html— Settings (relay-app#459, epic #449 /docs/DESIGN-NOTE.list-views-refresh.mdBatch 2 "Settings — restructure"). Copies the Stream/Transfers rail/topbar/⌘K shell, retargeted to Settings. - EC-confirmed scope (2026-07-18 issue comment on #459), not a fresh interpretation: re-read the comment thread directly before building. Three confirmed items, all reflected honestly against the current code (re-checked, not assumed from the brief's original audit):
- Change-password UI removed — the card that used to POST
/api/user/v1/passwordis omitted entirely, no placeholder. Turns out it's already gone from the realsettings.ts/index.htmltoo (the comment'ssettings.ts:212-231citation no longer matches current content) — this prototype doesn't reintroduce it. The separate forgot-password reset markup in the auth login flow (web/index.html, unauthenticated recovery) still exists there and was flagged by the same comment as a sweep candidate — noted in an HTML comment for the next implementation pass, not this Settings-page prototype's job to fix. - Timezone default — the picker pre-selects the browser-detected zone (
Intl.DateTimeFormat().resolvedOptions().timeZone), not first-alphabeticalAfrica/Abidjan. Also already fixed in the realdatetime.ts(displayTimeZone()/populateTimezoneSelect()) — the prototype mirrors that real implementation verbatim (comment + code) instead of re-deriving a "fix" that's already shipped. - Agreements "lists EAPA twice" — re-read
loadLegalStatusbefore reproducing this: each row already carries its own version + date, so the two seeded rows here are genuinely distinct acceptances (a BPA→EAPA program rename), not a fabricated duplicate-same-date bug. - Sectioned restructure: sticky left anchor rail (Account / Notifications / Integrations / Program / Danger) with scroll-spy, chosen over top tabs — card density varies too much per section (Notifications is long, Danger is one row) to hide any of it behind an unselected tab panel. Collapses to a sticky horizontal tab strip under 900px.
- Export relocated out of Danger Zone into its own non-destructive "Data" card under Account, next to Privacy & Defaults — Danger Zone is delete-only, per the brief.
- Slack placed under its own Integrations section (connection status only); the Slack notification-channel toggle stays in the Notifications card, since that's delivery preference, not connection state — one placement decision, kept consistent rather than duplicating the card.
- Skeletons + failure states, per the brief's explicit ask: a demo strip (Loaded / Loading / Failed, also
?state=loading/?state=error) drives every async card — Plan, Loop, Slack, Notifications, Communications, Agreements, Autojoin — through a real skeleton-shimmer state and a real error-with-retry state, not just prose describing one. - Card index:
app-v35/index.htmlgets a Settings card in the same "App shell — as shipped" section as the other list-shell/tools screens.
2026-07-30 — Send prototype: live recipient-side preview#
- New:
app-v35/send.html— Send (relay-app#457, epic #449 /docs/DESIGN-NOTE.list-views-refresh.md). Copies the Transfers/Stream rail/topbar/⌘K shell, retargeted to Send. - Confirmed, scoped-down gap: per the brief, Send's progressive disclosure — essentials (title/content/recipient/visibility/max receives) collapsing the rest (tags/expiry/bring-back/series) behind a "More options" disclosure with a live count badge — is already shipped (
send-claim.ts'ssend-more-options+updateSendMoreOptionsCount(), ~line 139) and is reproduced field-for-field here, not redesigned. The real gap was the empty right half of the viewport once that disclosure collapsed the form. Only new work: a live recipient-side preview in that column — a claim-landing card wired to realoninput/changelisteners on title/content/tags/visibility/max-receives/expiry so it visibly updates as you type, modeled onsend-claim.ts'sdoClaimPreview()(title, "From: X · date", provenance badges) and extended with a content preview, tag chips, and a receives-left/expiry footer per the brief's explicit list. Bring-back and Series are sender-only settings the recipient never sees, so they intentionally do not feed the preview. - Mobile posture noted inline (HTML comment): preview column drops below the form, never side-by-side.
- Card index:
app-v35/index.htmlgets a Send card in the same "App shell — as shipped" section as Transfers/Series/Sessions/Stream, plain.tagbadge per the Stream card's convention.
2026-07-30 — Stream list-shell prototype: pagination + shell alignment#
- New:
app-v35/stream.html— Stream (relay-app#454, epic #449 /docs/DESIGN-NOTE.list-views-refresh.md), the fourth and final list-shell screen after Transfers (#451), Series (#452), Sessions (#453). Copies Transfers' rail/topbar/⌘K shell and pager component near-verbatim (range · ‹ numbered pages › · page size 25/50/100), seeded with 70 focus areas (mulberry32(42)) so pagination is honestly necessary at 25/page. - Confirmed, scoped-down gap: per the brief's own inventory, Stream's search bar, sort dropdown (Last activity / Stalest first / Most items / Recently read / Title A→Z / Created), and combinable status/type/tag filter-chip row are already shipped and already "the most complete, natural donor pattern" — so none of that toolbar was redesigned into Transfers' popover-facet style. The real, confirmed gap was pagination alone (Stream renders its entire filtered list, no page size, no pager, no honest "x–y of N"); that's the only new chrome this prototype adds, positioned after the list per the shared list-shell anatomy.
- Not new work — flagging so it isn't re-done: the has-content suppression guard for the "Meet Stream" intro (#455/#604) is already live in production (
feature-intro.tsmaybeShowFeatureIntro()opts.hasContentbranch, wired fromstream.ts'sloadStreamList()). This prototype does not model the empty-first-run intro at all; it seeds a populated list on purpose. - Card index:
app-v35/index.htmlgets a Stream card in the same "App shell — as shipped" section as Transfers/Series/Sessions.
2026-08-03 — Responsive shell v1: the shell laws, at full scale#
- New:
shell-responsive-v1/—index.html(app),console.html(operator twin), sharedshell.css.shells-v35.htmlstates the seven shell laws and demos the three temperaments in miniature; this is the same system as a working prototype at real scale, one document per room that folds rather than forks. - Desktop: 220↔56px rail, brand-mark collapse persisted to
localStorage, the single 2px accent left-stripe, ⌘K principal search. At ≤860px the rail becomes an off-canvas drawer over a scrim — same groups, same order, same stripe, no bottom tabs (law 5). Drawer and sheet both dismiss four ways (trigger, backdrop, Esc, navigate) and return focus. - Cards are DEC-025 composed: the Code is the head and the one teal moment when shared; the head closes up on unshared objects with the title held at unchanged rank (L3) and the share action carrying the accent instead (L2). "Never shared · 41" appears as a filter chip, not a badge on every row (L4).
- Chrome budget is two rows — topbar + control row — with status, direction, personal state, the sharing axis and 115 tags all behind a transform-only filter sheet (
translateY, neverheight, perSPEC.app-components.md). - Console shares the CSS unchanged; indigo marks the operator layer (status strip + active stripe) and never the content, and the dense approvals table becomes cards below 860px rather than a tiny table. Reference implementation for
briefs/BRIEF.ui-component-kit.md. - Clean URLs:
/concepts/shelland/concepts/shell-console.
2026-08-03 — Cloud Files: Drive-shaped folders, search as the spine#
- New:
shelves-mobile-v1.html(/concepts/shelves-mobile) — the organizing layer at 390px, 390-first: lens/container segments, shelf list with predicates, origin markers, bottom sheets for filters / view-as / the object sheet (attribution basis + why-on-this-shelf + deciding properties). New:console-v35/org-ia.html— the org-admin governance screen: containers with deny-only overrides, rules with validity state, delegation, and the audit feed carrying each rule edit's predicate before → after. Updated:app-v35/catalog-shelves.htmlto SPEC.collections — attribution basis in the peek drawer (held vs reachable, opening a reachable object is a claim) and rule-validity surfaced to slot.author holders only. RCTX-1176/1177. - New:
app-v35/catalog-shelves.html(/concepts/shelves) — the organizing layer composed into the Catalog screen as a Shelves tab, the waycatalog.tsgrows. Reuses the existing rail tiers,.typecell/.statuscell/.tagchip, peek drawer and v3.5-a tokens; no new class prefix. Lens + containers sit in the rail on desktop and move into the content area below 900px. Slot predicate is visible; origin markers render only as the exception; the peek drawer answers "why is this here" and shows the properties that decide it. View as switches the same org shelf between Owner/Member/Viewer. Answers the composition gap infiles-v2.html, which stays as the model argument. RCTX-1106/1107. - New:
files-v2.html(/concepts/files) — the organizing layer. v1 drew folders; this draws containers and slots — sets populated by a rule, augmented by hand, filtered per viewer. Container rail (personal + org IA side by side), lens separation (Catalog and Workspace live; Graph and Journey greyed), membership origin markers (matched / added / excluded), org override indicators, and a view-as switch that changes what the same org shelf contains. Counts are post-filter throughout — never a total./concepts/filesnow points here; v1 stays reachable at/concepts/files-v1. Plan:relay-board/docs/product/organizing-layer.md. - New:
files-v1.html(/concepts/files) — the third projection of the corpus, after list (search) and graph (Context Map). Prototypes the Cloud Files model frombriefs/BRIEF.cloud-files.md: Google Drive folders, not Windows directories. Folders are loose, shallow buckets an object lives in one of; labels cut across them; search is the spine and sits inside the view rather than being somewhere you leave to, scoped to the current folder with a visible widen. Unfiled is a first-class state — a large share of the fake corpus is deliberately unfiled, and there are no counts, badges, or filing nags anywhere, because the brief's core test is that an unorganised workspace still reads as fine. "Shared with me" holds received/claimed relays as a peer of the tree. Also draws the two screens the model turns on: the integrity moment in the editor ("This was claimed by 2 people. Editing creates v5" — sent context never mutates, edits supersede) and the Git-familiar unified diff across a four-version chain, with an envelope header for title/label/folder changes.@-autocomplete authors references (every accepted one is a graph edge). No lock or shield glyphs anywhere: in v1 filing is organisation, never access.
2026-08-01 — Code presence: the display direction for DEC-025#
- New:
code-presence-v1.html— what a relay surface looks like when the Code is legitimately absent. Under DEC-025 lazy mint a Code exists only where an actor deliberately elevated context for handoff, so most objects never get one, and every surface built on "there is always a Code" now has a second state. Proposes four laws: L1 mark presence never absence (no placeholder, no em dash, no "not shared" stamp — a symbol for nothing happened is what reads as an error); L2 one teal moment per object, the accent tracking where intent lives (the Code when shared, the share action when not, so the two states differ by shape rather than hue); L3 the title never changes rank, same slot and size in both states; L4 on lists, absence is a filter you select, not a badge on every row. Relay detail drawn in both states with an annotation overlay, the mint moment as a live event (pulse family #7, the one animation on the page), a mixed list with a circulation segment and an honest counter, and the four rejected drafts rendered so they are not re-proposed. Clean URL:/concepts/code-presence. - The rejected drafts, kept visible: title promoted to hero (rejected by EC — title is the most generic field in the schema), title in Code costume, the internal ID shown as a stand-in (invariant C2 — IDs are machine handles, and their narrow alphabet is what keeps them shape-disjoint from Codes), and a placeholder in the Code slot.
- Canon correction in
PRODUCT.md: design principle #1 said the Code is the hero artifact full stop. Narrowed to every surface where sharing is the subject — share panel, handoff, claim, notifications, onboarding. The artifact is unchanged; the scope claim was the overreach. relay-appREFERENCE.product.md:47andREFERENCE.screens.md:19carry the same line and still need the same fix, which gates Train 3 app work. - Brief:
briefs/BRIEF.code-presence.md. MCP tiers:mcp/code-presence-display.html. Upstream: relay-platformdocs/DESIGN-NOTE.identity-and-codes.md, RCTX-1066, relayAJA9TN.
2026-07-30 — Public Views: support form#
- New:
public/support-form-v1.html— the support contact form (relayctx.com/support), the category's first interactive member. Proposes one addition to the slot contract:.form, left-aligned, sitting between.bodyand.actions; prefilled fields ring in accent so a person can see what the link filled in for them. Clickable states for arrival (bare ·?topic=account-merge·&ref=…· unknown-topic fallback · fully composed) and outcome (ticket created · ticket system down · security check failed · rate limited), plus a deep-link builder that makes the URL-prefill contract touchable. Clean URL:/concepts/support-form. - Note: the live
/supportshipped ahead of this concept (it was closing a 404 the app was already linking into) on a chrome copied from/feedback— so it is not yet a member. This page is the proposal to fold it in; adopting it is a render-layer reskin only.
2026-07-30 — Seats & Segments added to console Finance#
- New screen
console-v35/finance-lifecycle.html#fin-segments— "Seats & Segments": splits orgs into five commercial buckets (Free, EAP · Open, EAP · Grace, Paid · Full, Paid · Discounted) instead of one blended list, so unpaid-seat cost (AI usage + infra) stays separable from paid-seat revenue performance. Filter pills recompute the summary tiles live — the margin tile flips to "Net burn" when only unpaid segments are selected, since those orgs cost money and generate none. Sortable table (click any column), working CSV export, contract-org flag reusing the same purple used for discounted pricing. Nav item added to the Finance group; ported from an/impeccable-style artifact draft into the shell's real markup and token classes (b-free/b-eap-open/b-eap-grace/b-paid-full/b-paid-discbadges, new--purpletoken pair light/dark). - Flags two open decisions inline rather than deciding them here: what an expired EAP grace period converts to (today's
eap-graduationsweep drops it straight tofree— no discounted-tier conversion exists yet), and that the 30% graduation discount shown is a placeholder pending campaign terms. console-v35/index.htmlgained a missing card forfinance-lifecycle.htmlentirely (it linked onlyconsole.htmlbefore);concepts/index.html's existing finance-lifecycle card updated to describe the new screen.
2026-07-30 — Search v2 concept (one engine, two mounts)#
- New:
app-v35/search.html— interactive concept for the Search Experience v2 plan (relay-boardPRD.search-experience-v2): the/searchscreen + the ⌘K palette as two mounts of one engine (shared parser / scorer / row spec), two-pass local→engine results, narrowing operators with live chips, facet counts, unread + ⚡ agent-touch annotations rendered at last, intent-gated Code-status card, zero-query discovery, settled-only recents, URL-as-state. Carded on the app-v35 index under Concepts in review.
2026-07-30 — Public Views category + console notification layer#
- New category: Public Views (
public/) — every surface served without a session (error pages, maintenance, link-expiry, claim gates) unified on one chrome, the public.shell(public/shell.html): mark → status strip → headline → body → actions → support ref, live state switcher (404 · 500 · 503 · expired · notice), slot contract, and the/api/frontend-errortriage beacon (categorypublic, PB-… refs). Section renamed from "Errors & States"; the live error-page set stays put as a member. - New:
console-v35/notifications.html— error statuses in the shell: tier chips (active critical/warning counts) on every console screen + bell with per-admin unseen count and notification panel overplatform_alerts(incl. the newclient/publiccategories from the relay-platform error-triage pipeline). Interactive spike simulations; mark-seen (per-admin cursor) vs resolve (global) modeled as the backend contract.
2026-07-30 — Context Map v3.7: as-built alignment of the v3.6 refinement#
- New:
map-v37.html— v3.6's persistent-rail refinement updated to match what actually shipped in relay-app (branchclaude/context-map-graph-view-xh81fx): the rail's feed rows that touch the selection are tinted (not just re-titled), the type chips and new status chips (Open/Received/Locked, pre-filter counts, strike-through when excluded) really filter the canvas, and the control strip gains the Views menu with a default star (RCTX-592 — one default per user; a bare Graph open lands on the starred view, explicit links always win). Same map mechanics and v3.5 neutral-first tokens as v3.6.
2026-07-29 — app-v35: custody-shell gains the Overview lens-set#
custody-shell.html: the workspace switcher dropdown now has two zones — acting context (always exactly one) and "view" checkboxes to check other workspaces into a read-only overview. Foreign rows render receded (dashed) with their context chip; actions reduce to Timeline (read-only) and Open → (guided switch into the owning workspace).atoggles the all-contexts lens. Encodes the spec refinement: strict scoping governs acting, the lens-set governs scanning — unified-inbox pattern.
2026-07-29 — app-v35: Custody in the app shell#
- New:
app-v35/custody-shell.html— the custody flip inside the shipped shell anatomy (shell.html chrome): functional workspace switcher dropdown +[/]cycling with the lens-flip transition, topbar region readout, bell popover carrying guided switches (tap → lens flips → lands on the item), strictly-scoped Transfers list per context, claim simulator, Pass → across joined workspaces with dual-sided provenance timelines. Keys:[ ]1-3hbj/ko(timeline)p(pass)t(theme). Hub fresh-card now points here; the standalone walkthrough remains in the area index.
2026-07-29 — app-v35: Address custody walkthrough v2 (rulings applied)#
app-v35/custody-addressing.htmlupgraded to v2: the blend-vs-strict toggle is resolved (strict scoping per the SPEC-address-custody-v1 ruling) and removed; added the org-tagged bell with guided switching, one-tap Home, and the Pass → action — relaying an object between joined workspaces as an explicit policy-checked event, with the per-object timeline recording provenance on both sides (origin workspace, policy check, custody + region at each hop). Demonstrates "data crosses org walls only as a relay" and timeline continuity across contexts.
2026-07-29 — app-v35: Address custody walkthrough (interactive)#
- New:
app-v35/custody-addressing.html— prototype forSPEC-address-custody-v1/ RCTX-979. Per-membership contact-address mapping (1:1 picker), claim simulator (mapped / unmapped / billing-lapsed / membership-ended paths with the governance fallbacks), workspace switcher over custody-scoped lists with data-region chips, and the blend-vs-strict Personal-scoping question as a live toggle. Index card added under Concepts in review.
2026-07-29 — console-v35: Account migrations pattern-setter#
- New screen in
console-v35/console.html(shell + 6 screens now): Account migrations — the operator surface for the shipped merge/split backend (relay-boardSPEC-account-migration-v1, relay-platform/api/admin/v1/account-migrations). Kind badge (merge/split), consent progress (1/2), status chips across the full state machine (awaiting consent / consented / completed / cancelled), execute+cancel confirm modals, journal viewer, tier-1 + signed-pointer framing in the buildbar. Reached from the rail (Users section, warn pill = ready-to-execute count) or the Users row action "Merge…".
2026-07-29 — index-card CI check + pre-existing drift fixes#
- New:
scripts/check_index_cards.py, run in the "Content checks" workflow — fails a PR if a page under an area folder has zero references anywhere in the repo. See MAINTENANCE.md. - Fixed drift the new check found here:
onboarding-current-state.htmlandonboarding-journey-concept.htmlexisted but were never referenced — added as Reference cards next to Onboarding Flows.
2026-07-29 — Context Map v2 + Canvas Motion + Shells ported from frozen prototype#
- New:
map-v35-2.html(density × lenses × list, PR #185 / relay KTVANV),map-custody-concept.html(journey view + custody edge cases, same PR),canvas-motion.html(gc-* grammar motion, relay FMZRNG),shells-v35.html(App UI System — universal rail, shell temperaments, relay FMZRNG). All four only ever landed on theprototypebranch, which froze at the 2026-07-19 restructure and is slated for deletion 2026-08-09 — ported the files here so nothing is lost, with cards added in this same change. Not yet ratified: whethermap-v35-2supersedesmap-v35.html(v1) is an open decision, see MEMORY.md.
2026-07-26 — ComfyUI added to Apps#
- New:
app-comfyui.html— Relay's first node-graph-tool concept, alongside Slack/Chat/Relay Agent in the Apps section. A working prototype, not a mockup:relay-platform/clients/comfyui-relay-nodes(branchclaude/comfy-relay-integration-9yfv7r) is a real, tested ComfyUI custom-node package —Relay Infetches a Code and splits its markdown content from a tagged-on`relay-fieldsJSON block; typedRelay Fieldnodes pull one key out as STRING/INT/FLOAT for the graph. Zero backend changes needed to prove the in direction works. Diagram mirrors the real node inputs/outputs, not an artist's impression. - Deliberately not covered: pushing generated images back out into a relay — needs binary/object relay support first (Relay's
contentis text-only today), tracked separately so it doesn't block this concept. - Tracked: Linear
RCTX-823(epic, Plugin & Integration Payload Registry project) /RCTX-827(productionize this prototype against the registry).
2026-07-25 — Mobile: You becomes a Menu sheet, persistent bell, Activity unified#
app-mobile-v2.html: the You tab is no longer a 5th screen — Menu now slides a sheet up over the current screen and tab bar (same mechanic as the tools sheet), collapsing back down on a second tap, the backdrop, an explicit close, or picking any other tab. Nothing underneath is lost. Content unchanged (identity, this-week stats, Explore/tools entry, Security, Settings), just no longer its own route.- Added a persistent notification bell (top-right, every screen) opening the same dropdown-panel pattern as the Relay Agent concept's bell. Its badge reads the same count as the Activity tab badge, made explicit as a standing rule in
briefs/SPEC.app-components.md: Activity is the one unified space for notifications and activity, the bell is a shortcut into it, never a second inbox. - Explore's back-link now returns to Home and reopens the Menu sheet, since there's no You screen to return to.
2026-07-25 — cross-surface components: tools panel, profile/security, SPEC doc#
- New:
briefs/SPEC.app-components.md— the component inventory + surface capability matrix forconcepts/app-*.html, so Tools/Notifications/ Profile+Security stay consistent instead of drifting per file. Read this before adding chrome to any Apps-section concept. app-relay-agent.html: added the tools panel (+next to the input opens a sheet with Graph/Streams/Explore, Explore shown locked/Horizon rather than hidden), a notification bell with badge, and a quick-glance profile + security panel (passkey, active sessions).app-mobile-v2.html: brought the same three to Mobile — a "Jump to a feature" row on Home opens a bottom sheet (slides up over the tab bar) with the identical Graph/Streams/Explore tiles, and the You tab gained an identity header + Security section matching Relay Agent's panel. Wearable is the one surface that intentionally excludes all three (see its own concept notes) — Slack and Chat get an explicit N/A in the SPEC matrix since Relay is a guest in someone else's chrome there.
2026-07-25 — Relay Agent concept added to Apps#
- New:
app-relay-agent.html— Relay's own first-party conversational surface (not Relay's cards rendered by a third-party host, which is what the Chat concept covers). Same morning-brief → capture → claim loop, but replies use the actual designed app card component (working buttons, brand avatars) rather than a raw MCP tool-call block, since Relay controls this surface end to end. Deliberately shown able to approve a connection request directly, contrasting with the Chat concept's guest agents, which can't.
2026-07-25 — new Apps section: Wearable, Slack, Chat#
- Added an Apps section at the top of the gallery — the surfaces Relay actually runs on were scattered (Mobile was buried as the 6th of 7 sections) and wearable/Slack/chat had no home at all. Moved Mobile V2 (+ the superseded V1 and Phase 3) up into it, and added three new greenfield concepts alongside:
app-wearable-v1.html,app-slack.html,app-chat.html. - Wearable: not a shrunk phone — three faces only (Glance, Act, Capture), no keyboard/Search/You, digital-crown-first approve, voice-only capture.
- Slack: Relay as a native app, not a dashboard link-out. Reuses the MCP response-card component (
.cm/.cm-tool/.cm-bodyfrommcp/response-cards.html) inside Slack's own message/attachment chrome, with real inline approve/deny and/relay capture. - Chat: the agent's own chat window as the surface — a full claim → load → capture → pending-approvals transcript using the identical MCP card component, switchable across Claude/ChatGPT/Cursor-style chrome to show the card travels unchanged.
2026-07-25 — app-mobile-v2 remediation + Capture icon fix#
app-mobile-v2.html(live) taken through an/impeccablecritique pass (P0 error states, Activity/Home IA fix, Send+Claim segmented Capture, icon language, undo-on-deny, contrast/keyboard fixes — see PR #171) then a follow-up fix: the Capture tab's FAB read as a mic/walkie-talkie even though Capture is Send-or-Claim, a two-way handoff, not audio-only — swapped for a bidirectional exchange glyph; the mic icon stays inside the Send pane's actual voice-record button, where it's accurate.- Snapshots kept in
_archive/:app-mobile-v2.1.html(post-critique-pass, pre-icon-fix) andapp-mobile-v2.2.html(current, post-icon-fix). The live file atconcepts/app-mobile-v2.htmlalways tracks the latest.
2026-07-19 — Team & Collaborator Onboarding (new section)#
- New section:
onboarding-collaborator-v1.html— the internal, team-facing collaborator-welcome component (distinct from the app's own user-onboarding line above). Placeholder data; real per-person instances are gated onresources.relayctx.com/onboarding/<person>(relay-resourcesdocs/onboarding/). First built for the initial brand & product hire.
2026-07-19 — console-v35 nav completed to full audit inventory#
console-v35/console.html: added the remaining Batch 4 screens fromAUDIT.console-v35.mdto the rail nav as placeholders — Releases (Content); Onboarding mgmt, Legal, Trial users, Trash, Network (System). All render via the existing "on the map, not yet skinned" placeholder; no built screens touched. My Account intentionally not re-added — cut per Part 5 of the audit (redundant with the app,Account ↗deep-link instead).
2026-07-19 — area restructure#
- Folder created in the creative-domain restructure:
web/product prototypes and root-level strays (onboarding, mobile, launcher, errors) homed here. Old URLs 301 via_redirects. explore/direction studies (minimal/soft/swiss/maximal) split out tomarketing/web/explore/;explore/journey.html(product concept) stays.- Console fork preserved: prototype's 21-screen operator shell is canonical at
console-v35/console.html; main's 2026-07-18 finance-lifecycle build kept atconsole-v35/finance-lifecycle.htmlpending fold-in.
2026-07 (pre-restructure)#
- 07-18 Activation connect-first flow (#147); transfer-claim un-retired and synced to shipped claim process (#144); app-v35 gc-* kit explorer; Connect screen (tiered client picker, #143); Network page concept (#142); screen reality matrix + as-shipped design-system canon.
- 07-17 console-v35 Campaigns screen (F-6); Capture full concept (inbox + slackbox + Relay AI routing); Send → Capture experience (RCTX-730/733/734); campaign-x /x/{slug} edge cases; transfer-claim M2 states.
- 07-16 console-v35 operator shell + RBAC Roles & access screen; universal menu (no bottom tabs).
- 07-13/14 Explore journey/v2, sequential-onboarding storyboard.
- 07-12 and earlier Context Map line (map-v35/v36, graph-components, mobile map concept), app-v35 multi-screen shell (home/series/sessions/ manifest), onboarding prototypes, app-mobile-v2.