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]>
106 KiB
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/ 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— aBoardId(UUID), stable for the life of the board.name— display string.board_type— one of theBoardTypevariants.layout— aGridLayout { rows: u16, cols: u16 }.cells— a list ofCell.
A cell MUST carry:
id— aCellId(UUID).position— aGridPosition { row: u16, col: u16 }, 0-indexed.content— one of:Symbol { symbol_id, label },Text(String),Photo { image_ref, label }, orBlank.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 alterposition.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(defaultfalse) — 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 writesmedia:<id>; adata: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 asfr), 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 keybackused 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 wordscoldwithgloss_sensewaterare shown in Japanese as つめたい (cold water), not さむい (I am cold);tablewithdining, 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 keycold (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 asext_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.
- 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").
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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).
- 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.
- 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.
- 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).
- 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.
- 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).
- 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:
- A cell's
positionMUST NOT change once assigned, for the life of that cell, except by an explicit user/editor edit to anunlockedcell. Prediction, context, frequency, language switching, and any L3+ enrichment MUST NOT move a cell. - A client MUST NOT reflow, resort, or auto-arrange cells on a board whose cells are
locked. - 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.
- 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)
- 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. - 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.
- 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.
- 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:
-
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), orGlossOnly(glosses of another language's core list). -
A language record without a
CoreStatusMUST be read asGlossOnly. -
A client MUST NOT present
GlossOnlyvocabulary as that language's core vocabulary, and SHOULD show each language's status where the person chooses a language. -
(Proposed, after 0.2.0.) A word with no word in the person's language (no gloss, or a
senseits 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'slang*, §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-coreno_word.json, checked bytools/pagesets/catalog.pyand 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. -
(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_sensewhere 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 inaac-coresame_words.json, marks a hidden cell withext_aurasense_same_word(the languages, each with the key that keeps the word), and checks every board intools/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:
- 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.
- The whole word list MUST be off unless chosen, and a client MUST say where it comes from before it is chosen.
- 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.
- None of this limits what the person says: a word they have said is theirs, and is proposed thereafter; typed text is never changed.
- 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.
- 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):
- 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.
- 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).
- 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.
- 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, optionalmax_reach_mm,preferred_side. A client SHOULD adapt target size and timing from this profile, and MUST NOT require a smaller target thanmin_target_mm.
Timing-based methods are normative in their own right:
- Switch scanning — a conforming scanner MUST support row-column, linear, and group scan patterns, a configurable scan rate, and configurable acceptance/timing (§5.2).
- Dwell / eye-gaze — selection by sustained gaze MUST use a configurable dwell time with visible progress feedback (§5.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
- A client MUST let the person, or someone acting with them, set the scan rate and the dwell time directly.
- Automatic adaptation of timing MUST be off unless the person opts in.
- 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.
- 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
Mthe mean andP95the nearest-rank 95th percentile of the recorded response times, it MUST be at leastmax(⌊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:
- the order in which rows, groups, blocks or cells are scanned;
- the emphasis of a highlight;
- the dwell each cell needs;
- 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.
- 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.
- 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.
- Dwell. A cell's weighted dwell MUST lie within
[max(⌈0.8·D⌉, min(D, 300)), max(min(⌊1.5·D⌋, max), D)]ms, whereDis the person's dwell andmaxis their ceiling; for anyDof at least 150 ms the lower bound is at least 150 ms, and aDbelow that is never weighted below itself. A likelier cell MUST NOT need a longer dwell than a less likely one. A weighting MUST NOT changeD, 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 restoreDfor every cell at once. Because it is bounded, keyed toD, 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. - 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.
- 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.
- 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.
- 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.
- 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.
- Scanning the bar MUST NOT move or resize any cell or control (§3): the highlight is drawn on them where they are.
- 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:
- 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.
- 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).
- Where a client selects by dwell (§5.3), the navigation's controls MUST be dwell targets, as the board's cells are.
- A client MUST NOT give a way back to a board the person already has by moving or resizing any of its cells (§3).
- 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).
- 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.
- 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.
- 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)
- 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.
- 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).
- 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.
- 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).
- 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.
- 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).
- 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.
- 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).
- 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)
- 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.
- 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.
- 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:
- 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).
- 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.
- 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'simagesbyimage_idis 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
hiddenMUST 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 writtenhidden: true, and a cell's photo andsound(§2.1) are written as the button's image and sound. A cell withlang(§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 withlang, 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:
- A client MUST check a package's size and SHA-256 against the catalogue before using it, and MUST NOT use one that differs.
- 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.
- 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.
- 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).
- 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).
- 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.
- 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:
- Round-trips the published board vectors (§7) byte-identically.
- Preserves the motor-stability invariant (§3) across open/edit/save.
- Routes operations to the specified cascade levels and satisfies energy monotonicity (§6.1).
- Serves exactly L0–L2 offline (§6.2) and gates no level behind billing (§6.3).
- Ingests the interchange format without losing positions, content, or actions (§8).
- Leaves timing to the person and keeps proposals within §5.1–§5.3.
- States every language's core status honestly (§4.1).
- (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 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 (C5), dwell proposals against conformance/v1/dwell.json (C6), and language honesty (C7). It also checks the proposed adaptation from a prior against 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:
- 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 × colspositions, and every row covers allcolsof 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. - 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.
- 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).
- 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.
- 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.
- 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.
- 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.
- 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.
- 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. 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:
- 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.
- Hidden words and blank cells are empty places. A
Blankcell, a hidden cell (§3 item 3; the proposedhiddenfield) and an empty position MUST each be printed as an empty position — no words, no picture, no colour — and MUST NOT be closed up. - 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.
- 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.
- 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.
- 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).
- 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.
- 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.
- 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.
- 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
- 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. - 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.
- 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.
- 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.
- 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.
- 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.
- 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
- 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. - 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
- 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.
- 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.
- 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.
- 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' (backas in "come back") carriessenseand is never glossed. Word classes gainconjunction; 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.jsonversion0.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) andlang(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 asGlossOnly; 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).