Description
Scoped Search Filters turn Universal Search from a workspace-wide query into a deliberately bounded retrieval. Callers can select one registered entity type, constrain results to specific Dotabases or an explicit row set, filter by tags and DIIICE categories, choose a recency window, and sort by relevance, creation time, or update time. The same filter vocabulary travels through the web client, API schema, CLI, and MCP tool.
Filtering is part of the search envelope rather than a cosmetic client-side pass. The normalized scope, filters, trigger, sort, page size, and readable-Dotabase set contribute to the L2 cache key, so a broad cached response cannot satisfy a narrower request. A present empty rowIds array means “search nothing,” while an absent array means no row wall; this distinction preserves fail-closed scoped workflows.
Selling Points
- Users can search the part of the workspace they mean instead of manually discarding unrelated result types.
- The wire contract is shared across human and agent surfaces, keeping automation behavior aligned with the palette.
- Scope-aware cache keys prevent result leakage between broad and narrow searches or between different readable sets.
- Date sorting uses keyset pagination pushed into SQL, so it covers the full matching set rather than only a relevance candidate pool.
- Explicit empty scopes remain empty, a critical safety property for authority-derived row sets.
User Story
A project lead wants only recently updated artifact and task knowledge related to a release. They open search, choose the appropriate registered type and Dotabase filters, select the recent time window, and sort by update time. An automation can issue the equivalent API or MCP request and receive the same constrained result set rather than reimplementing filter logic.
Extension Surface
Configurable is the first true rung: callers change behavior entirely through the SearchQuery and SearchFilters contract in packages/search/src/internal/types.ts, with wire validation in packages/api/src/schemas/search.ts. No new provider or code is required to combine supported filters. Adding a new filter dimension still requires coordinated engine and schema work, so the feature is not itself pluggable.
Capabilities & Limits
- Supports entity scope, Dotabase IDs, explicit row IDs, tags, DIIICE values, recency buckets, and three sort modes.
- Includes normalized filter state in cache isolation and cursor semantics.
- Applies the access-readable set before retrieval, intersecting user choice with authorization.
- Limits: the retired domain filter is deliberately absent from the wire and UI because the server has no authoritative domain facet.
- Limits: a registered entity type without a compatible metadata column may not support every optional facet dimension.
Implementation Map
packages/search/src/internal/types.tspackages/api/src/schemas/search.tspackages/search/src/internal/cache/key.tspackages/search/src/internal/stages/retrieve.tsapps/web/src/modules/shell/search-palette/SearchPalette.tsx