hatch3r 1.7.0 → 1.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/README.md +38 -12
  2. package/agents/hatch3r-a11y-auditor.md +4 -0
  3. package/agents/hatch3r-architect.md +5 -1
  4. package/agents/hatch3r-ci-watcher.md +4 -0
  5. package/agents/hatch3r-context-rules.md +4 -0
  6. package/agents/hatch3r-creator.md +4 -0
  7. package/agents/hatch3r-dependency-auditor.md +4 -0
  8. package/agents/hatch3r-devops.md +4 -0
  9. package/agents/hatch3r-docs-writer.md +4 -0
  10. package/agents/hatch3r-fixer.md +5 -1
  11. package/agents/hatch3r-handoff-loader.md +243 -0
  12. package/agents/hatch3r-handoff-preparer.md +134 -0
  13. package/agents/hatch3r-implementer.md +5 -1
  14. package/agents/hatch3r-learnings-loader.md +4 -0
  15. package/agents/hatch3r-lint-fixer.md +4 -0
  16. package/agents/hatch3r-perf-profiler.md +8 -0
  17. package/agents/hatch3r-researcher.md +5 -1
  18. package/agents/hatch3r-reviewer.md +92 -0
  19. package/agents/hatch3r-security-auditor.md +24 -0
  20. package/agents/hatch3r-test-writer.md +4 -0
  21. package/agents/modes/requirements-elicitation.md +5 -1
  22. package/agents/modes/similar-implementation.md +6 -0
  23. package/agents/modes/user-flows.md +76 -0
  24. package/agents/shared/quality-charter.md +129 -0
  25. package/agents/shared/user-question-protocol.md +95 -0
  26. package/commands/board/shared-azure-devops.md +2 -0
  27. package/commands/board/shared-github.md +17 -0
  28. package/commands/board/shared-gitlab.md +4 -0
  29. package/commands/hatch3r-board-fill.md +2 -1
  30. package/commands/hatch3r-board-pickup.md +1 -1
  31. package/commands/hatch3r-board-shared.md +21 -0
  32. package/commands/hatch3r-create.md +2 -0
  33. package/commands/hatch3r-handoff.md +126 -0
  34. package/commands/hatch3r-pr-resolve.md +672 -0
  35. package/commands/hatch3r-quick-change.md +5 -3
  36. package/commands/hatch3r-report.md +167 -0
  37. package/commands/hatch3r-revision.md +1 -1
  38. package/commands/hatch3r-workflow.md +3 -1
  39. package/dist/cli/index.js +3144 -979
  40. package/dist/cli/index.js.map +1 -1
  41. package/package.json +4 -2
  42. package/rules/hatch3r-accessibility-standards.md +21 -0
  43. package/rules/hatch3r-accessibility-standards.mdc +21 -0
  44. package/rules/hatch3r-agent-orchestration.md +32 -1
  45. package/rules/hatch3r-agent-orchestration.mdc +32 -1
  46. package/rules/hatch3r-ai-evals.md +158 -0
  47. package/rules/hatch3r-ai-evals.mdc +154 -0
  48. package/rules/hatch3r-ai-ux-patterns.md +131 -0
  49. package/rules/hatch3r-ai-ux-patterns.mdc +127 -0
  50. package/rules/hatch3r-api-design.md +67 -9
  51. package/rules/hatch3r-api-design.mdc +67 -9
  52. package/rules/hatch3r-api-versioning.md +119 -0
  53. package/rules/hatch3r-api-versioning.mdc +115 -0
  54. package/rules/hatch3r-auth-patterns.md +170 -0
  55. package/rules/hatch3r-auth-patterns.mdc +166 -0
  56. package/rules/hatch3r-component-conventions.md +30 -0
  57. package/rules/hatch3r-component-conventions.mdc +30 -0
  58. package/rules/hatch3r-container-hardening.md +131 -0
  59. package/rules/hatch3r-container-hardening.mdc +127 -0
  60. package/rules/hatch3r-contract-testing.md +117 -0
  61. package/rules/hatch3r-contract-testing.mdc +113 -0
  62. package/rules/hatch3r-deep-context.md +3 -1
  63. package/rules/hatch3r-deep-context.mdc +3 -1
  64. package/rules/hatch3r-dependency-management.md +73 -1
  65. package/rules/hatch3r-dependency-management.mdc +72 -0
  66. package/rules/hatch3r-design-system-detection.md +142 -0
  67. package/rules/hatch3r-design-system-detection.mdc +138 -0
  68. package/rules/hatch3r-event-schema-evolution.md +90 -0
  69. package/rules/hatch3r-event-schema-evolution.mdc +86 -0
  70. package/rules/hatch3r-handoff-readiness.md +45 -0
  71. package/rules/hatch3r-handoff-readiness.mdc +40 -0
  72. package/rules/hatch3r-i18n.md +13 -0
  73. package/rules/hatch3r-i18n.mdc +13 -0
  74. package/rules/hatch3r-iteration-summary.md +2 -0
  75. package/rules/hatch3r-iteration-summary.mdc +2 -0
  76. package/rules/hatch3r-migrations.md +61 -16
  77. package/rules/hatch3r-migrations.mdc +61 -16
  78. package/rules/hatch3r-observability-logging.md +1 -1
  79. package/rules/hatch3r-observability-logging.mdc +1 -1
  80. package/rules/hatch3r-observability-metrics.md +1 -1
  81. package/rules/hatch3r-observability-metrics.mdc +1 -1
  82. package/rules/hatch3r-observability-tracing-detail.md +1 -1
  83. package/rules/hatch3r-observability-tracing-detail.mdc +1 -1
  84. package/rules/hatch3r-observability-tracing.md +1 -1
  85. package/rules/hatch3r-observability-tracing.mdc +1 -1
  86. package/rules/hatch3r-observability.md +1 -0
  87. package/rules/hatch3r-observability.mdc +1 -0
  88. package/rules/hatch3r-operability.md +149 -0
  89. package/rules/hatch3r-operability.mdc +145 -0
  90. package/rules/hatch3r-passkey-server.md +181 -0
  91. package/rules/hatch3r-passkey-server.mdc +177 -0
  92. package/rules/hatch3r-progressive-delivery.md +120 -0
  93. package/rules/hatch3r-progressive-delivery.mdc +116 -0
  94. package/rules/hatch3r-resilience-patterns.md +154 -0
  95. package/rules/hatch3r-resilience-patterns.mdc +150 -0
  96. package/rules/hatch3r-secrets-management.md +29 -0
  97. package/rules/hatch3r-secrets-management.mdc +29 -0
  98. package/rules/hatch3r-testing.md +139 -43
  99. package/rules/hatch3r-testing.mdc +139 -43
  100. package/rules/hatch3r-ux-states-and-flows.md +149 -0
  101. package/rules/hatch3r-ux-states-and-flows.mdc +145 -0
  102. package/skills/hatch3r-a11y-audit/SKILL.md +14 -0
  103. package/skills/hatch3r-ai-feature/SKILL.md +134 -0
  104. package/skills/hatch3r-api-spec/SKILL.md +5 -0
  105. package/skills/hatch3r-architecture-review/SKILL.md +14 -0
  106. package/skills/hatch3r-bug-fix/SKILL.md +5 -0
  107. package/skills/hatch3r-ci-pipeline/SKILL.md +14 -0
  108. package/skills/hatch3r-cli-aichat/SKILL.md +84 -0
  109. package/skills/hatch3r-cli-ast-grep/SKILL.md +85 -0
  110. package/skills/hatch3r-cli-az-devops/SKILL.md +89 -0
  111. package/skills/hatch3r-cli-bat/SKILL.md +85 -0
  112. package/skills/hatch3r-cli-comby/SKILL.md +85 -0
  113. package/skills/hatch3r-cli-csvkit/SKILL.md +84 -0
  114. package/skills/hatch3r-cli-delta/SKILL.md +86 -0
  115. package/skills/hatch3r-cli-difftastic/SKILL.md +84 -0
  116. package/skills/hatch3r-cli-docker/SKILL.md +89 -0
  117. package/skills/hatch3r-cli-duckdb/SKILL.md +84 -0
  118. package/skills/hatch3r-cli-fd/SKILL.md +85 -0
  119. package/skills/hatch3r-cli-fzf/SKILL.md +84 -0
  120. package/skills/hatch3r-cli-gh/SKILL.md +90 -0
  121. package/skills/hatch3r-cli-glab/SKILL.md +89 -0
  122. package/skills/hatch3r-cli-jq/SKILL.md +85 -0
  123. package/skills/hatch3r-cli-lazygit/SKILL.md +78 -0
  124. package/skills/hatch3r-cli-llm/SKILL.md +84 -0
  125. package/skills/hatch3r-cli-miller/SKILL.md +84 -0
  126. package/skills/hatch3r-cli-mods/SKILL.md +84 -0
  127. package/skills/hatch3r-cli-overview/SKILL.md +60 -0
  128. package/skills/hatch3r-cli-playwright/SKILL.md +89 -0
  129. package/skills/hatch3r-cli-podman/SKILL.md +84 -0
  130. package/skills/hatch3r-cli-ripgrep/SKILL.md +85 -0
  131. package/skills/hatch3r-cli-rtk/SKILL.md +91 -0
  132. package/skills/hatch3r-cli-sd/SKILL.md +85 -0
  133. package/skills/hatch3r-cli-stagehand/SKILL.md +79 -0
  134. package/skills/hatch3r-cli-taplo/SKILL.md +84 -0
  135. package/skills/hatch3r-cli-xsv/SKILL.md +89 -0
  136. package/skills/hatch3r-cli-yq/SKILL.md +85 -0
  137. package/skills/hatch3r-cli-zstd/SKILL.md +85 -0
  138. package/skills/hatch3r-context-health/SKILL.md +14 -0
  139. package/skills/hatch3r-cost-tracking/SKILL.md +14 -0
  140. package/skills/hatch3r-customize/SKILL.md +14 -0
  141. package/skills/hatch3r-dep-audit/SKILL.md +14 -0
  142. package/skills/hatch3r-design-system-detect/SKILL.md +162 -0
  143. package/skills/hatch3r-feature/SKILL.md +2 -0
  144. package/skills/hatch3r-gh-agentic-workflows/SKILL.md +13 -0
  145. package/skills/hatch3r-handoff-prepare/SKILL.md +160 -0
  146. package/skills/hatch3r-handoff-resume/SKILL.md +171 -0
  147. package/skills/hatch3r-incident-response/SKILL.md +14 -0
  148. package/skills/hatch3r-issue-workflow/SKILL.md +5 -0
  149. package/skills/hatch3r-logical-refactor/SKILL.md +14 -0
  150. package/skills/hatch3r-migration/SKILL.md +14 -0
  151. package/skills/hatch3r-observability-verify/SKILL.md +133 -0
  152. package/skills/hatch3r-perf-audit/SKILL.md +14 -0
  153. package/skills/hatch3r-pr-creation/SKILL.md +14 -0
  154. package/skills/hatch3r-qa-validation/SKILL.md +18 -0
  155. package/skills/hatch3r-recipe/SKILL.md +14 -0
  156. package/skills/hatch3r-refactor/SKILL.md +14 -0
  157. package/skills/hatch3r-release/SKILL.md +14 -0
  158. package/skills/hatch3r-reliability-verify/SKILL.md +144 -0
  159. package/skills/hatch3r-ui-ux-verify/SKILL.md +136 -0
  160. package/skills/hatch3r-visual-refactor/SKILL.md +15 -1
@@ -0,0 +1,149 @@
1
+ ---
2
+ id: hatch3r-ux-states-and-flows
3
+ type: rule
4
+ description: Four-state surface contract (loading/empty/error/partial), user-flow decomposition before implementation, and microcopy + tone discipline for end-user UIs
5
+ scope: "**/*.vue,**/*.jsx,**/*.tsx,**/*.svelte,**/components/**,**/*.html,**/messages/**,**/locales/**,**/copy/**"
6
+ tags: [ux, ui, frontend]
7
+ quality_charter: agents/shared/quality-charter.md
8
+ cache_friendly: true
9
+ ---
10
+ # UX States and Flows
11
+
12
+ ## User-Flow Decomposition (Mandatory Before Implementation)
13
+
14
+ Every user story produces three explicit flows before any UI code is written. Skipping this step is a regression — the implementer rejects specs lacking flow decomposition.
15
+
16
+ 1. **Happy Path** — numbered sequence of user actions paired with system responses and decision points covering the success route end-to-end. Includes entry point (route, prior screen, deep link), authentication state assumed, and exit point (resulting state, next screen).
17
+ 2. **Alternative Paths** — every documented branch (filters applied, multi-step forms, optional sections, permission tiers, locale variants). Each branch is numbered and references the decision point in the Happy Path where it diverges. Re-converges named.
18
+ 3. **Error-Recovery Path** — what the user does when a step fails (network drop, validation failure, expired session, permission denied, server outage, conflict on concurrent edit). Names the recovery action (retry, undo, refresh credential, contact support, drop changes) at every failure point.
19
+
20
+ Each flow is a numbered list with three columns: user action, system response, decision/branch. Reference `agents/modes/user-flows.md` for the canonical template. A flow is incomplete if any documented decision point has no specified branch outcome. The implementer treats acceptance criteria as a downstream artifact of the flow set — flows come first, criteria are derived.
21
+
22
+ Flow decomposition is also the contract between the feature designer and the reviewer: the reviewer walks every flow during code review and asserts each numbered step maps to a code path. A code path with no flow step is dead code or undocumented surface; a flow step with no code path is a missing implementation.
23
+
24
+ ## Four-State Surface Contract
25
+
26
+ Every async view renders all four states. Missing any state on an async view is a blocker — NN/g 2025 measured 92% of AI-generated dashboards omit empty state and 78% omit error state, so this is the regression bar to beat.
27
+
28
+ | State | Trigger | Rendering rules |
29
+ |-------|---------|-----------------|
30
+ | Loading | Request in flight >300ms | Skeleton matches final content dimensions (explicit width/height) to keep CLS <=0.1; spinner only for short modal actions <500ms; loading state announced via `aria-busy="true"` on the container |
31
+ | Empty | Successful response, 0 results | Distinguish three sub-types below: cold start, active filter, no permission. Each has a distinct heading, visual cue, and CTA |
32
+ | Error | Network failure, server error, validation failure | Plain-language cause + retry CTA + fallback or contact path; no "Oops" or "Something went wrong" — corrective verb required; render in `role="alert"` for assistive tech announcement |
33
+ | Partial | Some data succeeded, some failed | Banner naming the failed subset + degraded data rendered for the succeeded subset + retry option for the failed subset; never silently drop the failed subset |
34
+
35
+ State machines drive these transitions — model the view as `idle | loading | success | empty | error | partial` and assert every state has a render path in the component. Snapshot every state in tests (Storybook play function or vitest + Testing Library): missing snapshots are blockers.
36
+
37
+ Transitions between states have their own rules. Loading -> success swaps the skeleton for content without layout shift (the skeleton was already the final dimensions). Loading -> error replaces the skeleton with the error surface and announces it via `role="alert"`. Loading -> empty replaces the skeleton with the sub-typed empty surface (cold / filter / permission). Success -> partial overlays the banner without re-rendering the succeeded subset. Every transition has a measurable duration and an announcement strategy — never silent.
38
+
39
+ ## First-Run vs Filter vs Network — Content Structure
40
+
41
+ | State type | Heading level | Visual cue | CTA | Example |
42
+ |------------|---------------|------------|-----|---------|
43
+ | Cold start | h2 | Onboarding illustration | "Create your first <noun>" | "No <items> yet — create your first to begin" |
44
+ | Active filter | h3 inside results | Filter icon | "Clear filters" | "No results match these filters" |
45
+ | Network error | role=alert | Error icon | "Retry" + "Contact support" | "Couldn't load <items> — check your connection" |
46
+ | No permission | h3 | Lock icon | "Request access" | "You don't have access to <thing>" |
47
+
48
+ Cold start and active filter are not interchangeable — a first-run view directs the user to the onboarding action; an active-filter view offers "Clear filters" because the data exists behind the filter. Rendering "Clear filters" on a cold-start view is a usability defect (the button has no effect). Detect the sub-type from a state predicate (item count vs filter count vs auth scope), not from a single boolean.
49
+
50
+ Predicate ordering matters: check permission first (no-permission overrides everything), then filter state (active-filter overrides cold-start), then total count (cold-start when zero items exist anywhere). Inverting the order renders the wrong empty sub-type and the wrong CTA — a frequent source of "the button does nothing" bug reports.
51
+
52
+ ## Form UX
53
+
54
+ - Inline validation timing: validate on `blur`. After the first error on a field appears, re-validate on every keystroke with a 150ms debounce so the error tracks the user's correction in flight.
55
+ - Error recovery: clear the inline error immediately when the field becomes valid (no debounce on clear); re-enable the submit button in real time so the user sees recovery without re-tabbing.
56
+ - Error summary on submit: render at the top of the form with anchor links to each invalid field. Move focus to the summary heading (not to the first error field) so screen-reader users hear the count and list before being dropped into one field. Anchor link target is the input itself; the link text is the field label, not "Error 1".
57
+ - Required attributes per input: `autocomplete` (e.g., `email`, `tel`, `cc-number`, `one-time-code`), `inputmode` (e.g., `numeric`, `decimal`, `email`), `aria-describedby` pointing at the error or help text, and `aria-invalid="true"` when invalid. `enterkeyhint` on multi-step forms maps the soft-keyboard enter key to the next action.
58
+ - Never use a disabled submit button as the only error signal — users assume the page is broken. Allow submission and render validation outcome on submit. A submit attempt with invalid fields renders the summary, sets focus on it, and leaves the submit button operable for retry.
59
+ - Identifier-first auth: separate email and password screens; offer passkeys via WebAuthn Conditional UI (`autocomplete="username webauthn"`) so the OS surfaces the credential inline in autofill rather than behind a separate button. Passkey enrollment copy states the user-visible benefit in one sentence ("Sign in with your fingerprint — no password to remember").
60
+ - Positive confirmation for non-trivial fields (email, password strength, username availability): when valid, render an inline check or short affirmation. Pair with a screen-reader-only `aria-live="polite"` announcement.
61
+ - Multi-step forms render a step indicator with current step, total steps, and per-step labels. Each step is a separate `<form>` with its own validation and submit; never collect all fields on one screen behind tabs. Browser back button maps to previous step without data loss.
62
+ - Autosave drafts where the user expects persistence (long-form composition, settings panels). Surface autosave state with a passive indicator ("Saved 2s ago" or "Saving..."), never with a blocking modal.
63
+
64
+ ## Error-Recovery Patterns
65
+
66
+ - Retry button retries the same operation with the same input. Disable for 1s after click to avoid duplicate submits; re-enable on completion.
67
+ - Fallback offers an alternative path when retry will not help: cached view, contact support, alternate route. Render fallback below retry, not above.
68
+ - Undo for reversible mutations: surface a toast with the undo action and a >=10-second timeout. Persist the undo action across screen navigations until the timeout fires or the user confirms.
69
+ - Conflict on concurrent edit: surface a diff with three options (keep mine, keep theirs, merge); never overwrite silently.
70
+ - Session expiration: re-auth inline (modal or banner with credential field), preserving the user's in-flight data. Forced re-auth that drops form data is a defect.
71
+
72
+ ## Microcopy and Tone
73
+
74
+ Anchored to GOV.UK Design System (error pattern, plain English) and IBM Carbon (voice + tone).
75
+
76
+ - Plain language; second person; corrective verb on every error string ("Enter your email address", not "Email is required"). The verb names the action the user takes to recover.
77
+ - No jargon visible to end users: never expose "FIDO2", "WebAuthn", "HTTP 500", "null", "undefined", "401". Translate the implementation detail to the action the user can take. Implementation labels live in logs and error reports, not in UI strings.
78
+ - CTA labels are action-oriented and specific: "Save changes", "Create account", "Delete project" — not "Submit", "OK", "Confirm". Destructive verbs name the object: "Delete project Foo permanently".
79
+ - Error tone explains cause and offers recovery; never blame the user. "We couldn't save your changes — try again." not "You did something wrong." Distinguish system-fault from user-fault wording — for user-fault, name the field; for system-fault, use first-person plural ("we couldn't").
80
+ - ICU MessageFormat for every translatable string. Never concatenate strings to build sentences — singular, plural, and gender variants all live in one message ID with explicit categories. Translator memory stays stable across releases when keys are stable; rename keys is a breaking change.
81
+ - Cross-reference `rules/hatch3r-i18n.md` for translation mechanics and the Microcopy & Tone subsection that defines voice consistency across locales. Reserve 30-40% extra width in layouts for languages like DE and FI.
82
+ - Treat AI as a copy assistant, not author — AI generates tone variants and the human approves final voice strings. Brand voice strings are owned by a named maintainer, not by a model.
83
+ - Forbidden filler in any user-visible string: "Oops", "Whoops", "Something went wrong", "An unexpected error occurred". Lint these via a string-scan check in CI against the locale files. Replacements name the failure and the action — "Couldn't load <items>. Check your connection and retry."
84
+ - Empty-state copy follows the same plain-language rule: name what is absent and the action to fill it. "No drafts yet — start writing." beats "You have no drafts." because the action is in the same sentence.
85
+ - Truncation strategy: never mid-word in single-line truncations; use `text-overflow: ellipsis` with a tooltip or expand affordance for the full string. Multi-line truncation uses `-webkit-line-clamp` with a "Read more" affordance below.
86
+ - Time and date formatting: respect the user's locale via `Intl.DateTimeFormat`; never hard-code "MM/DD/YYYY" or "12:34 PM" in UI strings. Relative time ("3 minutes ago") for recent events; absolute for events >24h old.
87
+ - Numbers and units follow the locale's separator and grouping. Currency renders the user-selected currency, not the merchant's default. Round to the precision the user can act on — financial transactions to two decimals, weights to one.
88
+
89
+ ## Perceived Performance
90
+
91
+ - Skeleton show threshold: 300ms first-content latency. Below 300ms render the final view directly; above 300ms render skeleton first to avoid spinner flash. Implement via a delayed `setTimeout(showSkeleton, 300)` cleared on early response.
92
+ - Skeleton matches final content dimensions (explicit `width`, `height`, or `aspect-ratio`) so the layout does not shift when real content arrives — CLS <=0.1 baseline. Test by measuring CLS on the route under a throttled network profile (Slow 4G or 4x CPU).
93
+ - Optimistic UI for safe mutations (add to list, mark done, toggle like): apply the change in local state immediately and reconcile on server response. On reject, roll back the local state AND surface a non-blocking toast with retry. Use `useOptimistic` in React or framework equivalent.
94
+ - Pessimistic UI for destructive or financial actions (delete, payment, irreversible state change): wait for server confirmation before reflecting the change. Surface a progress indicator on the action itself, not on the page.
95
+ - Stale-while-revalidate for non-critical data: render the cached value immediately, refresh in the background, surface a non-blocking "Refresh available" affordance when the fresh value differs from the cached value. Never overwrite the rendered view silently — the user is mid-task on the stale data.
96
+ - 2026 Core Web Vitals gates at p75 of real-user data: LCP <=2.5s, INP <=200ms, CLS <=0.1. These are gating, not aspirational. Break long tasks (>50ms) with `scheduler.yield()` or `requestIdleCallback` to keep INP within budget.
97
+ - Streaming UI for long-running AI or tool responses: render tokens as they arrive without re-parsing the full buffer per chunk. Show a typing indicator only while no token has arrived; switch to streamed content on first delta. Provide cancel/abort at every streamed surface.
98
+ - Loading copy names the phase when total work is knowable ("Uploading 3 of 7..."), or names the activity when not ("Encoding..."). Generic "Loading..." is the fallback for sub-300ms cases that escape the skeleton threshold.
99
+
100
+ ## Streaming and Long-Running Operations
101
+
102
+ - Streaming text (AI responses, log tails, real-time data) renders incrementally. First-token latency target <=500ms; render the typing indicator only until first token, then switch to streamed content.
103
+ - Tool calls and side-effectful operations render as collapsible structured cards with status (pending, running, done, failed), arguments summary, duration, result preview. Hidden tool calls are a trust regression.
104
+ - Human-in-the-loop approval required for any side-effectful tool (write, send, pay, deploy). Default approval mode is opt-in; auto-accept lives behind an explicit setting with named scope and one-click revocation.
105
+ - Cancel/abort available at every long-running call. Abort triggers cleanup (rollback partial state, close streams, release locks). Show the user the post-abort state — never leave the UI in a "Cancelling..." limbo.
106
+ - Citation rendering for retrieval-grounded claims: inline link to the source span. Spans the model cannot ground from retrieved evidence are flagged visibly, not silently emitted.
107
+
108
+ ## Mobile and Touch
109
+
110
+ - Touch target minimum: 44pt on iOS HIG, 48dp on Material 3. The platform minimum supersedes WCAG SC 2.5.8 (24x24 CSS px) on touch surfaces — use the stricter bound.
111
+ - Spacing between adjacent interactive elements: >=8px to avoid mis-taps. Measure on the rendered DOM, not on the design comp — padding and margins count toward hit area only when they belong to the same interactive element.
112
+ - Avoid tap-to-reveal (hover-only tooltip) on touch surfaces. Use permanent labels or long-press with a visible affordance. Hover-only tooltips fail WCAG SC 1.4.13 Content on Hover or Focus on touch.
113
+ - Apply `env(safe-area-inset-*)` on full-bleed surfaces so primary CTAs do not sit under the iOS home indicator, notch, or Android gesture nav. Native equivalents: `safeAreaInsets` on iOS, `WindowInsets` on Android.
114
+ - Dynamic Type on iOS (`UIFont.preferredFont(forTextStyle:)` or SwiftUI `Font.body`) and rem-based font scaling on Android/web. Never use hard-coded `px` for text — fails text-resize verification at 200% zoom (WCAG SC 1.4.4) and 400% reflow (SC 1.4.10).
115
+ - Drag-only gestures (range slider, kanban reorder, swipe-to-delete) require a non-drag alternative per WCAG SC 2.5.7 — keyboard arrows, click-to-place, explicit "Delete" button.
116
+ - Pointer-event vs touch-event: prefer pointer events (`pointerdown`, `pointermove`, `pointerup`) so the same handler covers mouse, touch, pen. Synthesize click events on tap with a 300ms tolerance only on legacy mobile browsers — modern engines emit click immediately.
117
+ - Pinch-zoom: never disable user zoom on the viewport meta tag. WCAG SC 1.4.4 fails on disabled zoom. Use `maximum-scale=5` to allow up to 5x zoom while suppressing zoom-on-focus jitter.
118
+ - Orientation lock: respect WCAG SC 1.3.4 — content adapts to portrait and landscape unless an essential exception applies (e.g., piano keyboard, blueprint editor). Document the exception in the spec.
119
+
120
+ ## Heuristic Verification Gate
121
+
122
+ Run every check below before declaring a feature done. A "done" claim without these checks is not done.
123
+
124
+ - Nielsen 10 heuristics 5-minute walkthrough by a reviewer on the key user flow. Flag any heuristic violation (visibility of status, match to real world, user control, consistency, error prevention, recognition over recall, flexibility, minimalist design, error recovery, help/documentation); resolve before ship.
125
+ - Keyboard-only run through the flow (no mouse, no touch). Every step reachable, every focus state visible (>=2px outline at >=3:1 contrast), no traps, no off-screen focus.
126
+ - Screen-reader smoke test on the key route — one human pass per release using VoiceOver (macOS/iOS) or NVDA (Windows). Document the trace: which landmarks announced, which form labels heard, which dynamic updates registered.
127
+ - First-time-user walkthrough for P0 features: measure task-completion time and observe error recovery. Note where the user paused, backtracked, or asked for help. Three observed users per P0 feature minimum.
128
+ - State-coverage check: snapshot every async view in each of {loading, empty, error, partial, success} via Storybook play or component tests. Missing snapshots block the gate.
129
+ - Microcopy lint: a CI string-scan rejects banned filler ("Oops", "Whoops", "Something went wrong") in any locale file; rejects `disabled` on submit buttons without an accompanying error-state announcement; flags strings without a corrective verb on error keys (`error.*`, `validation.*`).
130
+ - Reduced-motion pass: toggle `prefers-reduced-motion: reduce` on the route and verify all non-essential transitions are removed; essential loaders simplify rather than disable.
131
+ - Reflow pass: zoom the route to 200% and 400% in a 1280x1024 viewport — no horizontal scroll, no clipped content, no overlapping interactive elements.
132
+
133
+ ## References
134
+
135
+ - WCAG 2.2 AA — new success criteria SC 2.5.8 (Target Size), SC 2.4.11 (Focus Not Obscured), SC 2.5.7 (Dragging Movements), SC 1.4.13 (Content on Hover or Focus)
136
+ - NN/g state-omission research 2025 — empty-state and error-state omission rates in AI-generated UIs (92% empty omitted, 78% error omitted)
137
+ - GOV.UK Design System — error message and error summary components, plain English readability guidance
138
+ - IBM Carbon Design System — voice and tone content guidelines, error message patterns
139
+ - Baymard Institute — inline form validation research and disabled-submit findings (top-10 form-abandonment driver)
140
+ - Google Core Web Vitals 2026 thresholds — LCP, INP, CLS at p75 real-user data
141
+ - Nielsen Norman Group — 10 usability heuristics for user interface design
142
+ - Mailchimp Content Style Guide — voice and tone baseline, clarity over cleverness
143
+ - Apple Human Interface Guidelines — Dynamic Type, safe area, touch target sizing
144
+ - Material 3 Design System — touch target sizing (48dp), state layers, ripple feedback
145
+ - W3C WAI-ARIA Authoring Practices — accessible widget patterns, live regions, focus management
146
+ - FIDO Alliance / Passkey Central — WebAuthn Conditional UI design guidelines for passwordless auth
147
+ - Vercel AI Elements — streaming message component patterns for AI chat surfaces
148
+ - Anthropic engineering blog — agent UI patterns, human-in-the-loop approval, tool-call transparency
149
+ - OpenAI Apps SDK UI guidelines — citation rendering, tool-result presentation
@@ -0,0 +1,145 @@
1
+ ---
2
+ description: Four-state surface contract (loading/empty/error/partial), user-flow decomposition before implementation, and microcopy + tone discipline for end-user UIs
3
+ globs: ["**/*.vue", "**/*.jsx", "**/*.tsx", "**/*.svelte", "**/components/**", "**/*.html", "**/messages/**", "**/locales/**", "**/copy/**"]
4
+ alwaysApply: false
5
+ ---
6
+ # UX States and Flows
7
+
8
+ ## User-Flow Decomposition (Mandatory Before Implementation)
9
+
10
+ Every user story produces three explicit flows before any UI code is written. Skipping this step is a regression — the implementer rejects specs lacking flow decomposition.
11
+
12
+ 1. **Happy Path** — numbered sequence of user actions paired with system responses and decision points covering the success route end-to-end. Includes entry point (route, prior screen, deep link), authentication state assumed, and exit point (resulting state, next screen).
13
+ 2. **Alternative Paths** — every documented branch (filters applied, multi-step forms, optional sections, permission tiers, locale variants). Each branch is numbered and references the decision point in the Happy Path where it diverges. Re-converges named.
14
+ 3. **Error-Recovery Path** — what the user does when a step fails (network drop, validation failure, expired session, permission denied, server outage, conflict on concurrent edit). Names the recovery action (retry, undo, refresh credential, contact support, drop changes) at every failure point.
15
+
16
+ Each flow is a numbered list with three columns: user action, system response, decision/branch. Reference `agents/modes/user-flows.md` for the canonical template. A flow is incomplete if any documented decision point has no specified branch outcome. The implementer treats acceptance criteria as a downstream artifact of the flow set — flows come first, criteria are derived.
17
+
18
+ Flow decomposition is also the contract between the feature designer and the reviewer: the reviewer walks every flow during code review and asserts each numbered step maps to a code path. A code path with no flow step is dead code or undocumented surface; a flow step with no code path is a missing implementation.
19
+
20
+ ## Four-State Surface Contract
21
+
22
+ Every async view renders all four states. Missing any state on an async view is a blocker — NN/g 2025 measured 92% of AI-generated dashboards omit empty state and 78% omit error state, so this is the regression bar to beat.
23
+
24
+ | State | Trigger | Rendering rules |
25
+ |-------|---------|-----------------|
26
+ | Loading | Request in flight >300ms | Skeleton matches final content dimensions (explicit width/height) to keep CLS <=0.1; spinner only for short modal actions <500ms; loading state announced via `aria-busy="true"` on the container |
27
+ | Empty | Successful response, 0 results | Distinguish three sub-types below: cold start, active filter, no permission. Each has a distinct heading, visual cue, and CTA |
28
+ | Error | Network failure, server error, validation failure | Plain-language cause + retry CTA + fallback or contact path; no "Oops" or "Something went wrong" — corrective verb required; render in `role="alert"` for assistive tech announcement |
29
+ | Partial | Some data succeeded, some failed | Banner naming the failed subset + degraded data rendered for the succeeded subset + retry option for the failed subset; never silently drop the failed subset |
30
+
31
+ State machines drive these transitions — model the view as `idle | loading | success | empty | error | partial` and assert every state has a render path in the component. Snapshot every state in tests (Storybook play function or vitest + Testing Library): missing snapshots are blockers.
32
+
33
+ Transitions between states have their own rules. Loading -> success swaps the skeleton for content without layout shift (the skeleton was already the final dimensions). Loading -> error replaces the skeleton with the error surface and announces it via `role="alert"`. Loading -> empty replaces the skeleton with the sub-typed empty surface (cold / filter / permission). Success -> partial overlays the banner without re-rendering the succeeded subset. Every transition has a measurable duration and an announcement strategy — never silent.
34
+
35
+ ## First-Run vs Filter vs Network — Content Structure
36
+
37
+ | State type | Heading level | Visual cue | CTA | Example |
38
+ |------------|---------------|------------|-----|---------|
39
+ | Cold start | h2 | Onboarding illustration | "Create your first <noun>" | "No <items> yet — create your first to begin" |
40
+ | Active filter | h3 inside results | Filter icon | "Clear filters" | "No results match these filters" |
41
+ | Network error | role=alert | Error icon | "Retry" + "Contact support" | "Couldn't load <items> — check your connection" |
42
+ | No permission | h3 | Lock icon | "Request access" | "You don't have access to <thing>" |
43
+
44
+ Cold start and active filter are not interchangeable — a first-run view directs the user to the onboarding action; an active-filter view offers "Clear filters" because the data exists behind the filter. Rendering "Clear filters" on a cold-start view is a usability defect (the button has no effect). Detect the sub-type from a state predicate (item count vs filter count vs auth scope), not from a single boolean.
45
+
46
+ Predicate ordering matters: check permission first (no-permission overrides everything), then filter state (active-filter overrides cold-start), then total count (cold-start when zero items exist anywhere). Inverting the order renders the wrong empty sub-type and the wrong CTA — a frequent source of "the button does nothing" bug reports.
47
+
48
+ ## Form UX
49
+
50
+ - Inline validation timing: validate on `blur`. After the first error on a field appears, re-validate on every keystroke with a 150ms debounce so the error tracks the user's correction in flight.
51
+ - Error recovery: clear the inline error immediately when the field becomes valid (no debounce on clear); re-enable the submit button in real time so the user sees recovery without re-tabbing.
52
+ - Error summary on submit: render at the top of the form with anchor links to each invalid field. Move focus to the summary heading (not to the first error field) so screen-reader users hear the count and list before being dropped into one field. Anchor link target is the input itself; the link text is the field label, not "Error 1".
53
+ - Required attributes per input: `autocomplete` (e.g., `email`, `tel`, `cc-number`, `one-time-code`), `inputmode` (e.g., `numeric`, `decimal`, `email`), `aria-describedby` pointing at the error or help text, and `aria-invalid="true"` when invalid. `enterkeyhint` on multi-step forms maps the soft-keyboard enter key to the next action.
54
+ - Never use a disabled submit button as the only error signal — users assume the page is broken. Allow submission and render validation outcome on submit. A submit attempt with invalid fields renders the summary, sets focus on it, and leaves the submit button operable for retry.
55
+ - Identifier-first auth: separate email and password screens; offer passkeys via WebAuthn Conditional UI (`autocomplete="username webauthn"`) so the OS surfaces the credential inline in autofill rather than behind a separate button. Passkey enrollment copy states the user-visible benefit in one sentence ("Sign in with your fingerprint — no password to remember").
56
+ - Positive confirmation for non-trivial fields (email, password strength, username availability): when valid, render an inline check or short affirmation. Pair with a screen-reader-only `aria-live="polite"` announcement.
57
+ - Multi-step forms render a step indicator with current step, total steps, and per-step labels. Each step is a separate `<form>` with its own validation and submit; never collect all fields on one screen behind tabs. Browser back button maps to previous step without data loss.
58
+ - Autosave drafts where the user expects persistence (long-form composition, settings panels). Surface autosave state with a passive indicator ("Saved 2s ago" or "Saving..."), never with a blocking modal.
59
+
60
+ ## Error-Recovery Patterns
61
+
62
+ - Retry button retries the same operation with the same input. Disable for 1s after click to avoid duplicate submits; re-enable on completion.
63
+ - Fallback offers an alternative path when retry will not help: cached view, contact support, alternate route. Render fallback below retry, not above.
64
+ - Undo for reversible mutations: surface a toast with the undo action and a >=10-second timeout. Persist the undo action across screen navigations until the timeout fires or the user confirms.
65
+ - Conflict on concurrent edit: surface a diff with three options (keep mine, keep theirs, merge); never overwrite silently.
66
+ - Session expiration: re-auth inline (modal or banner with credential field), preserving the user's in-flight data. Forced re-auth that drops form data is a defect.
67
+
68
+ ## Microcopy and Tone
69
+
70
+ Anchored to GOV.UK Design System (error pattern, plain English) and IBM Carbon (voice + tone).
71
+
72
+ - Plain language; second person; corrective verb on every error string ("Enter your email address", not "Email is required"). The verb names the action the user takes to recover.
73
+ - No jargon visible to end users: never expose "FIDO2", "WebAuthn", "HTTP 500", "null", "undefined", "401". Translate the implementation detail to the action the user can take. Implementation labels live in logs and error reports, not in UI strings.
74
+ - CTA labels are action-oriented and specific: "Save changes", "Create account", "Delete project" — not "Submit", "OK", "Confirm". Destructive verbs name the object: "Delete project Foo permanently".
75
+ - Error tone explains cause and offers recovery; never blame the user. "We couldn't save your changes — try again." not "You did something wrong." Distinguish system-fault from user-fault wording — for user-fault, name the field; for system-fault, use first-person plural ("we couldn't").
76
+ - ICU MessageFormat for every translatable string. Never concatenate strings to build sentences — singular, plural, and gender variants all live in one message ID with explicit categories. Translator memory stays stable across releases when keys are stable; rename keys is a breaking change.
77
+ - Cross-reference `rules/hatch3r-i18n.md` for translation mechanics and the Microcopy & Tone subsection that defines voice consistency across locales. Reserve 30-40% extra width in layouts for languages like DE and FI.
78
+ - Treat AI as a copy assistant, not author — AI generates tone variants and the human approves final voice strings. Brand voice strings are owned by a named maintainer, not by a model.
79
+ - Forbidden filler in any user-visible string: "Oops", "Whoops", "Something went wrong", "An unexpected error occurred". Lint these via a string-scan check in CI against the locale files. Replacements name the failure and the action — "Couldn't load <items>. Check your connection and retry."
80
+ - Empty-state copy follows the same plain-language rule: name what is absent and the action to fill it. "No drafts yet — start writing." beats "You have no drafts." because the action is in the same sentence.
81
+ - Truncation strategy: never mid-word in single-line truncations; use `text-overflow: ellipsis` with a tooltip or expand affordance for the full string. Multi-line truncation uses `-webkit-line-clamp` with a "Read more" affordance below.
82
+ - Time and date formatting: respect the user's locale via `Intl.DateTimeFormat`; never hard-code "MM/DD/YYYY" or "12:34 PM" in UI strings. Relative time ("3 minutes ago") for recent events; absolute for events >24h old.
83
+ - Numbers and units follow the locale's separator and grouping. Currency renders the user-selected currency, not the merchant's default. Round to the precision the user can act on — financial transactions to two decimals, weights to one.
84
+
85
+ ## Perceived Performance
86
+
87
+ - Skeleton show threshold: 300ms first-content latency. Below 300ms render the final view directly; above 300ms render skeleton first to avoid spinner flash. Implement via a delayed `setTimeout(showSkeleton, 300)` cleared on early response.
88
+ - Skeleton matches final content dimensions (explicit `width`, `height`, or `aspect-ratio`) so the layout does not shift when real content arrives — CLS <=0.1 baseline. Test by measuring CLS on the route under a throttled network profile (Slow 4G or 4x CPU).
89
+ - Optimistic UI for safe mutations (add to list, mark done, toggle like): apply the change in local state immediately and reconcile on server response. On reject, roll back the local state AND surface a non-blocking toast with retry. Use `useOptimistic` in React or framework equivalent.
90
+ - Pessimistic UI for destructive or financial actions (delete, payment, irreversible state change): wait for server confirmation before reflecting the change. Surface a progress indicator on the action itself, not on the page.
91
+ - Stale-while-revalidate for non-critical data: render the cached value immediately, refresh in the background, surface a non-blocking "Refresh available" affordance when the fresh value differs from the cached value. Never overwrite the rendered view silently — the user is mid-task on the stale data.
92
+ - 2026 Core Web Vitals gates at p75 of real-user data: LCP <=2.5s, INP <=200ms, CLS <=0.1. These are gating, not aspirational. Break long tasks (>50ms) with `scheduler.yield()` or `requestIdleCallback` to keep INP within budget.
93
+ - Streaming UI for long-running AI or tool responses: render tokens as they arrive without re-parsing the full buffer per chunk. Show a typing indicator only while no token has arrived; switch to streamed content on first delta. Provide cancel/abort at every streamed surface.
94
+ - Loading copy names the phase when total work is knowable ("Uploading 3 of 7..."), or names the activity when not ("Encoding..."). Generic "Loading..." is the fallback for sub-300ms cases that escape the skeleton threshold.
95
+
96
+ ## Streaming and Long-Running Operations
97
+
98
+ - Streaming text (AI responses, log tails, real-time data) renders incrementally. First-token latency target <=500ms; render the typing indicator only until first token, then switch to streamed content.
99
+ - Tool calls and side-effectful operations render as collapsible structured cards with status (pending, running, done, failed), arguments summary, duration, result preview. Hidden tool calls are a trust regression.
100
+ - Human-in-the-loop approval required for any side-effectful tool (write, send, pay, deploy). Default approval mode is opt-in; auto-accept lives behind an explicit setting with named scope and one-click revocation.
101
+ - Cancel/abort available at every long-running call. Abort triggers cleanup (rollback partial state, close streams, release locks). Show the user the post-abort state — never leave the UI in a "Cancelling..." limbo.
102
+ - Citation rendering for retrieval-grounded claims: inline link to the source span. Spans the model cannot ground from retrieved evidence are flagged visibly, not silently emitted.
103
+
104
+ ## Mobile and Touch
105
+
106
+ - Touch target minimum: 44pt on iOS HIG, 48dp on Material 3. The platform minimum supersedes WCAG SC 2.5.8 (24x24 CSS px) on touch surfaces — use the stricter bound.
107
+ - Spacing between adjacent interactive elements: >=8px to avoid mis-taps. Measure on the rendered DOM, not on the design comp — padding and margins count toward hit area only when they belong to the same interactive element.
108
+ - Avoid tap-to-reveal (hover-only tooltip) on touch surfaces. Use permanent labels or long-press with a visible affordance. Hover-only tooltips fail WCAG SC 1.4.13 Content on Hover or Focus on touch.
109
+ - Apply `env(safe-area-inset-*)` on full-bleed surfaces so primary CTAs do not sit under the iOS home indicator, notch, or Android gesture nav. Native equivalents: `safeAreaInsets` on iOS, `WindowInsets` on Android.
110
+ - Dynamic Type on iOS (`UIFont.preferredFont(forTextStyle:)` or SwiftUI `Font.body`) and rem-based font scaling on Android/web. Never use hard-coded `px` for text — fails text-resize verification at 200% zoom (WCAG SC 1.4.4) and 400% reflow (SC 1.4.10).
111
+ - Drag-only gestures (range slider, kanban reorder, swipe-to-delete) require a non-drag alternative per WCAG SC 2.5.7 — keyboard arrows, click-to-place, explicit "Delete" button.
112
+ - Pointer-event vs touch-event: prefer pointer events (`pointerdown`, `pointermove`, `pointerup`) so the same handler covers mouse, touch, pen. Synthesize click events on tap with a 300ms tolerance only on legacy mobile browsers — modern engines emit click immediately.
113
+ - Pinch-zoom: never disable user zoom on the viewport meta tag. WCAG SC 1.4.4 fails on disabled zoom. Use `maximum-scale=5` to allow up to 5x zoom while suppressing zoom-on-focus jitter.
114
+ - Orientation lock: respect WCAG SC 1.3.4 — content adapts to portrait and landscape unless an essential exception applies (e.g., piano keyboard, blueprint editor). Document the exception in the spec.
115
+
116
+ ## Heuristic Verification Gate
117
+
118
+ Run every check below before declaring a feature done. A "done" claim without these checks is not done.
119
+
120
+ - Nielsen 10 heuristics 5-minute walkthrough by a reviewer on the key user flow. Flag any heuristic violation (visibility of status, match to real world, user control, consistency, error prevention, recognition over recall, flexibility, minimalist design, error recovery, help/documentation); resolve before ship.
121
+ - Keyboard-only run through the flow (no mouse, no touch). Every step reachable, every focus state visible (>=2px outline at >=3:1 contrast), no traps, no off-screen focus.
122
+ - Screen-reader smoke test on the key route — one human pass per release using VoiceOver (macOS/iOS) or NVDA (Windows). Document the trace: which landmarks announced, which form labels heard, which dynamic updates registered.
123
+ - First-time-user walkthrough for P0 features: measure task-completion time and observe error recovery. Note where the user paused, backtracked, or asked for help. Three observed users per P0 feature minimum.
124
+ - State-coverage check: snapshot every async view in each of {loading, empty, error, partial, success} via Storybook play or component tests. Missing snapshots block the gate.
125
+ - Microcopy lint: a CI string-scan rejects banned filler ("Oops", "Whoops", "Something went wrong") in any locale file; rejects `disabled` on submit buttons without an accompanying error-state announcement; flags strings without a corrective verb on error keys (`error.*`, `validation.*`).
126
+ - Reduced-motion pass: toggle `prefers-reduced-motion: reduce` on the route and verify all non-essential transitions are removed; essential loaders simplify rather than disable.
127
+ - Reflow pass: zoom the route to 200% and 400% in a 1280x1024 viewport — no horizontal scroll, no clipped content, no overlapping interactive elements.
128
+
129
+ ## References
130
+
131
+ - WCAG 2.2 AA — new success criteria SC 2.5.8 (Target Size), SC 2.4.11 (Focus Not Obscured), SC 2.5.7 (Dragging Movements), SC 1.4.13 (Content on Hover or Focus)
132
+ - NN/g state-omission research 2025 — empty-state and error-state omission rates in AI-generated UIs (92% empty omitted, 78% error omitted)
133
+ - GOV.UK Design System — error message and error summary components, plain English readability guidance
134
+ - IBM Carbon Design System — voice and tone content guidelines, error message patterns
135
+ - Baymard Institute — inline form validation research and disabled-submit findings (top-10 form-abandonment driver)
136
+ - Google Core Web Vitals 2026 thresholds — LCP, INP, CLS at p75 real-user data
137
+ - Nielsen Norman Group — 10 usability heuristics for user interface design
138
+ - Mailchimp Content Style Guide — voice and tone baseline, clarity over cleverness
139
+ - Apple Human Interface Guidelines — Dynamic Type, safe area, touch target sizing
140
+ - Material 3 Design System — touch target sizing (48dp), state layers, ripple feedback
141
+ - W3C WAI-ARIA Authoring Practices — accessible widget patterns, live regions, focus management
142
+ - FIDO Alliance / Passkey Central — WebAuthn Conditional UI design guidelines for passwordless auth
143
+ - Vercel AI Elements — streaming message component patterns for AI chat surfaces
144
+ - Anthropic engineering blog — agent UI patterns, human-in-the-loop approval, tool-call transparency
145
+ - OpenAI Apps SDK UI guidelines — citation rendering, tool-result presentation
@@ -12,6 +12,7 @@ cache_friendly: true
12
12
 
13
13
  ```
14
14
  Task Progress:
15
+ - [ ] Step 0: Detect ambiguity (P8 B1)
15
16
  - [ ] Step 1: Read accessibility requirements from rules and specs
16
17
  - [ ] Step 2: Automated scan — run axe-core or similar on all pages/components
17
18
  - [ ] Step 3: Manual audit — load references/manual-audit-checklist.md
@@ -20,6 +21,19 @@ Task Progress:
20
21
  - [ ] Step 6: Verify fixes with re-scan and manual check
21
22
  ```
22
23
 
24
+ ## Step 0 — Detect Ambiguity (P8 B1)
25
+
26
+ Before any work, scan the invocation for unresolved questions in scope, intent, acceptance criteria, target environment, or irreversibility. If any are found, ask the user via the platform-native question tool per `agents/shared/user-question-protocol.md`. Do not proceed under silent assumption. Default path, not an exception. Triggers for THIS skill: WCAG conformance target (A vs AA vs AAA), scope (single component vs full app), surfaces to audit (which routes), fix authority (audit-only vs audit-and-fix), and screen-reader pass scope (per release vs per audit).
27
+
28
+ ## Fan-out Discipline (P8 B2)
29
+
30
+ This skill delegates per task size:
31
+ - Tier 1 (trivial single-file): inline execution acceptable.
32
+ - Tier 2 (multi-file or multi-concern): spawn parallel sub-agents per concern via the Task tool.
33
+ - Tier 3 (multi-module / high-risk): one fresh sub-agent per independent module or gate; orchestrator integrates only.
34
+
35
+ Never under-fan-out to save tokens. Token cost is dominated by quality and completeness gains. Emit `sub_agents_spawned: { count, rationale }` in your output.
36
+
23
37
  ## Progressive Disclosure
24
38
 
25
39
  - **Main skill file (this):** Workflow steps, automated scan, fix process, DoD.
@@ -0,0 +1,134 @@
1
+ ---
2
+ id: hatch3r-ai-feature
3
+ type: skill
4
+ description: Eval-driven development workflow for shipping AI features — write eval before prompt, measure, iterate, ship with caching + cost telemetry + model fallback + hallucination SLI
5
+ tags: [implementation, ai]
6
+ quality_charter: agents/shared/quality-charter.md
7
+ ---
8
+ # AI Feature Workflow (Eval-Driven)
9
+
10
+ ## Quick Start
11
+
12
+ Run this skill before shipping any LLM-driven feature. It defines the canonical eval-driven loop (write eval, write prompt, measure, iterate) and the production-readiness gates. Skipping any of the 9 steps = the feature is not done.
13
+
14
+ This skill is the implementation counterpart to `rules/hatch3r-ai-evals.md` (backend governance) and `rules/hatch3r-ai-ux-patterns.md` (UI governance). The rules define the bar; this skill defines the route to clearing the bar.
15
+
16
+ ## Step 0 — Detect Ambiguity (P8 B1)
17
+
18
+ Before any work, scan the invocation for unresolved questions in scope, intent, acceptance criteria, target environment, or irreversibility. If any are found, ask the user via the platform-native question tool per `agents/shared/user-question-protocol.md`. Do not proceed under silent assumption. Default path, not an exception. Triggers for THIS skill: task class (classification vs open-ended vs RAG vs agentic), model pin (Sonnet vs Opus vs Haiku), eval threshold values, budget per request (cost cap), and fallback policy (graceful degrade vs hard fail).
19
+
20
+ ## Fan-out Discipline (P8 B2)
21
+
22
+ This skill delegates per task size:
23
+ - Tier 1 (trivial single-file): inline execution acceptable.
24
+ - Tier 2 (multi-file or multi-concern): spawn parallel sub-agents per concern via the Task tool.
25
+ - Tier 3 (multi-module / high-risk): one fresh sub-agent per independent module or gate; orchestrator integrates only.
26
+
27
+ Never under-fan-out to save tokens. Token cost is dominated by quality and completeness gains. Emit `sub_agents_spawned: { count, rationale }` in your output.
28
+
29
+ ## Step 1: Define the task and success criteria
30
+
31
+ - Write down what "right" looks like in one paragraph — the user input class, the expected output shape, the failure modes you want to catch.
32
+ - Hand-author 20+ golden examples in `evals/<feature>/golden.jsonl` with `input` + `expected_output` (or a graded rubric when the task is open-ended).
33
+ - Save the threshold per metric in `evals/<feature>/thresholds.json`. Without an explicit threshold, "passing the eval" is undefined.
34
+ - Cross-reference `rules/hatch3r-ai-evals.md` Golden Dataset Versioning for filename and refresh policy.
35
+ - Source diversity matters more than count beyond 20 — include adversarial inputs, edge cases from prior incidents, and at least 3 examples per known input class.
36
+ - Label every example with the input class so per-class accuracy is computable in Step 4.
37
+
38
+ ## Step 2: Pick eval tool and metric
39
+
40
+ Match the task class to the tool:
41
+
42
+ - Classification → promptfoo with exact-match assertions.
43
+ - Open-ended generation → DeepEval or braintrust with LLM-as-judge + a 50-example human-labeled calibration set.
44
+ - Retrieval/RAG → RAGAS (context_precision, context_recall, faithfulness, answer_relevance).
45
+ - Tool-use / agentic → Inspect or BFCL-style harness.
46
+ - Safety/red-team → Garak or PyRIT scheduled weekly.
47
+
48
+ Pin the choice in `evals/README.md` so the next agent run picks the same tool.
49
+
50
+ ## Step 3: Write the prompt
51
+
52
+ - Author the prompt at `prompts/<feature>/v1.md` with frontmatter `{ id, version: 1, model_pinned, eval_set }`.
53
+ - Commit; record SHA-256 hash in `evals/<feature>/thresholds.json`.
54
+ - If the system prompt + tool definitions + RAG context exceed 1024 tokens, apply Anthropic `cache_control` breakpoints (or rely on OpenAI's automatic prefix cache for ≥1024-token deterministic prefixes). Longest-TTL block first.
55
+
56
+ ## Step 4: Run eval; iterate prompt
57
+
58
+ - Run `npx promptfoo eval` (or the chosen tool's CLI) against the golden set.
59
+ - Read the per-metric report. If below threshold, modify the prompt, bump to `v2.md`, re-hash, re-run.
60
+ - Treat each prompt revision like a code commit — small, named, testable.
61
+ - Stop iterating when every metric clears its threshold in `thresholds.json` and the pairwise win-rate vs the prior version is >=55%.
62
+ - Capture the eval report artifact in CI so the PR reviewer can read per-case pass/fail without re-running the suite locally.
63
+ - If iteration count exceeds 10 versions without convergence, escalate — the task may need decomposition (one sub-prompt per input class) or a retrieval-grounded approach.
64
+
65
+ ## Step 5: Wire production telemetry
66
+
67
+ - Per-request log line emits `model`, `tokens_in`, `tokens_out`, `cache_hit`, `cached_tokens`, `cost_usd`, `latency_ms`, `prompt_version`, `prompt_hash`, `cost_center`.
68
+ - Per-request OpenTelemetry span follows the OTel GenAI semantic conventions (`gen_ai.*` attributes).
69
+ - Aggregate dashboards: cost-per-request, hallucination_rate, citation_precision, refusal_rate, cache_hit_ratio.
70
+ - Cross-reference `skills/hatch3r-observability-verify` for the per-feature dashboard checklist.
71
+
72
+ ## Step 6: Wire fallback chain
73
+
74
+ - Primary model (e.g. Sonnet 4.7) → secondary (cheaper/faster, e.g. Haiku 4.5) → static fallback (cached or canned).
75
+ - Wrap in circuit-breaker + retry-with-decorrelated-jitter — cross-reference `rules/hatch3r-resilience-patterns.md` (Slice 8) for the primitives.
76
+ - Run the eval suite against the secondary path too — a silent quality cliff between primary and secondary is a regression.
77
+ - Static fallback text names the failure mode in user-readable language ("AI is briefly unavailable — retry in a minute") rather than dumping a stack trace into the UI.
78
+
79
+ ## Step 7: Add CI gate
80
+
81
+ - Eval runs on every PR that touches `**/prompts/**`, `**/rag/**`, `**/ai/**`, `**/llm/**`.
82
+ - PR blocks when any metric drops below the threshold in `evals/<feature>/thresholds.json`.
83
+ - Model-version upgrade (Sonnet to Opus, 4.6 to 4.7) triggers a full eval with a 5% accuracy budget; cross over 5% requires a named-reviewer sign-off + 24-hour canary at 5% traffic.
84
+
85
+ ## Step 8: Production verification
86
+
87
+ First 24 hours after deploy, monitor:
88
+
89
+ - `ai.hallucination_rate` — SLO <5% on golden set; alert if 7-day rolling rate >5%.
90
+ - `ai.refusal_rate` — track false-positive refusal rate separately.
91
+ - `ai.cost_per_request_usd` — p50/p95/p99 vs feature budget; alert at 50%/75%/90% of monthly budget.
92
+ - `ai.latency_ms` — first-token-latency p95 + total-response-latency p99.
93
+ - `ai.cache_hit_ratio` — should match the dev-environment baseline within 10%; a drop indicates prefix drift.
94
+ - `ai.tokens_per_request` — p95 should be within 20% of the eval-time distribution; a spike signals retrieval growth or prompt drift.
95
+
96
+ Cross-reference `skills/hatch3r-observability-verify`.
97
+
98
+ ## Step 9: Feedback loop
99
+
100
+ - Wire user thumbs-down to a feedback queue per response.
101
+ - Monthly triage job promotes thumbs-down examples into regression fixtures in `evals/<feature>/edge.jsonl`.
102
+ - Promotion is a manual review step — raw user feedback contains noise and adversarial labels.
103
+ - Capture an optional free-text comment with each thumbs-down; the comment is the highest-signal feature for triage clustering.
104
+ - Track feedback volume per response surface — a sudden spike in thumbs-down rate signals an upstream prompt or retrieval regression and gates a rollback.
105
+
106
+ ## Verdict
107
+
108
+ All 9 steps complete = the AI feature is "done". Anything less = not done. The orchestrator running this skill emits a single-line verdict per step (`STEP_N: PASS|FAIL <evidence-path>`) and aggregates them. One FAIL on any step blocks release.
109
+
110
+ Evidence paths point at concrete artifacts: the golden set (`evals/<feature>/golden.jsonl`), the prompt version (`prompts/<feature>/v<N>.md`), the eval report (`evals/<feature>/report-<run-id>.json`), and the dashboard URL for production SLI verification. Verdicts without evidence paths are not accepted by the gate.
111
+
112
+ ## When this skill runs
113
+
114
+ - After `hatch3r-implementer` finishes the surrounding non-AI feature code, before `hatch3r-qa-validation`.
115
+ - On every PR that introduces a new LLM call or modifies an existing prompt, model, or retrieval pipeline.
116
+ - Step 8 (production verification) executes against the post-deploy environment, not the PR branch.
117
+
118
+ ## Cross-References
119
+
120
+ - `rules/hatch3r-ai-evals.md` — backend governance (eval, cost, caching, fallback, SLI).
121
+ - `rules/hatch3r-ai-ux-patterns.md` — frontend UX patterns (streaming, tool-call cards, citations).
122
+ - `skills/hatch3r-ui-ux-verify/SKILL.md` — UI verification gate for AI surfaces.
123
+ - `skills/hatch3r-observability-verify` — observability wiring checklist.
124
+ - `rules/hatch3r-resilience-patterns.md` (Slice 8) — circuit-breaker + retry primitives reused in the fallback chain.
125
+
126
+ ## References
127
+
128
+ - promptfoo — `promptfoo.dev`
129
+ - DeepEval — `github.com/confident-ai/deepeval`
130
+ - RAGAS — `docs.ragas.io`
131
+ - Inspect (UK AISI) — `github.com/UKGovernmentBEIS/inspect_ai`
132
+ - Anthropic prompt caching guide — `docs.anthropic.com/en/docs/build-with-claude/prompt-caching`
133
+ - OpenTelemetry GenAI semantic conventions — `opentelemetry.io/docs/specs/semconv/gen-ai/`
134
+ - Berkeley Function Calling Leaderboard (BFCL v4) — `gorilla.cs.berkeley.edu/leaderboard.html`
@@ -14,6 +14,7 @@ cache_friendly: true
14
14
 
15
15
  ```
16
16
  Task Progress:
17
+ - [ ] Step 0: Detect ambiguity (P8 B1)
17
18
  - [ ] Step 1: Inventory existing endpoints
18
19
  - [ ] Step 2: Generate OpenAPI spec
19
20
  - [ ] Step 3: Validate schemas
@@ -21,6 +22,10 @@ Task Progress:
21
22
  - [ ] Step 5: Verify spec accuracy
22
23
  ```
23
24
 
25
+ ## Step 0 — Detect Ambiguity (P8 B1)
26
+
27
+ Before any work, scan the invocation for unresolved questions in scope, intent, acceptance criteria, target environment, or irreversibility. If any are found, ask the user via the platform-native question tool per `agents/shared/user-question-protocol.md`. Do not proceed under silent assumption. Default path, not an exception. Triggers for THIS skill: OpenAPI version (3.0 vs 3.1), spec output path, auth scheme (Bearer vs OAuth2 vs API key), breaking-change policy (block vs version vs document), and target consumers (SDK clients vs human docs vs both).
28
+
24
29
  ## Step 1: Inventory Existing Endpoints
25
30
 
26
31
  - Scan route definitions across the codebase (controllers, handlers, route files).
@@ -12,6 +12,7 @@ cache_friendly: true
12
12
 
13
13
  ```
14
14
  Task Progress:
15
+ - [ ] Step 0: Detect ambiguity (P8 B1)
15
16
  - [ ] Step 1: Read existing ADRs and the template
16
17
  - [ ] Step 2: Define the decision context — problem, constraints, options
17
18
  - [ ] Step 3: Evaluate options — pros/cons, prototype if needed, check ADR constraints
@@ -20,6 +21,19 @@ Task Progress:
20
21
  - [ ] Step 6: Update affected specs or docs to reference the new ADR
21
22
  ```
22
23
 
24
+ ## Step 0 — Detect Ambiguity (P8 B1)
25
+
26
+ Before any work, scan the invocation for unresolved questions in scope, intent, acceptance criteria, target environment, or irreversibility. If any are found, ask the user via the platform-native question tool per `agents/shared/user-question-protocol.md`. Do not proceed under silent assumption. Default path, not an exception. Triggers for THIS skill: problem framing (what decision needs to be made), constraint set (mandatory vs preferred), evaluation horizon (short-term vs long-term cost), supersedes which prior ADR, and ADR status target (PROPOSED for discussion vs ACCEPTED for binding decision).
27
+
28
+ ## Fan-out Discipline (P8 B2)
29
+
30
+ This skill delegates per task size:
31
+ - Tier 1 (trivial single-file): inline execution acceptable.
32
+ - Tier 2 (multi-file or multi-concern): spawn parallel sub-agents per concern via the Task tool.
33
+ - Tier 3 (multi-module / high-risk): one fresh sub-agent per independent module or gate; orchestrator integrates only.
34
+
35
+ Never under-fan-out to save tokens. Token cost is dominated by quality and completeness gains. Emit `sub_agents_spawned: { count, rationale }` in your output.
36
+
23
37
  ## Step 1: Read Existing ADRs and Template
24
38
 
25
39
  - Read all ADRs in project docs to understand current architecture and constraints.
@@ -14,6 +14,7 @@ cache_friendly: true
14
14
 
15
15
  ```
16
16
  Task Progress:
17
+ - [ ] Step 0: Detect ambiguity (P8 B1)
17
18
  - [ ] Step 1: Read the issue and relevant specs
18
19
  - [ ] Step 2: Produce a diagnosis plan
19
20
  - [ ] Step 2b: Browser reproduction (if UI bug)
@@ -25,6 +26,10 @@ Task Progress:
25
26
  - [ ] Step 6: Open PR
26
27
  ```
27
28
 
29
+ ## Step 0 — Detect Ambiguity (P8 B1)
30
+
31
+ Before any work, scan the invocation for unresolved questions in scope, intent, acceptance criteria, target environment, or irreversibility. If any are found, ask the user via the platform-native question tool per `agents/shared/user-question-protocol.md`. Do not proceed under silent assumption. Default path, not an exception. Triggers for THIS skill: reproduction steps incomplete, expected vs actual behavior unstated, severity unclear (P0/P1 vs P2/P3), affected environment unknown (staging vs prod), or fix may require schema/API change with downstream consumers.
32
+
28
33
  ## Step 1: Read Inputs
29
34
 
30
35
  - Parse the issue body: problem description, reproduction steps, expected/actual behavior, severity, affected area.
@@ -14,6 +14,7 @@ cache_friendly: true
14
14
 
15
15
  ```
16
16
  Task Progress:
17
+ - [ ] Step 0: Detect ambiguity (P8 B1)
17
18
  - [ ] Step 1: Audit existing pipeline
18
19
  - [ ] Step 2: Design stage structure
19
20
  - [ ] Step 3: Optimize test parallelization
@@ -21,6 +22,19 @@ Task Progress:
21
22
  - [ ] Step 5: Implement and validate
22
23
  ```
23
24
 
25
+ ## Step 0 — Detect Ambiguity (P8 B1)
26
+
27
+ Before any work, scan the invocation for unresolved questions in scope, intent, acceptance criteria, target environment, or irreversibility. If any are found, ask the user via the platform-native question tool per `agents/shared/user-question-protocol.md`. Do not proceed under silent assumption. Default path, not an exception. Triggers for THIS skill: CI platform (GitHub Actions vs GitLab vs CircleCI vs Azure Pipelines), pipeline duration target, runner sizing budget, deploy gate (auto vs manual approval for prod), and artifact retention policy.
28
+
29
+ ## Fan-out Discipline (P8 B2)
30
+
31
+ This skill delegates per task size:
32
+ - Tier 1 (trivial single-file): inline execution acceptable.
33
+ - Tier 2 (multi-file or multi-concern): spawn parallel sub-agents per concern via the Task tool.
34
+ - Tier 3 (multi-module / high-risk): one fresh sub-agent per independent module or gate; orchestrator integrates only.
35
+
36
+ Never under-fan-out to save tokens. Token cost is dominated by quality and completeness gains. Emit `sub_agents_spawned: { count, rationale }` in your output.
37
+
24
38
  ## Step 1: Audit Existing Pipeline
25
39
 
26
40
  - Map the current pipeline stages, their dependencies, and execution times.