Round #32Score 4/5Finance

A bank form exposed an ARIA bug that every generic demo had hidden

Route: /transfer
Desktop preview
Mobile preview

Captured at a 375px viewport. Long pages scroll inside the frame.

The screenshots stay in Japanese. Every round is a real screen for a real Japanese industry, so an English re-render would no longer be the screen the agent actually produced.

Write-up

A bank form exposed an ARIA bug that every generic demo had hidden

⁠Build log series⁠: I hand a real screen to an AI that has never seen Gunjo (@gunjo/ui) and let it build. This round, at a reader's suggestion, took on an industry-specific screen: a ⁠Japanese online-banking transfer flow⁠ (source account, recipient, amount, confirmation, identity check, result).

Same setup as always: only the shipped npm package and the docs site, no source access. Digit-grouped amounts, masked account numbers, balance checks, identity verification: finance-specific constraints never come up on generic screens.

Result: 4/5

tsc and build passed, the console stayed clear, I verified 375px and desktop, and every field's error state was wired up through ARIA.

The star this round: a strict banking form flushed out a hidden accessibility bug

The form system built across and (FormField and FormControl wiring ids and aria automatically) was certified as "real" by 's agent. ⁠Two rounds later, the bank form produced an actual bug⁠:

🔴 FormControl injects aria-describedby="...-description" even on fields that have no FormDescription, pointing at an id that does not exist. That is an ARIA bug axe (the accessibility checker) rejects.

A transfer form is full of ⁠fields with no description text⁠ (bank name, branch name, account type). A generic demo that dutifully gives every field a description ⁠can never trigger this defect⁠. It took a banking screen, an industry pattern made of description-less fields, to expose it.

The fix (issue #175, landed in the same PR)

FormField now checks whether a FormDescription child actually exists and ⁠reserves the description id only when it does⁠. Without one, the shared state is undefined and FormControl drops the attribute. The decision happens at render time, so it is safe under server rendering and hydration. ⁠Verified in a browser⁠: the three description-less controls in the docs now show aria-describedby: null, zero dangling references.

Industry-specific screens surface a different layer of gaps

The reader's instinct was right. Gaps that never appeared on generic screens (settings, ecommerce, dashboards) poured out of a banking form:

  • 🟠 ⁠No amount-input component.⁠ NumberInput is an <input type=number>, so it cannot express 1,000,000 with digit grouping. No yen prefix, no locale handling. It is front and center on every ecommerce, billing, and banking screen, and it got hand-rolled (issue #176, the biggest gap, headed to Codex).
  • 🟠 No masked-display component for account numbers (ordinary ****1234, the account type plus a masked number; issue #177), and no DescriptionList for the confirmation summary (issue #178).
  • 🟠 The Stepper still is not interactive (issue #157 reconfirmed), and there is no validation state layer (issue #166 reconfirmed).

The foundation still held: the compounding continues

What the agent singled out for praise was, once again, ⁠the fixes from earlier rounds⁠:

  • ⁠Form and FormField were the standout⁠: "zero hand-written ARIA on the wired fields. Four invalid states each connect to their role=alert through describedby."
  • ⁠Select label (issue #164), RadioGroupItem label (issue #162), CardTitle and AlertTitle as (issues #116 and #163), StatusScreen headingLevel (issue #104), and PasswordInput⁠ (which keeps the PIN out of the accessibility tree) all drew praise.
  • Dark mode inverted automatically (bg-card from white to rgb(2,8,23)).

What I took away

Generic demos: every field carries a description, so the bug stays hidden
Industry screen (banking): description-less fields everywhere, so the hidden bug surfaces

⁠Change the industry and a different face of the code gets tested.⁠ My overview post claims the system "covers the hard twenty percent". Rather than asserting that, I get to prove it one piece at a time, like this.

Next up: build log

  • ⁠Another industry⁠: an insurance or medical form, logistics tracking, or a POS. The more the industry changes, the more gaps fall out.

The run

Gunjo was still in early alpha at the time; issues are welcome.

This series is co-created with AI (Claude and Codex). A human designs the experiments, makes the calls, and fact-checks before publishing; the AI does the hands-on work and drafting.

Components from @gunjo/ui

The components this screen's source imports directly.

The code the agent actually wrote

Click a file to expand its source.

業界別「AI指示書パック」、先行登録を受付中です。