Skip to content

Commit a258114

Browse files
UnbreakableMJclaude
andcommitted
feat(standard): add §18 accessibility as opt-in mode layer — v1.33
Accessibility was three unenforceable lines in §13, a chapter scoped to graphical applications, while the estate is overwhelmingly Rust CLI/TUI. §18 makes it a first-class, auditable chapter covering CLI, TUI, and GUI. Accessible mode is mandatory for developers to implement and optional for users to activate. The Steelbore theme is untouched and remains the sole default; two additive sibling variants join the §11.1 registry. - §18 (new): activation precedence (--accessible / SPACECRAFT_A11Y / config / hints), CLI+TUI rules, TUI linear mode, GUI bridges (AccessKit for Rust; GtkAccessible / Semantics / QAccessible), verification, and remediation tracking for existing projects. - §11.1.1 (new): steelbore-high-contrast (only accent and error shift, to #7FAEDC and #FF8080; all six tokens >=7:1 on Void Navy) and steelbore-mono (4-bit ANSI). Void Navy remains the background in every variant. - §11: the AA guarantee covers foreground-on-Void-Navy only. 9 of 10 inter-token pairs fall below 3:1 (Amber on Red Oxide is 1.13:1), so text on a palette-colored fill now requires its own verification. - §10: bindings must be user-remappable; NVDA/Orca/VoiceOver modifier chords must not be captured. - §13: WCAG 2.1 AA -> WCAG 2.2 AA; EN 301 549 clause 11 (non-web software) adopted as the anchor for CLI/TUI. - §16: new §18 gate; §10 and §13 gates extended. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent b4a2077 commit a258114

2 files changed

Lines changed: 700 additions & 19 deletions

File tree

The_Steelbore_Standard.md

Lines changed: 280 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@ concerns.
2323

2424
## Changelog
2525

26+
- **v1.33 (2026-07-23):** **§18 added** — Accessibility codified as a
27+
first-class, auditable chapter covering CLI, TUI, and GUI. Accessible
28+
mode is an *opt-in layer*: mandatory for developers to implement, off
29+
by default for users, activated by `--accessible` / `SPACECRAFT_A11Y`
30+
/ config. The `Steelbore` theme is unchanged and remains the sole
31+
default; two additive sibling variants (`steelbore-high-contrast`,
32+
`steelbore-mono`) join the §11.1 registry. **§10** extended with
33+
keybinding remappability and reserved assistive-technology chords.
34+
**§11** clarified: palette contrast is verified against Void Navy only
35+
— text on a palette-colored fill requires its own pair verification.
36+
**§13** accessibility target raised from **WCAG 2.1 AA to WCAG 2.2
37+
Level AA**, with **EN 301 549 clause 11 (non-web software)** adopted
38+
as the normative anchor for CLI/TUI. Compliance Checklist updated.
39+
2640
- **v1.32 (2026-07-15):** **§17 added** — Development Progress Tracking
2741
& Reporting codified, specifying milestones, MVP, and total PRD
2842
completion tracking using a 20-character Unicode progress bar.
@@ -880,6 +894,28 @@ All interactive applications must support **both**:
880894
| **CUA** | Standard bindings (Ctrl+C/X/V/Z/S) must work in all text input contexts |
881895
| **Vim** | Modal editing layer (Normal / Insert / Visual mode) as opt-in feature. Minimum: hjkl navigation where full Vim layer is impractical |
882896

897+
**Remappability (mandatory).** Every binding must be user-remappable
898+
through the project’s configuration layer — a fixed, non-configurable
899+
keymap is non-compliant. Users of alternative input devices, non-QWERTY
900+
layouts, and assistive technology cannot be assumed to reach any
901+
particular chord.
902+
903+
**Reserved assistive-technology chords.** The following modifiers are
904+
claimed by screen readers and **must not** be captured by a Spacecraft
905+
Software application; capturing them takes keys away from the users who
906+
depend on them most:
907+
908+
| Chord | Claimed by |
909+
|----|----|
910+
| `Insert` / `CapsLock` | NVDA (Windows) — the NVDA modifier key |
911+
| `Insert` / `KP_Insert` | Orca (GNOME/Linux) — the screen reader’s own modifier |
912+
| `Ctrl`+`Option` | VoiceOver (macOS) — the "VO" modifier |
913+
914+
Every action reachable by pointer must also be reachable by keyboard;
915+
focus order must be linear and the focused element must be visibly
916+
indicated. See §18 for the wider accessibility requirements this
917+
supports.
918+
883919
————————————————————————
884920

885921
# §11 — Spacecraft Software Color Palette (WCAG-Compliant)
@@ -900,6 +936,23 @@ documents:
900936
Software surfaces.** No alternative background is permitted. This is
901937
non-negotiable.
902938

939+
**Scope of the contrast guarantee.** Every foreground token above is
940+
verified against the Void Navy background and passes WCAG Level AA
941+
(Molten Amber 7.64:1, Steel Blue 4.77:1, Radium Green 14.87:1, Red Oxide
942+
6.74:1, Liquid Coolant 14.74:1). That guarantee covers
943+
**foreground-on-background pairings only**. Palette tokens paired with
944+
*each other* are mostly far below the 3:1 floor — Molten Amber on Red
945+
Oxide is 1.13:1 and Radium Green on Liquid Coolant is 1.01:1, which is
946+
indistinguishable. Therefore:
947+
948+
- Rendering palette-colored **text on a palette-colored fill** (a chip,
949+
badge, filled button, or selected row) is **forbidden** unless that
950+
specific pair has been measured at ≥4.5:1 for text, or ≥3:1 for
951+
non-text UI boundaries.
952+
953+
- Color may never be the **sole** carrier of meaning. Every colored
954+
status must also carry a text tag or symbol — see §18.2.
955+
903956
For document/file generation → load the `spacecraft-document-format`
904957
skill. For IDE/terminal themes → load the `spacecraft-theme-factory`
905958
skill.
@@ -935,6 +988,40 @@ touching application logic — swap the theme, not every hex literal.
935988
- Existing apps are encouraged but not required to migrate; new apps are
936989
required.
937990

991+
### §11.1.1 — Accessibility Variants (additive siblings)
992+
993+
`steelbore` is and remains the **sole default theme**. The variants
994+
below are **additive siblings** inside the same theme registry, selected
995+
only by explicit user action or by the §18.1 accessible-mode toggle.
996+
They never alter, replace, or take precedence over `steelbore`, and the
997+
§11 canonical palette table above is unchanged by their existence.
998+
999+
| Variant | Selected by | Behavior |
1000+
|----|----|----|
1001+
| `steelbore` | **Default** — always, unless overridden | Canonical §11 palette, unchanged |
1002+
| `steelbore-high-contrast` | §18.1 accessible mode, or explicit selection | Every role token lifted to ≥7:1 (WCAG AAA) on Void Navy |
1003+
| `steelbore-mono` | Explicit selection, or `NO_COLOR` | 4-bit ANSI only — defers entirely to the user’s terminal palette |
1004+
1005+
`steelbore-high-contrast` lifts **only the two tokens that need it**.
1006+
Tokens already at or above 7:1 are carried over untouched, keeping the
1007+
variant as close to the brand as accessibility permits:
1008+
1009+
| Theme token | Base token | Variant hex | Contrast | |
1010+
|--------------|----------------|-------------|----------|-----|
1011+
| `background` | Void Navy | `#000027` | (canvas) | |
1012+
| `foreground` | Molten Amber | `#D98E32` | 7.64:1 | |
1013+
| `accent` | Steel Blue | `#7FAEDC` | 8.73:1 | |
1014+
| `success` | Radium Green | `#50FA7B` | 14.87:1 | |
1015+
| `error` | Red Oxide | `#FF8080` | 8.41:1 | |
1016+
| `info` | Liquid Coolant | `#8BE9FD` | 14.74:1 | |
1017+
1018+
Only `accent` (Steel Blue `#4B7EB0``#7FAEDC`) and `error` (Red Oxide
1019+
`#FF5C5C``#FF8080`) shift; the other four are the §11 values
1020+
verbatim. **Void Navy remains the background in every variant** — high
1021+
contrast is achieved by lifting foregrounds, never by abandoning the
1022+
canvas. These two hexes are accessibility-derived lifts of existing role
1023+
tokens, not new brand colors, and may not be used outside the variant.
1024+
9381025
————————————————————————
9391026

9401027
# §12 — Typography (FOSS-Licensed Fonts Only)
@@ -959,12 +1046,13 @@ or another FOSS-licensed repository.
9591046
- **Material Design** is the required component system for all graphical
9601047
applications. Theme Material components with the §11 color palette.
9611048

962-
- **WCAG 2.1 Level AA** contrast is the minimum for all color pairings.
963-
Any new color additions must be WCAG-verified before adoption.
1049+
- **WCAG 2.2 Level AA** contrast is the minimum for all color pairings.
1050+
Any new color additions must be WCAG-verified before adoption, and the
1051+
verification must state *which pairing* was measured (§11).
9641052

965-
- **Accessibility:** screen readers, keyboard-only navigation, and
966-
system accessibility preferences (reduced motion, high contrast) must
967-
all be respected.
1053+
- **Accessibility** is governed by **§18**, which applies to CLI, TUI,
1054+
and GUI alike. §13 is the graphical design system; §18 is the
1055+
accessibility contract. Where the two overlap, §18 governs.
9681056

9691057
————————————————————————
9701058

@@ -1304,6 +1392,179 @@ Progress must be reported:
13041392

13051393
————————————————————————
13061394

1395+
# §18 — Accessibility (Opt-In Mode Layer)
1396+
1397+
Spacecraft Software applications must be usable by people who navigate
1398+
by screen reader, by keyboard alone, or with low vision. This chapter is
1399+
the accessibility contract for **all** application classes — CLI, TUI,
1400+
and GUI — and supersedes §13’s design-system framing wherever the two
1401+
overlap.
1402+
1403+
**Two-sided rule.** Accessibility support is **mandatory for the
1404+
developer to implement** and **optional for the user to activate**:
1405+
1406+
- **Every** Spacecraft Software application MUST ship a working
1407+
accessible mode. This applies to new and existing projects alike —
1408+
there is no new-projects-only phase-in.
1409+
1410+
- Accessible mode is **off by default**. The default experience is the
1411+
`Steelbore` theme and standard rendering, entirely unchanged. Enabling
1412+
accessibility never becomes a precondition for using the software
1413+
normally, and shipping it never degrades the default presentation.
1414+
1415+
**Normative targets.** **WCAG 2.2 Level AA** where the success criteria
1416+
apply, and **EN 301 549 clause 11 (non-web software)** as the anchor for
1417+
CLI and TUI applications, which WCAG addresses only indirectly. Clause
1418+
11 is cited because it is the only normative text that speaks to
1419+
terminal software; the European Accessibility Act has been enforceable
1420+
since 2025-06-28.
1421+
1422+
## §18.1 — Activation
1423+
1424+
Accessible mode resolves once at startup from four sources. Precedence,
1425+
highest first:
1426+
1427+
| Source | Form |
1428+
|----|----|
1429+
| **1. Command-line flag** | `--accessible` / `--no-accessible` |
1430+
| **2. Environment** | `SPACECRAFT_A11Y=1` / `SPACECRAFT_A11Y=0` — the umbrella-wide environment variable |
1431+
| **3. Configuration** | `[accessibility] enabled = true` in the project’s config file |
1432+
| **4. Auto-detect hints** | `TERM=dumb`, `NO_COLOR`, or `GTK_MODULES` containing `gail:atk` |
1433+
1434+
- A hint (source 4) **may** enable accessible mode, but must never be
1435+
inferred from an ambiguous signal. An explicit `--no-accessible` or
1436+
`SPACECRAFT_A11Y=0` always wins, at every level.
1437+
1438+
- Unset at every source ⇒ **standard `Steelbore` rendering, unchanged**.
1439+
Silence is never read as consent to change the default presentation.
1440+
1441+
- The resolved state and the source that decided it must be reported
1442+
under `--verbose`, so a user can tell why the mode is on or off.
1443+
1444+
- The toggle is a **single switch** governing every behavior in §18.2
1445+
and §18.3 together. Per-feature accessibility flags fragment the
1446+
contract and are not a substitute.
1447+
1448+
## §18.2 — CLI & TUI Requirements
1449+
1450+
**The constraint that shapes everything here:** a terminal has no
1451+
accessibility tree. There is no ARIA, there are no roles, and there are
1452+
no live regions. A screen reader reads the emulator’s character grid, so
1453+
a redraw-based interface produces re-reads and speech loops rather than
1454+
useful speech. Accessibility cannot be delegated to the TUI framework —
1455+
no terminal UI library provides it — so the application must supply a
1456+
linear fallback itself.
1457+
1458+
### §18.2.1 — Rules that apply in every mode
1459+
1460+
These are not gated behind the toggle. They are correctness requirements
1461+
for all output, always:
1462+
1463+
- **Color is never the sole carrier of meaning.** Every colored status
1464+
carries a text tag: `[OK]`, `[ERROR]`, `[WARN]`, `[INFO]`. A red line
1465+
that says only "failed to connect" is non-compliant;
1466+
`[ERROR] failed to connect` is compliant.
1467+
1468+
- **No text on colored fills** unless that specific pair is verified per
1469+
§11 — palette tokens are verified against Void Navy, not against each
1470+
other.
1471+
1472+
- **Diagnostics go to `stderr`**, results to `stdout`, and the two are
1473+
never interleaved into one visual block.
1474+
1475+
- **`NO_COLOR`, `FORCE_COLOR`, `CLICOLOR`, and `TERM=dumb`** are honored
1476+
with the precedence already defined by the `spacecraft-cli-standard`
1477+
skill.
1478+
1479+
### §18.2.2 — Rules that apply in accessible mode
1480+
1481+
| Requirement | Rule |
1482+
|----|----|
1483+
| **No animation** | Spinners, marquees, blinking text, and progress animations are replaced by a single static line carrying monotonic progress (`Working… 40%`), rewritten at most once per second |
1484+
| **No decorative art** | ASCII art, banners, box-drawing decoration, and figlet headers are suppressed. Where the art is *informational* (a diagram, a chart), emit an equivalent text description instead — do not simply drop it |
1485+
| **Linear output** | Output is append-only and reads correctly top-to-bottom. Blank lines separate logical sections so a screen reader can navigate by paragraph |
1486+
| **Tabular fallback** | Any table offers a non-columnar rendering — one `field: value` pair per line — since column alignment conveys nothing through speech |
1487+
| **Prompt legibility** | Interactive prompts state the question, the available choices, and the default in plain text before awaiting input. Prompts that rely on cursor positioning or redraw to convey state are non-compliant |
1488+
1489+
### §18.2.3 — TUI linear mode
1490+
1491+
Any full-screen TUI MUST additionally provide a **non-redraw,
1492+
append-only stream mode**, reachable through the same §18.1 toggle. In
1493+
linear mode the application writes new state as new lines rather than
1494+
repainting regions, and does not take over the alternate screen buffer.
1495+
1496+
Where a TUI would otherwise be the only way to perform an operation, an
1497+
equivalent **non-interactive CLI path** must exist — flags plus `--json`
1498+
output — so the operation remains scriptable and reachable without
1499+
navigating a visual grid. Per §8, this path must be documented in the
1500+
project’s Texinfo manual alongside the interactive one.
1501+
1502+
## §18.3 — GUI Requirements
1503+
1504+
Graphical applications expose an accessibility tree to the platform’s
1505+
assistive-technology API. Which bridge to use depends on how the UI is
1506+
drawn:
1507+
1508+
| UI stack | Required bridge |
1509+
|----|----|
1510+
| **Rust, custom-drawn UI** | **AccessKit** (Apache-2.0) — one API over UI Automation (Windows), NSAccessibility (macOS), and AT-SPI (Linux). Already integrated in egui, Slint, Bevy, Freya, Xilem, and winit |
1511+
| **GTK 4** | `GtkAccessible` — WAI-ARIA roles and states surfaced over AT-SPI |
1512+
| **Flutter** | `Semantics` widgets and `SemanticsRole` |
1513+
| **Qt** | `QAccessible` |
1514+
1515+
Custom-drawn widgets are the failure case to watch: a canvas-rendered
1516+
control is invisible to assistive technology unless the application
1517+
publishes its role and state explicitly. This is precisely the gap
1518+
AccessKit exists to close, which is why it is required rather than
1519+
merely suggested for Rust GUI work (§3.1 already makes Rust the
1520+
preferred language).
1521+
1522+
**Requirements:**
1523+
1524+
- Every interactive element carries an explicit accessible **name** and
1525+
**role**. Purely decorative elements are explicitly marked decorative
1526+
so they are skipped rather than read as noise.
1527+
1528+
- State changes that matter to the user are **announced**, not merely
1529+
repainted.
1530+
1531+
- System preferences for **reduced motion** and **high contrast** are
1532+
honored — these are read from the platform, independently of the §18.1
1533+
toggle, because the user has already expressed the preference
1534+
system-wide.
1535+
1536+
- Keyboard reachability and focus visibility follow §10.
1537+
1538+
## §18.4 — Verification & Remediation
1539+
1540+
**Verification.** An accessibility claim is not satisfied by inspection.
1541+
Before a release:
1542+
1543+
- **CLI/TUI:** pipe the accessible-mode output through a speech
1544+
synthesizer (e.g. `espeak-ng`) and confirm it is comprehensible when
1545+
heard rather than seen. Confirm the non-interactive path completes the
1546+
same operations as the interactive one.
1547+
1548+
- **GUI:** exercise the application with a real screen reader — Orca on
1549+
Linux, NVDA on Windows, VoiceOver on macOS — and confirm every
1550+
interactive element announces a name and a role.
1551+
1552+
- **Contrast:** measure the actual pairings used, not just
1553+
foreground-on-background, and record the ratios (§11).
1554+
1555+
- **Keyboard:** complete every primary task without a pointing device.
1556+
1557+
**Remediation for existing projects.** §18 applies to every project
1558+
immediately on adoption of v1.33, which means projects predating it are
1559+
non-compliant until retrofitted. This is stated plainly rather than
1560+
softened into a recommendation. Until a project conforms, it MUST carry
1561+
a **dated remediation entry** in `PROJECTS.md` recording its current
1562+
accessibility state and the intended remediation. An absent entry is a
1563+
compliance failure in its own right — a project may be unfinished, but
1564+
it may not be silently unfinished.
1565+
1566+
————————————————————————
1567+
13071568
# §16 — Compliance Checklist (Audit Gate)
13081569

13091570
Before finalising **any** Spacecraft Software artifact, mentally verify:
@@ -1358,15 +1619,18 @@ Before finalising **any** Spacecraft Software artifact, mentally verify:
13581619
- [ ] **§9** PFA: no tracking, minimal permissions, local storage
13591620
default
13601621

1361-
- [ ] **§10** CUA + Vim-like key bindings planned/implemented
1622+
- [ ] **§10** CUA + Vim-like key bindings planned/implemented; bindings
1623+
user-remappable; assistive-technology modifier chords
1624+
(NVDA/Orca/VoiceOver) not captured
13621625

13631626
- [ ] **§11** Spacecraft Software color palette used; Void Navy
13641627
background mandatory; new apps expose colors via a named `Steelbore`
13651628
theme (§11.1) — no bare hex literals in UI logic
13661629

13671630
- [ ] **§12** FOSS-licensed fonts only (Share Tech Mono / Inconsolata)
13681631

1369-
- [ ] **§13** Material Design UI/UX; WCAG 2.1 AA verified
1632+
- [ ] **§13** Material Design UI/UX; WCAG 2.2 AA verified, stating which
1633+
pairing was measured
13701634

13711635
- [ ] **§14** ISO 8601 dates; 24h time; UTC Z is the default primary
13721636
timestamp (companion local time with UTC offset permitted, never a
@@ -1386,6 +1650,14 @@ Before finalising **any** Spacecraft Software artifact, mentally verify:
13861650
with milestone percentages, MVP, total PRD completion, and a Unicode
13871651
progress bar
13881652

1653+
- [ ] **§18** Accessible mode implemented and off by default; §18.1
1654+
toggle honored with correct precedence; status never color-only; no
1655+
animation or decorative art in accessible mode; TUI ships a linear
1656+
mode and a non-interactive CLI path; GUI publishes accessible names
1657+
and roles (AccessKit for Rust); verified with a real screen reader;
1658+
existing projects carry a dated remediation entry in `PROJECTS.md`
1659+
until they conform
1660+
13891661
- [ ] **§6.3** All commits to Spacecraft Software Git remotes
13901662
cryptographically signed with the
13911663
`Mohamed.Hammad@SpacecraftSoftware.org` key and showing "Verified" on
@@ -1407,6 +1679,7 @@ skipping it.
14071679
| Generating DOCX / ODT / PDF on demand | `spacecraft-document-format` |
14081680
| Authoring or building a Texinfo manual | `spacecraft-texinfo-document` |
14091681
| Creating IDE / terminal themes | `spacecraft-theme-factory` |
1682+
| Implementing or auditing accessibility (§18) | `spacecraft-accessibility` |
14101683
| All other Spacecraft Software work | `spacecraft-standard-constitution` |
14111684

14121685
# Concept Index

0 commit comments

Comments
 (0)