Commit the previously-untracked standard directories and catalog them in the
root README alongside proof:
- aac/ — communication cargo class: portable boards + a ten-level
offline-first cascade (Apache-2.0 code / CC-BY-4.0 spec).
- map/ — geospatial cargo class: range-requestable signed tilesets +
an F0–F4 fidelity cascade (Apache-2.0 code / CC-BY-4.0 spec).
- sandbox/— isolated, metered, attested execution across the heterogeneous
compute fabric (Apache-2.0 code / CC-BY-4.0 spec).
- jouleclaw-otel-authz, jouleclaw-trust — new jouleclaw reference crates.
Root README now lists aac, map, sandbox, and proof in the catalog, the tree,
and the contribution guide.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
151 lines
11 KiB
Markdown
151 lines
11 KiB
Markdown
# AAC — Specification
|
||
|
||
**Version 0.1.0 (draft) · Status: draft · Licence: CC-BY-4.0**
|
||
|
||
This document specifies the AAC open standard: the data model for a portable communication board, the access-method abstraction, the energy-tiered communication cascade, canonical serialization, the interchange format, and the receipt. The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHOULD**, **SHOULD NOT**, **MAY**, and **OPTIONAL** are to be interpreted as described in RFC 2119.
|
||
|
||
The Rust reference implementation in [`aac-rs/`](aac-rs/) is normative-by-example: where this prose and the reference types disagree, that is a defect to be reconciled, not a license to diverge.
|
||
|
||
---
|
||
|
||
## §1. Scope and terms
|
||
|
||
AAC (augmentative and alternative communication) is technology that lets a person who cannot rely on speech compose and produce utterances. This standard specifies how a **board** — a person's communication surface and the customization invested in it — is represented, accessed, and exchanged so that it is portable across implementations and devices, operable offline, and never gated behind payment.
|
||
|
||
- **Board** — a surface holding cells, of a given `BoardType` (`Grid | VisualScene | Keyboard | Hybrid | QuickAccess`).
|
||
- **Cell** — a single selectable target on a board, at a fixed grid position, with content and an action.
|
||
- **Utterance** — the message a user composes by selecting cells.
|
||
- **Access method** — the physical channel by which a user selects (`DirectTouch | EyeGaze | HeadTracking | SwitchScan{switches} | Joystick | Bci | PartialVoice | Pointer`).
|
||
- **Client** — software that opens, renders, drives, and speaks a board.
|
||
- **Cascade level** — one of ten tiers (L0–L9) through which a communication operation is resolved.
|
||
|
||
This standard does **not** specify rendering pixels, a UI toolkit, a TTS engine, or symbol artwork. It specifies the data and the invariants that make a voice portable.
|
||
|
||
---
|
||
|
||
## §2. The board data model
|
||
|
||
A board **MUST** be representable as the following structure (field names are normative; the reference type is `aac_core::Board`):
|
||
|
||
- `id` — a `BoardId` (UUID), stable for the life of the board.
|
||
- `name` — display string.
|
||
- `board_type` — one of the `BoardType` variants.
|
||
- `layout` — a `GridLayout { rows: u16, cols: u16 }`.
|
||
- `cells` — a list of `Cell`.
|
||
|
||
A **cell** **MUST** carry:
|
||
|
||
- `id` — a `CellId` (UUID).
|
||
- `position` — a `GridPosition { row: u16, col: u16 }`, 0-indexed.
|
||
- `content` — one of: `Symbol { symbol_id, label }`, `Text(String)`, `Photo { image_ref, label }`, or `Blank`.
|
||
- `action` — one of: `Speak(text)`, `Navigate(BoardId)`, `Modifier(GrammarModifier)`, `Backspace`, `Clear`, `Predict`, `SpeakAll`, `Buffer(text)`.
|
||
- `style` — colors and optional font size; a client **MAY** override style for accessibility (§5) but **MUST NOT** alter `position`.
|
||
- `frequency` — usage count, monotonically non-decreasing.
|
||
- `locked` — whether the cell is protected from structural edits.
|
||
|
||
Boards form a **graph**: a `Navigate` action edges from one board to another. The graph is the source of truth; a grid layout is one projection of it. A `Blank` cell is meaningful — it reserves a position to preserve the motor grid (§3) and **MUST NOT** be elided on round-trip.
|
||
|
||
---
|
||
|
||
## §3. Motor stability (normative invariant)
|
||
|
||
A user's motor plan — the learned muscle memory of where each word lives — is the single most valuable property of a configured board. Therefore:
|
||
|
||
1. A cell's `position` **MUST NOT** change once assigned, for the life of that cell, except by an explicit user/editor edit to an `unlocked` cell. Prediction, context, frequency, language switching, and any L3+ enrichment **MUST NOT** move a cell.
|
||
2. A client **MUST NOT** reflow, resort, or auto-arrange cells on a board whose cells are `locked`.
|
||
3. Hiding a word for teaching (progressive disclosure) **MUST** be done by rendering its cell as visually inactive **in place** — never by removing it and collapsing the grid.
|
||
4. Two openings of the same board on the same or different conforming clients **MUST** present identical cell positions.
|
||
|
||
An implementation that rearranges a locked board is non-conformant regardless of any other quality.
|
||
|
||
---
|
||
|
||
## §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.
|
||
|
||
---
|
||
|
||
## §5. Access model
|
||
|
||
Every access method is a first-class input. A board **MAY** be driven by any method; the method and its tuning travel with the user's profile, not the board.
|
||
|
||
- **AccessMethod** — as enumerated in §1. `SwitchScan { switches }` carries the switch count (1, 2, or more).
|
||
- **MotorProfile** — `fine_motor`, `sustained_press`, `tremor_level`, `min_target_mm`, optional `max_reach_mm`, `preferred_side`. A client **SHOULD** adapt target size and timing from this profile, and **MUST NOT** require a smaller target than `min_target_mm`.
|
||
|
||
Timing-based methods are normative in their own right:
|
||
|
||
1. **Switch scanning** — a conforming scanner **MUST** support row-column, linear, and group scan patterns, a configurable scan rate, and configurable acceptance/timing. Adaptive rate, where enabled, **MUST** stay within explicit `[min, max]` bounds.
|
||
2. **Dwell / eye-gaze** — selection by sustained gaze **MUST** use a configurable dwell time with visible progress feedback, and **SHOULD** adapt to fatigue within bounds.
|
||
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.
|
||
|
||
---
|
||
|
||
## §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.
|
||
|
||
---
|
||
|
||
## §9. The receipt
|
||
|
||
Every operation **MAY** report a two-part energy cost (`measured + estimated`) in microjoules, with an honest provenance tag indicating whether a reading came from hardware instrumentation, a model, or an estimator. The receipt exists for **transparency only**. An implementation **MUST NOT** convert a receipt into a charge, a quota, or a gate. "This session used 3.2 mJ" is a fact shown to the user; it is never a bill.
|
||
|
||
---
|
||
|
||
## §10. Conformance
|
||
|
||
An implementation is conformant if it:
|
||
|
||
1. Round-trips the published board vectors (§7) byte-identically.
|
||
2. Preserves the motor-stability invariant (§3) across open/edit/save.
|
||
3. Routes operations to the specified cascade levels and satisfies energy monotonicity (§6.1).
|
||
4. Serves exactly L0–L2 offline (§6.2) and gates no level behind billing (§6.3).
|
||
5. Ingests the interchange format without losing positions, content, or actions (§8).
|
||
|
||
The [`aac-conformance`](aac-rs/crates/aac-conformance) harness checks the cascade routing table (C1), energy monotonicity (C2), the offline invariant (C3), and wire round-trips (C4). 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. Selection of an access method, vocabulary, and communication approach for a given person is a clinical decision for a qualified speech-language pathologist and the user's team. The standard provides the portable substrate; it does not replace assessment, training, or support.
|