================================================================================ GATE 6 — DESIGN CONSISTENCY AUDIT (node W15_gate_design_consistency_audit) Repo: oms-web (Next.js 14 / Tailwind 3 / Prisma+Postgres, standalone) Branch: feat/3250-oms-ui-bug-fixes-chips-s HEAD: 2fa4249 "4. Dead Code (oms-bug-fixes)" Gate: gates/nextjs-tailwind-standalone/design-consistency-audit-gate.md Ticket: #3250 Result: FAIL — 3 unresolved P1 findings (all [accessibility]; WCAG blockers) 4 findings auto-fixed and re-verified (see "AUTO-FIXES APPLIED") ================================================================================ FEATURE FILES AUDITED (12) app/(app)/admin/items/page.tsx app/(app)/admin/projects/page.tsx app/(app)/admin/suppliers/page.tsx app/(app)/admin/uom/page.tsx app/(app)/admin/users/page.tsx app/(app)/expense-summary/[project]/page.tsx app/(app)/expense-summary/page.tsx app/(app)/expense-summary/ExpenseSummaryRowActions.tsx app/(app)/expenses/page.tsx app/(app)/orders/page.tsx components/forms/ExpenseForm.tsx components/forms/ResetPasswordForm.tsx Shared components the feature files render through, read as supporting evidence and cited where a finding's root cause lives there (three of them are also where an auto-fix landed): tailwind.config.ts, app/globals.css, components/ui/{DataTable,StatusBadge,RowActions,RepeaterTable,Toast,table}.tsx, components/ui/icons/SortIcon.tsx, components/ui/fields/{DatePicker,Listbox,TextField,SelectField}.tsx, components/ui/FilterBar.tsx, app/(app)/expenses/ExpenseRowActions.tsx. -------------------------------------------------------------------------------- SKILL RESOLUTION (gate file "Resolution order", per-skill, as required) -------------------------------------------------------------------------------- No slash-command layer was available for either skill, so resolution-order steps 1 and 2 were both unavailable. Both skills resolved via step 3 — read as FILES, and followed directly. Neither was skipped or degraded. As already recorded by Gate 5 (W14), the gate file's stated skill path (.claude/skills/nextjs-tailwind-/SKILL.md) does not exist in this checkout; the real location is one level up, outside the repo: 1. nextjs-tailwind-design-system-audit .... step 3 (file) OK, fully readable /opt/drcarrot-deploy/cross-repo-orchestration/skills/ nextjs-tailwind-design-system-audit/SKILL.md 2. nextjs-tailwind-accessibility-audit .... step 3 (file) OK, fully readable /opt/drcarrot-deploy/cross-repo-orchestration/skills/ nextjs-tailwind-accessibility-audit/SKILL.md -------------------------------------------------------------------------------- DESIGN-SPEC INPUT — RESOLVED, WITH A CAVEAT -------------------------------------------------------------------------------- The node input names the design spec as `docs/specs/ticket-3250-design.md`. That file DOES NOT EXIST in this checkout — `docs/specs/` contains only ticket-3239-design.md and ticket-3248-design.md, and `grep -rn 3250 --include=*.md` over the whole repo returns nothing. (Gate 5 recorded the same absence.) The audit was NOT run blind: the design_spec node input carried the spec's full substance inline (views, form fields, unmapped tokens, R1–R6 findings), and the underlying design bundle it was decoded from is present on disk (/tmp/design_template.html, 128767 bytes, and the /tmp/dev-hub-spec-*.html family). Token claims below were checked against tailwind.config.ts, which itself carries per-token provenance comments back to those bundles. Consequence: this gate could verify "does the code use the tokens the spec says exist" and "are the same visual concepts implemented consistently". It could NOT re-derive measured pixel values from the design, because there is no committed spec artifact to diff against. That is a process gap worth closing before Gate 7 (responsive), not a defect in this branch's code. -------------------------------------------------------------------------------- COMMANDS ACTUALLY RUN (real output, not predicted) -------------------------------------------------------------------------------- 1. Repo's own lint, before any change: npx next lint --dir app --dir components -> "✔ No ESLint warnings or errors" 2. Which a11y rules that lint actually enforces (the reason 1. proves little): npx eslint --print-config components/forms/ExpenseForm.tsx -> jsx-a11y rules enabled: 6 of ~35 alt-text, aria-props, aria-proptypes, aria-unsupported-elements, role-has-required-aria-props, role-supports-aria-props eslint-plugin-jsx-a11y 6.10.2 is installed (via eslint-config-next), so the remaining rules are available but off under next/core-web-vitals. 3. Expanded jsx-a11y sweep over the 12 feature files (15 additional rules: label-has-associated-control, control-has-associated-label, click-events-have-key-events, no-static-element-interactions, no-noninteractive-element-interactions, interactive-supports-focus, anchor-is-valid, anchor-has-content, heading-has-content, no-redundant-roles, tabindex-no-positive, mouse-events-have-key-events, no-noninteractive-tabindex, scope, aria-activedescendant-has-tabindex): components/forms/ExpenseForm.tsx:135 control-has-associated-label components/forms/ExpenseForm.tsx:177 control-has-associated-label components/forms/ExpenseForm.tsx:269 control-has-associated-label components/forms/ResetPasswordForm.tsx:55 control-has-associated-label 4 problems Triaged by hand against the source: :135 TRUE POSITIVE -> finding A11Y-6 below. :177 false positive -> the is WRAPPED by the