Wire the board filter that the /boards toolbar reserves as a permanently disabled [Filter] button today (page.tsx: "Filter is a disabled seam here — Epic 6 wires board filtering"). Stories 3.7 / 3.8 / 4.2 / 4.5 / 4.7 all defer board filtering to "Epic 6" in prose, and the 3.8.4 over-cap banner ("refine the board filter") points at this seam — but no Epic-6 story ever owned it: Story 6.1 scoped its filter builder to the /issues navigator only, naming the board "the documented extension when a use case lands." This is that use case. (Not a bug — the disabled state is a deliberate seam; the gap is the missing story, the same shape as the board-column-admin planning gap.)
The verified shape (rung 1 — Atlassian docs). A Jira board is backed by a filter and the user narrows it with board quick-filters / its saved filter — filtering is a first-class board affordance, not navigator-only. Today the board read (boardsService.getBoard / loadColumnCards) takes no predicate and projects every card (bounded only by the 3.8 cap), so a user cannot shrink an over-cap board even though the banner tells them to.
The fix — REUSE, not rebuild. The structured filter AST + compiler (lib/filters/*, 6.1) and saved filters (lib/savedFilters/*, 6.2) are done, and the issue list already threads a compiled predicate into its read (findByProjectFiltered via resolveFilterAst). This story threads that SAME predicate into the board projection (each column shows only matching cards), mounts the SAME filter builder + saved-filter picker on the board toolbar (board-scoped, URL-addressable, reload-safe), and points the over-cap "refine filter" CTA at it. The 3.8 bounded/virtualized load + over-cap truncated flag now apply to the filtered set, and the 4.5 Scrum sprint-scope filter composes with it (narrow WITHIN the active sprint).
Plus — the missing Work type facet (6.15.5). The shipped quick filter (IssueFilterBar) is a curated four-facet subset (text · kind · status · assignee); the Work type field (WorkItemType — code/design/test/… + the nullable Untyped bucket) was reachable only via [Advanced], so a user could not filter the board (or the /issues list) by Work type from the quick popover. The FilterAST + 6.1 registry already DEFINE and COMPILE type (enumField('type', 'type-select', { nullable, WORK_ITEM_TYPES })), so this is a missing quick-filter facet, not a grammar change — 6.15.5 adds the Work type facet group to the SHARED IssueFilterBar (so /issues gains it too), and the board reuses it.
Out of scope. The filter grammar/compiler/registry (6.1 owns type — already complete, no change) and the board read (6.15.2 threads whatever AST — type already compiles); cross-project boards (still the 3.7 Epic-6 extension); altering the Scrum scope filter (4.5). No new migration.
pnpm install, pnpm prisma migrate dev (reports "No difference detected" — this story adds no schema; it reuses the 6.1 filter substrate), pnpm db:seed, pnpm dev.pnpm test:coverage — Vitest (real Postgres) over the filtered board read (predicate applied per column, the cap/truncated computed over the FILTERED set, workspace + 6.4-permission scope) ≥ 90% per-file branch/fn/line.zhuyue@motir.co / !QAZ1qaz → moooon / motir → /boards. The toolbar Filter is now enabled; open it, build a quick filter (e.g. type = Bug) or pick a saved filter → the board re-projects so every column shows only matching cards; the active filter shows as a chip/summary; Clear restores the full board. The selection survives a reload (it is in the URL).Design narrows the board to design work items. The SAME facet appears on /issues (shared IssueFilterBar).pnpm test:e2e --grep board-filter — apply a filter on a board end-to-end → only matching cards across columns → clear restores.--el-*, shape via element-semantic tokens; next-intl (en + zh).