v0.6.0-prerelease — Phase 5: Verification-Gate USP
Pre-releaseTHE Verification-Gate. THE wisp-design differentiator.
No other live-edit tool gates accept on (a11y + screenshot + anti-slop)
simultaneously. UI-UX-Pro-Max stops at "generated text", Impeccable stops
at "wrote to file", Onlook/Stagewise stop at "wrote to file", Huashu has
5-dim radar but no gate, Open-design has 5-dim gate but no source-edit.
wisp-design alone links source-edit + a11y-block + screenshot-diff +
anti-slop-lint in one accept-gate.
Built by a 4-agent team (architect / coder / security / tester) with
disjoint file ownership and security-architect-flagged coordination
between the parallel agents.
Quality-gate metrics (100-component-sample FPR canary)
hard-ban FPR = 0.00% (target <= 5%) PASS
FN-rate = 0.00% (caught 30/30 known-slop)
soft-warn FPR = 45.71% (target <= 20%) PINNED [AUDIT-PENDING for Phase 6]
verdict = USP delivered, calibration TODO
Hard-ban FPR being 0.00% on real-world-good components (shadcn/Radix/MUI
patterns) while still catching 100% of known-slop is the central proof
point. The soft-warn FPR is too noisy on Tailwind defaults — security's
audit pointed at the round-number-whitespace rule firing per-occurrence;
fix via file-level aggregation (>0.7 ratio threshold) lands in Phase 6.
What landed
Contracts (src/contracts/verify.ts, 491 lines)
VerifyModeenum across 5 modes (stop-hook|live-accept|
live-with-screenshot|audit|audit-strict)- Lookup tables:
MODE_CHECK_SETS,MODE_BLOCKS_ON_FAIL,
MODE_TIMING_BUDGET_MS AntiSlopRuleId(7 hard-bans + 5 soft),HARD_BAN_RULESSet- Aggregator helpers, per-check budgets, audit options schema
Verify modules (src/verify/, 8 files)
anti-slop-linter.ts(648) - pre-compiled regex set, 7 hard-bans
(em-dash-ui, gradient-text-headline, default-glassmorphism,
hero-metric-template, side-stripe-decoration, purple-blue-gradient,
generic-ai-illustration) + 5 soft-suggestionsa11y-axe.ts(381) - axe-core via jsdom or Playwright when availableconsole-scan.ts(221) - 3 modes (session-log, bridge-poll, static)tab-order.ts(232) - focus-trap-leak detection, tabindex auditreduced-motion.ts(112) - CSS regex pass for motion-without-guardmulti-viewport.ts(276) - Playwright 4 viewports x {light,dark} = 8 PNGs_sandbox.ts(384, security) - safe-launch with 6 URL guards
(loopback-only, no userinfo, http(s) only, port 1025-65535) +
chromium hardening (sandbox ON, disable-extensions, etc.) +
restricted context (no downloads, no permissions) + route-handler
aborts non-loopback hostsgate.ts(259) - orchestrator viaPromise.allSettled, per-check
timeout, 5-mode routing, blocked field for audit-strict
CLI (src/agent/audit.ts, 308 lines)
wisp-design audit [paths...]with--mode fast|full|strict,
--format text|json|markdown,--screenshot- Exit codes: 0/1/2/3 for pass/strict-block/bad-flag/throw
Stop-Hook (src/hooks/dispatcher.ts)
git diff HEAD --name-onlyviaexecFileSync(path-injection safe)- 50-file cap, UI-extension filter, 15ms tail-reserve
- Dynamic-import linter (Node module-cache amortises after turn 1)
WISP_DESIGN_STRICT=1env:permissionDecision:blockJSON to stdout- Default: stderr warn, exit 0 (never blocks user on internal error)
Doctor (12/12 OK)
axe-coreFAIL when missing,playwright+pixelmatchWARN- Doctor surfaces optionalDep absence so users can see it but don't have
to install. Same path for both optional deps.
Tests (tests/verify/, 155 new tests in 9 files)
anti-slop-linter.test.ts(54) - 7 hard-bans + 5 soft-suggestions
each with KNOWN-BAD + KNOWN-GOOD, plus extractCssFromFile per extanti-slop-fp-rate.test.ts(7) - 100-component canarya11y-axe.test.ts(12) - contrast, alt-missing, [data-wisp-ui] exclusionconsole-scan.test.ts(11) - 3-mode coverage + severity routingtab-order.test.ts(12) - focus-trap, tabindex, focus-ringreduced-motion.test.ts(8) - guard coverage + long-transition failmulti-viewport.test.ts(20) - graceful skip + isLoopbackUrl unit tests- SandboxError code discrimination
gate.test.ts(18) - parallel timing, mode routing, aggregatesaudit-cli.test.ts(13) - exit codes, formats, flag parsing
Cumulative: 502/502 tests green (155 verify + 77 agent/skills + 99
source + 94 browser + 77 bridge + 2 smoke).
npm deps
axe-core ^4.10.0as regulardependencyplaywright ^1.49.0+pixelmatch ^7.1.0asoptionalDependencies@types/pixelmatchas devDep
Open Decision #7 confirmed
warn-default in v0.x, hard-block via audit --mode strict opt-in.
Override-flow via floating-bar with session-log entry.
Phase-5 deferred items (Phase 6+)
- 4 regex tightenings per security audit:
- oklch() branch for
purple-blue-gradient - brace-anchoring for selector windows
- broader CSS-property scan for
default-tailwind-blue(fill/stroke) - file-level aggregation for
round-number-whitespace
- oklch() branch for
- Multi-viewport baseline-comparison + visual regression
- reduced-motion pixelmatch-based two-render diff
- Soft-warn FPR drop from 45.71% to <20% via aggregation fix
Quality gates
typecheck: clean
test: 502/502 in ~5s (33 files)
build: 15 dist bundles (index.js 32.74 kB + 7 verify + 4 agent + live.js)
doctor: 12/12 OK
Next
Phase 6 - Session-Replay + Component-Lib-Awareness. Session logger writes
.wisp/sessions/<id>.jsonl (Improvement #2 vs Impeccable's no-undo);
wisp-design history viewer; component-detect.ts detects shadcn/Radix/
MUI/Tailwind to prefer prop-edits over CSS-overrides (Improvement #11);
structure-variant-mode (Improvement #6); in-session policy-proposal flow
(Improvement #5); morph-mode interpolation between variants (Improvement #3);
plus Phase-5 deferred fixes (anti-slop regex tightenings, FPR aggregation,
multi-viewport baseline comparison).