Repository navigation
Phase 2 step 6: accessibility hardening for the Astryx beta path - #110
Merged
Merged
Conversation
…urfaces Tests only; the fixes follow. Target: WCAG 2.2 AA on the Astryx beta path. - e2e/composer-blocks-a11y.spec.ts (experimental config): builds records-table, auth-form and guide-steps on Astryx through the hosted path with a stubbed gateway (no model call), for each block's approved example and three boundary calls (smallest valid call, every optional prop at its maximum length and count, and the same with unbroken tokens). It checks axe with wcag2a, wcag2aa, wcag21a, wcag21aa and wcag22aa on the canvas with no exclusion; the title as the surface's one level-2 heading; table regions named by their columns; Tab and Shift+Tab order with no trap; a focus indicator of 3:1 that is never entirely hidden (SC 1.4.11, 2.4.11); 24 px targets; text spacing; 200% zoom (640 px) and 320 px reflow, a table scrolling only inside its own region; and an accepted block in Preview. Checks are soft, so one run reports every defect. shadcn/ui v3 scans run for information only and never fail. - apps/composer/app/astryx-renderers-a11y.test.ts: server-rendered checks of the shared Astryx renderers (headings, table names, header and badge wrapping, long-word wrapping). Against main (d7251db): the renderer tests fail 8 of 10 (the two that pass guard what must not change); the e2e fails all 13 Astryx tests (no heading; tables named only "Table"; the studio's green focus ring at 2.41:1 on the canvas white; header cells cut off; long text and the auth form overflowing at 320 px; the page 11 px too wide at 320 px; focused controls entirely hidden under the sticky header at 640 and 320 px). The 6 shadcn/ui v3 scans pass, as information. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
…heme Tests only. - A data table's columns get a minimum width (the renderer unit test). Without one, an 8-column table at 320 px crushed its first and last columns below a letter's width and cut their text off (the e2e's 320 px reflow check, still red after the first fixes). - The surface keeps axe and its focus indicators when the reader prefers a dark scheme (an e2e pass at 1280 px). Astryx's reset declares `color-scheme: light dark`, so the canvas's tokens turned dark inside a white canvas, and Astryx's dark primary button is 3.11:1 (white on #2694FE): 9 of 12 surfaces failed this pass. - A traversal fix in the e2e: it reads each field's unfocused border after taking focus off the fields. The target-size check had left the last field focused, so the 640 px pass read that field's focused border as its unfocused one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
The shared Astryx renderers and the A2UI canvas. These reach the default
build too: every Astryx surface in Preview and the Studio gains them.
- Text: a heading variant renders as h1, h2 or h3 (Astryx Text renders
heading elements for display types), so a block's title is a level-2
heading (WCAG 1.3.1, 2.4.6). A container heading keeps role="heading"
on its own text and never wraps its block children in a heading. Every
variant breaks a long unbroken word (overflow-wrap: anywhere, 1.4.10).
Astryx's reset already zeroes heading margins and sizes, so nothing
moves.
- Table: the keyboard-scrollable region is named by its columns
("Table: Ticket, Subject, ...") instead of Astryx's "Table" for every
table (2.4.6, 4.1.2); header text wraps instead of truncating with an
ellipsis (1.4.4, 1.4.10); and a data column gets a 96 px floor with
Astryx's proportional() widths, as Astryx advises, so a narrow table
scrolls inside its region (the reflow exception for two-dimensional
content) instead of crushing columns below a letter's width. Eight
columns still fit the composer's canvas at 1280 px.
- Badge: a long label wraps inside the badge (a guide's facts ran out of
the card at 640 and 320 px); a one-line badge keeps Astryx's height.
- A2uiCanvas: each surface's grid item may shrink with the canvas
(min-width: 0); a form's inputs held it 24 px past a 320 px viewport.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
… draws light
Composer CSS scoped to [data-astryx-canvas] (Build and Preview). It ships
in the default build's stylesheet.
- Focus: the studio's unlayered :focus-visible ring (#97B063, 2.41:1 on
the canvas white, below SC 1.4.11's 3:1) replaced Astryx's own. Inside
the canvas, revert-layer hands each focused element back to Astryx: its
accent ring on buttons, its accent border on fields (#0064E0, 5.4:1).
Astryx's table scroll region has no indicator of its own, so it gets the
same accent ring, inset because the region bleeds to its card's edge.
- Scheme: Astryx's reset declares `color-scheme: light dark` on the root,
so a reader who prefers dark got Astryx's dark tokens inside the white
canvas, where its primary button is 3.11:1 (SC 1.4.3 needs 4.5:1). The
canvas now draws light, as its white background and the existing note
in this file ("a global dark scheme would silently retint the canvas
surfaces") intend.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
… and fits 320 px
Two composer shell defects on the beta path's Build page; both ship in the
default build, and neither touches a request or a block code path.
- Focus not obscured (SC 2.4.11): Shift+Tab through a block surface at
640 and 320 px left focused fields, buttons and short table regions
entirely under the sticky header (141 and 255 px tall there). The root's
scroll-padding-top now follows the header's measured height, so the
browser scrolls a focused control into view below it.
- Reflow (SC 1.4.10): the Build options row's context select ("auto -
inferred from your goal") made the page 11 px wider than a 320 px
viewport. Each option now wraps under its label and is capped at the
row's width.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
The shared A2uiCanvas change (f5c0ed9) let every surface's grid item shrink with its canvas. The shadcn/ui v3 information-only scan then showed its side effect outside the beta path: a wide shadcn table moved from overflowing the page into shadcn's own table container, which is not keyboard-focusable, so axe reported scrollable-region-focusable even at 1280 px on the 8-column call. shadcn renderer fixes are deferred. So A2uiCanvas is back to main's, and the same rule applies in composer CSS to the Astryx canvas only: [data-astryx-canvas] [data-a2ui-surface] { min-width: 0 }. The Astryx results are unchanged (all pass), and the shadcn scans match main's again (page overflow at 320 px from its wide table; the wireframe Separator chips' contrast). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
…e authorization Docs only. - docs/blocks/ACCESSIBILITY.md (new): what the automated checks prove, each defect found on main and its fix, what this environment could and could not check by hand (no screen reader is installed; the accessibility tree as Chromium exposes it is recorded; keyboard by the test runner, in Chromium only), the checks that still need a person, the waivers proposed to the owner, and the shadcn/ui v3 scans as information. - docs/blocks/BETA.md (new): the beta's known gaps, the auth-form SC 1.3.5 exception first, with its host mitigation (each field's type and autocomplete token by its template id, paste and password managers, host-owned errors and credentials). The rest of this page is a §11 deliverable for the plan's documentation step. - The decision record gains "Step 6, authorized" with the owner's scope in the owner's words; the release plan's status note and docs/BLOCKS.md record that step 6 is built. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
Docs only, and separate from step 6's accessibility work, so it can be split out. When directing step 5's merge (#109), the owner confirmed the field reading of the unmetered rule that BETA-OPERATIONS.md left "the owner's to confirm", and accepted the decision-record wording and the default artifact's minifier-only runtime rename. The decision record quotes the four confirmations in the owner's words under "Step 5, authorized"; BETA-OPERATIONS.md now says the reading is confirmed. The step 6 section's opening now says when the owner authorized it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
dspack-studio-composer | d6b2859 | Oct 17 2026, 04:08 AM |
The independent review of 057606a found defects the spec could not see. These tests catch each one, and fail against that head's build (all 14 Astryx e2e specs; 3 of 13 renderer unit tests): - Content drawn over other content: each Astryx stack's children are checked for overlap. guide-steps' two tables overlapped by 20 px, and every table region by 4 px with the element after it. A contrast node axe leaves undecided because another element in the canvas covers it now fails, instead of being decided from colors. - 400% zoom: 320 x 256 joins 640 x 512 and 320 x 720, with reflow, text spacing, axe and the keyboard pass at each. At 320 x 256 the sticky header hid every focused control (SC 2.4.11), in Build and Preview. The pass starts from script, so a covered canvas fails the check instead of blocking a click. - Text spacing at the narrow sizes: a provider button's label was cut off at 320 px (SC 1.4.12). - Forced colors: a keyboard pass where every stop must carry an outline. Fields showed only the caret. - Every Astryx reference surface in Preview at 1280 px and the narrow sizes: the inline confirmation dialog was cut off at 320 px. - Crushed columns: a header narrower than 90 px fails. - Contrast arithmetic composites a translucent color over what lies beneath it. - Renderer units: h3 (Astryx's body-scale `large`) is not a heading; a display variant without text renders no empty heading; a children-mode table's columns get the same 96 px floor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
…mode column floor
Review findings on the shared Astryx renderers:
- h3 is the profile's projection of Astryx's `large`, which the
contract keeps body text ("Headings are expressed via the display
types ..., never via the rendered element"). It rendered as <h3>; it
is a paragraph again, as on main. h1 and h2, from the display types,
stay headings.
- A display variant without text rendered an empty heading, which a
screen reader announces blank. It renders a paragraph.
- A children-mode table (a model's nested cells; no block uses one)
crushed six columns to 37 px at 320 px. Its header cells get the same
96 px floor as data columns, so it scrolls in its focusable region. In
Chromium's automatic table layout the floor holds: six columns make a
588 px table that scrolls in a 200 px region, where they were 26 to
47 px.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
…is cut off, and fields keep focus in forced colors Review findings, each caught by the new tests: - Table regions overlapped their neighbours. Astryx bleeds a table's scroll region 16 px on every side; main's rule zeroing the vertical bleed matched only the Studio's [data-canvas], never Composer's canvas. guide-steps' two tables overlapped by 20 px, hiding a row behind the next header, and every table region overlapped the element after it by 4 px. The rule now matches [data-astryx-canvas] too. - An inline Astryx dialog (400 px, capped at 90vw) was wider than a 320 px canvas once surfaces narrowed with it: its edge and buttons were cut off. It now fits its container. - Astryx keeps a button's label on one line with an ellipsis. With WCAG's text spacing at 320 px, "Continue with Microsoft" was cut off (SC 1.4.12). Labels wrap. Astryx's height for the button's size is a minimum, and the vertical padding is what one line leaves of it. So a one-line button keeps Astryx's height (32 px, measured), and a wrapped one grows. - In forced colors an Astryx field's focus (an accent border and an inset shadow) disappeared, leaving only the caret. A focused field gets an outline there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
…oll away At 320 x 256 (400% zoom of a 1280 x 1024 window) the sticky header was 255 px tall, its nav wrapped, and it covered the whole viewport: every focused control was hidden under it (WCAG 2.2 SC 2.4.11), in Build and Preview. Under 720 px wide, where the nav wraps, or under 600 px tall, the header is static and scrolls away with the page. The scroll padding that keeps focus clear of the header applies only while the header is sticky. A resize re-checks it, since the header's position can change without its size changing (1280 x 900 sticky, 1280 x 500 static, measured). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
docs/blocks/ACCESSIBILITY.md: - The checks, with exact sizes: 1280 x 900, 640 x 512, 320 x 256 and 320 x 720. Also overlap, forced colors, crushed columns, covered text, and both Preview specs. - The review's fixes, marked "review", and the fail-first counts. - The review's corrections. The table names are 2.4.6, not 4.1.2. The table region had the studio's ring, not none. The first round's sizes were 640 x 450 and 320 x 720. The Studio exhibit gets the renderer changes only, not Composer's canvas CSS or shell. - "Still needs a person" gains TalkBack, desktop-height zoom, text-only zoom, Windows forced colors beyond Chromium's emulation, landscape (1.3.4), speech input (2.5.3), the guide-steps overlap by eye, and Astryx surfaces that are not blocks. - Outside the blocks, for information: axe finds aria-required-children on the plan-comparison reference, unchanged by this step. The release plan's step 6 note and docs/BLOCKS.md name the added checks. Two CSS comments are corrected: the header is over 200 px tall at 320 px wide (223 px measured with a short project name, not a fixed 255), and a table overlaps the elements on both sides of it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
The re-review of 09f4e60 found the spec's "nothing drawn over" claim broader than its checks, and an inline dialog cut off at 320 x 256 that no check saw. These checks close both gaps: - Text, line by line: every line of text in the canvas is sampled across its width and height, after scrolling it into view. It fails when another element in the canvas draws over it, or when a box that does not scroll cuts it off. Text in a table's region may be scrolled out of view, and screen-reader-only text is skipped. It runs with every reflow measurement: 1280 px, every narrow size, and with text spacing at each. - A box other than a table's region that scrolls its own content fails. - Contrast axe leaves undecided is decided at every size and in dark, not only at 1280 px in light. - Preview: the accepted block gets text spacing, axe and the contrast rule at each narrow size. Every Astryx reference surface gets axe, the contrast rule, reflow and text spacing at every size. One violation outside the blocks that predates step 6 is allowed by name: plan-comparison's aria-required-children, recorded in ACCESSIBILITY.md. Against 09f4e60's build, only the reference spec fails: the delete-project dialog at 320 x 256 scrolls its content inside a 108 px box, with and without text spacing, and axe reports scrollable-region-focusable on it. Every block surface passes the new checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
…ule spares icon-only buttons; the header scrolls away while its nav wraps The re-review's findings on 09f4e60: - F1. An inline dialog kept Astryx's 75vh height cap, and so did the Layout inside it, which reads --container-max-height. At 320 x 256 the delete-project dialog showed 108 px of its content in a scroll box of its own. axe flags that box as not keyboard-focusable (scrollable-region-focusable). In the canvas an inline dialog is part of the page, so it now takes its content's height. The new reference checks fail before this and pass after. - F3. The button rule's `height: auto` met Astryx's aspect-ratio on an icon-only button. A clone with Astryx's compiled icon-only classes was 976 x 976 in a stretching column, where Astryx draws it 976 x 32. The rule now applies only to a button named by its visible label. Astryx gives icon-only buttons and custom-content ones an aria-label and sizes them itself. Measured: 976 x 32 in a column, 32 x 32 in a row or a box, as in Astryx. - F4. A label's unbroken word now breaks where it would overflow (overflow-wrap: break-word). A 70-character word fills a full-width button in three lines (204 x 72). `anywhere` was tried and rejected: it let a row of buttons split "Cancel" into "Canc / el" at 320 px. The remainder is a word wider than its whole row, which only a model-written label could hold; it is recorded in ACCESSIBILITY.md. - F5. From 721 to 960 px wide the nav wraps by itself, and the sticky header was up to 325 px tall: 54% of a 601 px window. The header now scrolls away at 960 px wide or less, as well as at 600 px tall or less. Measured with a project open: static to 960 px, with no scroll padding; sticky from 961 px, 135 px tall, with its padding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
docs/blocks/ACCESSIBILITY.md now claims what the checks prove: - the line-by-line text check; - the scroll-box check; - undecided contrast at every size and in dark; - Preview's subset of checks, stated exactly; - the one violation outside the blocks, allowed by name in the reference spec. It records the detection evidence: each injected defect caught. It also records the second review's fixes, marked "second review": the dialog's height, word breaks in labels, icon-only buttons spared, and the header static to 960 px. "Still needs a person" gains: - listening to long and shared table-region names; - Windows high contrast in a dark theme too; - focus indicators with motion on; - the shell at tablet and 721 to 1000 px sizes; - the Studio exhibit's heading outline. "Outside the blocks" records the one residual from the label fix: a model-written word wider than its whole row of buttons. The release plan's step 6 note names the line-by-line check and the dialog fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
The verification of 0af44ba found gaps in the text check, and two defects outside the blocks that no check reached: - The text check now brings every line of a text to the middle of the window before sampling it. At 320 x 256 a tall cell's lines had run past the window unsampled: 487 of guide-steps' 940 lines. It also hit-tests every element in the canvas, so a cover that ignores the pointer no longer escapes. Neither change fails a block or reference surface. - A new Preview spec imports two model-shaped surfaces the blocks never produce, under the same renderers and canvas rules. The first holds a standard, a fullscreen and an alert dialog with long labels. The second holds a children-mode table, Astryx's large type and display text with no words. Each is checked at every size with layout, text spacing, axe and the contrast rule; the second's headings are checked too. Against 0af44ba's build only the new spec fails, with two defects: - At 320 x 256 the fullscreen dialog keeps Astryx's 100dvh height and cuts its content off, and the next dialog draws over the overflow. - With text spacing at 640 x 512 and 320 x 720, the alert dialog's footer cuts off "Keep my archived projects". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
The overlap check compared neighbours in a horizontal stack by their edges alone. A row that wraps puts the next item on the line below, to the left of the first one's right edge. That read as an overlap: a false failure of 114 px once a dialog's footer row wraps, which the next commit makes it do. Neighbours now overlap only where their boxes intersect, in either direction. Detection holds. With Astryx's 16 px vertical table bleed injected again into guide-steps, the check reports the original 4, 20 and 4 px overlaps; without it, none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
…ooter's buttons wrap The verification of 0af44ba: - N1. A fullscreen inline dialog kept Astryx's 100dvh height. At 320 x 256 it cut its own content off, and the next dialog drew over the overflow. A canvas dialog's height is now its content's (`height: auto`), as for the height cap before. Standard and alert dialogs measure as they did. - F4, the rest. An alert dialog's two long labels were each narrower than its footer but too wide together. With WCAG's text spacing at 640 x 512 and 320 x 720, "Keep my archived projects" was cut off. Astryx's footer row now wraps, so each button takes a row of its own when they do not fit. At 320 px the delete-project dialog shows "Cancel" and then "Delete project", each whole; at 640 px they still sit side by side. The spec that failed for both now passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
docs/blocks/ACCESSIBILITY.md now records the verification round: - The text check scrolls every line into view and hit-tests every element, even one that ignores the pointer. It caught a cover over the last two lines of a 2,529 px cell at 320 x 256, and a cover with pointer-events: none. The check before the verification missed both; the record says so. - Neighbours overlap only where their boxes intersect. - A new spec imports model-shaped surfaces the blocks never produce: dialogs, a children-mode table, Astryx's large type and empty display text. - The dialog row in "What changed" gains two fixes, marked "verification": a fullscreen dialog's viewport height, and footer buttons that wrap. "Outside the blocks" narrows the label residual: a row of buttons outside a dialog's footer whose longest words together are wider than it. It also records the button rule's two latent edges: an icon-only button with an empty label, and a labelled button while it loads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 2 step 6 (docs/blocks/PHASE-2-RELEASE-PLAN.md, §10), as the owner authorized it on 2026-10-16: accessibility hardening for the Astryx beta path, to WCAG 2.2 AA. Not for automatic merge. No deploy, no Cloudflare change, no paid model call.
What it adds
Automated coverage (
e2e/composer-blocks-a11y.spec.ts, in the experimental config that CI runs). Each Astryx block (records-table, auth-form and guide-steps) is built through the hosted path with a stubbed gateway, so no model is called. Each is built from four calls: the approved example, the smallest valid call, every optional prop at its maximum, and the same with unbroken tokens.Every surface is checked at 1280 x 900, at 640 x 512 and 320 x 256 (200% and 400% zoom of a 1280 x 1024 window), and at 320 x 720:
axe with
wcag2a,wcag2aa,wcag21a,wcag21aaandwcag22aaover the whole canvas, with nothing excluded, at every size and with a dark preference. Contrast that axe leaves undecided is decided from computed colors, compositing a translucent color over what lies beneath it. Text that another element covers fails.Structure: the title is the surface's one level-2 heading, and each table region is named by its columns.
Keyboard:
Layout:
A data table scrolls only inside its own focusable region.
Two specs check Preview. One covers an accepted block: heading, axe and focus ring, plus layout, text spacing, axe and keyboard at the narrow sizes. The other covers every Astryx reference surface's axe, layout and text spacing at every size. It allows one pre-existing violation outside the blocks, by name. A third imports two model-shaped surfaces the blocks never produce (inline dialogs, a children-mode table, Astryx's
largetype, empty display text) and checks them the same way. Checks are soft, so one run lists every defect.apps/composer/app/astryx-renderers-a11y.test.tsserver-renders the Astryx renderers. The shadcn/ui v3 scans run for information only and never fail.Fixes. Each failed first; details and file references are in
docs/blocks/ACCESSIBILITY.md. Rows marked (review) came from the first independent review, (second review) from the second, and (verification) from its verification.<p>: no headingslarge(review). A variant without text is never an empty heading (review)Docs.
docs/blocks/ACCESSIBILITY.md(new) covers:docs/blocks/BETA.md(new): the beta's known gaps, the auth-form SC 1.3.5 exception first, with its host mitigation.docs/BLOCKS.mdrecord that step 6 is built.Production-visible changes
These fixes are in shared code, so the default build carries them too:
packages/astryx-renderers(Text, Table, Badge): every Astryx surface in production's Preview, and the Studio exhibit. The exhibit gets only these, not Composer's CSS or shell.apps/composer/app/globals.css, scoped to[data-astryx-canvas]:af-ui.css).composer.tsx).build-view.tsx).They change no request byte, no
/api/modelsreply and no block code path. The default artifact still carries none ofcheck-default-artifact's markers. They change the default artifact's bytes, by design; the comparison is below. If the owner prefers, the shell changes (709725f, ec1a3e9, and the header rule in a6ffba4) can be split out.Boundaries kept
A2uiCanvas, but the shadcn information scan showed it would move a wide shadcn table into a container shadcn does not make focusable. So 7aa423c revertsA2uiCanvasand scopes the rule to the Astryx canvas.Not changed, with reasons.
aria-required-children. It is not a block, and it predates this step. It is recorded in ACCESSIBILITY.md, for a separate change.Commits
A2uiCanvasback to main's)Evidence
Fail-first.
Against main (d7251db): the renderer tests failed 8 of 10; the two that passed guard what must not change. The e2e failed all 13 Astryx specs, and the 6 shadcn scans passed, as information.
After the first fixes: the 320 px reflow check still failed on the 8-column call (crushed columns), and the added dark pass failed 9 of 12 surfaces. The column-floor unit test failed before its fix.
The review's findings, against 057606a's build: the new checks failed all 14 Astryx specs:
3 of 13 renderer tests failed. All pass after the fixes.
The second review's findings, against 09f4e60's build: the strengthened checks failed only the reference spec. The delete-project dialog at 320 x 256 scrolled its content in a box of its own, with and without text spacing, and axe reported
scrollable-region-focusableon it.The verification's findings, against 0af44ba's build: the new beyond-the-blocks spec failed.
The text check finds what it claims. With defects injected into the page, it caught each of these, and reported nothing on the clean page:
The check before the verification missed the last two.
The overlap check still catches the original defect. With Astryx's vertical table bleed injected again, it reports the original 4, 20 and 4 px overlaps.
Suites.
rediscover > restoredConflictfails, at 5401 ms against its 5000 ms limit. It times out locally in every run; CI passes it, and this change does not touch apps/agent.check-default-artifact: 29 files clean of 15 markers. So do the experimental build, the beta deploy check and the web build.test(run 39001296397) passed at 04:17:18Z, and Workers Builds' preview build of the branch passed.Production unchanged where it must be.
hosted-build.test.tspasses, and/api/modelsis pinned byte for byte byblocks-beta.test.mjs; both are in the composer unit run above. No request builder, Worker, sidecar or block code changed.index.txt: Next's per-build ids and asset names only;[data-astryx-canvas]rules and the header rule;TableRendernow imports Astryx's ownproportional();E_2CpGYfe1p1n1xjWkdjJwith main's CSS and runtime: checked at 04:21:42Z, after the last push's preview build and CI. Each push's Workers Builds run is a preview build of the branch.Independent accessibility review.
The first review, of 057606a, found two blocking findings: the guide-steps table overlap, and focus hidden at 320 x 256. It also found four should-fix findings (dialog clipping,
largeas h3, button labels under text spacing, forced-colors field focus), nits, and gaps in the list of checks that need a person. All are addressed above, except the two left as they are, with reasons.The second review, of 09f4e60, found nothing blocking in the three blocks, and confirmed five of the first review's six findings fixed. Its should-fix findings:
Its nits: F3 icon-only buttons, F4 long words in labels, F5 a tall sticky header from 721 to 960 px, and F6 doc wording. All are addressed above; the F4 remainder is recorded.
The verification of 0af44ba confirmed:
It found the three blocks ready for the owner's decision, apart from the checks that need a person. It asked for three things, all done in d6b2859:
N3, covers that ignore the pointer, is fixed too, and N4 is recorded.
The final check of d6b2859 found it ready for the owner's decision on the three blocks, apart from the checks that need a person.
Still needs a person
No screen reader is installed here, and Chromium is the only browser: no NVDA, VoiceOver or TalkBack pass was done, and none is claimed. Still needed (ACCESSIBILITY.md has the detail):
Proposed waivers (for the owner)
docs/blocks/BETA.md). GA stays blocked.🤖 Generated with Claude Code
https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi