# Interface Copy Specification

Writes every string an interface needs — including the ones for the states that go wrong — with the key, the context and the mechanics each string carries.

## Deliverable

One Markdown document, `ui-copy-specification.md`, in the structure set out under **Output** below. It takes the output of **User Flow Specification** and is the input to both the build and the translation.

## Required inputs

- **A flow or screen inventory** — the states that need words. Sections 3 and 5 of `user-flow-specification.md` are the expected form.
- **The product's voice constraints** — how it addresses the reader, how formal it is, the terms it must use and the terms it must not.
- **The locales the strings will ship in**, or a statement that only one is planned.

If the inventory is absent, stop and report it. Copy written without a state list produces strings for the screens that work and silence for the ones that fail.

## Optional inputs

- Layout constraints that impose a character budget on a particular string
- The status and error responses the system returns, with the conditions that trigger them
- The existing string catalogue and the key scheme it uses
- Terminology already decided, with who decided it
- Wording that must appear verbatim for legal or regulatory reasons
- What the people answering support requests hear readers misread

Where a character budget is not supplied, the string is written short and marked `budget unknown`. A budget is never invented, because a number in a specification is read as a constraint by whoever builds from it.

## Execution

**1 — Enumerate the states that need words.** From the inventory: every screen, and every empty, loading, error, permission-denied and partial-success state on it. A state the inventory does not define gets no string; it goes on the missing list instead.

**2 — Give every string a key.** Stable, structured by where the string lives, and independent of the words themselves, so rewording does not orphan a translation. Record the state each key belongs to.

**3 — Write the furniture.** Titles, section labels, field labels, helper text, buttons and confirmations. A button names the action it performs rather than agreeing with the sentence above it, so it still makes sense to a reader who arrives at it alone.

**4 — Write the empty and loading states.** What will be here, what puts it here, and what the reader can do in the meantime. An empty state that only reports emptiness wastes the one moment the reader is looking for instruction.

**5 — Write the errors.** What happened, what the reader can do next, and who to ask when there is nothing they can do. Map each message to the condition or response that triggers it, and keep internal causes the reader cannot act on out of the message.

**6 — Record the mechanics of each string.** The variables and what fills them, the plural forms required, the character budget where a layout imposes one, and whether the string may be truncated or must not be.

**7 — Flag what translation will break.** Strings assembled from fragments, strings whose meaning depends on word order, and strings that must agree in gender or number with a variable. Each one with the note a translator needs to render it correctly.

## Output

`ui-copy-specification.md`, in this order:

- **1. Input and date** — which inventory the strings were written from, and when
- **2. Voice constraints applied** — address, formality, required terms, forbidden terms, each with its source
- **3. Strings** — per string: key, the state it serves, the text, and the context a translator needs
- **4. Errors** — per message: the condition it answers, what happened, and what the reader can do next
- **5. Mechanics** — per string: variables and their sources, plural forms, character budget or `budget unknown`, truncation behaviour
- **6. Translation risks** — strings depending on order, gender, number or assembly, each with the note the translator needs
- **7. States without strings** — states in the inventory whose behaviour is undefined, listed with who must decide them
- **8. Missing information** — what blocked a string, and who can supply it

## Validation

The specification is ready when all of these hold:

- Every state in the input inventory has either a string or an entry in section 7
- Every string carries a key, the state it serves, and the context it is read in
- Every error message names what happened and what the reader can do next
- Every string with a variable declares what fills it and the plural forms it needs
- A character budget appears only where a supplied layout constraint produced it
- No string exists for a state the inventory does not define

Fail the run if a string appears for an undefined state, or if a character budget appears that no supplied constraint produced.

## Failure handling

- **No state inventory** — stop. Report that there is nothing to write against, and that a screen list without failure states produces copy only for the path that works.
- **No voice constraints** — write plainly, record every choice made as an assumption in section 2 with its source recorded as none supplied, and name who must confirm them.
- **System responses unknown** — write the messages the flow defines, mark each `response unmapped` in section 4, and list in section 8 what mapping them requires.
- **Conflicting terminology** — record both terms and both sources, use neither in the strings, and raise the conflict in section 8 as blocking.
- **Partial inventory** — write for the states that are defined, mark the rest `INCOMPLETE — pending <state>`, and deliver. A string invented for an undefined state fixes the wrong behaviour in place.
