Round #30Score 4.5/5Foundation / generic UI

The next cold agent recognized the new FormField system as real

Route: /account

Write-up

The next cold agent recognized the new FormField system as real

⁠Build log series⁠: I hand a real screen to an AI that has never seen Gunjo (@gunjo/ui) and let it build. This round covered an ⁠account and workspace settings hub⁠ with Profile, Security, Team, Notifications, Billing, and a dangerous-actions section.

The agent received the shipped npm package and docs site, with no source access. The assignment was a GitHub or Stripe-style multisection settings area with a validated, savable form in each section, a team table, an invitation dialog, and a dangerous action that required typing the workspace name to confirm.

Result: 4.5/5

The screen cleared tsc and build with no console or hydration errors. ⁠The page had exactly one h1, preserved heading order, connected every form error through ARIA, and collapsed section navigation into a Select at 375px.⁠

The main result: the form system built after proved itself

⁠Round found that Form was only presentational and provided no form system, so I built and shipped the shared FormField state from issue #152.⁠ In the ⁠very next round, a different cold agent found that implementation and recognized it as a complete system:⁠

⁠Assessment: this is a real form, validation, and accessibility system, not a wrapper.⁠ The agent found FormFieldContext and useFormField() in the TypeScript source, then verified the automatic wiring in a browser. Passing error and required to FormField made FormLabel supply htmlFor, FormControl inject id, aria-invalid, and aria-describedby, FormMessage use role="alert", and the input show a red border.

The agent also verified ⁠the PasswordInput fix from issue #153 in :⁠ the ARIA attributes injected by FormControl reached the inner input, where the old wrapper behavior could easily have swallowed them.

⁠A defect surfaced in , the implementation changed in issues #152 and #153, and a different agent verified the result in #30.⁠ The fix-and-retest loop had advanced from validating small repairs to ⁠validating a newly built higher-level component.⁠

Why it stopped at 4.5, and what I fixed this round

The remaining issues were consistency in accessibility and minor layout friction, not overall quality:

  • Issue #162:⁠ RadioGroupItem had no label even though Switch and Checkbox did. I added label and description.
  • Issue #163:⁠ AlertTitle hard-coded <h5>. I added as, following the pattern from issue #116.
  • Issue #164:⁠ Select had no label. I added one along with FormControl integration.
  • Issue #165:⁠ vertical Tabs could not form a left rail because the component forced a bordered card and a horizontal row. I added a data-[orientation=vertical] variant that produces ⁠a left rail without custom class overrides.⁠ A browser check confirmed flex-direction: column in vertical mode.

All four shipped as backward-compatible source changes. The central remaining work was ⁠the validation and state-management layer for Form in issue #166: issue #152 completed the accessibility half, leaving the other half.

What I took away: higher-level components multiply the payoff

#1 through #28: small component fixes become strengths on the next screen
#29 and #30: a new coordination component, the form system, is recognized as complete on the next screen

⁠A cold agent can immediately verify an investment in the coordination layer, not just individual controls.⁠ This session also caught a missing "use client" directive after useId was added to Select. ⁠A clean build exposed it before the change shipped.⁠

Next up: build log

  • ⁠An error page, notification and toast flow, or search filters.⁠

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.

The code the agent actually wrote

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