# UX behavior (docs/features/{surface}-ux.md)

**Truth document.** States what a person sees and can do on a surface, and what the surface promises never to do. Present tense, like every truth document. It is one product's surface; a shape every product's surfaces share, such as a settings area or an analytics page, is a playbook (`templates/playbook.md`), which the UX document names in its Purpose and fills with its own values.

**`type: ux`**, plus `status:` and `objects:` — the objects the surface presents (`references/frontmatter.md`). The doctrine it answers to (the state vocabulary, the routing doctrine, the information architecture) is named in its Purpose for people and computed through shared objects for tooling.

```yaml
---
type: ux
description: "{at most 300 characters: what this document settles and where its boundary sits}"
status: active                    # draft until the surface it decides is built
objects: [workspace, run]         # the objects the surface presents
owns:                             # transitional, only when this document speaks for the surface's components (references/frontmatter.md)
  - packages/{pkg}/src/{surface}/**
---
```

**Why this genre exists.** A feature doc (LLD) states what a feature is, how its data flows, and which contracts it honours — all of which stay plausibly true through a rewrite of the surface. Nothing else in the repo states what a person *observes*. So a change to the wire lands, the interface absorbs it, and the absorption reads as maintenance: no test fails, no lint fires, no document is contradicted. This document is the thing a silent change contradicts.

**Not a test plan.** `docs/tests/{feature}.md` records that behavior was driven and holds `Pinned:` traces; this document *decides* the behavior it later verifies. Written after the code, it is a transcript. Write it first.

**Scope decides placement, not medium.**

| The behavior is… | Where it lives |
| --- | --- |
| One surface's — a panel, an editor, a dialog | `docs/features/{surface}-ux.md`; its component files' headers name it |
| Cross-cutting — routing, information architecture, the state vocabulary every surface obeys, presentation of streams | `docs/architecture/` — owns no code, like every architecture doc |

**Ownership: a component file names one document in its header.** A surface's components are frequently already spoken for — by the page's feature document, by the feature behind one panel — and a file's header names exactly one document. Where the header already names the feature document, this document is named in that feature document's **See also** line under For the agent instead, phrased as *different promises over the same files*, and the object closure links the two through the objects both name. Where no document speaks for the component, its header names this one; prefer that header pointer, because the See also line is the weaker binding. A document nothing implicates rots, and a surface rewritten under an unimplicated document is the failure this genre exists to prevent.

---

## Required sections

### Purpose

One sentence: what a person comes to this surface to do. Then the sharper half — **what this surface is not for**, naming the neighbouring surface that is. A purpose that admits everything cannot refuse anything, and a surface that cannot refuse accretes.

### Anatomy

The regions, and what each is for. An ASCII sketch beats a paragraph. Name each region the way the interface names it, not the way the component tree does — a reader holds the screen, not the file list.

### States

**The complete set, exhaustively.** Every surface has more states than its happy path, and an unenumerated state is one the interface improvised — which is exactly how a surface starts lying. One row per state: what causes it, what a person sees, and what they can do from it.

| State | Entered when | The person sees | Can do |
| --- | --- | --- | --- |

Never omit a state because it is rare or ugly. The failed, empty, and stale states are the ones a person meets on their worst day, and they are the ones no one designs.

### Affordances

What a person can do, and what each action does. A disabled control states why it is disabled — a control that is simply inert teaches nothing and gets clicked again.

### Promises

**What this surface never does**, stated as absolutes. This is the section the rest of the system is measured against: a backend change that would break one of these is a breaking change, whoever ships it. Write the ones that are easy to violate accidentally — never silently discard typed input, never show a completed state over incomplete work, never move a control under a cursor mid-interaction.

### Transitions

What moves the surface between states, and who causes each move — the person, the server, or elapsed time. Server-caused transitions are the ones worth naming precisely, because they are the ones a person did not ask for.

---

## Optional sections

**Copy** — the exact words, where the wording is load-bearing (a refusal, an irreversible confirmation). **Density and rhythm** — where a surface deliberately differs from the design system's default. **Open questions** — decisions deliberately left open, so an implementer knows what to ask rather than guessing.

## Rules

- **Present tense, no history.** The journey lives in `docs/history/`; this document simply becomes correct.
- **Describe the observable, not the implementation.** "The rail shows every phase, the current one marked" — never "`railFromView` maps `view.phases`". Naming a component in a UX document is a boundary leak, and the name goes stale before the behavior does.
- **Every state gets a person-facing sentence.** If you cannot say what a person sees, the state is not designed yet — write it as an open question rather than eliding it.
- **No screenshots.** They rot invisibly and cannot be diffed.
