fix(craft): address review findings on state-coverage

Four P2 findings from #502 review addressed in one pass.

- Edge state Test matrix added under the five-states table (dashboard,
  mobile, form, search, detail-view scenarios with concrete thresholds).
- Server-driven empty pattern added as trailing note in the empty-state
  composition section.
- Retry discipline subsection added after error severity tiers
  (immediate first retry, exponential 2s/4s/8s backoff, 3-retry floor,
  Last-attempted timestamp).
- README enforcement-levels subsection added distinguishing auto-checked
  P0 rules from guidance; partial-stateful skill clarification added
  after the Files table.

No rewrites. ~30 lines added. File stays inside the 80-110-line craft
target.
This commit is contained in:
Mohamed Abdallah
2026-05-05 10:41:16 +03:00
parent 0f8e453180
commit ee95b90971
2 changed files with 30 additions and 0 deletions

View File

@@ -42,6 +42,15 @@ a follow-up PR, with no skill edit needed. The cost of a missed
reference is a missing paragraph in the system prompt, not a broken
skill — so the loud failure mode is not worth the friction.
### Enforcement levels
Craft files mix auto-checked rules and guidance.
- **Auto-checked.** Rules wired into `apps/daemon/src/lint-artifact.ts` — currently the P0 list in `anti-ai-slop.md` (Tailwind-indigo accent, two-stop hero gradients, emoji-as-icons, etc.). The linter blocks artifact generation on these.
- **Guidance.** The rest. The agent reads them, reviewers apply them, the linter doesn't.
A purely behavioral craft file (state-coverage, animation-discipline) is guidance unless a specific rule is later promoted into `lint-artifact.ts`.
## Files
| File | Section name | When to require |
@@ -51,6 +60,8 @@ skill — so the loud failure mode is not worth the friction.
| `anti-ai-slop.md` | `anti-ai-slop` | Marketing pages, landing pages, decks |
| `state-coverage.md` | `state-coverage` | Any skill with stateful UI (dashboards, mobile apps, forms, list/table views) |
**Partial-stateful skills.** A skill that's mostly static but contains an embedded form, data table, or query surface should opt in. State-coverage rules apply to the stateful component, not the whole page.
More sections (`motion`, `icons`, `craft-details`) will be added in
follow-up PRs as we wire the linter side.

View File

@@ -24,6 +24,16 @@ Render-and-screenshot test: every list, table, card, form, and panel in the
artifact has all five. Missing states are the most common silent failure of
AI-generated UI.
**Test matrix.** Concrete edge scenarios the surface must survive:
| Skill type | Edge scenario |
|---|---|
| Dashboard / table | 10,000+ rows, all numeric columns, sort + filter applied |
| Mobile card / list | 200-char title, missing avatar, missing secondary CTA |
| Form | All optional fields empty, all required fields at max length |
| Search results | Single-character query, query with only special chars, 1,000+ result count |
| Detail view | Missing all optional metadata, RTL primary content with LTR embeds |
## Form-specific states
Forms add three states on top of the five.
@@ -47,6 +57,8 @@ Empty is not the absence of state. It is its own state with a job.
- **Cleared empty** — celebratory phrasing, optional next-action.
- **Error-as-empty** — never. An error is its own state with recovery information; do not collapse error into empty.
**Server-driven vs client-driven.** When a search or query API can return fallback content in the empty payload (suggestions, related categories, popular results), prefer that over a client-side echo. Algolia, Elastic, and most modern search backends support this — the server has more context for what "no results, but maybe try X" should mean.
## Error state composition
Every error must answer three questions, in this order:
@@ -69,6 +81,13 @@ Severity tiers:
Match severity to surface scope. A field validation failure does not warrant
a page-level error.
**Retry discipline.** A retry surface is not a button alone. It has timing rules:
- First retry fires immediately on user click.
- Second and third retries use exponential backoff: 2 s, 4 s, 8 s max.
- After 3 failed retries, replace "Retry" with "Contact support" plus a copyable error ID. The user has done their job; the system now needs a human.
- Show "Last attempted: Xs ago" on the error surface after the first retry, so the user knows how stale the failure is.
## Loading state thresholds
Pick the indicator by expected duration, not by what's available in the