Conflicts: - aac-web components/grid_cell.rs: visual-scenes' accessible name (built each time from the words shown, WCAG 2.5.3: the Edit label with its hidden, recording and sequence notes; "Say the next line"; a word cell named by what it says when that holds the words shown) kept whole, with word-finding's `class:path-next=on_path` beside it. word-finding's usage::with_via(click_via(&ev), ..) around handle_cell_action and its CellCounts strip merged cleanly. word-finding's edit_label/aria_label were main's, which visual-scenes had replaced. - aac-web components/output_strip.rs scan_draw: visual-scenes finds the bar whether or not it is in the scan (so a bar turned off while highlighted loses its outline); word-finding adds the way's .guide-banner in the bar's place. Both: the bar is outlined when !help && !guide && it is scanned, the guide banner when it is shown. - aac-web state.rs: AacAppState keeps scene (visual-scenes) and finder and usage (word-finding). The page-set catalogue needed no change (catalog.py --check: up to date, 119 packages; phrases/build.py --check: 99 reproducible). Co-Authored-By: Claude Opus 5.5 <[email protected]>
498 lines
106 KiB
Markdown
498 lines
106 KiB
Markdown
# AAC — Specification
|
||
|
||
**Version 0.2.0 (draft) · Status: draft · Licence: CC-BY-4.0**
|
||
|
||
This document specifies the AAC open standard: the data model for a portable communication board, the access-method abstraction, the energy-tiered communication cascade, canonical serialization, the interchange format, and the receipt. The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHOULD**, **SHOULD NOT**, **MAY**, and **OPTIONAL** are to be interpreted as described in RFC 2119.
|
||
|
||
The Rust reference implementation in [`aac-rs/`](aac-rs/) is normative-by-example: where this prose and the reference types disagree, that is a defect to be reconciled, not a license to diverge.
|
||
|
||
---
|
||
|
||
## §1. Scope and terms
|
||
|
||
AAC (augmentative and alternative communication) is technology that lets a person who cannot rely on speech compose and produce utterances. This standard specifies how a **board** — a person's communication surface and the customization invested in it — is represented, accessed, and exchanged so that it is portable across implementations and devices, operable offline, and never gated behind payment.
|
||
|
||
- **Board** — a surface holding cells, of a given `BoardType` (`Grid | VisualScene | Keyboard | Hybrid | QuickAccess`).
|
||
- **Cell** — a single selectable target on a board, at a fixed grid position, with content and an action.
|
||
- **Utterance** — the message a user composes by selecting cells.
|
||
- **Access method** — the physical channel by which a user selects (`DirectTouch | EyeGaze | HeadTracking | SwitchScan{switches} | Joystick | Bci | PartialVoice | Pointer`).
|
||
- **Client** — software that opens, renders, drives, and speaks a board.
|
||
- **Cascade level** — one of ten tiers (L0–L9) through which a communication operation is resolved.
|
||
|
||
This standard does **not** specify rendering pixels, a UI toolkit, a TTS engine, or symbol artwork. It specifies the data and the invariants that make a voice portable.
|
||
|
||
---
|
||
|
||
## §2. The board data model
|
||
|
||
A board **MUST** be representable as the following structure (field names are normative; the reference type is `aac_core::Board`):
|
||
|
||
- `id` — a `BoardId` (UUID), stable for the life of the board.
|
||
- `name` — display string.
|
||
- `board_type` — one of the `BoardType` variants.
|
||
- `layout` — a `GridLayout { rows: u16, cols: u16 }`.
|
||
- `cells` — a list of `Cell`.
|
||
|
||
A **cell** **MUST** carry:
|
||
|
||
- `id` — a `CellId` (UUID).
|
||
- `position` — a `GridPosition { row: u16, col: u16 }`, 0-indexed.
|
||
- `content` — one of: `Symbol { symbol_id, label }`, `Text(String)`, `Photo { image_ref, label }`, or `Blank`.
|
||
- `action` — one of: `Speak(text)`, `Navigate(BoardId)`, `Modifier(GrammarModifier)`, `Backspace`, `Clear`, `Predict`, `SpeakAll`, `Buffer(text)`.
|
||
- `style` — colors and optional font size; a client **MAY** override style for accessibility (§5) but **MUST NOT** alter `position`.
|
||
- `frequency` — usage count, monotonically non-decreasing.
|
||
- `locked` — whether the cell is protected from structural edits.
|
||
|
||
Boards form a **graph**: a `Navigate` action edges from one board to another. The graph is the source of truth; a grid layout is one projection of it. A `Blank` cell is meaningful — it reserves a position to preserve the motor grid (§3) and **MUST NOT** be elided on round-trip.
|
||
|
||
*(Proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance.)* A reader **MUST** keep every field of a board or a cell that it does not recognize and write it back unchanged when it saves the board. A board saved by a newer client then loses nothing when an older client opens and saves it. A field's type never changes from one version to the next: a version that needs another type adds a field under a new name. A reader that finds an optional field it knows (§2.1) with a value not of that field's type **MUST** read the field as absent (its default) and keep the value as it keeps an unknown field, under the same name, unless the board is changed there; a reader **SHOULD** read each board on its own, so that one board it cannot read is kept as stored and the others load. New fields go on the board or on the cell, never inside `style`, `position` or `layout`: a reader need not keep unknown fields there.
|
||
|
||
### §2.1 Optional cell fields *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A cell **MAY** carry these fields. Each has a default, and a serializer **MUST** omit a field that has its default, so that a board using none of them serializes exactly as it did before they existed (§7):
|
||
|
||
- `hidden` (default `false`) — the word is hidden in place (§3 item 3, §3.1).
|
||
- `sound` (default absent) — a recording the cell plays in place of speaking its words: typically the person's own voice, recorded while they could (message banking). Its value is a reference the client resolves (the reference app keeps recordings on the device and writes `media:<id>`; a `data:` URI carries the bytes themselves). A client that cannot play it **MUST** speak the cell's words instead. A recording is played as it was recorded; a client **MUST NOT** present it as a synthetic voice made from it.
|
||
- `symbol` (default absent) — the symbol concept chosen for the cell in place of the one its words name (§4); the empty string means no symbol, the words alone.
|
||
- `lang` (default absent) — the language the cell's words are written in (a language code such as `fr`), when they are the person's own words rather than keys a client glosses into the person's language. A client **MUST** show and speak such words exactly as written, in whatever language it is set to, and **MUST NOT** gloss or translate them. Absent, the words are keys (in the reference app, English) shown and spoken through the client's glosses.
|
||
- `sense` (default absent) — the sense of the cell's key, when it is not the sense the client's glosses of that key carry (the key `back` used as in "come back", where its glosses are the body part). A client **MUST NOT** gloss such a cell: its words exist in the keys' language only, and in another language it has none (§4.1 item 4).
|
||
- `gloss_sense` *(proposed, after 0.2.0; default absent)* — the sense the cell's words are glossed in, where some languages say that sense with another word than the general key's: the words `cold` with `gloss_sense` `water` are shown in Japanese as つめたい (cold water), not さむい (I am cold); `table` with `dining`, in Korean as 식탁. The cell's words stay the word itself, so a client that does not know the field shows and says "cold". A client that does **MUST** gloss the words in that sense where its glosses have it (the reference keeps such glosses under the key `cold (water)`), find the word's symbol and word class by the word, and fall back to the general key's gloss where they have none. The reference carries it in the open board interchange format as `ext_aurasense_gloss_sense`.
|
||
|
||
A cell's word class, where a board states it (the reference writes it in the open board interchange format as `ext_aurasense_word_class`), is one of: `pronoun`, `determiner`, `verb`, `adjective` (describing words, adverbs among them), `preposition`, `conjunction`, `question`, `negation`, `social`, `interjection`, `core_noun`, `fringe_noun`. A client that colours cells by class **SHOULD** use the Fitzgerald Key's families, and text that reads on each colour at 4.5:1 or more; the reference's colours are `aac_core::WordCategory::fitzgerald` (conjunctions, as prepositions, take the key's "other" colour).
|
||
|
||
### §2.2 Sequences *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A cell **MAY** carry a sequence: two or more lines, said one press at a time (a greeting, a joke, a song, the opening lines of a conversation). A sequence has an order (`in_order`, or `shuffle`: a new order each time round), what a press after the last line says (`start_again`: the first line again; `stay`: the last line again), whether its lines join the message (default: they are said only), and **MAY** have an idle time after which the next press starts again from the first line. A line **MAY** name a cell of the same board by its position, and then says that cell's words — and plays its recording (§2.1 `sound`) — as they are when it is said; a line **MAY** carry a recording of its own.
|
||
|
||
1. Each activation of the cell says the next line, by any access method. The client **SHOULD** show the line said and where the person is ("2 of 4").
|
||
2. Where the person is in a sequence is the person's, not the board's: using a sequence **MUST NOT** change the board, its export or its content address (§7). A client **SHOULD** keep it for the person across a reload.
|
||
3. Undo just after a line (the reference: the message bar's Delete, by any access method) **MUST** step the sequence back one line, which the next press says again. A partner **MUST** be able to start a sequence again, and **SHOULD** be able to step it back, without a press of the person's.
|
||
4. A press while a line is still being said **MUST** be honoured: that line stops and the next is said; the person sets the pace. The hold and release times of §5 still decide what is a press.
|
||
5. In a modelling mode (a partner showing how), a press **SHOULD** show the line the person's next press will say, and **MUST NOT** move the sequence on.
|
||
6. A client that cannot play a sequence **MUST** say the cell's own words (which a writer sets to its first line) and **MUST** keep the sequence when it saves the board (§2).
|
||
|
||
The reference carries a sequence as the cell's `ext_aurasense_sequence` (version 1: `lines` of `{say, at?: [row, col], sound?}`, `order`, `at_end`, `add_to_message`, `reset_after_minutes`) until a later version makes it a field of its own; the person's places are kept on the device by person, never in the board (`aac_core::behaviours::SequencePlace`, aac-web `sequences.rs`).
|
||
|
||
### §2.3 Board behaviours *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A board **MAY** declare that it closes after a choice (a popup), or that it speaks without building a message.
|
||
|
||
1. **Popups.** After a cell of a popup that says or adds words is chosen (or a sequence's line is said), a client **MUST** go back to the board that opened it. A popup's continuation pages count as the popup: the return goes to the board that opened its first page. The person **MUST** be able to keep popups open, for all boards; the choice travels with their settings. This belongs to the vocabulary's design and returns to the board that opened the popup, not to Home: it is not the option of going Home after each word (§5.6 item 6), which stays the person's alone and, where they have chosen it, wins.
|
||
2. **Speak only.** The cells of a board that speaks without building a message say their words at once and **MUST NOT** add them to the message; the message is left as it was.
|
||
|
||
The reference carries these as the board's `ext_aurasense_behaviour` (`after_choice: "return"`, `message: "speak_only"`).
|
||
|
||
### §2.4 Links that say words *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A cell that goes to another board **MAY** carry words ("I want" opening the page of things to want). A client **MUST** add them to the message as a speaking cell would, then open the board. The reference carries them as the cell's `ext_aurasense_link_says` (the words themselves).
|
||
|
||
### §2.5 Visual scenes *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A board **MAY** be a visual scene: a picture of a meaningful event or place — the person's own photo, or a drawing — with hotspots on it. A hotspot is a cell (§2): it says its words, adds them to the message, opens a board, plays a recording (§2.1 `sound`) and can be hidden, as any cell can.
|
||
|
||
1. **A hotspot never moves.** A hotspot's place is a region of the picture, in parts of the picture's width and height, never in screen units, so it is where it was on every screen, at any size and either way up; the picture **MUST** be shown whole, scaled but never cropped or stretched. A client **MUST NOT** move, resize or reshape a hotspot except by an explicit edit of that hotspot: adding, hiding or removing another, or changing the picture, leaves it where it is on the picture. A hidden hotspot keeps its place, cannot be chosen by touch, switch or dwell, and is drawn only while editing or while hidden words are shown for now (§3.1 item 3).
|
||
2. **Hotspots are cells of the grid.** Each hotspot has a grid position like any cell, kept as §3 requires, so that a client without scenes shows the hotspots as buttons of the board's grid. The board's first row holds the scene's row of words (item 3); hotspots are below it.
|
||
3. **The row of words.** A scene **SHOULD** be shown with its row of words — the scene's own words and a few core words, so that the person can say more than the picture shows: the cells of the first row that are not hotspots, each in its own slot (its column), in order, under the picture or beside it at the end the language reads towards, as the scene says. A client **MAY** put them in the other place on a screen where that makes the picture much larger (beside it on a phone on its side; the reference: twice as large), and beside it in more than one column on a short screen rather than make a word smaller than a person can reach; the words keep their order, and the hotspots their places on the picture. A word's place on a scene is a slot of the row of words only: a word added to a scene (a link to another board, a recording) goes to an empty slot of the row, and where there is none the client **MUST** say so rather than put it where the picture would hide it.
|
||
4. **Every access method.** A touch, a pointer or a look on a hotspot chooses it (where hotspots overlap, the smaller, which is drawn on top); one just beside a hotspot (a near miss) **SHOULD** choose the nearest within a reach the person sets (§5.1: theirs, within a range, never changed for them); a look beside the picture and away from the row of words **MUST NOT** choose anything. Each hotspot **SHOULD** be at least the target size of WCAG 2.2 (24 CSS pixels) on every screen the client fits, and a client's own starter scenes **MUST** be. A switch scan reads the hotspots in reading order — from the top of the picture down, each band in the language's direction — in rows, then the row of words, with the bar and the navigation as on any board (§5.5, §5.6); it **MUST NOT** rest on a place with nothing to choose. The scan's highlight **MUST** be drawn on the hotspot's own outline, in colours that can be seen on any picture. Dwell treats each hotspot as a place (§5.8 item 2). Auditory scanning names a hotspot by its words (§5.7 item 5). The person **MUST** be able to leave a scene by every access method they use (§5.6).
|
||
5. **Words on the picture.** A client **SHOULD** offer to show a hotspot's words on the picture when it is chosen — large, then fading, taking no press — and to show every hotspot's words all the time (the transition to literacy of Light, McNaughton and colleagues). Both are the person's settings, not the board's. Nothing else **MAY** be drawn over the picture outside editing but the highlight of the access method in use.
|
||
6. **Pictures taken in the moment.** A client that lets a partner make scenes **SHOULD** let them take a photo with the device's camera, mark a hotspot on it by dragging a box across it or drawing round the thing, and give it words or a recording, so that the person can use it at once (just-in-time programming). Marking and moving a hotspot **MUST** also be possible without dragging (WCAG 2.2 2.5.7): the reference takes a tap on one corner and a tap on the opposite one, and moves and sizes a hotspot with buttons and arrow keys in its editor. Each such change is one edit an undo takes away (§3.1), behind any editing lock (§3.1 item 4).
|
||
7. **A scene a client cannot show** — another version, a picture that did not travel with the board or is not on this device, or a cell with no place in the scene (a hotspot of another version, or one whose place is not on the picture, below the row of words) — **MUST** be shown as its grid, every cell a button where it is, with a note saying why, and kept as it is when the board is saved (§2); an import that finds one **MUST** warn.
|
||
|
||
The reference carries a scene as the board's `ext_aurasense_scene` (version 1: `image`, the picture — `media:<id>` on the device, or a `data:` URI, as it is exported, so that the picture travels inside the scene —, and `image_license`, the picture's licence as the open board interchange format writes one; or, read from another writer, `image_id`, the id of the picture among the board's `images`; `width` and `height`, the picture's size in pixels; `description`, what it shows; and `words`, `below` or `beside`) and a hotspot as the cell's `ext_aurasense_hotspot` (version 1: `rect`, `[x, y, width, height]` in ten-thousandths of the picture's width and height from its top-left corner, never mirrored; and optionally `polygon`, the corners of a shape inside that rectangle), until a later version makes them fields of their own (`aac_core::scene`; aac-web `scenes.rs`, `components/scene_board.rs`).
|
||
|
||
---
|
||
|
||
## §3. Motor stability (normative invariant)
|
||
|
||
A user's motor plan — the learned muscle memory of where each word lives — is the single most valuable property of a configured board. Therefore:
|
||
|
||
1. A cell's `position` **MUST NOT** change once assigned, for the life of that cell, except by an explicit user/editor edit to an `unlocked` cell. Prediction, context, frequency, language switching, and any L3+ enrichment **MUST NOT** move a cell.
|
||
2. A client **MUST NOT** reflow, resort, or auto-arrange cells on a board whose cells are `locked`.
|
||
3. Hiding a word for teaching (progressive disclosure) **MUST** be done by rendering its cell as visually inactive **in place** — never by removing it and collapsing the grid.
|
||
4. Two openings of the same board on the same or different conforming clients **MUST** present identical cell positions.
|
||
|
||
An implementation that rearranges a locked board is non-conformant regardless of any other quality.
|
||
|
||
### §3.1 Editing never moves another word *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
1. An edit to a cell — its words, action, picture, recording, colour, or whether it is hidden — **MUST NOT** change the position of any other cell. A new cell goes only into an empty position; removing a cell leaves its position empty; copying a cell to another position makes a new cell (a new `id`), and the original stays where it is. Undoing an edit restores what it changed and nothing else.
|
||
2. A grid **MAY** grow, or shrink, only at its end (its last rows and columns), and shrink only where those are empty, so that no cell's position changes.
|
||
3. A hidden cell (§2.1) **MUST** keep its position and **MUST** be rendered as visually inactive and not selectable, by touch, switch or dwell alike. A client **MAY** let the person or their partner show hidden cells for now, selectable in place; this changes nothing on the board. While editing, a client **SHOULD** show hidden cells in place, marked as hidden.
|
||
4. A client **MAY** lock editing and settings against accidental change (a PIN, or a control held for some seconds). A lock **MUST NOT** stand between the person and their words: cells stay selectable while it is on.
|
||
|
||
The reference implements these as `Board::place_cell`, `edit_cell` (which puts the position back whatever the change), `remove_cell` and `resize` in `aac-core`, and, in its app, Edit mode, which checks every change against the positions before it and refuses one that would move a word.
|
||
|
||
---
|
||
|
||
## §4. Symbols
|
||
|
||
Cell `Symbol` content references a symbol by `symbol_id` and `SymbolSource`, **not** by embedded pixels. A board therefore travels as a small, text-like document; artwork is resolved by the client from a symbol library. A client **MUST** preserve the `symbol_id` and `label` on round-trip even if it cannot render the referenced artwork, and **SHOULD** fall back to rendering the `label` text when artwork is unavailable. This keeps a board legible across implementations that ship different symbol sets.
|
||
|
||
### §4.1 Language honesty
|
||
|
||
A board travels between languages as a graph edge (a translation of each label), but a word list translated from one language is not another language's core vocabulary: the words people use most differ from language to language. Therefore:
|
||
|
||
1. Every language a client offers **MUST** state how its core vocabulary was obtained, as a `CoreStatus`: `ValidatedNativeCorpus` (a published core list derived from speakers of that language), `StakeholderValidated` (nominated and rated by its speakers and communication partners), `PrimesOnly` (a provisional seed from semantic primes and frequency lists), or `GlossOnly` (glosses of another language's core list).
|
||
2. A language record without a `CoreStatus` **MUST** be read as `GlossOnly`.
|
||
3. A client **MUST NOT** present `GlossOnly` vocabulary as that language's core vocabulary, and **SHOULD** show each language's status where the person chooses a language.
|
||
|
||
4. *(Proposed, after 0.2.0.)* A word with no word in the person's language (no gloss, or a `sense` its glosses do not carry, §2.1) **MUST NOT** be hidden or silenced, except on a page set made to be glossed — one whose packages are the keys' words for every language (a catalogue's `lang` `*`, §8.1) — which **MAY** hide such a word in place (§3 item 3) and, while editing, **SHOULD** mark it as having no word yet, so that someone can give it the person's own words (`lang`, §2.1); showing hidden words for now does not show it. Everywhere else — a client's own boards, the person's own and imported boards, page sets written in a language — the word **MUST** be shown and said in the keys' language (or the language it was written in), marked as being in that language, so that it is read and said as such; except a word the language does not have, which **MUST** be left out in its place there too, as on a glossed page set: a key the client's gloss data marks, on purpose, as having no word in that language ("the" in Polish, which has no articles) — never a word of the keys' language put into the person's message. A key merely not translated yet is no such word: it is shown in the keys' language, marked so. A client's build **MUST** fail on a word of its own boards that is neither translated nor marked, in any language it offers (the reference: `aac-core` `no_word.json`, checked by `tools/pagesets/catalog.py` and a test over its own boards). A key that opens another board (and a key that acts on the message) **MUST** always show a name: its own in the person's language, else the name of the board it opens in that language, else its name in the keys' language, marked as being in that language.
|
||
|
||
5. *(Proposed, after 0.2.0.)* **One word, one place.** A board **MUST NOT** show the same words on two of its cells, in any language a client offers: a person cannot tell two buttons that read the same apart, and a partner cannot model on them. Keys that are different words in the keys' language may be one word in another ("also" and "too" are both *también* in Spanish; "he" and "she" both *o* in Turkish). Where the language has a word of its own for each, the glosses **MUST** give each its own (§2.1 `gloss_sense` where the word depends on the sense). Where it says both with one word, the word **MUST** show once: at the key whose meaning the word has ("one", not "a", in a language with no article); on a set that grows (§8.1: words shown in stages, the rest hidden in their places until later), at the key shown first, so that a key hidden for later never leaves the board without the word, and the word is never at one place today and another tomorrow (the key shown later is the one left out when it comes). The other cell is hidden in its place in that language (§3 item 3) and no cell moves. A board kept by an earlier version, a backup or a file that does not say when each word of a set that grows is first shown is given it from what the word carries (its stage on the set's ladder, or the set's first words), so that updating or restoring takes no word away. A word someone hides takes away what they saw when they hid it: where the cell was, in the language it was hidden in, the only place of a word that other keys of the board share (their places left out as the same word, or hidden until a later stage of a set that grows, to be left out for it when they come), the word stays hidden in every language, also when the set grows; where it was a word of its own there, only that key is hidden, and in a language that says it as another key's word, the word passes to the next of those keys that is shown. A client **MUST** record which, with the hide (the reference: `ext_aurasense_hid`, `{"in": "es", "word": true}`), and **MUST** take a hide found without it, on a board kept by an earlier version, as made in the person's language when it is first read, and as that version showed the board: one that showed every key's word took the word away only where it showed at no other key then — where another key still shows it, only that key was hidden, and the word stays there. Words that differ only by case are the same words, except in a language that tells words apart by case (German writes a noun with a capital: *Essen*, food; *essen*, eat). Only a word is hidden so: a cell that opens a page or does something never is, and two keys that are different meanings spelled alike (homonyms) are told apart in their words, never hidden, so that no meaning leaves the board. A slot that a partner fills in ("I enjoy …", each with its own photo and words) is told apart by what is filled in; a navigation control (§5.6 item 5) is the client's control, not a word. A client's own boards and the page sets it offers **MUST** be checked for this when they are built, in every language — a set that grows at each of its steps, for a word left out while the key that keeps it is not shown — and a build that finds the same words twice, or a word left without its place, **MUST** fail. The reference keeps the pairs two readers of the language agreed on in `aac-core` `same_words.json`, marks a hidden cell with `ext_aurasense_same_word` (the languages, each with the key that keeps the word), and checks every board in `tools/pagesets/pslib/samewords.py` (every package, on every catalogue build) and in a test over its own boards.
|
||
|
||
The reference ships 45 languages: English is `ValidatedNativeCorpus`; the other 44 are `GlossOnly` until their speakers validate their own. (Conformance C7.)
|
||
|
||
### §4.2 What a suggestion may propose *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A client **MAY** suggest words — a next word, a sentence start, the completion of a word being typed — from a language model and from what the person has said. A model built from published text (subtitles, news, the web) proposes whatever that text holds, including rude, sexual and violent words, and a word proposed unprompted is a word put in the person's mouth. Therefore:
|
||
|
||
1. A client **MUST** propose only words from the person's vocabulary — the words of the boards they use, in their language — and words they have said themselves, unless the person, or someone acting with them, has chosen to include a language's whole word list.
|
||
2. The whole word list **MUST** be off unless chosen, and a client **MUST** say where it comes from before it is chosen.
|
||
3. A model **MAY** rank the permitted words whatever the choice; ranking a word is not proposing it. Letter predictions (which keys to order or highlight) **MAY** use the whole word list, because a letter proposes no word.
|
||
4. None of this limits what the person says: a word they have said is theirs, and is proposed thereafter; typed text is never changed.
|
||
5. What a client learns from the person's words is theirs. It **MUST** stay on their device unless they choose otherwise, and **MUST** be forgettable by them, in every language at once, with a confirmation so that no stray selection erases it. It **SHOULD** be portable between devices and clients.
|
||
6. The whole word list is chosen for one language at a time: a choice made for one language **MUST NOT** carry to another.
|
||
|
||
The reference implements this as `SuggestionScope` in `aac-core` (default `Vocabulary`), and the learned memory as `PredictionMemory` (plain data, versioned: `PredictionEngine::memory`, `restore_memory`, `forget_memory`); a conformance vector is to follow.
|
||
|
||
### §4.3 People in symbols *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A board is used all over the world, so the people its symbols show must not default to one skin, one gender or one age. Following Unicode's emoji model (UTS #51):
|
||
|
||
1. **Skin.** A client that draws people **MUST** draw them by default in a generic, non-realistic colour — no one's skin — and **MUST** let the person choose one of the five skin tones of the emoji modifiers U+1F3FB–U+1F3FF, applied to every person in every set it can re-tone. A symbol whose skin colour cannot be changed without changing something that is not skin **MAY** be kept as drawn, and the client **SHOULD** list which.
|
||
2. **Gender.** A concept that does not name a gender **SHOULD** be drawn with a figure that reads as no particular gender, or with no figure; a gendered figure is for a gendered word (*mother*, *man*, *girl*).
|
||
3. **Age.** A concept that does not name an age **SHOULD NOT** be drawn with a child's figure: a board used by an adult shows adults.
|
||
4. The skin tone is the person's choice, kept for them rather than for a board, and changing it **MUST NOT** move or resize any cell (§3).
|
||
|
||
The reference implements skin as `aac_core::symbols::SkinTone`: the neutral is UTS #51 §2.4's own example, #FFCC22, and the five tones are OpenMoji's; hair keeps its colour whatever the tone. Its symbol build writes skin (and OpenMoji's skin shadow) as the CSS custom properties `--aac-skin` and `--aac-skin-shade` over the neutral, and lists every person symbol and its treatment in `tools/symbols/people-review.md`.
|
||
|
||
---
|
||
|
||
## §5. Access model
|
||
|
||
Every access method is a first-class input. A board **MAY** be driven by any method; the method and its tuning travel with the user's profile, not the board.
|
||
|
||
- **AccessMethod** — as enumerated in §1. `SwitchScan { switches }` carries the switch count (1, 2, or more).
|
||
- **MotorProfile** — `fine_motor`, `sustained_press`, `tremor_level`, `min_target_mm`, optional `max_reach_mm`, `preferred_side`. A client **SHOULD** adapt target size and timing from this profile, and **MUST NOT** require a smaller target than `min_target_mm`.
|
||
|
||
Timing-based methods are normative in their own right:
|
||
|
||
1. **Switch scanning** — a conforming scanner **MUST** support row-column, linear, and group scan patterns, a configurable scan rate, and configurable acceptance/timing (§5.2).
|
||
2. **Dwell / eye-gaze** — selection by sustained gaze **MUST** use a configurable dwell time with visible progress feedback (§5.3).
|
||
3. No access method **MAY** be a precondition for opening or reading a board; a board authored for eye-gaze **MUST** still open under touch or switch.
|
||
|
||
### §5.1 Timing belongs to the person
|
||
|
||
1. A client **MUST** let the person, or someone acting with them, set the scan rate and the dwell time directly.
|
||
2. Automatic adaptation of timing **MUST** be off unless the person opts in.
|
||
3. A client **MUST NOT** change timing silently. It **MAY** measure the person's own responses and **propose** a change, which takes effect only when they accept it — or, if they opted in, automatically under the rules of §5.2 and §5.3.
|
||
4. A proposal **MUST** be derived from this person's responses, never from a population norm alone.
|
||
|
||
### §5.2 Scan-rate floor
|
||
|
||
A scan rate that a client recommends, proposes or applies from measured responses **MUST** sit above the person's typical press, so that the highlight has not moved on when they act:
|
||
|
||
- it **MUST NOT** be derived from fewer than 10 recorded responses;
|
||
- with `M` the mean and `P95` the nearest-rank 95th percentile of the recorded response times, it **MUST** be at least `max(⌊100·M/65⌋, P95)` — the reference rule — clamped to `[300, 5000]` ms;
|
||
- a change within 10% of the current rate **SHOULD NOT** be proposed.
|
||
|
||
(Conformance C5.)
|
||
|
||
### §5.3 Dwell proposals
|
||
|
||
A dwell proposal **MAY** be shorter as well as longer — a person whose dwell is too long is slowed down as surely as one whose dwell is too short makes errors:
|
||
|
||
- it **MUST NOT** be derived from fewer than 10 selections;
|
||
- one step **longer** when more than 20% of recent selections were undone;
|
||
- one step **shorter** when fewer than 5% were undone and more than 20% of attempts were abandoned late (gaze left after at least half the dwell);
|
||
- a shorter proposal **MUST NOT** go below 300 ms; no dwell may be below 150 ms or above the configured maximum;
|
||
- an opted-in client applies at most one change per measurement window, then measures afresh.
|
||
|
||
The reference steps along the ladder `DT(X) = 300·e^(X/12) − 150` ms. (Conformance C6.)
|
||
|
||
### §5.4 Adaptation from a prior never moves a cell *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A client **MAY** use a prior over the options on a board — a language model, or the person's own usage counts — together with the person's measured press timing. It **MAY** change only these four things:
|
||
|
||
1. the **order** in which rows, groups, blocks or cells are scanned;
|
||
2. the **emphasis** of a highlight;
|
||
3. the **dwell** each cell needs;
|
||
4. **which option a switch press selects**.
|
||
|
||
It **MUST NOT** change any cell's position or size, nor which cells a row, group or block contains (§3). The AI may rank, order, highlight or weight; the person chooses the words.
|
||
|
||
1. **Consent.** Each of these is an adaptation under §5.1. It **MUST** be off unless the person opts in. What it would change **MUST** be available to show them before they opt in and while it is on. A client **MUST NOT** apply anything other than what it shows: an adaptation shown for one board **MUST NOT** apply on another, and turning an opt-in off **MUST** discard what was applied, so that opting in again needs a fresh preview.
|
||
2. **Order.** A new order **MUST** take effect only at the start of a pass, so that a highlight never jumps mid-pass. Turning the opt-in off **MUST** restore the fixed order no later than the next pass. The reference visits units by descending prior mass and members by descending weight, with ties broken by position. This minimises the expected number of highlights before the intended one.
|
||
3. **Dwell.** A cell's weighted dwell **MUST** lie within `[max(⌈0.8·D⌉, min(D, 300)), max(min(⌊1.5·D⌋, max), D)]` ms, where `D` is the person's dwell and `max` is their ceiling; for any `D` of at least 150 ms the lower bound is at least 150 ms, and a `D` below that is never weighted below itself. A likelier cell **MUST NOT** need a longer dwell than a less likely one. A weighting **MUST NOT** change `D`, propose a change to it, or restart the §5.3 measurement window, and **MUST NOT** change the length of a dwell already in progress. Turning the opt-in off **MUST** restore `D` for every cell at once.
|
||
Because it is bounded, keyed to `D`, previewed, and undone at once, a per-cell weighting within these bounds is not a timing proposal under §5.1 item 4 or §5.3: it **MAY** be derived from a population prior such as a language model, and **MAY** be re-applied after every selection.
|
||
4. **Selection.** A press may be weighed against the person's press-offset distribution, so that a press landing just after the highlight has moved on selects what they meant. The following rules apply:
|
||
- An option **MUST** be identified by its position at its scan level, never by its rank in a pass, so that an order applied between passes cannot make one option name two cells.
|
||
- A press **MUST** be measured only from onsets that could have produced it. The reference admits an onset when the press lands between half a scan interval before it and two intervals after it.
|
||
- The distribution **MUST** be learned only from selections the person kept. The presses of every level of a selection (the row and the cell) belong to it. A selection counts as kept only after further selections have been made without it being undone — an Undo reached by scanning is itself a selection, and **MUST NOT** confirm the selection it undoes. Presses that led into a row, group or block the person then left without choosing a cell **MUST NOT** be learned, nor presses the distribution does not explain better than a spurious press. The reference learns a selection once three newer selections have been completed, so it survives two consecutive undos.
|
||
- The client **MUST NOT** act on the distribution before 10 such presses.
|
||
- The prior **MUST NOT** select on its own: the presses themselves **MUST** favour any selected option at least 4:1 over every other option, and a lone option at least 4:1 over the hypothesis that every press was spurious. The reference caps the prior's ratio between any two options at 99:4 and selects only when the leader's posterior odds over the runner-up reach 99:1; a persisted rule that would weaken the 4:1 floor is not used.
|
||
- When the evidence is short of that, the scan continues and the next press adds evidence. A level that would end after such a press — a row's single pass, or the last cycle — **SHOULD** be offered again; the reference offers at most two extra passes per visit.
|
||
- Until the person opts in and 10 presses have been kept, a press selects what was highlighted.
|
||
|
||
(Conformance C8–C11, proposed.)
|
||
|
||
### §5.5 Controls beside the board are scanned too *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
The controls a client shows beside the board that act on the message — the reference's message bar: Repeat, Delete, Clear, ✨ (the sentence helper) when it is installed, Speak, and 🔍 (the way to the message's words, §14.1 item 7) — **MUST** be reachable by switch scanning, not only where a board repeats them as cells.
|
||
|
||
1. They are scanned as one more group, the **bar**: the controls that can be pressed now (shown and enabled), in their order on screen. Selecting the bar steps into its controls one at a time, as into a row; a pass over them without a press returns to the top level, as a row's does. Timing, cycles, highlight and audio cues are the board's.
|
||
2. The person **MUST** be able to choose where the bar is scanned: **after the board** (the default), **before the board**, or **not at all**. The choice travels with their scan settings (§5) and survives a reload or restart.
|
||
3. In every scan pattern the bar is one more top-level unit: one more row in row-column scanning, one more group in group and block scanning, one more step in linear and inverse scanning. Where no board is on screen (a text mode), the bar's controls are themselves the top level.
|
||
4. Whether and where the bar is in a pass is settled when the pass begins, so the highlight never jumps mid-pass; an order from a prior (§5.4) never moves it. A bar with nothing to press is not scanned.
|
||
5. Scanning the bar **MUST NOT** move or resize any cell or control (§3): the highlight is drawn on them where they are.
|
||
6. A row the person opens from the bar (the reference's sentence helper, under the message) is scanned first while it is open: its controls one at a time, then the board as a whole. A press on the board hands scanning to the board's scan, the bar included; a choice there that changes the words, or that scan running out of passes, brings scanning back to the row. Closing the row gives scanning back to the board.
|
||
|
||
### §5.6 The way back, and help, are scanned and dwelt on too *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A person who opens a board by switch or by gaze **MUST** be able to get back, and to ask for help, by the same means. Therefore:
|
||
|
||
1. The controls a client shows beside the board that move between boards — the reference's Back and Home — and its control that asks for help **MUST** be reachable by switch scanning as one more group, the **navigation**, as the bar is: §5.5 items 1, 3, 4 and 5 apply to it as written there for the bar. Only the controls that would do something now are in it: on the home board Back and Home are not, and help always is.
|
||
2. The person **MUST** be able to choose where the navigation is scanned — after the board, before it, or not at all — apart from where the bar is. With both on the same side of the board, the bar comes first. The choice travels with their scan settings and survives a reload or restart. For a person who used an earlier version, adding the navigation to their scan is offered, not done (§5.7 item 9).
|
||
3. Where a client selects by dwell (§5.3), the navigation's controls **MUST** be dwell targets, as the board's cells are.
|
||
4. A client **MUST NOT** give a way back to a board the person already has by moving or resizing any of its cells (§3).
|
||
5. Going to a board that is already on the way to the one on screen (as a Back cell does) **SHOULD** return to it rather than open it again on top, so that the navigation's Back never steps through boards the person has left. A cell that goes to another board and is labelled as a control (Back, Home) **MUST** show the control's word in the person's language — or draw the control's symbol (the reference: Back as its arrow) with that word as its accessible name — never a translation of the label in another sense (the body part for "back"), and its label is not vocabulary (§4.2).
|
||
6. A client **MAY** offer to go back to the home board after each word chosen on another board. It is the person's choice, not the board's: it **MUST** be off unless they choose it, and it travels with their settings, not with a board.
|
||
7. Asking for help **MUST** say its message aloud at once and show it in large print, in the person's language where its translation is trusted and in the client's own language otherwise. Where no voice speaks the person's language it **MUST** say the message in a language a voice on the device speaks (the reference: English), and say on screen that it did; where no voice can say it at all, the screen **MUST** say to show it to someone nearby. The message **MUST NOT** cover the board (the reference shows it in the message bar's place). It **MUST NOT** claim that anything was sent, nor that a translation has been reviewed by a speaker of the language when it has not.
|
||
8. A panel the client opens over the board (its settings and the like) **MUST** be operable by switch scanning and by dwell, and closable by them: its controls are scanned in their order on screen, in groups where the panel groups them, and are dwell targets; a list to choose from or a slider opens its choices (or less and more) as controls of their own. A control that would leave the client (a link to another page) is not scanned. A panel opened by someone helping **SHOULD** wait for a press of the person's switch before its scan moves, so that it never moves under their hand.
|
||
|
||
The reference scans Back, Home and Help as `ScanConfig::nav` (`BarPlacement`), names them `ScanHighlight::Nav`/`NavItem` and `ScanChoice::NavItem`, and keeps Help's messages and the navigation words with how they were read (`aac-web/src/help_messages.json`, and `aac-core/src/nav_labels.json`, which the open board interchange export uses too): each translation was read by two independent model readers, and only those both agreed on are used; a native speaker's review is still to come.
|
||
|
||
### §5.7 Switches belong to the person *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
1. A client **MUST** let the person, or someone acting with them, choose which inputs are their switches — any key, a gamepad button, a touch on the board — by pressing the switch, and **MUST** keep the choice across a reload or restart. Teaching a switch **MUST** listen only while the client shows that it is listening.
|
||
2. With two switches a client **MUST** offer step scanning: one switch moves the highlight one step, the other selects; the highlight never moves by itself, and the scan never stops under the person. With one switch it **SHOULD** offer inverse scanning: the highlight moves at the scan rate while the switch is held, and letting go selects. A client **MAY** give further switches other steps (the reference: back one step, and out of a row).
|
||
3. The hold (acceptance) and release times of §5 apply to every switch, each read on its own: a press of one switch is never taken as a second press of another.
|
||
4. A client **MUST** let the person choose the scan pattern (§5 item 1), the number of passes before a scan that moves by itself stops, and whether each pass starts at the row (group, cell) of their last choice. These change only the order in which things are visited, never a cell's position or size (§3).
|
||
5. Auditory scanning — a tone, or the name of what is highlighted, as the highlight moves — **MUST** be off unless the person chooses it. A name **MUST NOT** be said over the person's own words, nor stop them, and **MUST** be said in a voice that is not theirs; where there is no other voice, a tone is played instead. When the person asks for the whole name first, the highlight **MUST NOT** move on until it has been said, or until a time fitted to it has passed.
|
||
6. **No change locks the person out.** A change to how the person reaches the client — the access method, the switches, selection by dwell or by switch, what moves the highlight, the scan's cues (a person who scans by ear cannot scan without them), the scan rate, the dwell time, and the hold and release times — made by switch scanning or dwell **MUST** be provisional: unless it is kept, with the new way of choosing, within a stated time (the reference: 15 s), everything **MUST** go back to how it was. What it goes back to **MUST** outlive a reload: a change still waiting when the client restarts goes on waiting, or, its time up, is undone. Choosing what is already chosen is not a change. A change made by someone helping (by touch, mouse or keyboard) during the wait takes effect at once and **MUST** be kept, whatever becomes of the person's. The question **MUST NOT** cover the board (the reference asks it in the message bar's place, or at the foot of an open panel).
|
||
7. A client **MUST** refuse, and say so, a change to the switches that would leave no switch for something the access method needs (to select; in step and inverse scanning, to move the highlight). Teaching a switch an input another switch has **SHOULD** swap the two.
|
||
8. **The way out.** A person is locked out when their switch does nothing any more (it was taught away, or the access method was changed to one it has no part in). Holding down, for a set time (the reference: 8 s), a key or gamepad button that has no role in the person's current access method and is one of their switches — or, while they scan, any input — **MUST** bring switch scanning back with that input as switch 1 — kept, not replaced — keeping the person's other switches, and what moves the highlight where it still works; and **MUST** say so. For a person who looks, points or touches, an input that is not one of their switches (a hand resting on a laptop's keyboard) **MUST NOT** be counted. An input that is one of the person's working switches **MUST NOT** be counted, however long it is held (resting on a switch, or holding it in inverse scanning, is using it). Keys pressed with a modifier (⌘, Ctrl, Alt), modifiers themselves, and the keys a keyboard holds down to move or scroll are not counted, and a key **MUST** stop counting as held when a modifier comes up, or the page loses the focus or is hidden (a key-up that never comes is not a hold). It is provisional (item 6), kept only by a press of that same switch after it has come up from the hold, past the release time (a contact bouncing as it comes up keeps nothing); meanwhile the way the person chose before — looking, pointing, touching — **MUST** go on working, so that going back can be chosen with it. The timing comes back as it was before a change still waiting to be kept, or, with none, as times that lock nobody out (the reference: no scan made faster than its default, no hold time, the default release time).
|
||
9. A client **MUST NOT** change how a person who used an earlier version reaches it without asking: a person who scanned with two switches keeps what they had, and new scan steps (step scanning, the navigation) are offered once, in words. Settings a newer version adds **MUST** be kept where an older version does not overwrite them.
|
||
|
||
### §5.8 Pointing and touching *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
1. A client that selects by dwell **MUST** offer it for a pointer (a head mouse, an eye tracker that moves the pointer) as for gaze, with visible progress on the target and the person's dwell time (§5.1). It **MUST** be off for a pointer unless chosen: an ordinary mouse is the same input, and a mouse resting on a word must not say it.
|
||
2. It **MUST** offer that a target just selected is not selected again until the pointer or gaze has left it, and **SHOULD** offer that a switch selects what is pointed at.
|
||
3. For touch, a client **SHOULD** offer selection only once a touch has been held for a time the person sets, selection when the finger lifts (over whatever it is on then), ignoring touches for a time the person sets after a selection, and a first touch that says what a button is with a second that selects it. Each of these times belongs to the person (§5.1); none is applied unless they choose it. While one of them is on, the client **MUST NOT** let the page pan under the finger.
|
||
|
||
### §5.9 One target *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A board whose only cell that can be chosen is one cell (a single big message, a first switch's page) is chosen by any press:
|
||
|
||
1. A touch, a click or a dwell anywhere on the board **MUST** choose that cell, under the person's touch and dwell settings (§5.8).
|
||
2. In switch scanning, when the scan has that cell alone — the message bar and the navigation not scanned, as the person may choose (§5.5, §5.6) — every press of any of the person's switches **MUST** choose it at once, with no highlight to wait for and no step; the highlight rests on it. With the bar or the navigation in the scan, the scan goes on as usual, so that they stay reachable.
|
||
3. A client **SHOULD** offer a larger highlight (a thicker outline, and the rest of the board dimmed) as one of the person's scan settings, for learning to scan. It **MUST NOT** move or resize any cell (§3).
|
||
|
||
---
|
||
|
||
## §6. The cascade
|
||
|
||
A communication operation **MUST** be resolved through the lowest cascade level that can satisfy it. The ten levels and their order are normative:
|
||
|
||
| Level | Name | Order-of-magnitude energy |
|
||
|-------|------|---------------------------|
|
||
| L0 | `CacheHit` | ~1 µJ |
|
||
| L1 | `SymbolLookup` | ~10 µJ |
|
||
| L2 | `LocalPredict` | ~100 µJ |
|
||
| L3 | `ContextPredict` | ~1 mJ |
|
||
| L4 | `SemanticExpand` | ~10 mJ |
|
||
| L5 | `ConversationAi` | ~100 mJ |
|
||
| L6 | `GenerativeComm` | ~1 J |
|
||
| L7 | `VoiceClone` | ~5 J |
|
||
| L8 | `MultimodalGen` | ~10 J |
|
||
| L9 | `AdaptiveModel` | ~15 J |
|
||
|
||
**§6.1 Energy monotonicity.** The estimated energy of level `Lₙ` **MUST** be strictly greater than that of `Lₙ₋₁`. (Conformance suite C2.)
|
||
|
||
**§6.2 Offline invariant.** Levels L0, L1, and L2 — and **only** these — **MUST** be offline-capable. A conforming client **MUST** serve every L0–L2 operation with no network access, and **MUST NOT** make any L0–L2 operation contingent on connectivity. (Conformance suite C3.) The practical consequence is normative: a network failure **MUST NOT** prevent a user from selecting cells, looking up symbols, or completing words.
|
||
|
||
**§6.3 Free at every level.** No cascade level **MAY** be gated behind payment, quota, balance, or subscription at the protocol layer. An implementation **MUST NOT** refuse, degrade, or rate-limit a communication operation on the basis of billing state. Hosted enrichment services (L3+) **MAY** be operated commercially, but a conforming client **MUST** remain fully functional through L2 with no account.
|
||
|
||
**§6.4 Enrichment is optional.** L3 and above add intelligence (context, sentence construction, voice cloning, symbol generation, model adaptation). They **MUST** be reached only when a lower level cannot close the request, and their absence **MUST NOT** degrade L0–L2 behavior.
|
||
|
||
---
|
||
|
||
## §7. Canonical serialization and content addressing
|
||
|
||
A board **MUST** have a canonical serialization. JSON is the interchange encoding; a canonical form (sorted keys, normalized number forms) **MUST** round-trip byte-identically through a conforming serializer. A board's content identity **MAY** be expressed as a content address (e.g. BLAKE3) over its canonical bytes; two boards with equal canonical bytes are the same board.
|
||
|
||
---
|
||
|
||
## §8. Interchange (ingest)
|
||
|
||
A board **MUST** export to the canonical form of §7 and **MUST** be re-importable from it without loss of cell positions, content, actions, or symbol references.
|
||
|
||
A conforming engine **SHOULD** additionally **ingest** the open board interchange format and common community exports. Ingestion is one-directional and additive: it reads existing work into the substrate so a user does not start over. On ingest:
|
||
|
||
- Cell positions present in the source **MUST** be preserved (§3); positions absent from the source **MUST** be assigned deterministically (row-major fill) and then fixed.
|
||
- Unsupported or unknown fields **MUST** be reported as non-fatal warnings, never silently dropped where they affect meaning.
|
||
- A format the engine cannot yet read **MUST** fail explicitly (a named "format not yet supported" error), never partially and silently.
|
||
- *(Proposed, after 0.2.0.)* Every field of a board or button that the engine does not map **MUST** be kept with the board or cell (§2) and written back on export as it came. One warning per ingest **MUST** name, in plain words, those it keeps but cannot act on (the reference: "This board uses features this version can't do yet: … They are kept."); fields that only describe or place the board need no warning. A behaviour such as a sequence or a popup is then never lost without a word.
|
||
- *(Proposed, after 0.2.0.)* A Back or Home cell (one that goes to another board and is labelled as that control, §5.6 item 5) is exported with the control's word in each language as its translations, never a gloss of its label; a cell with `sense` (§2.1) is exported with its words in the keys' language only (`ext_aurasense_sense`), and ingested with its sense.
|
||
- *(Proposed, after 0.2.0.)* A scene's picture (§2.5) is exported inside the scene, as a `data:` URI with its licence, so that a reader that keeps the scene's extension keeps the picture with it (one that does not shows the hotspots as buttons, without the picture, which it could not use); a scene that names one of the board's `images` by `image_id` is read too. The picture is ingested under the rules for a button's image; a scene whose picture is not in the file, or with a cell that has no place in it, is shown as its grid, with a warning. Its hotspots are buttons of the grid, each with its words.
|
||
- *(Proposed, after 0.2.0.)* A button the open board interchange format marks `hidden` **MUST** be ingested as a hidden cell, in place (§3.1), not shown and not dropped. A button's image and sound, when the file holds them (inline, or as a file of the package), **SHOULD** be kept with the cell, under the licence they came with; one that is only a link to another site **MAY** be left out, with a warning. On export, a hidden cell is written `hidden: true`, and a cell's photo and `sound` (§2.1) are written as the button's image and sound. A cell with `lang` (§2.1) is written with its words as they are, in that language, and never glossed; a button whose words another app wrote in a language other than the keys' is ingested with `lang`, as written.
|
||
|
||
### §8.1 Page-set catalogue *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A client that offers page sets to start from **MAY** take them from a catalogue: a JSON document (`format` `aac-pagesets`, `version` 1) of families — a style of page set, with its name, what it is, its licence, its sources, and each language's `CoreStatus` (§4.1) and share of its words that have words in that language — each with its packages (open board interchange `.obz` files). A package is listed with its file name, its size in bytes and its SHA-256, and either `lang` `*` (keys the client glosses into the person's language) or the language its words are written in; where that language's words change with the speaker's gender ("I am tired": *cansado* / *cansada*), each package also names the `gender` (`f` or `m`) whose words it holds. Therefore:
|
||
|
||
1. A client **MUST** check a package's size and SHA-256 against the catalogue before using it, and **MUST NOT** use one that differs.
|
||
2. A client **SHOULD** download a package only when a person chooses its set, and **MAY** keep it on the device so the set can be added again offline.
|
||
3. Adding a set **MUST NOT** change or remove a board the person has (§3.1): its boards get new ids and go beside theirs, as one change an undo takes away.
|
||
4. Where a family recommends a setting (the reference's Fixed Paths: going back to Home after each word), a client **MUST** ask the person before turning it on (§5.6 item 6).
|
||
5. Where the person's language is not the set's, the client **MUST** say so before the set is added, with the language's status (§4.1).
|
||
6. Where a family has a package in the person's language, a client **MUST** offer that one (the exact language tag first, then its base language), and otherwise its glossed or English package. Where that language's packages differ by the speaker's gender, the client **MUST NOT** choose one for the person: it asks which words are theirs, and keeps the answer.
|
||
7. Adding a set is an import (§8): whatever the import reports — a feature kept but not acted on, a word not kept — **MUST** be shown when the set is added, and each board's licence kept with it.
|
||
|
||
A package's manifest, boards and buttons **MAY** carry `ext_aurasense_pageset` (the family, its version, the package's size, a button's stage: the first size at which it appears, and its `shown_from`: the step of the set's growth at which it is first shown, 0 from the start). It describes the set: a reader keeps it, and need not report it. Only `shown_from` changes what is shown: of two keys said with one word, the one shown first keeps it (§4.1 item 5). A set started with fewer words (a Growing Core stage, Fixed Paths' first words) hides its later words in their places for later, not as the person's hides: a client **MUST** treat them so — the reference marks them `ext_aurasense_shown_later` when the set is added, and, on a board kept by an earlier version, a hidden word of such a set whose `shown_from` is after its start when it is first read — so that a word hidden at its only place stays hidden as the set grows, in every such set alike.
|
||
|
||
The reference's catalogue is `aac-rs/data/pagesets/index.json`, written by `tools/pagesets/catalog.py` from the sets' sources; the packages are rebuilt from the same sources, byte for byte, wherever they are served, and a build whose packages differ from the catalogue fails.
|
||
|
||
---
|
||
|
||
## §9. The receipt
|
||
|
||
Every operation **MAY** report a two-part energy cost (`measured + estimated`) in microjoules, with an honest provenance tag indicating whether a reading came from hardware instrumentation, a model, or an estimator. The receipt exists for **transparency only**. An implementation **MUST NOT** convert a receipt into a charge, a quota, or a gate. "This session used 3.2 mJ" is a fact shown to the user; it is never a bill.
|
||
|
||
---
|
||
|
||
## §10. Conformance
|
||
|
||
An implementation is conformant if it:
|
||
|
||
1. Round-trips the published board vectors (§7) byte-identically.
|
||
2. Preserves the motor-stability invariant (§3) across open/edit/save.
|
||
3. Routes operations to the specified cascade levels and satisfies energy monotonicity (§6.1).
|
||
4. Serves exactly L0–L2 offline (§6.2) and gates no level behind billing (§6.3).
|
||
5. Ingests the interchange format without losing positions, content, or actions (§8).
|
||
6. Leaves timing to the person and keeps proposals within §5.1–§5.3.
|
||
7. States every language's core status honestly (§4.1).
|
||
8. *(Proposed, after 0.2.0.)* Adapts from a prior only by order, emphasis, bounded dwell and selection, never by moving a cell, and only with the person's opt-in (§5.4).
|
||
|
||
The [`aac-conformance`](aac-rs/crates/aac-conformance) harness checks the cascade routing table (C1), energy monotonicity (C2), the offline invariant (C3), wire round-trips (C4), the scan-rate floor against the published response-time vectors in [`conformance/v1/scan_rate.json`](conformance/v1/scan_rate.json) (C5), dwell proposals against [`conformance/v1/dwell.json`](conformance/v1/dwell.json) (C6), and language honesty (C7). It also checks the proposed adaptation from a prior against [`conformance/v1/adaptive.json`](conformance/v1/adaptive.json) (§5.4, vector version `0.3.0-draft`). These checks are labelled `[proposed]` and counted separately; an implementation of 0.2.0 is not held to them:
|
||
|
||
- that order never moves a position (C8);
|
||
- that every adaptation requires opt-in (C9);
|
||
- that weighted dwell stays within its bounds (C10);
|
||
- that selection follows the person's presses (C11).
|
||
|
||
C5, C6 and C8–C11 recompute every expected value from the raw inputs with an independent oracle before comparing the engine against it. Any FAIL makes the run non-zero.
|
||
|
||
---
|
||
|
||
## §11. Non-claims
|
||
|
||
This standard and its reference implementation are **not** a medical device and have **not** been certified as a speech-generating device (SGD) for insurance or Medicaid funding. They make no clinical claim. Choosing an access method, vocabulary, and communication approach is best done by the person with their team, often with a speech-language pathologist — but it is never a prerequisite: no one needs a professional's permission to start communicating with AAC. The standard provides the portable substrate; it does not replace assessment, training, or support.
|
||
|
||
---
|
||
|
||
## §12. Keyboards and alphabet access *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A person who can spell — with ALS/MND, locked-in syndrome, Parkinson's, a brain injury, or a child learning to write — may say anything with letters. A keyboard that only a device's own keyboard offers leaves out everyone who cannot press its keys precisely: switch users, eye-gaze users, people whose hands shake. A keyboard is therefore a board like any other:
|
||
|
||
1. **Keys are cells.** A client that offers typing **MUST** offer a keyboard whose keys every access method it offers for boards (§5) reaches: touch with its settings, switch scanning in each of its scan patterns and with its cues, dwell, and switches; Help and a way back to the board (§5.6) stay reachable beside it by every one of those methods, whatever keyboard is chosen — with the device's own keyboard, which a switch cannot type with, they are what is left to scan. A choice that leaves a switch or gaze user without these keys (the device's own keyboard) is provisional (§5.7), behind any editing lock, and the way out brings the keys back. Keys sit at fixed positions on a grid of `rows × cols` positions, and every row covers all `cols` of them (a key may cover several side by side — a word suggestion is wide), so a scanner made for boards scans a keyboard unchanged. The device's own keyboard **SHOULD** remain available to those who type by touch.
|
||
2. **Nothing moves (§3).** A keyboard's layout **MUST** depend only on the language and the arrangement the person chose — never on the screen, a language pack's arrival, what was typed or what is predicted. Its controls (Space, Delete, Speak, …) **MUST** keep their positions on every page of one keyboard (letters, more letters, numbers). Word suggestions have a row of their own; while another row (a sentence helper's, a first-letters expander's) is shown in its place, no key moves.
|
||
3. **Arrangements.** For each language a client **SHOULD** offer the national layout where one exists (the letters where a published keyboard standard puts them — InScript, IS 13194, for the Indic scripts; Kedmanee, TIS 820-2538, for Thai; CRULP's phonetic layout for Urdu — with the standard's Shift layer on a page of its own, each key in the same place; a right-to-left script's national layout keeps its physical order), the alphabet's own order, and a frequency order: the positions a row-column scan reaches in fewest steps (one diagonal at a time) hold the letters the language writes most, Space first. Frequencies **MUST** come from text in that language. A frequency layout is fixed when it is published: new statistics do not move a key. An alphabetical or frequency layout of a right-to-left script reads right to left. Until the person chooses, the arrangement **SHOULD** follow the access method: the frequency order for switch scanning; colour groups (item 6) for eye gaze and head tracking where the alphabet fits them, else the alphabet's order with large keys; and the device's own keyboard for touch and a mouse. A person **SHOULD** be able to choose larger keys (fewer to a page).
|
||
4. **Every language, honestly.** Every language a client offers **MUST** have a keyboard, or say why not and what to use instead. Where an arrangement cannot be had for a language (no national layout here, no letter statistics), the client **MUST** say so and give the nearest one. Where a writing system needs an input method the client does not have (kana to kanji; pinyin beyond a word list), the client **MUST** say so where the person types, and leave the device's own keyboard available, rather than type something wrong.
|
||
4a. **Reachable sizes.** A key **MUST NOT** be drawn smaller than a person can reach — at least 24 CSS px wide and 32 px tall — whatever the screen: where the keys do not fit (a phone on its side), the keyboard scrolls, and a scan keeps its highlight in view, rather than shrink them. Text the person reads **MUST** keep its end in view.
|
||
5. **Writing systems.** Keys **MUST** type what the language writes, in NFC: Hangul jamo compose into syllables as on the 2-set keyboard (Delete takes off one jamo); a tone or accent key puts its mark on the letter typed before it; kana take their voiced and small forms from a key after them; an Ethiopic consonant opens its orders.
|
||
6. **Two looks a letter.** For gaze with an ordinary webcam, a client **SHOULD** offer colour groups, after the E-tran frame: a few large targets round the edge of the screen, each with a colour and a mark that does not depend on colour; the first look chooses a group (drawn small inside its target, each letter at the place it will have), the second the letter, at that place. The most written letter and Space **SHOULD** take one look. The middle, where the text is shown, **MUST NOT** select anything, nor, on the second look, the place the eyes already rest on. A key is a place for dwell (§5.8): after a key is chosen by dwell, the look **MUST** leave that place before it can choose again, whatever key is there now (a new page, a group's letters), unless the person turned "look away" off.
|
||
7. **The alphabet by ear.** A client **MAY** read the alphabet aloud in groups, most written letters first, then the letters of a group one at a time, for a person who spells but cannot see the screen well. A yes **MUST** be the person's own signal: a switch, a look, or a partner's tap relaying the person's own yes. A client **MUST NOT** offer, or depend on, anyone holding, steering or supporting the person's hand, arm or a board for them (facilitated spelling methods; ASHA position statement PS2018-00351), and **MUST NOT** guess a letter for them. Each cue **MUST** be said in full before the person's own response time (§5.1) begins. Word suggestions **MAY** be offered aloud the same way, before the groups (one suggestion: the word itself). A letter **MUST** be said by its name in the language, as people spell aloud — never handed to a voice bare, which reads it as a word or not at all — and so **MUST** a sign, a mark and the client's own words; the names are data with a review, and a client **MUST NOT** offer the alphabet by ear in a language whose names are not reviewed, nor without a voice that speaks it (saying why). Cues are prompts, as auditory scanning's are (§5.1): they **MUST NOT** be said over, or cancel, the person's own words, and one cue gives way only to another; after the message is spoken, the next cue waits until it has been said to its end — a voice that says it a sentence at a time has not finished between two sentences. Auditory scanning of the keys names each letter the same way. What a letter can still become (its tones and accents, a kana's other forms, an Ethiopic consonant's orders) **SHOULD** be offered next, and Stop **MUST** be one of the choices. A client **SHOULD** record which choices a partner relayed, **SHOULD** let the person accept only their own switch or look, and **MUST NOT** learn the words of a message spelled with relayed choices into the person's suggestions unless the person keeps them with their own yes.
|
||
8. **Phrases.** A client with a keyboard **SHOULD** let the person keep phrases of their own and say them, by every access method, with their recent messages; and a key **SHOULD** leave the keyboard for the board, by every access method.
|
||
9. **Sources.** The word lists, keyboard data and letter names a client ships **MUST** be credited where the person can read them, with their licences (a share-alike source's notices in full).
|
||
|
||
The data model and the arrangements are refined in [`spec/keyboard.md`](spec/keyboard.md). The reference implements keyboards for all 45 languages in `aac_core::keyboard` (`keyboard(language, LayoutKind)`; `colour_groups`; `by_ear`, the order of the alphabet read aloud), and its app's text mode (`aac-web` `components/keyboard.rs`, `components/alphabet_by_ear.rs`). Its frequency orders were computed from each language's pack (`data/lang/`); Gujarati and Kannada, without a pack, are alphabetical, and Chinese pinyin is typed on QWERTY, its characters from the pinyin index (`data/pinyin/`) split the likeliest way. Its standard layouts are read from xkeyboard-config (`tools/keyboard/build_layouts.py`), and its letter names (`keyboard/letter_names.json`) were drafted and checked by AI models, not native speakers (43 of 45 languages agreed; Amharic and Tagalog not yet).
|
||
|
||
---
|
||
|
||
## §13. Printed boards and books *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A paper board is every person's backup — for when the device is broken, flat, wet or not allowed — and the book a partner reads from in partner-assisted scanning. A client that prints boards (on paper, or to a PDF) prints the person's own boards, and the board's invariants hold on paper as on the screen:
|
||
|
||
1. **Positions match the device (§3).** Every printed cell **MUST** be at its own row and column, in the arrangement the device shows that board in the same language: mirrored for a right-to-left language as the screen is, column 0 where the language starts reading. Within one print every cell **MUST** be the same size and every page's grid **MUST** start at the same corner, so that a position is at the same place on every page. The person **MUST** be able to choose the cell size.
|
||
2. **Hidden words and blank cells are empty places.** A `Blank` cell, a hidden cell (§3 item 3; the proposed `hidden` field) and an empty position **MUST** each be printed as an empty position — no words, no picture, no colour — and **MUST NOT** be closed up.
|
||
3. **What a cell shows.** A cell **MUST** print the words it shows on the device, in the language it shows them in: a navigation control shows the control's word, never a gloss in another sense (§5.6 item 5), and the person's own words are printed as written. It **MUST** print its symbol or photo as the device draws it, or none where the device draws none. A client **SHOULD** offer the cells' own colours (Fitzgerald colours, where a board has them) and a black-and-white, high-contrast rendering.
|
||
4. **A board is split only when asked.** A board that does not fit one page at the chosen size **MUST NOT** be split across pages, shrunk below that size, or rearranged, unless the person chooses it. A client **SHOULD** say what would fit (a smaller size, the other way up) and **MAY** offer to continue the board on further pages; each part **MUST** then say which rows and columns it holds and keep them in their places.
|
||
5. **Navigation works on paper.** In a print of several boards, a cell that goes to a board in the print **MUST** show that board's page number; a cell whose board is not printed shows its words alone. A book **SHOULD** start with the home board, then the boards it leads to, nearest first and in reading order, and **SHOULD** list the boards and their pages. Every page **MUST** show its number.
|
||
6. **Partner-assisted scanning.** A book for partner-assisted scanning **MUST** number its rows in the order a scan reads them, and **SHOULD** give each row a colour too. It **SHOULD** offer a way out, read after the last row and printed outside the grid so that no cell moves — *not on this page* (back to the home board), *it's something else*, and *I want to spell it* (to the alphabet) — and a page on which the person's own yes and no are written. Its instructions **MUST** ask for the person's own signals only, and **MUST NOT** ask a partner to hold, steer or support the person's hand or arm, nor to guess a word for them (§12 item 7, where §12 is adopted).
|
||
7. **Alphabet sheets.** A client **MAY** print an alphabet board and a colour-group frame for spelling by eye pointing (after the E-tran frame: groups of letters round a window, each place with a colour and a mark that does not depend on colour, a letter chosen in two looks). Its letters **MUST** be the language's own, in its own order; where a client has no reviewed alphabet for a language it **MUST** say so rather than print another language's. Where the client also shows colour groups on screen (§12 item 6), the paper frame **SHOULD** be the same frame.
|
||
8. **Credits.** A print that shows symbols **MUST** carry each symbol set's attribution and licence as that licence requires — for the reference's sets, CC BY-SA 4.0: the credit the set asks for, the licence's name and address, and that the symbols were adapted — on the page, or on a page of the print. A set licensed for non-commercial use only (the reference's optional ARASAAC and Sclera) is credited the same way, with its terms' own citation and a note that the print may not be used commercially.
|
||
9. **On the device.** Printing is a local operation (§6.2): it **MUST** work with no network, and **MUST NOT** send the boards, the person's name or their words anywhere.
|
||
10. **Scenes.** A scene (§2.5) **MUST** be printed whole, on one page: its picture scaled to the room the page leaves, never cropped, each hotspot outlined where it is on the picture with its words — in a book for partner-assisted scanning, with its number in the order a scan reads it, counting only the hotspots printed —, and its row of words under it at the print's cell size, each word in its slot, also when the screen shows them beside it: a page is taller than it is wide, and the words under a picture as wide as the page are at the print's cell size, where beside it they would take the picture's width. A picture whose licence asks for a credit **MUST** be credited on its page. Where the row of words does not fit across the page at the chosen size, the client **MUST** say so and what size fits, as for a grid (item 4).
|
||
|
||
The reference plans a print in `aac_core::print` (`plan`, `book_order`, `tiles`, `cell_box`, `WayOut`; the alphabet sheets from `print::alphabet::sheet_alphabet`: every app language's alphabet from its keyboard (§12), and the screen's colour frame, place for place, where the letters fit one) and draws it in its app's print view (`aac-web` `components/print_view.rs`) for the browser's own print, which also saves a PDF and writes every script in the device's own fonts. Browsers do not print alike: Chrome and Firefox use the page's `@page` size and margins, while Safari on iPad (iPadOS 26.5, in a tab and as a Home Screen web app alike) prints on the paper chosen in its own options, with margins and a footer of its own, scaling each page to the width left. The reference's page boxes are therefore never taller for their width than 1.18 (0.57 sideways), so that each prints on one sheet of A4 or US Letter, whichever is chosen there; and the symbols are written into the print itself, since Firefox prints no symbol drawn from a separate file. Where the browser's print does not open (reported in 2026 for iOS 27 Home Screen apps, and in an app's own browser), the reference saves the pages as one HTML file holding their styles, symbols and photos, which opens and prints anywhere with no connection.
|
||
|
||
---
|
||
|
||
## §14. Finding words and modelling *(proposed — draft for the version after 0.2.0; not part of 0.2.0 conformance)*
|
||
|
||
A big vocabulary is learned by being shown where its words are: a partner choosing words on the person's own board while talking with them (modelling, or aided language input: Sennott, Light & McNaughton 2016, https://journals.sagepub.com/doi/10.1177/1540796916638822; O'Neill, Light & Pope 2018, a meta-analysis, https://pubs.asha.org/doi/10.1044/2018_JSLHR-L-17-0132), and anyone asking where a word lives. Therefore:
|
||
|
||
### §14.1 The way to a word
|
||
|
||
1. **Words as shown.** A client that finds words **MUST** find them as the person sees them: the words each place shows in the person's language (the client's glosses, or the person's own words as written, §2.1 `lang`), and the words it says, in every language it offers. Matching **SHOULD** ignore case and accents and treat as one what a script writes two ways (Unicode's compatibility equivalents, NFKD: ligatures, full- and half-width forms, presentation forms; katakana and hiragana; a Hangul syllable and the jamo typed for it, compound vowels apart, so that a syllable still being typed is found) — but never a mark that makes another word: kana keep their voicing marks (かぎ is not かき), joined again where they were written apart (ガ, か゛) — **SHOULD** find a word by its other common spellings (German ä as ae; a Japanese word in kanji or in kana, from a published dictionary), and **SHOULD** list a match as written first. Another spelling is the same word only in the sense the place's words mean: a spelling **MUST** be taken as the place's words only where the dictionary gives it in that sense (a client's gloss carries its word: はな glossing "nose" is 鼻, never 花); a spelling that only sounds the same, where the sense is not known (the person's own words), **MAY** find the place after every match of its words, and **MUST NOT** stand for it as a message's word (item 7). Text written without spaces (Chinese, Japanese, Thai) **SHOULD** be read as the words of the boards that make it up, so that a word of the boards inside it ("水" in "喝水") comes before a word that only starts with it ("水果"); what no known word covers stays one word ("でんき" with no dictionary of the language), never a character at a time.
|
||
2. **Places.** A place is a cell, or any other place a board has that says words or opens a board (a visual scene's hotspot); each is found, and pressed on the way, alike. A hidden place (§3.1) **MUST** be found and said to be hidden. A word with no word in the person's language yet (§4.1 item 4) shows none, and is not found by words it does not show.
|
||
3. **Never an invented way.** A way **MUST** be made only of presses this person can make from the board on screen with their access method: places that open a board, and the navigation's Home and Back (§5.6) only where they reach them (by switch scanning, only while the navigation is in their scan). A word on a board no such press leads to **MUST** be said to be so (the client **MAY** open that board when asked); where Home or Back would lead there but are not in a switch user's scan, the client **MUST** say so and **SHOULD** offer to put them in the scan, as a change to how the person reaches it (§5.7 item 6). A word on no board **MUST** be said to be on none, and a client **SHOULD** then offer to add it, behind its editing lock (§3.1 item 4). A way through a hidden place **SHOULD** be given only when there is no other, and **MUST** say so.
|
||
4. **Order.** Of several places, the best match **SHOULD** come first and, among equal matches, the nearest: the fewest hidden places on the way, then the fewest presses.
|
||
5. **On the places themselves.** The way **MUST** be shown on the places to press — the place to press next on the board on screen, or Home or Back — with its words where the client shows messages, never over the board, and **MUST NOT** move or resize any cell (§3). It follows the person: after each press it is worked out again from the board on screen, and choosing the word — at the place shown or at any other place that shows it — ends it.
|
||
6. **Every access method.** Touch, switch scanning and dwell follow a way as they choose anything; its controls (the next place, stop) **MUST** be reachable and operable by switch scanning and by dwell, as the message bar's are (§5.5, §5.6), also where the person turned the message bar out of their scan. What the way hides in its place (a row opened from the bar) **MUST NOT** be scanned or dwelt on meanwhile — nothing that cannot be seen ever is — and where it hides a row the person's scan began with, the way's controls take that row's place in the scan. A client **MAY** offer to start each scan pass at the place to press next: it changes only the order a pass visits (§5.7 item 4), from the start of the next pass, and is the person's choice.
|
||
7. **The message's words.** A client with a message bar **SHOULD** offer there, by every access method, the way to each word of the message in turn — or of what is typed, in a keyboard (§12) — so that the person learns where the words they spell are, and a partner can model the same words: a word that came from a place is that place; any other is read into words (at spaces, and where it is written without them by a dictionary of the language's words and the boards' own; pieces of one run that no place shows stay together, so a dictionary's fragments never stand for the word typed; in kana, a run is read by a list of the language's kana words, with the inflecting classes of each of their dictionary entries, and the boards' own words: the fewest words first, a word typed in an inflected form counting as one word a little dearer than a listed one but less than a word and a particle (よんで, not よん|で), a one-kana particle right after a word counting half, and the copula だ so too, after which the particles that end a sentence fit (あした|だ|よ); a plain command (まて, のめ, きけ) counting a little more than a word and a particle and less than two words, so it is one word, never one-kana words of the boards (ま|て "hand", の|め "eye"), while ねこ|の|め stays; at the same cost, the reading with fewer one-kana words that are not particles, then the one with more particles, then the one with its particles earlier (これ|は|なに, not これ|はな|に), then the one with the longer first piece; what neither the list nor an inflection covers stays one stretch, with the one-kana words next to it part of it), and each **MUST** be shown the way only to a place that shows that very word (case, accents and other spellings aside) — or, for a verb or adjective typed in an inflected form, to its dictionary form or a board's own form of the same word (いきたい to いく, やめたい to やめて) — never to one that only starts with it, contains it or says it; a word no place shows **MUST** be said to be on no board. No way is better than a wrong one. A client reading kana so **MUST** guarantee that a piece read as a particle leads only to a place whose sense is that particle (と as "with"; に never "two", は never "teeth"); that a one-kana word of the boards leads there only where the reading takes it as a word of its own (め in め|が|いたい), never for a piece of a word the list or an inflection reads longer (えき, はなや, たすけて, きて, わからない); that a piece another reading as good as the one taken does not have leads nowhere (あれ|は|いや or あれ|はい|や: never はい "yes"); that an inflected form is read by its readings with the fewest endings taken off, among the list's words — after an object with を, not a verb that takes none (ふくをきて is 着る's, not 来る's) — and leads nowhere when those name two words of the list (よんで: 読む or 呼ぶ; かった: 買う or 勝つ), whatever the boards show, but where everyday speech settles the pair (まって is 待つ's, not 舞う's; きて 来る's, not 着る's: a published table of pairs, each with its reason, never a dictionary's frequencies), and nowhere when that word is on no board (つけて is つける's, never つく's, so never the board's つかれた "tired"); that it leads to a board's word only where that word is the very word — its dictionary entry, known by the sense the board gives it (its kanji, else its gloss), or by its spelling where all the spelling's entries agree, or, for a verb of a noun and する (でんわする), by the noun's taking する — of the class the endings taken off follow (かえりたい and かえってきた are 帰る's, never the board's かえる "change", 変える; いらない is 要る's, never いる "stay", 居る), or to a board's own form of that word, read by its own fewest endings where those name one word (つかれた is つかれる's, never つく's); that a form whose spelling is also a board's word that is a noun in the board's sense (した: 下 "down", and する's past) is read as the verb after を or が, or at the end of a sentence after a question word or an adverb (しゅくだいをした, どうした) — a plain command at the end only after を or が, に or へ, a place said without に (ここ, こっち) or an urging adverb (はやく, すぐ, また), as the word after a question word (なにいろ), and as neither after any other adverb (とてもこい) — as the noun alone, after の, この, その, あの, どの, どんな, an adjective or な, or before a case particle, の, から, まで, です or だ (した, つくえのした, したにある, しただよ), as the board's word where it is read only as a command (それはしろ) but not when the command is all the sentence says (しろよ), and otherwise leads nowhere, while a board's word that is not a noun in its sense — an adverb, a set phrase, the board's own form of a verb (よく "often", すみません, しない "won't") — is itself; that a form whose spelling is also a word of the list of another part of speech (いろ: 色 "colour", and いる's imperative; たった "only"; はじめて "for the first time"; きた: 北 "north") is read the same way — the verb where the sentence says so (せんせいがたった), the word where it says that (なにいろ, どんないろ, いろがすき: the board's いろ if a board shows it, else nowhere) — and elsewhere as a published table of such words says, each with its reason (the form for きた, いた, して, とって, もって; neither, so nowhere, for いろ, たった, はじめて, みたい, きって), never to the verb otherwise; that a pair settled by speech may leave forms of it open, each with its reason (きたい and きたくない: 来る or 着る, so nowhere), and that a thing put on is an object with the を left out, as said (ふくきて is 着る's); and that until the list is on the device, nothing cut out of a longer run of kana of one script leads anywhere — a board's word (はなや is not はな "nose", よんで not よん "four", わからない not ない "not") or a particle (こども is not も "too") — only a whole run (one kana typed alone, between spaces, is that word) or a piece between other scripts (トイレ in トイレにいきたい, と in 水と).
|
||
|
||
### §14.2 Modelling
|
||
|
||
1. A client with a modelling mode **MUST** keep a partner's choices in it apart from the person's: they **MUST NOT** add to a cell's `frequency` (§2), which is the person's own use, nor be learned as the person's words (§4.2) or kept as their history — also when the message they built is spoken, then or later. It **SHOULD** count how often each place was modelled, apart. A partner modelling **SHOULD** be able to follow the board's links and work the message's controls, so that a word on any board can be modelled.
|
||
2. A client **MAY** show on each place how often the person chose it, how often partners modelled it, or both: off unless chosen, behind the editing lock where there is one, never over the place's words, and never moving or resizing a cell (§3).
|
||
|
||
### §14.3 The record of choices
|
||
|
||
1. A client **MAY** keep a record of each choice: when (with the device's offset from UTC), the words as shown, the board, the place on it (row and column), what it does, the access method that chose it (touch, mouse, keyboard, switch, pointer dwell, eye gaze, head tracking), whether it was the person or a partner modelling, whose profile was in use, and, for a scene's hotspot, where on the picture. It **MUST** be off unless the person, or someone acting with them, turns it on, for that person (on a shared device, for that profile only), and turning it on or off, and reading it, **SHOULD** be behind the editing lock.
|
||
2. **The person can see it.** While the record is on, the client **MUST** show the person so, wherever they are in it, without covering the board, in a control they reach by every access method they use (the reference: a red dot beside Back, Home and Help, scanned and dwelt on with them, which opens the record — and where a switch user turned Back, Home and Help out of their scan, the dot alone stays in it); changing to a profile that is recorded **MUST** say so. One exception: on a board with one target, where every press chooses it at once (§5.9), the dot is not scanned — immediacy is what those boards are for (cause and effect, first switches) — and stays in view, for a partner to reach by touch or a pointer.
|
||
3. The record and the modelling counts are the person's (§4.2 item 5): they **MUST** stay on the device and be sent nowhere unless the person chooses otherwise; they **MUST** be readable by the person (the reference: CSV) and clearable, with a confirmation no stray selection gives; a backup **MUST NOT** hold them unless the person chooses it for that backup; and a profile deleted **MUST** take its record with it.
|
||
4. **Deleting a profile.** A client with more than one profile **SHOULD** let a partner delete one, never the last, behind the editing lock where there is one, after a confirmation that names the person, says what goes and what stays, and offers a backup first; the confirmation **MUST** be a second, separate choice, so that no single stray selection deletes anyone (§5.7). Deleting a profile **MUST** remove everything the client keeps for that profile alone — its settings, its record of choices and its choices about the record, its places in sequences (§2.2) — and **MUST NOT** remove what other profiles share; the confirmation **MUST** say what stays (the reference keeps the boards, the recordings, the words and sentences learned for suggestions, the recent messages and the modelling counts, which the device keeps for everyone together, and says that they cannot be taken out for one person). Where what was learned from the person cannot be forgotten for them alone, the client **MAY** offer, unticked, to forget it for everyone on the device, saying so.
|
||
|
||
The reference finds words and ways in `aac_core::finder` (`search_key`, `Finder::find`, `Finder::find_word`, `Finder::way`, `Reach`, `words_in`, `Place::Hotspot`; Japanese spellings from JMdict, CC BY-SA 4.0, chosen by sense in `finder_ja.json`, `ja_spellings`; kana read by `read_listed` with the kana readings of JMdict's common entries and each entry's inflecting classes, `data/kana`, verbs and adjectives led to their dictionary forms by `ja_inflect`, its rules written from the grammar, and the app's words' classes in their senses by `ja_word_kinds`, `finder_ja.json`), starts a scan pass at a place with access-core's `ScanEngine::start_passes_at` (and keeps the record's dot in a scan without the navigation with `ScanEngine::keep_nav`), and keeps the record and the counts in `aac_core::usage` (`Selection`, `csv`, `UsageBackup`). Its app has Find a word (the partner menu), the way in the message bar's place, 🔍 in the message bar for the message's words, and the counts and the record in Analytics (aac-web `finder.rs`, `usage.rs`, `components/word_finder.rs`); the record lives in the browser's IndexedDB, and in a backup as `AacBackup::app["usage"]`.
|
||
|
||
---
|
||
|
||
## Proposed (draft, after 0.2.0)
|
||
|
||
- **§4.1 item 5 One word, one place (new).** No board shows the same words on two cells in any language: the glosses tell the keys apart where the language can, and where it says both with one word, it shows once, at the key whose meaning it has — on a set that grows, at the key shown first (`ext_aurasense_pageset.shown_from`, §8.1, worked out for boards from earlier versions) — the other hidden in its place. A hide takes away what was seen when it was made (`ext_aurasense_hid`). Builds check it, at every step of a set that grows, and fail on a clash or a word left without its place.
|
||
- **§2.1 `gloss_sense` (addition).** A cell may name the sense its words are glossed in ("cold", glossed as cold water); its words stay the word, so a client without it shows and says "cold".
|
||
- **§2.1 `sense`, and word classes (additions).** A cell whose key is used in another sense than its glosses' (`back` as in "come back") carries `sense` and is never glossed. Word classes gain `conjunction`; a client that colours by class uses the Fitzgerald Key's families with text at 4.5:1 or more.
|
||
- **§4.1 item 4 (new).** A board never shows words in another language than the person's: a key with no word in their language is hidden in place, and marked while editing so that someone can give it their own words. A word the language does not have ("the" in Polish), marked so on purpose in the gloss data, is left out on every board, the client's own included; a word not translated yet is shown in English, marked so.
|
||
- **§8 controls and senses on export (addition); §8.1 Page-set catalogue (new).** Back and Home cells carry the control's word in every language, never a gloss. A catalogue of page-set families lists each package with its size and SHA-256 (and its language and speaker form, where a family has a package per language); a client checks them, downloads a package only when chosen, offers the person's language's package without assuming their speaker form, adds a set beside the person's boards as one undoable change that shows what the import reports, asks before turning on a setting a set recommends, and states the language's status before a set is added.
|
||
|
||
- **§2 Unknown fields are kept (addition).** A reader keeps the fields of a board or cell that it does not recognize and writes them back unchanged, so a board saved by a newer client loses nothing when an older one saves it.
|
||
- **§4.2 What a suggestion may propose (new).** Suggestions (next words, sentence starts, completions) come only from the person's vocabulary and their own words, unless a language's whole word list is chosen — off by default, chosen per language, its source stated before it is chosen. A model may rank permitted words, and letter predictions may use the whole list. Nothing limits what the person says, and what is learned from them stays on their device, forgettable and portable.
|
||
- **§4.3 People in symbols (new).** People are drawn by default in no one's skin, and in any of the five Unicode skin tones the person chooses; concepts that name no gender or age are drawn with neutral, adult figures.
|
||
- **§5.4 Adaptation from a prior never moves a cell (new).** A prior may change only four things: scan order, emphasis, bounded per-cell dwell, and which option a press selects (Bayesian selection over the person's learned press timing, after Nomon). Each is opt-in, shown before it is applied, tied to the board it was shown for, and discarded on opt-out. Per-cell dwell weighting within its bounds is not a §5.1/§5.3 timing proposal. Selection learns only from kept selections — every level of them, never an abandoned row, never a selection an Undo reached by scanning undid, never a press the model does not explain — identifies options by position, and never lets the prior select. Conformance C8–C11, vector `adaptive.json` version `0.3.0-draft`.
|
||
- **§2.1 Optional cell fields (new).** `hidden` (hidden in place), `sound` (the person's own recording, played in place of the voice; the words are spoken if it cannot play), `symbol` (a symbol chosen for the cell) and `lang` (the person's own words, in that language, never glossed), each omitted at its default so older boards serialize unchanged.
|
||
- **§3.1 Editing never moves another word (new).** New cells go only into empty positions, removing leaves the position empty, copies are new cells, grids change only at their end and only where empty; hidden cells keep their place and cannot be selected, and may be shown for now; a lock on editing never locks the person out of their words.
|
||
- **§8 Interchange (addition).** Hidden buttons, images and sounds of the open board format are kept on ingest and written on export. Every field an engine does not map is kept and written back, with one plain-words warning per ingest naming what it keeps but cannot act on.
|
||
- **§2.2 Sequences (new).** A cell may say its lines one press at a time, in order or shuffled, starting again or staying at the end, optionally restarting after an idle time; a line may name another cell of the board by position (its words and recording as they are). The person's place is theirs, never the board's; Undo steps back a line; a press during a line goes to the next; modelling shows the next line without moving on; a client that cannot play it says the cell's words and keeps it.
|
||
- **§2.3 Board behaviours (new).** A popup goes back to the board that opened it after a word (its continuation pages count as the popup); the person may keep popups open, and their "go Home after each word" wins. A speak-only board's cells say their words without adding them to the message.
|
||
- **§2.4 Links that say words (new).** A link may add words to the message before it opens its board.
|
||
- **§5.9 One target (new).** On a board with one cell to choose, a touch or dwell anywhere chooses it, and, when nothing else is in the scan, every switch press chooses it at once; a larger highlight is offered for learning to scan.
|
||
- **§5.5 Controls beside the board are scanned too (new).** The message bar's controls are one more group of the scan — after the board by default, before it, or off, as the person chooses — in every scan pattern, without moving anything; a row opened from it is scanned first while open.
|
||
- **§5.6 The way back, and help, are scanned and dwelt on too (new).** Back, Home and Help are one more group of the scan, placed apart from the bar, and dwell targets; no way back is given to a person's own board by moving anything; going to a board already on the way returns to it; navigation cells show the control's word, never a gloss in another sense; going back to Home after each word is the person's option; help says and shows its message at once, never over the board, in the person's language where two independent readers agreed on it (in another language a voice here speaks where none speaks theirs), and claims nothing was sent nor that a speaker reviewed it; panels (their lists and sliders too) are operable and closable by switch and dwell, and wait for the person's switch before their scan moves.
|
||
- **§5.7 Switches belong to the person (new).** Any key, gamepad button or touch can be a switch, taught by pressing it while the client shows it is listening; two switches give step scanning, one can give inverse scanning; hold and release times apply to each switch on its own; pattern, passes and "start at the last choice" only reorder the visit; auditory cues are opt-in, in another voice or a tone, never over or stopping the person's words. No change locks the person out: changes made by scanning or dwell (timing included) are provisional until kept with the new way of choosing, survive a reload until kept, and never cover the board; changes leaving nothing to select with are refused; holding down a switch that does nothing for the person (never one of their working switches, nor a key that is no switch of someone who looks, points or touches) brings switch scanning back with it as switch 1, provisionally, kept by pressing it again once it has come up, while their earlier way of choosing still works. People who used an earlier version keep what they had, and are offered what is new.
|
||
- **§5.8 Pointing and touching (new).** Dwell for pointers as for gaze (off for a pointer unless chosen), with "look away before selecting again" and selection by switch; touch can select on hold, on lifting the finger, ignore repeated touches, and say a button before selecting it — all at times the person sets, with no panning under the finger.
|
||
- **§12 Keyboards and alphabet access (new).** A keyboard is cells every access method reaches, at positions that depend only on the language and the arrangement chosen (national, alphabetical, most written letters first), with its controls in place on every page; every language has one or says why not; colour groups give gaze two coarse looks a letter; the alphabet by ear reads letters aloud by their reviewed names for the person's own yes, never over their words and never with anyone holding or steering for them.
|
||
- **§2.5 Visual scenes (new).** A board may be a picture with hotspots, each a cell that does what any cell does. A hotspot's place is a region of the picture, never of the screen; the picture is shown whole; nothing but an explicit edit of a hotspot moves it, and a hidden one keeps its place. Hotspots are cells of the grid (a client without scenes shows them as buttons) and the first row is the scene's row of words, under or beside the picture, each in its slot. Touch, pointer and gaze go to the hotspot they are on or the nearest within the person's reach (a look beside the picture chooses nothing); a scan reads hotspots in reading order, in rows, then the words, its highlight on each hotspot's outline. Words appear on the picture when a hotspot is chosen, or always, as the person chooses. A partner can take a photo and mark hotspots in the moment (a box, drawn round the thing, or two corners tapped; moved by buttons and arrow keys), each change one undo. A scene a client cannot show is its grid, with a note. Exported, the picture travels inside the scene with its licence; printed, a scene is one page with its hotspots outlined where they are and its picture credited.
|
||
- **§13 Printed boards and books (new).** A print keeps every cell at its row and column, mirrored for right-to-left as on screen, one cell size for the whole print, hidden and blank cells as empty places, the device's own words and symbols, and a board whole unless the person asks to split it; in a book, links show page numbers and the home board comes first; partner-scanning books number their rows and offer a way out outside the grid and a page for the person's own yes and no, asking for no help with the person's hand; alphabet sheets use the language's own alphabet or say there is none yet; symbol credits are printed; and nothing leaves the device.
|
||
|
||
- **§14 Finding words and modelling (new).** Words are found as the person sees them, case, accents and a script's two ways of writing aside; places are cells or any place that says words (a scene's hotspot); a way is only presses the person can make (places that open boards; Home and Back where they reach them), avoids hidden places unless there is no other, and is never invented — a word no press reaches, or on no board, is said to be so, with an offer to add it behind the lock (or Home to a switch user's scan); the way is drawn on the places themselves, followed by every access method, its controls scanned and dwelt on, and a scan may start each pass at the next press; the message's words can be found in turn, each only as itself. Modelling never counts as the person's use nor is learned as their words; counts on the words are off unless chosen and never cover them; a record of each choice (time, words, board, place, access method, person or partner, profile) is off unless chosen for that person, shown to them while on (in their scan even without Back, Home and Help), stays on the device, reads as CSV, clears with a confirmation, goes into a backup only when chosen, and goes with its profile; a profile, never the last, is deleted after a confirmation that names the person and offers a backup, with everything kept for it alone and nothing shared. Kana keep their voicing marks; another spelling is the same word only in the sense meant.
|
||
|
||
## Changes since 0.1.0
|
||
|
||
- **§4.1 Language honesty (new).** Every language states its `CoreStatus`; an absent status reads as `GlossOnly`; glosses are never presented as a language's core vocabulary. The earlier claim that one ~400-word core covers ~80% of every language is withdrawn. Conformance C7.
|
||
- **§5.1 Timing belongs to the person (new).** Scan rate and dwell are set by the person; automatic adaptation is off unless they opt in; changes are proposed, never silent.
|
||
- **§5.2 Scan-rate floor (new).** A measured rate sits above the person's typical press (`max(⌊100·M/65⌋, P95)`, ≥ 10 responses). The previous reference rule set it to 80% of the mean press, so on average the highlight had moved on when the person pressed. Conformance C5.
|
||
- **§5.3 Dwell proposals (new).** Proposals go both ways, with floors. The previous reference could only lengthen the dwell, including by 50 ms every 30 selections regardless of how the person was doing; §5 item 2 no longer says dwell "should adapt to fatigue". Conformance C6.
|
||
- **§11** now says access and vocabulary decisions are never a prerequisite for starting.
|
||
- **Reference implementation** (not normative): the demonstrator can be mounted under a sub-path (`AAC_BASE_PATH`, `AAC_SW_URL`, `AAC_APP_TITLE`, `AAC_HIDE_ENERGY`); its Settings gain a Timing section implementing §5.1–§5.3; dwell reads a monotonic clock that works in browsers (`web-time`); 538 gloss corrections across 44 languages (`aac-core/src/gloss_audit_2026-09-28.json`).
|