Skip to content

Commit 3d716bb

Browse files
V31 Gate 8: Prove Auxillaries UX accessibility
Adds the contained Auxillaries support-plane accessibility shell with named landmarks, skip navigation, active-pane state announcements, compact readiness summary, expandable source-safe audit detail, responsive/reduced-motion CSS, and keyboard-readable pane state semantics. Adds a Gate 8 checker, proof contract, focused Jest coverage, workflow wiring, roadmap/spec/parity updates, and Auxillaries documentation for the low-detail guided UX contract.
1 parent fd195d2 commit 3d716bb

16 files changed

Lines changed: 793 additions & 11 deletions

.github/workflows/bitcode-gate-quality.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ jobs:
102102
node scripts/check-v31-gate5-wallet-btd-pane-readiness.mjs --skip-branch-check
103103
node scripts/check-v31-gate6-organization-team-role-policy-authority.mjs --skip-branch-check
104104
node scripts/check-v31-gate7-interfaces-pane-admission-cross-surface-contracts.mjs --skip-branch-check
105+
node scripts/check-v31-gate8-auxillaries-ux-accessibility-responsive-proof.mjs --skip-branch-check
105106
else
106107
echo "Unexpected BITCODE_SPEC.txt pointer: $POINTER" >&2
107108
exit 1
@@ -143,6 +144,9 @@ jobs:
143144
pnpm --dir uapi exec jest --runTestsByPath \
144145
tests/userDataRoute.test.ts \
145146
tests/auxillariesWalletPane.test.tsx \
147+
tests/auxillariesContent.access.test.tsx \
148+
tests/auxillariesWorkspacePanels.access.test.tsx \
149+
tests/auxillariesWorkspacePanels.test.tsx \
146150
tests/api/auxillariesGithubConnectionRoute.test.ts \
147151
tests/api/vcsRoutes.test.ts \
148152
tests/auxillariesExternalsPane.test.tsx \

BITCODE_SPEC_V31.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,10 @@ Gate 8 UX precision:
278278
- Auxillaries default presentation is low-detail and guided, with expandable audit detail for every pane.
279279
- Responsive behavior must be stable on mobile and desktop without overlapping text or decorative card nesting.
280280
- Accessibility proof covers focus order, keyboard operation, labels, state announcement, contrast, and reduced-motion posture where applicable.
281+
- The contained Auxillaries support plane must expose one named main landmark, one skip link to `#auxillaries-active-pane`, one named pane navigation region, and one named active pane region per selected pane.
282+
- The active pane region must announce ready/loading state, show a compact guided summary and source-safe readiness chips, and keep audit metadata behind an expandable control.
283+
- The expandable audit detail may expose pane names, availability counts, completed panes, surface state, and source-safety posture; it must not require ordinary users to read raw JSON.
284+
- Workspace pane controls must be regular buttons with keyboard-native behavior, `aria-current` on the selected pane, `aria-disabled` mirroring disabled state, and screen-reader descriptions for active/ready/locked posture.
281285

282286
Gate 9 telemetry/recovery precision:
283287

BITCODE_SPEC_V31_DELTA.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,14 @@ Closure acceptance:
197197
- Profile, Connects, Interfaces, Wallet/BTD, and organization panes work across mobile and desktop without overlap;
198198
- keyboard, focus, labels, state announcement, contrast, and reduced-motion posture are tested.
199199

200+
Gate 8 implementation centers:
201+
202+
- the contained Auxillaries shell exposes one named main landmark, a keyboard-reachable skip link to `#auxillaries-active-pane`, named pane navigation, and a named active-pane region with `aria-live` state announcement;
203+
- the active-pane region carries a compact guided summary, readiness chips, loading/ready state, and source-safe expandable audit detail without raw JSON;
204+
- workspace panel buttons carry `aria-current`, `aria-disabled`, and screen-reader state descriptions while retaining concise visible labels;
205+
- route-scoped Auxillaries CSS enforces overflow wrapping, mobile single-column behavior, focus-visible rings, contrast-preserving chips, and reduced-motion posture;
206+
- focused Jest coverage proves named landmarks, skip navigation, active-pane announcements, loading state, expandable audit detail, and keyboard-readable panel states.
207+
200208
### Gate 9: Auxillaries Telemetry Proof And Recovery Runs
201209

202210
Gate 9 adds Auxillaries telemetry and recovery proof.

BITCODE_SPEC_V31_NOTES.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,15 @@ Gate 6 is closed only when organization policy authority is package-owned, sourc
110110
Protected-source and settlement-adjacent actions must fail closed unless every required authority input admits the action.
111111
`packages/api` may map the BTD object into `OrganizationPolicyAuthority`, but routes, Profile panes, Terminal detail cards, telemetry, and proof hooks must not rederive the authority decision from local heuristics.
112112
The support UI may show policy measurements, blockers, recovery routes, and roots; it must not reveal protected source or treat multi-sig readiness as value-bearing mainnet approval.
113+
114+
## Gate 7 closure note
115+
116+
Gate 7 is closed only when Interfaces admission is package-owned and cross-surface.
117+
The admission catalog must cover Terminal, API, MCP, ChatGPT App, Exchange hook, Conversations hook, and future interface hooks with auth mode, supported actions, currently admitted actions, policy requirements, source-safety class, blockers, readiness, deferred-product depth, and interface-admission roots.
118+
Exchange and Conversations may appear as source-safe hooks, but their market and product depth must stay explicitly blocked until later versions implement those surfaces.
119+
120+
## Gate 8 closure note
121+
122+
Gate 8 is closed only when Auxillaries UX is usable before audit expansion and provable after expansion.
123+
The contained support plane must expose a named main landmark, keyboard skip link, named pane navigation, active-pane state announcement, readable loading/ready posture, and expandable audit detail for every pane without raw JSON.
124+
The panel controls must be keyboard-native, focus-visible, labelled, and state-described, and route-scoped CSS must prove responsive mobile/desktop layout, no horizontal overflow pressure, contrast-preserving readiness chips, and reduced-motion posture.

BITCODE_SPEC_V31_PARITY_MATRIX.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,17 @@ No `_legacy/` source is active source truth.
138138

139139
| Requirement | Source evidence | Current V31 judgment |
140140
| --- | --- | --- |
141-
| Interfaces pane exposes admitted surfaces | `AuxillariesInterfaceAdmission` records in `packages/api/src/routes/auxillaries-contract.ts` enumerate Terminal, API, MCP, ChatGPT App, Exchange hook, Conversations hook, and future interface hooks; `uapi/app/auxillaries/components/AuxillariesInterfacesPane.tsx` renders the catalog | drafted |
142-
| Each surface names auth, actions, policy, source-safety, blockers, and readiness | `packages/api/src/routes/__tests__/auxillaries-contract.test.ts` asserts auth mode, `supportedActions`, current `allowedActions`, `policyRequirements`, `sourceSafetyClass`, blockers, readiness, and roots | drafted |
143-
| Deferred Exchange and Conversations remain explicitly out of scope | Exchange and Conversations hook records are blocked with `deferredProductDepth` values and deferred blockers; `uapi/tests/orbitalsInterfacesPane.test.tsx` reads those blockers in the catalog | drafted |
141+
| Interfaces pane exposes admitted surfaces | `AuxillariesInterfaceAdmission` records in `packages/api/src/routes/auxillaries-contract.ts` enumerate Terminal, API, MCP, ChatGPT App, Exchange hook, Conversations hook, and future interface hooks; `uapi/app/auxillaries/components/AuxillariesInterfacesPane.tsx` renders the catalog | closed |
142+
| Each surface names auth, actions, policy, source-safety, blockers, and readiness | `packages/api/src/routes/__tests__/auxillaries-contract.test.ts` asserts auth mode, `supportedActions`, current `allowedActions`, `policyRequirements`, `sourceSafetyClass`, blockers, readiness, and roots | closed |
143+
| Deferred Exchange and Conversations remain explicitly out of scope | Exchange and Conversations hook records are blocked with `deferredProductDepth` values and deferred blockers; `uapi/tests/orbitalsInterfacesPane.test.tsx` reads those blockers in the catalog | closed |
144144

145145
## Gate 8 Parity
146146

147147
| Requirement | Source evidence | Current V31 judgment |
148148
| --- | --- | --- |
149-
| Guided low-detail UX is default | Auxillaries component tests | pending |
150-
| Audit detail is expandable without layout breakage | responsive/browser proof | pending |
151-
| Keyboard, focus, labels, state announcements, contrast, and reduced motion are tested | accessibility proof | pending |
149+
| Guided low-detail UX is default | `uapi/app/auxillaries/components/AuxillariesContent.tsx` renders the contained active-pane summary and readiness chips before audit expansion; `uapi/tests/auxillariesContent.access.test.tsx` asserts the named main, active pane, status, ready/loading state, and skip link | closed |
150+
| Audit detail is expandable without layout breakage | `uapi/app/auxillaries/components/AuxillariesContent.tsx` renders source-safe `details` audit metadata; `uapi/styles/auxillaries-bitcode.css` keeps audit grids responsive at desktop/tablet/mobile breakpoints | closed |
151+
| Keyboard, focus, labels, state announcements, contrast, and reduced motion are tested | `uapi/app/auxillaries/auxillaries-ux-accessibility-proof.ts`, `uapi/tests/auxillariesContent.access.test.tsx`, and `uapi/tests/auxillariesWorkspacePanels.access.test.tsx` cover landmarks, labels, `aria-current`, `aria-disabled`, status announcements, evidence files, and viewport posture; route CSS covers focus-visible rings, contrast chips, wrapping, and `prefers-reduced-motion` | closed |
152152

153153
## Gate 9 Parity
154154

SPECIFICATIONS_ROADMAP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
- Current active canonical pointer: `BITCODE_SPEC.txt` -> `V30`
66
- Current active canon: `BITCODE_SPEC_V30.md`
77
- Current draft target: `BITCODE_SPEC_V31.md`
8-
- Current working gate: V31 Gate 7 Interfaces Pane Admission And Cross-Surface Contracts, which turns the Interfaces pane into the source-safe admission catalog for Terminal, API, MCP, ChatGPT App, Exchange, Conversations, and future hooks with auth mode, supported actions, current admitted actions, policy requirements, source-safety class, blockers, readiness, deferred-product boundaries, and proof roots.
8+
- Current working gate: V31 Gate 8 Auxillaries UX Accessibility And Responsive Proof, which makes the Auxillaries support plane low-detail by default with a named main landmark, keyboard skip link, named pane navigation, active-pane state announcements, expandable audit detail, responsive mobile/desktop layout, focus/label/contrast posture, and reduced-motion proof.
99
- Purpose: concise running index of Bitcode/ENGI specification history, current work, and planned work.
1010

1111
This roadmap is not an active system specification.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"check:v31-gate5": "node scripts/check-v31-gate5-wallet-btd-pane-readiness.mjs",
7272
"check:v31-gate6": "node scripts/check-v31-gate6-organization-team-role-policy-authority.mjs",
7373
"check:v31-gate7": "node scripts/check-v31-gate7-interfaces-pane-admission-cross-surface-contracts.mjs",
74+
"check:v31-gate8": "node scripts/check-v31-gate8-auxillaries-ux-accessibility-responsive-proof.mjs",
7475
"check:spec-quality": "node scripts/run-bitcode-spec-quality.mjs --mode basic",
7576
"check:spec-quality:title": "node scripts/run-bitcode-spec-quality.mjs --mode strict-from-title",
7677
"check:spec-quality:v24": "node scripts/run-bitcode-spec-quality.mjs --mode strict-version --version V24",
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
#!/usr/bin/env node
2+
3+
import { execFileSync } from 'node:child_process';
4+
import { existsSync, readFileSync } from 'node:fs';
5+
import path from 'node:path';
6+
import { fileURLToPath } from 'node:url';
7+
8+
const __filename = fileURLToPath(import.meta.url);
9+
const __dirname = path.dirname(__filename);
10+
const defaultRepoRoot = path.resolve(__dirname, '..');
11+
12+
function read(root, relativePath) {
13+
return readFileSync(path.join(root, relativePath), 'utf8');
14+
}
15+
16+
function fileExists(root, relativePath) {
17+
return existsSync(path.join(root, relativePath));
18+
}
19+
20+
function git(root, args) {
21+
return execFileSync('git', args, { cwd: root, encoding: 'utf8' }).trim();
22+
}
23+
24+
function assertCheck(failures, condition, message) {
25+
if (!condition) failures.push(message);
26+
}
27+
28+
function parseArgs(argv) {
29+
const args = {
30+
skipBranchCheck: false,
31+
repoRoot: defaultRepoRoot,
32+
};
33+
34+
for (let index = 0; index < argv.length; index += 1) {
35+
const arg = argv[index];
36+
if (arg === '--skip-branch-check') args.skipBranchCheck = true;
37+
else if (arg === '--repo-root') args.repoRoot = path.resolve(argv[++index]);
38+
else if (arg === '--help' || arg === '-h') args.help = true;
39+
else throw new Error(`Unknown argument ${arg}`);
40+
}
41+
42+
return args;
43+
}
44+
45+
function printHelp() {
46+
process.stdout.write(
47+
[
48+
'Usage: node scripts/check-v31-gate8-auxillaries-ux-accessibility-responsive-proof.mjs [--skip-branch-check] [--repo-root <path>]',
49+
'',
50+
'Checks V31 Gate 8 Auxillaries low-detail UX, named landmarks, skip navigation, active-pane state announcements, responsive CSS, reduced-motion posture, tests, docs, and workflow coverage.',
51+
].join('\n'),
52+
);
53+
process.stdout.write('\n');
54+
}
55+
56+
function main() {
57+
const args = parseArgs(process.argv.slice(2));
58+
if (args.help) {
59+
printHelp();
60+
return;
61+
}
62+
63+
const root = args.repoRoot;
64+
const failures = [];
65+
const pointer = read(root, 'BITCODE_SPEC.txt').trim();
66+
67+
assertCheck(
68+
failures,
69+
pointer === 'V30',
70+
`BITCODE_SPEC.txt must remain V30 during V31 gate work. Observed ${pointer || 'empty'}.`,
71+
);
72+
73+
if (!args.skipBranchCheck) {
74+
const branch = git(root, ['branch', '--show-current']);
75+
assertCheck(
76+
failures,
77+
branch === 'version/v31' || /^v31\/gate-(?:8|9|10)-[a-z0-9][a-z0-9-]*$/u.test(branch),
78+
`V31 Gate 8+ work must occur on version/v31 or v31/gate-8+ branches. Observed ${branch || 'detached HEAD'}.`,
79+
);
80+
}
81+
82+
for (const relativePath of [
83+
'uapi/app/auxillaries/components/AuxillariesContent.tsx',
84+
'uapi/app/auxillaries/components/shared/AuxillariesWorkspacePanels.tsx',
85+
'uapi/app/auxillaries/auxillaries-ux-accessibility-proof.ts',
86+
'uapi/styles/auxillaries-bitcode.css',
87+
'uapi/tests/auxillariesContent.access.test.tsx',
88+
'uapi/tests/auxillariesWorkspacePanels.access.test.tsx',
89+
'BITCODE_SPEC_V31.md',
90+
'BITCODE_SPEC_V31_DELTA.md',
91+
'BITCODE_SPEC_V31_NOTES.md',
92+
'BITCODE_SPEC_V31_PARITY_MATRIX.md',
93+
'SPECIFICATIONS_ROADMAP.md',
94+
'uapi/app/auxillaries/README.md',
95+
]) {
96+
assertCheck(failures, fileExists(root, relativePath), `Missing V31 Gate 8 file: ${relativePath}`);
97+
}
98+
99+
const content = read(root, 'uapi/app/auxillaries/components/AuxillariesContent.tsx');
100+
const workspacePanels = read(root, 'uapi/app/auxillaries/components/shared/AuxillariesWorkspacePanels.tsx');
101+
const proofContract = read(root, 'uapi/app/auxillaries/auxillaries-ux-accessibility-proof.ts');
102+
const css = read(root, 'uapi/styles/auxillaries-bitcode.css');
103+
const contentTest = read(root, 'uapi/tests/auxillariesContent.access.test.tsx');
104+
const panelsTest = read(root, 'uapi/tests/auxillariesWorkspacePanels.access.test.tsx');
105+
const spec = read(root, 'BITCODE_SPEC_V31.md');
106+
const delta = read(root, 'BITCODE_SPEC_V31_DELTA.md');
107+
const notes = read(root, 'BITCODE_SPEC_V31_NOTES.md');
108+
const parity = read(root, 'BITCODE_SPEC_V31_PARITY_MATRIX.md');
109+
const roadmap = read(root, 'SPECIFICATIONS_ROADMAP.md');
110+
const auxReadme = read(root, 'uapi/app/auxillaries/README.md');
111+
const packageJson = read(root, 'package.json');
112+
const workflow = read(root, '.github/workflows/bitcode-gate-quality.yml');
113+
const jestConfig = read(root, 'uapi/jest.config.cjs');
114+
115+
for (const contentPhrase of [
116+
'aria-label="Bitcode Auxillaries support plane"',
117+
'Skip to active support pane',
118+
'href="#auxillaries-active-pane"',
119+
'role="navigation"',
120+
'aria-label="Auxillaries pane navigation"',
121+
'role="region"',
122+
'aria-live="polite"',
123+
'aria-busy',
124+
'role="status"',
125+
'auxillaries-active-pane-summary',
126+
'auxillaries-audit-detail',
127+
'source-safe summary only',
128+
]) {
129+
assertCheck(failures, content.includes(contentPhrase), `AuxillariesContent must expose ${contentPhrase}.`);
130+
}
131+
132+
for (const panelPhrase of ['aria-current', 'aria-disabled', 'aria-describedby', 'sr-only']) {
133+
assertCheck(failures, workspacePanels.includes(panelPhrase), `Workspace panels must expose ${panelPhrase}.`);
134+
}
135+
136+
for (const proofPhrase of [
137+
'AUXILLARIES_UX_ACCESSIBILITY_PROOF_CONTRACT',
138+
'summarizeAuxillariesUxAccessibilityProofContract',
139+
'auxillariesMain',
140+
'auxillariesPaneNavigation',
141+
'auxillariesActivePane',
142+
'phone',
143+
'tablet',
144+
'laptop',
145+
'widescreen',
146+
]) {
147+
assertCheck(failures, proofContract.includes(proofPhrase), `Auxillaries UX proof contract must include ${proofPhrase}.`);
148+
}
149+
150+
for (const cssPhrase of [
151+
'.auxillaries-skip-link',
152+
'focus-visible',
153+
'overflow-wrap: anywhere',
154+
'@media (max-width: 1023px)',
155+
'@media (max-width: 640px)',
156+
'@media (prefers-reduced-motion: reduce)',
157+
'scroll-behavior: auto',
158+
]) {
159+
assertCheck(failures, css.includes(cssPhrase), `Auxillaries CSS must include ${cssPhrase}.`);
160+
}
161+
162+
for (const testPhrase of [
163+
"getByRole('main'",
164+
"getByRole('link'",
165+
"getByRole('navigation'",
166+
"getByRole('region'",
167+
'aria-live',
168+
'aria-busy',
169+
'auxillaries-audit-detail',
170+
'source-safe summary only',
171+
'queryByText(/\"currentStep\"/)',
172+
'summarizeAuxillariesUxAccessibilityProofContract',
173+
]) {
174+
assertCheck(failures, contentTest.includes(testPhrase), `Auxillaries content accessibility tests must cover ${testPhrase}.`);
175+
}
176+
177+
for (const panelTestPhrase of ['aria-current', 'aria-disabled', 'Locked auxillary']) {
178+
assertCheck(failures, panelsTest.includes(panelTestPhrase), `Workspace panel accessibility tests must cover ${panelTestPhrase}.`);
179+
}
180+
181+
for (const docPhrase of [
182+
'Gate 8',
183+
'low-detail',
184+
'expandable audit',
185+
'named main landmark',
186+
'skip link',
187+
'active pane',
188+
'keyboard',
189+
'focus',
190+
'labels',
191+
'state announcement',
192+
'contrast',
193+
'reduced-motion',
194+
'responsive',
195+
]) {
196+
assertCheck(
197+
failures,
198+
spec.includes(docPhrase) ||
199+
delta.includes(docPhrase) ||
200+
notes.includes(docPhrase) ||
201+
parity.includes(docPhrase) ||
202+
roadmap.includes(docPhrase) ||
203+
auxReadme.includes(docPhrase),
204+
`V31 Gate 8 docs/spec must describe ${docPhrase}.`,
205+
);
206+
}
207+
208+
assertCheck(
209+
failures,
210+
/Current working gate: V31 Gate (?:8|9|10)\b/u.test(roadmap),
211+
'Roadmap must track V31 Gate 8 or a later V31 gate as current working gate.',
212+
);
213+
assertCheck(failures, packageJson.includes('"check:v31-gate8"'), 'package.json must expose check:v31-gate8.');
214+
assertCheck(
215+
failures,
216+
workflow.includes('check-v31-gate8-auxillaries-ux-accessibility-responsive-proof.mjs'),
217+
'Gate quality workflow must run the V31 Gate 8 checker.',
218+
);
219+
assertCheck(
220+
failures,
221+
workflow.includes('tests/auxillariesContent.access.test.tsx') && jestConfig.includes('auxillariesContent.access.test.tsx'),
222+
'Gate quality and Jest config must include Auxillaries content accessibility tests.',
223+
);
224+
225+
if (failures.length) {
226+
process.stderr.write('V31 Gate 8 Auxillaries UX/accessibility closure check failed:\n');
227+
for (const failure of failures) process.stderr.write(`- ${failure}\n`);
228+
process.exit(1);
229+
}
230+
231+
process.stdout.write('V31 Gate 8 Auxillaries UX/accessibility closure check passed.\n');
232+
}
233+
234+
main();

0 commit comments

Comments
 (0)