RelayCTX / Concepts

What a surface looks like when the Code isn’t there

Under DEC-025 a Code is minted only when someone deliberately hands context over. Most objects will never have one. Every surface built on the assumption that a Code is always present now has a second state it was never drawn for.

This page draws that second state. The Code stays the hero artifact; nothing is promoted to stand in for it.

DEC-025 · identity-and-codes relay AJA9TN v3.5 neutral-first proposal · 2026-08-01

A Code means someone chose to share this. No Code means it never left. both states are correct

Four laws

Ordered by how easy each one is to break by accident. L3 is the load-bearing one: it is the rule the rejected draft violated, and the rule a designer breaks by reflex when they see empty space where the Code used to be.

L1
Mark presence, never absence

No placeholder, no em dash in the Code slot, no dashed outline, no “not shared” stamp. A symbol standing for nothing happened is exactly what reads as an error: scanning a list, nobody can tell a deliberate dash from a failed fetch. Shared objects are marked. Unshared objects are quiet.

L2
One teal moment per object

The accent tracks where intent lives. Shared: the Code, in --accent-text. Unshared: the invitation, in --accent-fill. The surface never loses its accent and never doubles it, and the two states differ by shape (a mono token against a filled button) rather than by hue, so the distinction survives greyscale and the plain-text harness.

L3
The title never changes rank

Same slot, same size, same weight, same colour in both states. The title’s job is recall, finding your own work again; the Code’s job is sharing. Different jobs, so they neither compete nor substitute. On an unshared object the title is a label, which is what it always was.

L4
Absence is addressable, not annotated

On lists, “never shared” is a filter you select, not a badge on every row. Make the set selectable and absence reads as a population you can count, instead of a mark repeated dozens of times that each looks like missing data.

Relay detail, both states

Same object, same layout, one difference. On the shared relay the hero slot holds the Code. On the unshared one the slot is absent, not empty: the layout closes up and the share action takes the accent. Read them side by side; the contrast is the whole product story.

SharedCode present
Stream/Launchpad

Q3 pricing model, assumptions and open questions

L3 title: 19px / 600 / text-bright
You2 days ago4 actions
L2 the accent lives on the Code
Relay AJA9TN

Shared 2 days ago · claimed once by Dana

Unsharednever left this workspace
Stream/Launchpad

Q3 pricing model, assumptions and open questions

L3 title: 19px / 600 / text-bright — identical
You2 days ago4 actions
L1 hero slot absent, not empty. Nothing renders here
L2 the accent moved to the act

The elevation moment

This is the surface the Code was designed for, and lazy mint makes it better: minting on every object made the Code wallpaper, minting on intent makes it earned. Its first appearance now has a cause, so it gets the one event animation on the panel and nothing else moves. Press the button.

Share panelinteractive
Q3 pricing model

Hand this context to a person, an agent, or your next session.

A Code means someone chose to share this.

Relay

Anyone with this Code can claim the context.

The list, mixed

Most rows have no Code, and that has to look ordinary. The rail carries a Code or carries nothing, so the eye reads circulation down a single column without a symbol for the negative case. The state stays reachable because the segment control makes it a set you can select and count.

What the title does instead

Every rejected direction below was an attempt to fill the hole the Code left. Each is drawn here so it is not proposed again.

Stream/Launchpad
Q3 pricing model, assumptions and open questions
You2 days ago
Adopted
Nothing changes

The title keeps its rank. It was a label before the Code was absent and it is a label now, so the surface has no gap to fill and no new component to build.

This looks like the least interesting answer on the page, which is the point: the interesting decision was refusing the other four.

Stream/Launchpad
Q3 pricing model
You2 days ago
Rejected by EC
Title promoted to hero

The title is the most generic field in the schema; every competing tool has one. It cannot carry a verb surface.

The deeper cost is what it teaches: that the hero slot is a container for whatever happens to be available, rather than a claim about identity.

Stream/Launchpad
Q3 pricing model
You2 days ago
Rejected
Title in Code costume

Mono, uppercase, letterspaced, sitting in the Code’s slot. It borrows the artifact’s clothes while having none of its properties: not short, not unique, not shareable, not speakable over a phone.

Worse than promoting the title outright, because it is the same mistake wearing a disguise.

Stream/Launchpad
Q3 pricing model, assumptions and open questions
r7f3a91c04d2e
Rejected · invariant C2
Show the internal ID

IDs are lowercase hex machine handles and are not a display surface. The narrow alphabet is deliberate: it keeps them shape-disjoint from uppercase Codes, which is what lets one resolver dispatch on shape alone.

Rendering one to a person also invites the demand to prettify it, and prettifying identifiers is identity churn.

Stream/Launchpad
——————
Q3 pricing model, assumptions and open questions
Rejected · breaks L1
A placeholder in the Code slot

An em dash, a ghost lozenge, or a “not shared” chip. At a glance none of them is distinguishable from a failed load, and each spends the row’s attention budget on a non-event.

It also forces screen readers to announce nothing-happened to the people least able to skip past it.

Rules this page is holding to

Accessible tree

  • The prefix is aria-hidden and paired with a visually hidden type label, so a screen reader reads “Relay AJA9TN”, never the Unicode character name.
  • Absence produces no announcement. State reaches assistive tech through the filter and through the share action’s own label.
  • Codes as text use --accent-text: 5.5:1 light, 10.4:1 dark. Fills take the #0d1514 ink flip in dark; white on teal is 1.9:1 and is never used.

Motion

  • One event animation on the whole page, at the mint: pulse family #7, characters landing top-down, 55ms stagger, once, system teal.
  • Under prefers-reduced-motion the Code still arrives, it just arrives instantly.
  • #00D9C8 stays motion-only and is not rendered statically anywhere here.

Copy

  • Capability language only. “A Code means someone chose to share this” clears the RCTX-1073 gate; describing how minting works does not.
  • Buttons name the act, never the machinery: “Share this relay”, not “Generate Code”.
  • The list counter describes what is drawn, never the corpus.

What ratifying this unblocks

  • relay-app REFERENCE.product.md:47 and REFERENCE.screens.md:19, both still carrying “hero artifact on every relay surface”. They gate all Train 3 app work.
  • The narrowed line: the Code is hero on every surface where sharing is the subject. Share panel, handoff, claim, notifications, onboarding.
  • Rollout touchpoint #1 is undersized. The 52 code references in relay-detail.ts are mechanical; the visual hierarchy of every relay surface is the real work.
Brief: BRIEF.code-presence.md MCP tiers: code-presence-display Upstream: relay-platform DESIGN-NOTE.identity-and-codes.md · RCTX-1066