@design-ai/cli 4.61.0 → 4.63.0

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "design-ai",
3
- "version": "4.61.0",
3
+ "version": "4.63.0",
4
4
  "description": "Senior product designer for any AI coding agent. 20 skills, 17 commands, 4 review agents covering UI/UX, website improvement, design systems, motion, illustration, print, video, game UI, conversational, and spatial design. Korean market depth.",
5
5
  "author": {
6
6
  "name": "Sungjin Park",
package/CHANGELOG.md CHANGED
@@ -2,6 +2,62 @@
2
2
 
3
3
  User-facing release notes for design-ai. Versions follow semver.
4
4
 
5
+ ## v4.63.0 — Dogfood round 2: dashboard-design route and flow-design keyword depth (2026-07)
6
+
7
+ The dogfood loop's second turn, run immediately after v4.62.0 on fresh briefs. It first verified the v4.62 fixes live (flow briefs route to `flow-design`, recall selections are 100% design corpus, `pack` trims to the character boundary), then probed three new task classes and shipped what the weakest one surfaced. Evidence trail in `docs/DOGFOOD-DASHBOARD-FINDINGS.md`. All additive and backward-compatible.
8
+
9
+ ### Added
10
+ - **`dashboard-design` route** — the data-dense screen class (대시보드, 정산, 어드민, 백오피스, KPI / dashboard, admin panel, back-office, analytics) previously matched **zero** route keywords and fell through to design-system scaffolding. The new route curates the knowledge that already existed for this class (`dashboard-composition`, `money-and-amount`, `korean-density-conventions`, `list-and-feed` + layout/typography foundations) and adds data-screen check requirements: money/number formatting evidence, table accessibility (caption/scope/aria-sort), and density/responsive degradation. The settlement-dashboard brief moved from `[low] design-from-brief score=0` to `[medium] dashboard-design score=2`.
11
+ - **`examples/dashboard-design-settlement.md`** (examples now 223) — the route's worked example, adapted from the dogfooded 정산 대시보드 artifact (원화 표기, tabular-nums 우측 정렬, 상태 배지 색+텍스트, 테이블 접근성, 밀도 강등 전략).
12
+
13
+ ### Changed
14
+ - **`flow-design` keywords deepened, verified in both directions.** Korean step-flow vocabulary (위저드, 단계별 플로우, 스텝, 이어하기) lifts an onboarding-wizard brief from `[low] score=1` to `[medium] score=3`; compound states-design keywords (에러 상태, 빈 상태 화면, 상태 설계, 검색 결과 없음, empty state, error state) route a states-design brief to `flow-design [medium] 3` above `illustration [low] 1`, while a genuine illustration brief (빈 상태 일러스트/마스코트) still routes `illustration [high] 4`. The route eval checkpoint stays 6/6 and representative briefs route unchanged.
15
+
16
+ ### Verified
17
+ - All 8 audits passed.
18
+ - `npm run release:check`.
19
+ - `npm run release:metadata`.
20
+ - `git diff --check`.
21
+ - Route eval 6/6; example-qa 21/21 routes; representative-brief routing unchanged.
22
+ - Main-branch GitHub Actions (`Design-AI audit`, `Deploy doc site`) passed for the constituent commits.
23
+
24
+ ### Versions
25
+ - `package.json` + `.claude-plugin/plugin.json`: 4.62.0 → 4.63.0.
26
+ - `vscode-extension/package.json`: remains 0.4.1.
27
+
28
+ ### What this enables
29
+ - The single most common Korean B2B design task class — data-dense dashboard/admin screens — now routes to purpose-built curation and checks, and flow briefs match in the vocabulary Korean users actually write. The loop's second turn also doubles as live regression evidence for everything v4.62.0 shipped.
30
+
31
+ ## v4.62.0 — Dogfood loop: flow-design route, trust & safety corpus, recall purity, SDK walkthrough (2026-07)
32
+
33
+ A full dogfood cycle shipped as one release: a real design task (커뮤니티 앱 신고·차단 플로우) was driven end-to-end through the Agent SDK, and everything the run surfaced — a routing gap, recall pollution, a corpus gap, and a real byte-accounting bug — is fixed here, together with the walkthrough the run produced. See `docs/DOGFOOD-SDK-FINDINGS.md` for the evidence trail.
34
+
35
+ ### Added
36
+ - **`flow-design` route** — interaction/feature-flow briefs (신고, 차단, 온보딩, 가입, 결제 플로우, 설정, 알림 / report, block, onboarding, signup, checkout flows) now route to a dedicated route with flow-appropriate curated skills/knowledge and route-specific check requirements (states/steps, edge/error paths, entry/completion). The dogfood brief moved from `[low] design-from-brief score=1` to `[high] flow-design score=4`; compound keywords were chosen so existing routes' briefs are unaffected (route eval checkpoint still 6/6).
37
+ - **`knowledge/patterns/trust-safety-moderation.md`** (corpus now 95) — report flow and reason taxonomy, moderation status pipeline including the 정보통신망법 제44조의2 임시조치(30일)/이의제기 obligations, block semantics (bidirectional scope, non-notification principle), report-abuse prevention, and the accessibility floor.
38
+ - **`examples/flow-design-report-block.md`** (examples now 222) — the route's top worked example, expanded from the dogfooded artifact.
39
+ - **Agent SDK walkthrough** — `docs/integrations/agent-sdk-walkthrough.md` (+ Korean mirror): a copy-pastable Node consumer script driving `route` → `pack` → author → `check` → `learn.captureFromCheck` with temp-profile isolation, with outputs verified against a live run; linked from the README install table and `docs/SDK.md`, and guarded against drift by `cli/sdk/flow-example.test.mjs`.
40
+
41
+ ### Changed
42
+ - **Recall injection now excludes everything under `docs/`** (`prompt`/`pack --with-recall`, `learn --recall`, `route --explain` related knowledge): recall injects design knowledge, and the design corpus is `knowledge/`, `examples/`, `skills/`, `agents/`, `commands/` — `docs/` is product documentation. The dogfood run showed repo-meta docs outranking real knowledge (docs/case-study.md at #1); enumerating meta files proved whack-a-mole, so the principled directory rule replaced it. Raw `search`/`search --ranked` is unchanged and still returns `docs/` hits.
43
+
44
+ ### Fixed
45
+ - **`pack` could exceed `maxBytes` by 1-2 bytes** when a context file was truncated mid-UTF-8-character: the decoder's 3-byte U+FFFD replacement could outweigh the dangling bytes it replaced. `takeUtf8` now trims to the last complete character boundary before decoding. Caught by the new walkthrough regression guard (which fails on the unfixed code) and additionally covered by a Korean-content budget-sweep invariant test.
46
+
47
+ ### Verified
48
+ - All 8 audits passed.
49
+ - `npm run release:check`.
50
+ - `npm run release:metadata`.
51
+ - `git diff --check`.
52
+ - Main-branch GitHub Actions (`Design-AI audit`, `Deploy doc site`) passed for the constituent commits.
53
+
54
+ ### Versions
55
+ - `package.json` + `.claude-plugin/plugin.json`: 4.61.0 → 4.62.0.
56
+ - `vscode-extension/package.json`: remains 0.4.1.
57
+
58
+ ### What this enables
59
+ - The dogfood loop is closed and shipped: flow briefs route correctly, recall injects only design knowledge, Korean community/social products get trust & safety guidance with the regulatory floor, `pack`'s byte budget is a hard guarantee, and SDK adopters get a verified end-to-end walkthrough.
60
+
5
61
  ## v4.61.0 — Ranked-search eval checkpoint (2026-07)
6
62
 
7
63
  Closes the last open follow-up from the AI-learning Phase A review (FU-3 in `docs/AI-LEARNING-PHASE2.md`): `design-ai search` gains eval-checkpoint modes mirroring the route/prompt/pack/learn pattern, run through the shipped ranked (BM25) search path. This is the standing evidence artifact for any future decision to promote `--ranked` to the default search mode. Additive and backward-compatible; default `search` behavior is unchanged.
package/README.ko.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  [![Audit](https://img.shields.io/badge/audit-passing-brightgreen)](https://github.com/sungjin9288/design-ai/actions/workflows/audit.yml)
4
4
  [![Docs](https://img.shields.io/badge/docs-live-indigo)](https://sungjin9288.github.io/design-ai/ko/)
5
- [![Knowledge files](https://img.shields.io/badge/knowledge-94-blue)](knowledge/PRINCIPLES.md)
6
- [![Examples](https://img.shields.io/badge/examples-221-blue)](examples/README.md)
5
+ [![Knowledge files](https://img.shields.io/badge/knowledge-95-blue)](knowledge/PRINCIPLES.md)
6
+ [![Examples](https://img.shields.io/badge/examples-223-blue)](examples/README.md)
7
7
  [![Skills](https://img.shields.io/badge/skills-20-blue)](skills/README.md)
8
8
 
9
9
  > 🇰🇷 한국어 / [🇺🇸 English](https://github.com/sungjin9288/design-ai/blob/main/README.md)
@@ -12,7 +12,7 @@
12
12
 
13
13
  > **모델이 아니에요. 파인튜닝도 아니에요.** 디자인 전문 지식을 구조화한 코퍼스 + 에이전트가 바로 실행할 수 있는 지시문이에요. 범용 LLM을 이번 세션에서만큼은 시니어 디자이너로 바꿔주는 셈이에요.
14
14
 
15
- > **배포 상태, 2026-07-05 확인:** 로컬 `npm run release:check`는 통과했고, GitHub Pages 문서는 live 상태이며, GitHub Release `v4.60.0`과 npm `@design-ai/cli@4.60.0`(`latest`) publish가 provenance와 함께 확인됐어요. 이번 릴리스는 Agent SDK(`@design-ai/cli/sdk`)에 TypeScript 선언과 opt-in `learn.*` 로컬 쓰기 네임스페이스를 추가했고, 읽기 전용 8 verb는 그대로라 CLI 출력도 변함없어요. live `npm run registry:smoke`가 published `@design-ai/cli@4.60.0`에 대해 깨끗이 통과했어요(retrieval 표면과 route enrichment 포함). Homebrew formula는 `v4.60.0`에 pinning되어 있고, VS Code Marketplace에는 `sungjin.design-ai-vscode@0.4.1`이 공개되어 있어요. 자세한 내용은 [`docs/external-status.md`](docs/external-status.md)를 확인하세요.
15
+ > **배포 상태, 2026-07-06 확인:** 로컬 `npm run release:check`는 통과했고, GitHub Pages 문서는 live 상태이며, GitHub Release `v4.62.0`과 npm `@design-ai/cli@4.62.0`(`latest`) publish가 provenance와 함께 확인됐어요. 이번 릴리스는 도그푸드 루프를 마감했어요 — `flow-design` 라우트, trust & safety 코퍼스 파일과 워크드 예제, recall 주입의 `docs/` 제외(디자인 지식 전용), `pack` UTF-8 바이트 예산 픽스, Agent SDK 워크스루(영/한). live `npm run registry:smoke`가 published `@design-ai/cli@4.62.0`에 대해 깨끗이 통과했어요(retrieval 표면과 route enrichment 포함). Homebrew formula는 `v4.62.0`에 pinning되어 있고, VS Code Marketplace에는 `sungjin.design-ai-vscode@0.4.1`이 공개되어 있어요. 자세한 내용은 [`docs/external-status.md`](docs/external-status.md)를 확인하세요.
16
16
 
17
17
  ## 한눈에 보는 커버리지
18
18
 
@@ -88,7 +88,7 @@ CLI 명령어: `design-ai install [--json]`, `update [--dry-run] [--json]`, `uni
88
88
  | **Cursor** | 이 폴더를 열고 `AGENTS.md`를 `.cursorrules`로 심볼릭 링크하거나 복사해요. [워크스루](docs/integrations/cursor-walkthrough.md). |
89
89
  | **Aider** | `AGENTS.md`를 시스템 프롬프트로 전달해요. [워크스루](docs/integrations/aider-walkthrough.md). |
90
90
  | **Anthropic / OpenAI SDK** | 관련 스킬 `PLAYBOOK.md` 파일을 프롬프트에 포함시켜요. [워크스루](docs/integrations/sdk-walkthrough.md). |
91
- | **Node.js / Agent SDK** | `import { route, prompt, pack, search, recall, check, routes, version } from "@design-ai/cli/sdk"` — CLI 셸 실행이나 MCP 서버 없이 design-ai의 결정적 기능을 함수로 바로 호출해요. 읽기 전용(Phase A). [SDK 레퍼런스](docs/SDK.md). |
91
+ | **Node.js / Agent SDK** | `import { route, prompt, pack, search, recall, check, routes, version } from "@design-ai/cli/sdk"` — CLI 셸 실행이나 MCP 서버 없이 design-ai의 결정적 기능을 함수로 바로 호출해요. 읽기 전용(Phase A). [SDK 레퍼런스](docs/SDK.md). [워크스루](docs/integrations/agent-sdk-walkthrough.md). |
92
92
  | **일반 프롬프트** | 어떤 `skills/*/PLAYBOOK.md` 본문이든 붙여넣으세요 — 각각 자기 완결적이에요. |
93
93
 
94
94
  에이전트별 설치 방법은 [`docs/USING.md`](docs/USING.md)를, 구체적인 사용 예시는 위 워크스루 링크를 참고하세요.
@@ -172,7 +172,7 @@ design-ai는 한국 시장을 1순위로 만들어졌고, 글로벌 시장 패
172
172
 
173
173
  ## 상태
174
174
 
175
- 전체 단계 로그는 [`docs/ROADMAP.md`](docs/ROADMAP.md), 현재 완료 범위는 [`docs/PRODUCT-READINESS.md`](docs/PRODUCT-READINESS.md)에서 확인하세요. 현재 **v4.60.0**: Agent SDK(`@design-ai/cli/sdk`) — TypeScript 선언 + opt-in `learn.*` 로컬 쓰기 네임스페이스, public npm publish, provenance-backed GitHub Actions release, public registry smoke, Website Console MCP readiness, workspace learning restore/eval coverage, handoff bundle verification, 90%+ component coverage가 완료됐어요.
175
+ 전체 단계 로그는 [`docs/ROADMAP.md`](docs/ROADMAP.md), 현재 완료 범위는 [`docs/PRODUCT-READINESS.md`](docs/PRODUCT-READINESS.md)에서 확인하세요. 현재 **v4.62.0**: 도그푸드 루프 마감(`flow-design` 라우트, trust & safety 코퍼스, 디자인 지식 전용 recall, `pack` 바이트 예산 보장, SDK 워크스루), ranked-search eval 체크포인트(`search --eval`), Agent SDK(`@design-ai/cli/sdk`) — TypeScript 선언 + opt-in `learn.*` 로컬 쓰기 네임스페이스, public npm publish, provenance-backed GitHub Actions release, public registry smoke, Website Console MCP readiness, workspace learning restore/eval coverage, handoff bundle verification, 90%+ component coverage가 완료됐어요.
176
176
 
177
177
  핵심 디자인 컨설팅 워크플로우는 로컬 릴리스 기준으로 준비되어 있어요. 웹사이트 개선 컨트롤 타워는 zero-dependency static Web App과 `website-improvement` route/skill/command로 제공되고, Site Profile, audit checklist, MCP readiness, refactor prompt, handoff evidence tracking, bundle export/verify/repair를 한 번에 다뤄요. 로컬 학습 선호도는 `design-ai learn`으로 관리해요 — profile bootstrap, feedback 캡처, 읽기 전용 signal registry, 반복 QA 신호에서 만드는 skill 제안, 그리고 backup/restore/curate/audit까지 전부 로컬에서만 동작하는 opt-in 기능이에요. AI 모델 학습이나 fine-tuning은 여전히 현재 배포 범위 밖이에요.
178
178
 
package/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  [![Audit](https://img.shields.io/badge/audit-passing-brightgreen)](https://github.com/sungjin9288/design-ai/actions/workflows/audit.yml)
4
4
  [![Docs](https://img.shields.io/badge/docs-live-indigo)](https://sungjin9288.github.io/design-ai/)
5
- [![Knowledge files](https://img.shields.io/badge/knowledge-94-blue)](knowledge/PRINCIPLES.md)
6
- [![Examples](https://img.shields.io/badge/examples-221-blue)](examples/README.md)
5
+ [![Knowledge files](https://img.shields.io/badge/knowledge-95-blue)](knowledge/PRINCIPLES.md)
6
+ [![Examples](https://img.shields.io/badge/examples-223-blue)](examples/README.md)
7
7
  [![Skills](https://img.shields.io/badge/skills-20-blue)](skills/README.md)
8
8
 
9
9
  > 🇺🇸 English / [🇰🇷 한국어](https://github.com/sungjin9288/design-ai/blob/main/README.ko.md)
@@ -12,7 +12,7 @@ A model-agnostic design knowledge base + skill system. Drop it in front of any A
12
12
 
13
13
  > **Not a model. Not a fine-tune.** A structured corpus of design expertise + agent-ready instructions that turn a general-purpose LLM into an expert.
14
14
 
15
- > **Distribution status, checked 2026-07-05:** local `npm run release:check` passes, GitHub Pages docs are live, GitHub Release `v4.60.0` is published, `@design-ai/cli@4.60.0` is public on npm (`latest`) with provenance, and the live `npm run registry:smoke` passes cleanly against `@design-ai/cli@4.60.0`. The Homebrew formula is pinned to `v4.60.0`, and `sungjin.design-ai-vscode@0.4.1` is public on the VS Code Marketplace. See [`docs/external-status.md`](docs/external-status.md).
15
+ > **Distribution status, checked 2026-07-06:** local `npm run release:check` passes, GitHub Pages docs are live, GitHub Release `v4.62.0` is published, `@design-ai/cli@4.62.0` is public on npm (`latest`) with provenance, and the live `npm run registry:smoke` passes cleanly against `@design-ai/cli@4.62.0`. The Homebrew formula is pinned to `v4.62.0`, and `sungjin.design-ai-vscode@0.4.1` is public on the VS Code Marketplace. See [`docs/external-status.md`](docs/external-status.md).
16
16
 
17
17
  ## Coverage at a glance
18
18
 
@@ -89,7 +89,7 @@ See [`docs/DISTRIBUTION.md`](docs/DISTRIBUTION.md) for the full distribution gui
89
89
  | **Aider** | Pass `AGENTS.md` as system prompt. [Walkthrough](docs/integrations/aider-walkthrough.md). |
90
90
  | **Anthropic / OpenAI SDK** | Embed relevant skill `PLAYBOOK.md` files in your prompt. [Walkthrough](docs/integrations/sdk-walkthrough.md). |
91
91
  | **VS Code** | Install the public Marketplace extension for sidebar trees + quick-pick commands. [Walkthrough](docs/integrations/vscode-walkthrough.md). |
92
- | **Node.js / Agent SDK** | `import { route, prompt, pack, search, recall, check, routes, version } from "@design-ai/cli/sdk"` — call design-ai's deterministic verbs as functions, no CLI shell-out or MCP server needed. Read-only (Phase A). [SDK reference](docs/SDK.md). |
92
+ | **Node.js / Agent SDK** | `import { route, prompt, pack, search, recall, check, routes, version } from "@design-ai/cli/sdk"` — call design-ai's deterministic verbs as functions, no CLI shell-out or MCP server needed. Read-only (Phase A). [SDK reference](docs/SDK.md). [Walkthrough](docs/integrations/agent-sdk-walkthrough.md). |
93
93
  | **Plain prompt** | Paste any `skills/*/PLAYBOOK.md` body — each is self-contained. |
94
94
 
95
95
  See [`docs/USING.md`](docs/USING.md) for per-agent setup details, or the linked walkthroughs for concrete example sessions.
@@ -214,7 +214,7 @@ Refresh refs/ on demand: `./tools/extractors/run-all.sh`.
214
214
 
215
215
  ## Status
216
216
 
217
- See [`docs/ROADMAP.md`](docs/ROADMAP.md) for the full phase log and [`docs/PRODUCT-READINESS.md`](docs/PRODUCT-READINESS.md) for the current completion boundary. Currently at **v4.60.0**: the Agent SDK (`@design-ai/cli/sdk`) with shipped TypeScript types and the opt-in `learn.*` local-write namespace, public npm publish, provenance-backed GitHub Actions release, public registry smoke, Website Console MCP readiness, workspace learning restore/eval coverage, handoff bundle verification, and 90%+ component coverage are complete.
217
+ See [`docs/ROADMAP.md`](docs/ROADMAP.md) for the full phase log and [`docs/PRODUCT-READINESS.md`](docs/PRODUCT-READINESS.md) for the current completion boundary. Currently at **v4.62.0**: the closed dogfood loop (`flow-design` route, trust & safety corpus, design-knowledge-only recall, `pack` byte-budget guarantee, SDK walkthrough), the ranked-search eval checkpoint (`search --eval`), the Agent SDK (`@design-ai/cli/sdk`) with shipped TypeScript types and the opt-in `learn.*` local-write namespace, public npm publish, provenance-backed GitHub Actions release, public registry smoke, Website Console MCP readiness, workspace learning restore/eval coverage, handoff bundle verification, and 90%+ component coverage are complete.
218
218
 
219
219
  Core design consulting workflows are locally release-ready. The website improvement control tower ships as a zero-dependency static Web App plus a `website-improvement` route/skill/command, covering Site Profiles, audit checklists, MCP readiness, refactor prompts, handoff evidence tracking, and bundle export/verify/repair. Local learning preferences are available through `design-ai learn` — profile bootstrap, feedback capture, a read-only signals registry, skill-proposal generation from repeated QA signals, and full backup/restore/curate/audit tooling, all local-only and opt-in. AI model training or fine-tuning remains outside the shipped scope.
220
220
 
package/cli/lib/check.mjs CHANGED
@@ -361,6 +361,62 @@ const ROUTE_REQUIREMENTS = {
361
361
  ],
362
362
  },
363
363
  ],
364
+ "flow-design": [
365
+ {
366
+ id: "flow-states-steps",
367
+ title: "Flow states and steps coverage",
368
+ required: [
369
+ { label: "steps or stages", patterns: [/\b(step|stage|sequence)\b/i, /단계|순서/] },
370
+ { label: "state", patterns: [/\b(state|status)\b/i, /상태/] },
371
+ { label: "transition between states", patterns: [/\b(transition|move[sd]? to|becomes?)\b/i, /전환|이동/] },
372
+ ],
373
+ },
374
+ {
375
+ id: "flow-edge-cases",
376
+ title: "Flow edge case and error path coverage",
377
+ required: [
378
+ { label: "error or failure path", patterns: [/\b(error|failure|fail(?:ed|s)?)\b/i, /에러|오류|실패/] },
379
+ { label: "cancel or abandon path", patterns: [/\b(cancel|abandon|back out|dismiss)\b/i, /취소|중단/] },
380
+ { label: "edge case", patterns: [/\bedge case\b/i, /예외|엣지 ?케이스/] },
381
+ ],
382
+ },
383
+ {
384
+ id: "flow-entry-exit",
385
+ title: "Flow entry, exit, and completion coverage",
386
+ required: [
387
+ { label: "entry point", patterns: [/\b(entry point|entry|trigger)\b/i, /진입점|진입/] },
388
+ { label: "completion or success", patterns: [/\b(complete|completion|success|done)\b/i, /완료|성공/] },
389
+ { label: "exit or abandonment", patterns: [/\b(exit|leave|drop[- ]?off|abandonment)\b/i, /이탈|나가기/] },
390
+ ],
391
+ },
392
+ ],
393
+ "dashboard-design": [
394
+ {
395
+ id: "dashboard-money-format",
396
+ title: "Amount, unit, and number-format coverage",
397
+ required: [
398
+ { label: "amount or currency", patterns: [/\b(amount|currency|price)\b/i, /금액|원\b/] },
399
+ { label: "number formatting", patterns: [/\b(comma|tabular[- ]nums?|number format|right[- ]align(?:ed)?)\b/i, /콤마|천\s*단위|우측\s*정렬/] },
400
+ ],
401
+ },
402
+ {
403
+ id: "dashboard-table-a11y",
404
+ title: "Table accessibility coverage",
405
+ required: [
406
+ { label: "table structure", patterns: [/\btable\b/i, /테이블/] },
407
+ { label: "caption or header scope", patterns: [/\b(caption|scope=|column header)\b/i, /캡션|헤더/] },
408
+ { label: "sort state", patterns: [/\baria-sort\b/i] },
409
+ ],
410
+ },
411
+ {
412
+ id: "dashboard-density-responsive",
413
+ title: "Density and responsive degradation coverage",
414
+ required: [
415
+ { label: "density", patterns: [/\b(density|dense|compact)\b/i, /밀도|촘촘/] },
416
+ { label: "responsive degradation", patterns: [/\b(responsive|horizontal scroll|degrade[sd]?|demote[sd]?)\b/i, /강등|가로\s*스크롤/] },
417
+ ],
418
+ },
419
+ ],
364
420
  };
365
421
 
366
422
  function routeRequirementResult(routeId, requirement, text) {
@@ -31,6 +31,8 @@ const ROUTE_EXAMPLE_QUERIES = {
31
31
  "figma-token-sync": "token palette",
32
32
  "design-pr-review": "dogfood findings review",
33
33
  "stability-review": "dogfood findings release",
34
+ "flow-design": "flow report block moderation onboarding",
35
+ "dashboard-design": "dashboard settlement admin data table KPI",
34
36
  };
35
37
 
36
38
  const ROUTE_CATEGORY_BOOSTS = {
@@ -53,6 +55,8 @@ const CANONICAL_ROUTE_EXAMPLES = {
53
55
  "print": ["examples/print-business-card-spec.md", "examples/print-packaging-spec.md"],
54
56
  "game-ui": ["examples/component-game-menu.md"],
55
57
  "slide-deck": ["examples/slide-deck-example.md"],
58
+ "flow-design": ["examples/flow-design-report-block.md"],
59
+ "dashboard-design": ["examples/dashboard-design-settlement.md"],
56
60
  };
57
61
 
58
62
  export function parseExamplesArgs(args) {
package/cli/lib/pack.mjs CHANGED
@@ -150,6 +150,33 @@ export function parsePackArgs(args) {
150
150
  };
151
151
  }
152
152
 
153
+ // UTF-8 continuation bytes have the high bits `10xxxxxx` (0x80-0xBF). A slice
154
+ // that stops mid-character ends with 1-3 leading bytes of a multi-byte
155
+ // sequence and no continuation bytes yet — trimming those dangling leading
156
+ // bytes keeps the slice on a clean character boundary.
157
+ function trimIncompleteUtf8Tail(bytes) {
158
+ let end = bytes.length;
159
+ // A byte is a "leading" byte of a multi-byte sequence if its top two bits
160
+ // are `11` (0xC0-0xFF); continuation bytes are `10xxxxxx` (0x80-0xBF).
161
+ // Walk back over trailing continuation bytes, then drop the leading byte
162
+ // that started the (now truncated) sequence, unless that leading byte
163
+ // already had enough continuation bytes to be complete.
164
+ let back = 0;
165
+ while (end - back - 1 >= 0 && (bytes[end - back - 1] & 0xc0) === 0x80 && back < 3) {
166
+ back += 1;
167
+ }
168
+ const leadIndex = end - back - 1;
169
+ if (leadIndex >= 0) {
170
+ const lead = bytes[leadIndex];
171
+ const expectedLength = lead >= 0xf0 ? 4 : lead >= 0xe0 ? 3 : lead >= 0xc0 ? 2 : 1;
172
+ const availableLength = end - leadIndex;
173
+ if (expectedLength > availableLength) {
174
+ end = leadIndex;
175
+ }
176
+ }
177
+ return bytes.subarray(0, end);
178
+ }
179
+
153
180
  function takeUtf8(content, maxBytes) {
154
181
  const buf = Buffer.from(content, "utf8");
155
182
  if (buf.byteLength <= maxBytes) {
@@ -160,7 +187,8 @@ function takeUtf8(content, maxBytes) {
160
187
  };
161
188
  }
162
189
 
163
- const sliced = buf.subarray(0, Math.max(0, maxBytes)).toString("utf8");
190
+ const boundedBytes = trimIncompleteUtf8Tail(buf.subarray(0, Math.max(0, maxBytes)));
191
+ const sliced = boundedBytes.toString("utf8");
164
192
  return {
165
193
  content: sliced,
166
194
  bytes: Buffer.byteLength(sliced, "utf8"),
@@ -109,7 +109,7 @@ export function buildRecallContext({
109
109
  const candidateCount = collectCorpusDocuments({ designAiPath, dirs }).length;
110
110
 
111
111
  const hits = query
112
- ? rankedSearchCorpus({ query, designAiPath, dirs, limit: recallLimit, excludeGeneratedIndex: true }).hits
112
+ ? rankedSearchCorpus({ query, designAiPath, dirs, limit: recallLimit, excludeNonKnowledge: true }).hits
113
113
  : [];
114
114
 
115
115
  const selected = hits.map((hit) => ({
@@ -150,7 +150,7 @@ export function buildLearnRecall({
150
150
 
151
151
  const corpusCandidateCount = collectCorpusDocuments({ designAiPath, dirs }).length;
152
152
  const corpusHits = normalizedQuery
153
- ? rankedSearchCorpus({ query: normalizedQuery, designAiPath, dirs, limit, excludeGeneratedIndex: true }).hits
153
+ ? rankedSearchCorpus({ query: normalizedQuery, designAiPath, dirs, limit, excludeNonKnowledge: true }).hits
154
154
  : [];
155
155
  const corpusSelected = corpusHits.map((hit) => ({
156
156
  id: hit.relPath,
package/cli/lib/route.mjs CHANGED
@@ -284,6 +284,60 @@ export const ROUTES = [
284
284
  ],
285
285
  keywords: ["release", "stability", "stale", "quarterly", "launch", "릴리스", "안정화", "오래된", "출시"],
286
286
  },
287
+ {
288
+ id: "flow-design",
289
+ label: "Feature flow design",
290
+ command: null,
291
+ skills: ["skills/ux-audit/SKILL.md", "skills/design-critique/SKILL.md"],
292
+ agents: ["agents/a11y-reviewer.md"],
293
+ knowledge: [
294
+ "knowledge/patterns/ui-reasoning.md",
295
+ "knowledge/patterns/async-control.md",
296
+ "knowledge/patterns/trust-safety-moderation.md",
297
+ "knowledge/patterns/form-design.md",
298
+ "knowledge/patterns/error-states.md",
299
+ "knowledge/patterns/onboarding.md",
300
+ ],
301
+ keywords: [
302
+ "플로우", "신고", "차단", "온보딩", "회원가입", "결제 플로우", "설정 화면", "알림 설정",
303
+ "모더레이션", "처리 상태", "사용자 여정",
304
+ "flow design", "onboarding flow", "sign-up flow", "signup flow", "checkout flow",
305
+ "report flow", "block flow", "moderation flow", "user journey", "wizard", "stepper",
306
+ "settings screen", "notification settings",
307
+ // G-2 (docs/DOGFOOD-DASHBOARD-FINDINGS.md): Korean wizard/step vocabulary that the
308
+ // v4.62 keyword set missed (English wizard/stepper made it in, Korean forms didn't).
309
+ "위저드", "단계별 플로우", "스텝", "이어하기",
310
+ // G-3 (docs/DOGFOOD-DASHBOARD-FINDINGS.md): compound state-design keywords so a
311
+ // states-design brief outscores illustration's bare `빈 상태` hit. Kept compound
312
+ // (not bare `상태`/`에러`/`빈`) to avoid hijacking other routes' bare terms.
313
+ "에러 상태", "빈 상태 화면", "상태 설계", "검색 결과 없음", "empty state", "error state",
314
+ ],
315
+ },
316
+ {
317
+ id: "dashboard-design",
318
+ label: "Dashboard / data screen design",
319
+ command: null,
320
+ skills: ["skills/design-critique/SKILL.md", "skills/handoff-spec/SKILL.md"],
321
+ agents: ["agents/a11y-reviewer.md"],
322
+ knowledge: [
323
+ "knowledge/patterns/dashboard-composition.md",
324
+ "knowledge/patterns/money-and-amount.md",
325
+ "knowledge/i18n/korean-density-conventions.md",
326
+ "knowledge/patterns/list-and-feed.md",
327
+ "knowledge/layout/spacing-and-grid.md",
328
+ "knowledge/typography/type-scale-fundamentals.md",
329
+ ],
330
+ keywords: [
331
+ // G-1 (docs/DOGFOOD-DASHBOARD-FINDINGS.md): dashboard/admin/back-office screen
332
+ // briefs previously matched zero route keywords and fell through to
333
+ // design-from-brief. Compound where a bare term would hijack another route
334
+ // (`테이블` bare belongs to component-spec; `데이터` bare is too generic for any
335
+ // single route, so it is only used here in the compound `데이터 테이블`).
336
+ "대시보드", "정산", "매출 화면", "지표", "어드민", "백오피스", "데이터 테이블",
337
+ "정산 내역", "KPI",
338
+ "dashboard", "admin panel", "back-office", "back office", "analytics screen", "data table",
339
+ ],
340
+ },
287
341
  ];
288
342
 
289
343
  export function routeIds() {
@@ -482,9 +536,10 @@ function relatedKnowledgeFor({ brief, sourceRoot, curatedRelPaths }) {
482
536
  dirs: RELATED_KNOWLEDGE_DIRS,
483
537
  limit: RELATED_KNOWLEDGE_RECALL_LIMIT,
484
538
  designAiPath: sourceRoot,
485
- // Recall/injection surface: keep generated index/meta docs (COVERAGE.md,
486
- // INDEX.md, docs/reference/*) out of the advisory related-knowledge list.
487
- excludeGeneratedIndex: true,
539
+ // Recall/injection surface: keep non-knowledge docs (generated index/meta docs,
540
+ // package-excluded repo-meta docs, docs/integrations/ walkthroughs) out of the
541
+ // advisory related-knowledge list (docs/DOGFOOD-SDK-FINDINGS.md, F-2).
542
+ excludeNonKnowledge: true,
488
543
  });
489
544
 
490
545
  return hits
@@ -40,6 +40,24 @@ export function isGeneratedIndexDoc(relPath) {
40
40
  || normalized.startsWith("docs/reference/");
41
41
  }
42
42
 
43
+ // Predicate for the full RECALL-injection exclusion set (docs/DOGFOOD-SDK-FINDINGS.md,
44
+ // F-2): generated index/meta docs (isGeneratedIndexDoc) OR anything under docs/.
45
+ // Rationale: recall injects DESIGN KNOWLEDGE into an agent's context, and the
46
+ // design corpus lives in knowledge/, examples/, skills/, agents/, commands/ —
47
+ // docs/ is product documentation (guides, roadmap, dogfood/inspection records,
48
+ // portfolio material, integration walkthroughs). Enumerating individual meta
49
+ // files proved to be whack-a-mole: the Phase 764 dogfood first surfaced
50
+ // docs/case-study.md ranked #1, and the follow-up probe surfaced
51
+ // docs/DOGFOOD-SDK-FINDINGS.md itself at 3x the top knowledge score because it
52
+ // quotes the brief's vocabulary. Same recall-injection-surfaces-only boundary
53
+ // as isGeneratedIndexDoc: raw `search --ranked` never applies this — a user
54
+ // explicitly searching docs/ still gets docs/ hits.
55
+ export function isRecallExcludedDoc(relPath) {
56
+ const normalized = String(relPath || "").replace(/\\/g, "/");
57
+ return isGeneratedIndexDoc(normalized)
58
+ || normalized.startsWith("docs/");
59
+ }
60
+
43
61
  // N = max(limit*5, 25): the number of top lexical candidates handed to the embedding
44
62
  // reranker. Documented constant (docs/AI-LEARNING-PHASE2.md, Phase B CLI wiring).
45
63
  export function embeddingCandidateCount(limit) {
@@ -82,25 +100,27 @@ export function rankedSearchCorpus({
82
100
  dirs = DEFAULT_SEARCH_DIRS,
83
101
  limit = 20,
84
102
  indexDir = defaultIndexDir(),
85
- // Opt-in RECALL filter: when true, drop generated index/meta docs
86
- // (isGeneratedIndexDoc) BEFORE applying `limit`, so the limit fills with real
87
- // knowledge instead of index files. Default false keeps raw `search --ranked`
88
- // byte-unchanged. Filtering before the limit preserves determinism (score desc,
89
- // id asc) the rank pass already orders fully, we only remove excluded ids.
90
- excludeGeneratedIndex = false,
103
+ // Opt-in RECALL filter: when true, drop non-knowledge docs (isRecallExcludedDoc —
104
+ // generated index/meta docs, package-excluded repo-meta docs, docs/integrations/
105
+ // walkthroughs) BEFORE applying `limit`, so the limit fills with real knowledge
106
+ // instead of those files. Default false keeps raw `search --ranked` byte-unchanged.
107
+ // Filtering before the limit preserves determinism (score desc, id asc) the rank
108
+ // pass already orders fully, we only remove excluded ids.
109
+ excludeNonKnowledge = false,
91
110
  } = {}) {
92
111
  const documents = collectCorpusDocuments({ designAiPath, dirs });
93
112
  const stats = buildLexicalStats(documents.map(({ id, text }) => ({ id, text })));
94
113
  const textById = new Map(documents.map((doc) => [doc.id, doc.text]));
95
114
 
96
115
  // When excluding, rank the FULL candidate pool first (limit = documents.length)
97
- // so that filtering out index docs cannot let a real-knowledge hit fall off the
98
- // pre-limit cutoff; then re-apply `limit`. Ordering is unchanged (score desc, id asc).
116
+ // so that filtering out non-knowledge docs cannot let a real-knowledge hit fall
117
+ // off the pre-limit cutoff; then re-apply `limit`. Ordering is unchanged (score
118
+ // desc, id asc).
99
119
  const ranked = rankLexical(query, stats, {
100
- limit: excludeGeneratedIndex ? documents.length : limit,
120
+ limit: excludeNonKnowledge ? documents.length : limit,
101
121
  });
102
- const filtered = excludeGeneratedIndex
103
- ? ranked.filter((hit) => !isGeneratedIndexDoc(hit.id)).slice(0, limit)
122
+ const filtered = excludeNonKnowledge
123
+ ? ranked.filter((hit) => !isRecallExcludedDoc(hit.id)).slice(0, limit)
104
124
  : ranked;
105
125
 
106
126
  const hits = filtered.map((hit) => ({
@@ -205,6 +205,17 @@ This review answers the five open questions against the shipped Phase A implemen
205
205
  - **FU-3 (Q1, gates default promotion):** Land a ranked-search eval checkpoint so any future `--ranked` default promotion is evidence-backed and announced. _Done (2026-07-05): `design-ai search --eval-template`/`--eval [--strict]` landed in `cli/lib/search-eval.mjs` and `cli/commands/search.mjs`, mirroring the route/prompt/pack/learn eval-checkpoint pattern; cases run through `rankedSearchCorpus` (the shipped ranked path), and the default template includes the three Korean particle-form regression cases from FU-1 (버튼/버튼을/접근성이) plus English cases, doubling as a retrieval-level Hangul-bigram regression check._
206
206
  - **FU-4 (Q5, Phase B):** Specify and implement `~/.design-ai/config.json` as the Phase B provider config home with per-invocation `--embeddings` still required. _Done (2026-07-03, Phase B): `cli/lib/local-config.mjs` reads `~/.design-ai/config.json` (or `DESIGN_AI_CONFIG_FILE`); the config only supplies the provider — every invocation still requires the explicit `--embeddings` flag to arm it._
207
207
 
208
+ ### Ranked-default decision closure (2026-07-06)
209
+
210
+ With FU-3 landed and shipped (v4.61.0), the promotion question that Decision 1 deferred was formally revisited and **closed for the 4.x line: `search --ranked` remains opt-in across all three surfaces (CLI, MCP `design_ai_search`, SDK `search()`)**. The evidence and reasoning:
211
+
212
+ - **The two modes answer different questions.** Default `search` is grep-like — line-precise hits (`lineNumber`) that feed the `show file:line` workflow. Ranked is retrieval-like — file-level relevance (`score`, `matchedTokens`). Neither is a strict upgrade of the other; flipping the default would remove the line-precise contract rather than improve it.
213
+ - **The SDK semver contract now binds the default.** Since v4.59.0/v4.60.0, `search(query)`'s unranked return shape (including `lineNumber`) is pinned by the SDK contract test as a semver-stable surface. Changing any surface's default without the others desynchronizes CLI/MCP/SDK; changing all three is by definition a major-version event — exactly the "announced major-version default change, never a silent one" bar Decision 1 set.
214
+ - **The practical benefit is already absorbed.** Every surface where relevance ranking matters (recall injection in `prompt`/`pack`, `learn --recall`, `route --explain` related knowledge) already uses the ranked scorer internally. The remaining delta from flipping the interactive default is small, and agent consumers opt in explicitly today.
215
+ - **Quality stays evidence-backed either way.** The FU-3 checkpoint (`search --eval`, 6/6 passing incl. the Korean particle-form cases) runs in the release gates, so ranked quality is continuously measured without needing the default flip to justify the eval.
216
+
217
+ If a future major version (5.0) reopens this, the prerequisites are already written: flip CLI + MCP + SDK defaults together, provide a line-hit escape hatch (e.g. `--lines`), re-pin the smoke assertions and SDK contract in the same change, and cite the then-current FU-3 eval results in the CHANGELOG announcement.
218
+
208
219
  ### Phase B gate: cleared-with-conditions
209
220
 
210
221
  Phase B may be scheduled. Conditions that must be met before or during Phase B:
@@ -0,0 +1,52 @@
1
+ # Dogfood findings — dashboard/data-screen class (Phase 766)
2
+
3
+ Second dogfood pass, run immediately after the v4.62.0 dogfood-loop release to (a) verify the v4.62 fixes hold on fresh briefs and (b) probe a different task class. Method identical to [DOGFOOD-SDK-FINDINGS.md](DOGFOOD-SDK-FINDINGS.md): the full SDK flow (`route` → `pack --withRecall` → author → `check` → `learn.captureFromCheck`, temp-profile isolated), preceded by a cheap three-brief routing/recall probe to pick the weakest class.
4
+
5
+ **Probe briefs** (three distinct classes): 정산 대시보드 (settlement dashboard), B2B 온보딩 위저드 (onboarding wizard), 빈 상태·에러 상태 설계 (empty/error states). The settlement dashboard scored worst and became the full run's brief.
6
+
7
+ ## v4.62 regression evidence (all three fixes verified live)
8
+
9
+ - **`flow-design` route works**: the onboarding-wizard probe routed to `flow-design` (was impossible before v4.62). Confidence was only `[low] score=1` — see G-2.
10
+ - **Recall purity holds**: every probe's recall selections were 100% design corpus (`knowledge/`, `examples/`) — zero `docs/` entries, where the round-1 probes had repo-meta docs at #1.
11
+ - **`pack` byte-budget guarantee holds**: the 60,000-byte pack used 59,998 bytes — the character-boundary trim landing 2 bytes under budget instead of the pre-fix "fill exactly and sometimes overflow".
12
+
13
+ ## The full run (settlement dashboard)
14
+
15
+ **Brief**: 커머스 셀러용 정산 대시보드 설계 — 일별 매출·수수료·정산 예정 금액 표, 기간 필터, 엑셀 내보내기, 미정산 알림.
16
+
17
+ - `route()`: `[low] design-from-brief score=0, matched=[]` — **zero keyword hits**, pure fallback. Worse than round 1's report/block brief (score=1).
18
+ - `pack()`: the fallback route curates design-system skills (`color-palette`, `design-system-builder`) and foundation knowledge; `dashboard-composition.md` reached the pack only through the recall block, and `money-and-amount.md` / `korean-density-conventions.md` not at all — despite `relatedKnowledge` correctly surfacing dashboard-composition (27) and money-and-amount (13). The knowledge exists; no route curates it.
19
+ - `check(artifact, { routeId: "design-from-brief" })`: `warn 9/10`, the single warn again being `route-design-from-brief-design-system-foundation` — the same route-mismatch fingerprint as round 1, on a different class.
20
+ - `learn.captureFromCheck`: `added 1, skipped 0` into the temp profile; real profile untouched.
21
+
22
+ ## Findings
23
+
24
+ ### G-1. Route-table gap: data-dense screen briefs (dashboard/admin/back-office) have no route
25
+
26
+ The dashboard class — 정산·매출·지표·어드민·백오피스 screens, arguably the single most common Korean B2B design task — falls through with **zero** keyword matches, landing on design-system scaffolding skills. The curated knowledge for this class already exists and is strong: `patterns/dashboard-composition.md`, `patterns/money-and-amount.md`, `i18n/korean-density-conventions.md`, `patterns/list-and-feed.md`, plus layout/typography foundations.
27
+
28
+ **Proposed fix**: a `dashboard-design` route (`command: null`, like `flow-design`): keywords 대시보드, 정산, 매출 화면, 지표, KPI, 어드민, 백오피스, 데이터 테이블, dashboard, admin, back-office, analytics, KPI, data table; curated knowledge as above; check requirements suited to data screens (금액/단위 표기 evidence, 테이블 접근성, 밀도/반응형 강등 전략); a worked example adapted from this run's artifact (example-qa gate).
29
+
30
+ _Done (2026-07-06): `dashboard-design` route added to `cli/lib/route.mjs` (`command: null`, mirroring `flow-design`/`handoff-spec`), with skills `design-critique` + `handoff-spec`, agent `a11y-reviewer`, and curated knowledge `dashboard-composition.md`, `money-and-amount.md`, `korean-density-conventions.md`, `list-and-feed.md`, `spacing-and-grid.md`, `type-scale-fundamentals.md`. Keywords: 대시보드, 정산, 매출 화면, 지표, 어드민, 백오피스, 데이터 테이블, 정산 내역, KPI, dashboard, admin panel, back-office, back office, analytics screen, data table — compound where a bare term would hijack another route (`테이블` bare stays owned by `component-spec`; `데이터` bare is never used alone). Re-ran the dogfood brief: `route()` now returns `[medium] dashboard-design score=2` (matched `대시보드`, `정산`) — up from the prior `[low] design-from-brief score=0, matched=[]` zero-hit fallback. Added `ROUTE_REQUIREMENTS["dashboard-design"]` to `cli/lib/check.mjs` (money/number-format evidence, table accessibility incl. `aria-sort`, density/responsive degradation — bilingual patterns mirroring house style); checking the dogfooded settlement artifact directly against `--route dashboard-design` scores `pass 12/12` (all 9 base checks plus all 3 new route-specific requirements). Added `examples/dashboard-design-settlement.md`, an expanded version of the dogfooded artifact (explicit `<caption>`/`scope="col"`/`aria-sort` table markup, 4.5:1 contrast ratio, export-failure and empty-result edge cases) that satisfies every example-qa bar (12/12) and is the top-ranked example for the route (canonical-boosted score 42 vs. next-best 24). Wired into `cli/lib/examples.mjs` (`ROUTE_EXAMPLE_QUERIES` + `CANONICAL_ROUTE_EXAMPLES`) and `examples/README.md`. Appended `dashboard-design` to the `EXPECTED_ROUTE_CATALOG_IDS` tuple in `tools/audit/smoke_assertions.py` (shared by `package-smoke.py` and `registry-smoke.py`) and bumped both README example-count badges (222 → 223, matching `check-coverage.py`'s top-level-only `examples/*.md` count). `knowledge/COVERAGE.md` was left to its normal regeneration via `tools/audit/check-coverage.py`, matching the F-1 precedent. `example-qa` now reports `21/21 routes and 21/21 examples pass` (was 20/20)._
31
+
32
+ ### G-2. `flow-design` keyword gaps: Korean wizard/step vocabulary missing
33
+
34
+ The onboarding-wizard probe — unambiguously a flow brief — matched only `온보딩` (`score=1 [low]`). 위저드, 단계(별), 이어하기 and similar step-flow Korean vocabulary are absent from the v4.62 keyword set (English `wizard`/`stepper` made it in; the Korean forms didn't).
35
+
36
+ **Proposed fix**: additive keywords on `flow-design` (위저드, 단계별 플로우, 스텝, 이어하기, 팀 초대 …), gated by the route eval checkpoint and the round-1 brief still scoring `[high]`.
37
+
38
+ _Done (2026-07-06): added 위저드, 단계별 플로우, 스텝, 이어하기 to `flow-design`'s keyword list in `cli/lib/route.mjs` (additive; existing `wizard`/`stepper` English forms kept as-is). Checked all other routes' keyword lists for collisions first — no hits. Re-ran the onboarding-wizard probe brief: `route()` now returns `[medium] flow-design score=3` (matched `온보딩`, `위저드`, `이어하기`) — up from the prior `[low] flow-design score=1` (matched `온보딩` only). Gate held: the round-1 report/block brief still scores `[high] flow-design score=4` (matched `플로우`, `신고`, `차단`, `처리 상태`), unchanged. Route eval checkpoint (`--eval --strict`, 6 cases) stays `pass 6/6`._
39
+
40
+ ### G-3. Reverse hijack: `빈 상태` belongs to the illustration route, so states-design briefs misroute
41
+
42
+ The empty/error-states probe routed `[low] illustration score=1` via `빈 상태` (an empty-state-*illustration* keyword), tied with `palette-from-brand`. But a 빈 상태·에러 상태 *design* brief is a screen-states task — `flow-design`'s check requirements (states, edge/error paths) and its curated `error-states.md` are the right home; illustration is only right when the brief actually asks for artwork.
43
+
44
+ **Proposed fix**: add compound state-design keywords to `flow-design` (에러 상태, 빈 상태 화면, 상태 설계, empty state, error state, 검색 결과 없음 …) so a states brief outscores illustration's single `빈 상태` hit, while an actual illustration brief (빈 상태 일러스트, 마스코트 …) keeps matching illustration harder. Verify both directions in the route eval.
45
+
46
+ _Done (2026-07-06): added 에러 상태, 빈 상태 화면, 상태 설계, 검색 결과 없음, empty state, error state to `flow-design`'s keyword list in `cli/lib/route.mjs`, all compound (never bare `상태`/`에러`/`빈`) so `illustration`'s bare `빈 상태`/`empty state` keywords are left untouched. Verified both directions: the states-design probe brief now routes `[medium] flow-design score=3` (matched `에러 상태`, `상태 설계`, `검색 결과 없음`) ahead of `[low] illustration score=1` (matched `빈 상태` only) — up from the prior `[low] illustration score=1` top result. The control brief (an actual illustration request, "서비스 빈 상태 일러스트와 마스코트 캐릭터 디자인") still routes `[high] illustration score=4` (matched `일러스트`, `마스코트`, `캐릭터`, `빈 상태`), unchanged. Route eval checkpoint stays `pass 6/6`._
47
+
48
+ ## Verdict
49
+
50
+ - **v4.62 loop fixes: all holding on fresh briefs** — the loop's second turn is regression evidence for the first.
51
+ - **Backlog (evidence-backed)**: G-1 `dashboard-design` route (route + check reqs + example) → G-2/G-3 `flow-design` keyword expansion (small, eval-gated, both directions).
52
+ - The two-round pattern converges: each round's misroute lands on `design-from-brief` with the same check-warn fingerprint — route-table coverage, not check logic, is the recurring gap class.
@@ -0,0 +1,56 @@
1
+ # Dogfood findings — Agent SDK end-to-end flow (Phase 764)
2
+
3
+ A real design task driven entirely through the Agent SDK (`@design-ai/cli/sdk`, shipped v4.59.0–v4.61.0), per the accepted composed slice in [NEXT-SURFACE-DECISION.md](NEXT-SURFACE-DECISION.md): SDK adoption evidence and a dogfood pass in one run.
4
+
5
+ **Scope of this dogfood**: the full consumer flow `route(brief)` → `pack(brief, { withRecall })` → author the artifact → `check(artifact, { routeId })` → `learn.captureFromCheck(artifact, { routeId })`, on a genuine brief, with the learning write isolated to a temp profile via `DESIGN_AI_LEARNING_FILE`.
6
+
7
+ **The brief** (deliberately chosen from a suspected corpus gap): 커뮤니티 앱의 게시물 신고 및 사용자 차단 플로우 설계 — 신고 사유 선택, 처리 상태 안내, 차단 후 상호작용 차단 범위.
8
+
9
+ ## What worked
10
+
11
+ ### 1. The SDK flow itself: zero friction
12
+
13
+ Every step worked first-try in a plain Node ESM script — no CLI shell-out, no MCP server, no docs consultation beyond `docs/SDK.md`:
14
+
15
+ - `route(brief, { limit: 3, explain: true })` returned scored routes with `relatedKnowledge`.
16
+ - `pack(brief, { withRecall: true, recallLimit: 5, maxBytes: 60000 })` returned a bounded 15-file context bundle (60,000 bytes exactly at budget) with the plan, checklist, and recall block.
17
+ - `check(artifact, { routeId })` returned `warn 9/10` with a precise per-result breakdown.
18
+ - `learn.captureFromCheck(artifact, { routeId })` captured the single non-pass result into the temp profile (`added 1, skipped 0`) and wrote nothing anywhere else.
19
+ - `DESIGN_AI_LEARNING_FILE` isolation behaved exactly as documented — the real user profile was untouched.
20
+
21
+ This is the adoption story: the flow a hosted agent would run is four function calls. It is recorded as the basis for the Agent SDK walkthrough.
22
+
23
+ ### 2. The eval/check loop caught the routing mismatch on its own
24
+
25
+ The one `warn` (`route-design-from-brief-design-system-foundation`) is not noise — it is the check system correctly reporting that a flow-design artifact lacks design-system-foundation evidence, which is exactly what finding 1 below predicts: the brief should never have landed on `design-from-brief` in the first place.
26
+
27
+ ## Findings
28
+
29
+ ### F-1. Route-table gap: flow/feature-design briefs fall through to the wrong route
30
+
31
+ `route()` scored the report/block brief `[low] score=1`, matching only the keyword `앱`, and fell back to `design-from-brief` — whose command, skills (`color-palette`, `design-system-builder`, `handoff-spec`), checklist ("Produce foundations, tokens, component baseline"), and check requirements all target a **from-scratch design-system brief**, not a **feature-flow spec**. There is no route for interaction/flow design (신고, 차단, 온보딩, 결제 플로우류) — a very common real-task class. The mismatch propagated end-to-end: wrong skills in the pack, wrong checklist, and a guaranteed check warn.
32
+
33
+ **Proposed fix**: a `flow-design` (or `feature-flow`) route with keywords for common flows (신고/차단/온보딩/가입/결제/설정/알림, report/block/onboarding/signup/checkout/settings), curated knowledge (`ui-reasoning`, `async-control`, forms/patterns), and route-specific check requirements suited to flow specs (states, edge cases, error paths) rather than token foundations.
34
+
35
+ _Done (2026-07-06): `flow-design` route added to `cli/lib/route.mjs` (`command: null`, mirroring `handoff-spec`/`design-system-qa`), with skills `ux-audit` + `design-critique`, agent `a11y-reviewer`, and curated knowledge `ui-reasoning`, `async-control`, `trust-safety-moderation` (F-3), `form-design`, `error-states`, `onboarding`. Keywords use compound Korean/English terms (`결제 플로우`, `설정 화면`, `알림 설정`, `report flow`, `signup flow`, `moderation flow`, …) chosen to avoid stealing bare terms already owned by other routes (`앱`/`서비스`/`프로덕트`/`app`/`product` → `design-from-brief`; `component`/`form` → `component-spec`). Re-ran the dogfood brief: `route()` now returns `[high] flow-design score=4` (matched `플로우`, `신고`, `차단`, `처리 상태`), with `design-from-brief` still present at `[low] score=1` (matched `앱`) as a secondary candidate — up from the prior single `[low] design-from-brief score=1` result. Added `ROUTE_REQUIREMENTS["flow-design"]` to `cli/lib/check.mjs` (states/steps, edge/error paths, entry/exit/completion — bilingual patterns mirroring house style); the Walkthrough 3 sample artifact now scores `warn 8/12` against `--route flow-design` (3 route-specific warns, as expected for a short sample), matching the walkthrough doc's existing "mostly-pass" framing. Added `examples/flow-design-report-block.md`, an expanded version of the dogfooded artifact that satisfies every example-qa bar (12/12) and is now the top-ranked example for the route. Updated the `EXPECTED_ROUTE_CATALOG_IDS` tuple in `tools/audit/smoke_assertions.py` (the single source both `package-smoke.py` and `registry-smoke.py` import from) and both README example-count badges (221 → 222, matching `check-coverage.py`'s top-level-only `examples/*.md` count — the new file lives at `examples/flow-design-report-block.md`, not under `examples/cases/`). `knowledge/COVERAGE.md` was left to its normal regeneration via `tools/audit/check-coverage.py` (not hand-edited), matching the F-3 precedent. Incidental fix: this route's 15-file pack combination exposed a pre-existing off-by-a-few-bytes bug in `cli/lib/pack.mjs`'s `takeUtf8` — truncating mid-UTF-8-character let `Buffer.toString("utf8")` insert a 3-byte U+FFFD replacement character that could be larger than the partial bytes it replaced, letting `usedBytes` exceed `maxBytes` by 1-2 bytes on multi-file packs with tight budgets; fixed by trimming to the last complete UTF-8 character boundary before decoding (`trimIncompleteUtf8Tail`), verified against ASCII, Korean (1/2/3-byte-cut), and 4-byte emoji boundary cases. Full suite green (585 tests), all 8 audits, release-metadata, package-smoke, registry-smoke self-test, and ci:local pass. Route eval: default `--eval-template` checkpoint (6 cases) still `pass 6/6` under `--eval --strict`; four other representative briefs (design-review, website-improvement, component-spec, palette-from-brand, design-system-qa, motion-design eval checkpoints) all still resolve to their prior top route unchanged._
36
+
37
+ ### F-2. Recall pollution: repo-meta docs outrank design knowledge
38
+
39
+ For this brief, `relatedKnowledge` surfaced `pricing-page-design` (37.0), `korean-document-style` (22.8), `dashboard-composition` (10.8) — none relevant — and the pack's recall block selected `docs/case-study.md` (49.1, the **top** hit), `docs/project-card.md` (30.8), `docs/interview-story.md` (30.4), and `docs/integrations/codex-walkthrough.ko.md` (30.2). Those are repo-meta documents (portfolio/case-study material, integration walkthroughs), not design knowledge; three of the four are even excluded from the npm package by the `files` field. The v4.58 generated-index exclusion (`COVERAGE.md`, `INDEX.md`, `docs/reference/*`) does not cover them.
40
+
41
+ **Proposed fix**: extend the recall exclusion list from "generated index files" to a "non-knowledge docs" set — at minimum the package-excluded meta docs (`docs/case-study.md`, `docs/project-card.md`, `docs/interview-story.md`, `docs/resume-bullets.md`, …) and `docs/integrations/*` walkthroughs — for recall-injection surfaces only (raw `search` stays unfiltered, same boundary as v4.58).
42
+
43
+ _Done (2026-07-06): `isRecallExcludedDoc(relPath)` added in `cli/lib/search-ranked.mjs`, extending `isGeneratedIndexDoc` with the package-excluded repo-meta docs (the exact `!docs/*.md` set from `package.json` `files`: case-study, evidence-checklist, evidence-gallery, implementation-evidence, interview-story, project-card, project-roadmap, readme-improvement, resume-bullets) and the `docs/integrations/` prefix. `rankedSearchCorpus`'s opt-in filter option was renamed `excludeGeneratedIndex` → `excludeNonKnowledge` (only 3 internal call sites + tests referenced the old name) and now applies the broader predicate; `cli/lib/recall.mjs` (both call sites) and `cli/lib/route.mjs`'s `relatedKnowledgeFor` pass it unchanged. Re-ran the dogfood brief through the SDK: `recall()`'s `corpus.selected` and `route --explain`'s `relatedKnowledge` no longer surface `docs/case-study.md` / `docs/project-card.md` / `docs/interview-story.md` / `docs/integrations/codex-walkthrough.ko.md` — those slots are now filled by real corpus knowledge. Raw `search --ranked` is unaffected (verified unfiltered). Full suite green (585 tests), all 8 audits, release-metadata, package-smoke, registry-smoke self-test, and ci:local pass._
44
+
45
+ _Follow-up F-2b (2026-07-06): the enumerated meta-doc list proved to be whack-a-mole — the post-fix probe surfaced `docs/DOGFOOD-SDK-FINDINGS.md` itself as the new top recall hit (141.2, ~3× the best knowledge score) because this document quotes the brief's vocabulary, with `docs/inspection-*.md` and `docs/announcements/*` next in line. Resolved by the principled rule: `isRecallExcludedDoc` now excludes **everything under `docs/`** (recall injects design knowledge; the design corpus is `knowledge/`, `examples/`, `skills/`, `agents/`, `commands/` — `docs/` is product documentation). The per-file meta list was removed as dead code. Raw `search`/`search --ranked` still returns `docs/` hits unfiltered. Post-change probe: `recall()` top hit for the dogfood brief is `knowledge/patterns/trust-safety-moderation.md` (the F-3 file), with zero `docs/` entries._
46
+
47
+ ### F-3. Corpus gap: no trust & safety / moderation UX knowledge
48
+
49
+ Nothing in `knowledge/` covers report/block/moderation patterns: 신고 사유 분류 설계, 처리 상태 커뮤니케이션(접수→검토→조치), 차단 의미론(양방향 범위, 비통지 원칙), 신고 남용 방지, and the Korean regulatory angle (정보통신망법 제44조의2 임시조치 30일, KCSC 처리 관행). For a product with Korean community/social apps in scope, this is a real gap — the artifact had to be authored from general principles alone.
50
+
51
+ **Proposed fix**: `knowledge/patterns/trust-safety-moderation.md` (hand-written), covering the above plus accessibility specifics for report sheets/status badges; pairs naturally with the F-1 flow route's curated knowledge.
52
+
53
+ ## Verdict
54
+
55
+ - **SDK**: walkthrough-ready as-is; no API changes needed. The flow is the walkthrough.
56
+ - **Backlog generated (evidence-backed, in priority order)**: F-2 recall exclusion (small, mirrors the shipped v4.58 exclusion mechanism), F-3 trust-safety knowledge file (corpus), F-1 flow-design route (route table + check requirements + smoke surface updates).