open-standards/aac/spec/board.md
Transaction Science 384ee7a927 fix(aac-web): the partner menu closes on a tap beside it; a binned recording is never kept ready for a cell; SPEC: lang
A tap beside the open partner menu closes it and presses nothing behind
it, so no sliver of a cell is left at the menu's edge (axe target-size
on iPad, once Aphasia supports joined the bar). A recording played from
the bin is decoded for that play only, never cached where a cell would
find it. SPEC §2.1 and spec/board.md document the cell's lang field (the
person's own words, never glossed), and §8 how it travels.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 23:34:58 -04:00

57 lines
4.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AAC sub-spec — The board data model
Normative refinement of [SPEC §2](../SPEC.md). Reference: `aac_core::{Board, Cell, GridLayout, GridPosition, CellContent, CellAction, BoardType}`.
A **board** is a person's communication surface. It is a small, text-like document — artwork is referenced, not embedded (§4) — so a voice travels cheaply between devices and implementations.
```
Board = (id: BoardId, name: String, board_type: BoardType,
layout: GridLayout, cells: [Cell])
Cell = (id: CellId, position: GridPosition, content: CellContent,
action: CellAction, style: CellStyle, frequency: u64, locked: bool,
[hidden: bool], [sound: String], [symbol: String], [lang: String])
```
The bracketed fields are optional (proposed, [SPEC §2.1](../SPEC.md)) and omitted at their defaults, so a board that uses none of them serializes as it did before them (§8).
## 1. Identity — `id: BoardId`, `id: CellId`
Both are UUIDs, stable for the life of the structure. A `BoardId` is the target of a `Navigate` action, so it is also the edge label of the board graph (§5). Two openings of the same logical board MUST present the same `BoardId` and the same set of `CellId`s.
## 2. Board type — `board_type`
One of `Grid` (a symbol grid), `VisualScene` (photo-based with hotspots, for emerging communicators), `Keyboard` (text input, for literate users), `Hybrid` (mixed symbol + text), `QuickAccess` (high-frequency phrases — the home board). The type is a rendering hint and a vocabulary-strategy marker; it MUST NOT change a cell's `position` semantics (§3 of SPEC).
## 3. Layout — `layout: GridLayout { rows: u16, cols: u16 }`
The grid dimensions. `capacity = rows × cols` is the maximum number of non-overlapping cells. A board MAY hold fewer cells than its capacity; absent positions render as empty grid (distinct from a `Blank` cell, which is an explicit, addressable reservation — see §5).
## 4. Position — `position: GridPosition { row: u16, col: u16 }`
0-indexed. A position is assigned once and is **immutable** for the life of the cell (motor stability — see [`motor_stability.md`](motor_stability.md)). No two cells on a board MAY share a position.
## 5. Content — `content: CellContent`
One of:
- `Symbol { symbol_id, label }` — a symbol referenced by registry id plus its text label. The label MUST survive round-trip even where the artwork cannot be rendered ([`../SPEC.md` §4]).
- `Text(String)` — plain text, for keyboard boards and literate users.
- `Photo { image_ref, label }` — a referenced image with a label, for visual scenes.
- `Blank` — an intentional, addressable empty. A `Blank` reserves its position to preserve the surrounding motor grid and MUST NOT be elided on round-trip.
## 6. Action — `action: CellAction`
What activation does: `Speak(text)`, `Navigate(BoardId)`, `Modifier(GrammarModifier)`, `Backspace`, `Clear`, `Predict`, `SpeakAll`, `Buffer(text)`. `Navigate` edges the board graph; `Modifier` applies a grammatical transform (`Plural`, `PastTense`, `PresentProgressive`, `FutureTense`, `Possessive`, `Negation`, `Question`, `Pronoun(name)`) to the message bar; `Buffer` adds to the message bar without speaking.
The board graph is the source of truth; a grid is one projection of it. A conforming editor MUST keep the `Navigate` edges referentially intact: deleting a board MUST report, not silently break, any cell that navigates to it.
## 7. Optional fields *(proposed — SPEC §2.1)*
- `hidden` — the word is hidden in place ([`motor_stability.md`](motor_stability.md) §3). Default `false`.
- `sound` — a recording the cell plays in place of speaking its words (the person's own voice: message banking), as a reference the client resolves (`media:<id>` in the reference app, or a `data:` URI). A client that cannot play it speaks the words. Default absent.
- `symbol` — the symbol concept chosen for the cell in place of the one its words name; `""` is words only. Default absent.
- `lang` — the language the cell's words are written in (`fr`, `es`, `ar`…) when they are the person's own words: shown and spoken exactly as written, never glossed. Absent: the words are keys the client glosses into the person's language. Default absent.
## 8. Canonicality
A board serializes to the canonical interchange form of [SPEC §7](../SPEC.md). Round-trip MUST preserve every `position`, `content`, `action`, and `symbol_id` byte-for-byte. Conformance suite **C4** pins the wire round-trip; the published vectors live in [`../conformance/v1/`](../conformance/v1/).