Skip to main content

Search

Every Constellation module offers search over its own data. This page explains what a search bar covers, what result quality to expect, and where the boundaries are — in particular, that search is app-local: a search bar only ever returns results from the module you are using.

App-local by default

Each module's search bar (or search page) queries that module's own data and nothing else. Results are always scoped to your active organisation, and every module applies its own visibility rules on top, so search respects the same tenancy and permission boundaries as the rest of the product.

ModuleWhere you searchWhat it covers
Project TrackerNavbar search bar (/projects)Initiatives, projects, tasks, issues, feedback, comments (see visibility caveats), plus people and quick commands
WikiNavbar search bar (/wiki)Wiki pages — tenant- and classification-scoped, so pages above your clearance never appear
DirectoryAdmin navbar search barOrganisations and users (admin area)
CatalogNavbar search bar (/catalog) + dedicated /search pageCatalog entries — Text search from the navbar; the dedicated /search page adds Semantic (vector-embedding) and Hybrid modes

Guests and external collaborators see correspondingly less: in Project Tracker, guest members only get initiative, project, task, and issue results from projects they actively collaborate on. Feedback is the exception — it is searchable tenant-wide for everyone, matching how the rest of Project Tracker treats feedback.

Project Tracker, Wiki, Directory, and Catalog render the same shared search component (GlobalSearch from @constellation-platform/ui, ADR-017), so the core interaction model is the same everywhere:

  • Keyboard shortcut⌘K (macOS) / Ctrl+K focuses the search bar.
  • Full keyboard navigation — arrow keys move through results, Enter opens the highlighted one, ⌘/Ctrl+Enter opens it in a new browser tab, and Escape closes the panel.
  • Open in a new tab — each result row shows an "open in new tab" icon, revealed on hover or on the keyboard-highlighted row, that opens that record in a new browser tab without leaving the search panel.
  • Scope tabs (where the app provides them) — filter the result panel by type, with per-scope counts. Project Tracker uses these (Tasks, Issues, Comments, and so on); Wiki, Directory, and Catalog currently present a single, untabbed result list.
  • Recent items — an empty query shows your recent searches and recently viewed records where the host app provides them.

The component itself never talks to a backend: each app injects its own data source, which is what keeps every bar app-local by construction. The convention for adopting it in a module lives in the shared packages overview.

What to expect in Project Tracker

Project Tracker has the most advanced retrieval of the modules. Result groups are relevance-ranked and typo-tolerant, and each group returns up to 10 results.

Ranking

  • Multi-term queries match terms independently (AND semantics) — ranked retrieval finds records containing both words anywhere, not just that exact phrase.
  • Results are relevance-ranked, not newest-first. Matches in a title or key rank above matches that only appear in a description; ties break on most recently updated.
  • The last word is treated as a prefix while you type, so the panel keeps matching mid-word (retrie already matches "retrieval").

Query syntax

  • Web-style operators: "quoted phrases" for exact phrases, OR between terms, and -term to exclude. A query using any of these is treated as a structured operator query — matched exactly as written and, as a result, not typo-tolerant (see the typo-tolerance note below).
  • Inline filters: in:, status:, and type: narrow the result panel (for example type:comment deploy). These are applied by the panel itself, on top of the server's results.
  • Command mode: starting the query with > switches to quick commands (create task, switch theme, and so on) instead of searching records.

Typo tolerance

When a result group finds nothing for your query, Project Tracker retries that group with trigram-based fuzzy matching, so a transposition like retreival still finds "retrieval". Three caveats:

  • The fallback needs at least 3 characters to work with.
  • Queries carrying explicit operators (quotes, OR, -exclusions) never fall back — fuzzy matching cannot honour those semantics, so an operator query that matches nothing simply returns nothing.
  • Fuzzy matching covers initiatives, projects, tasks, issues, and feedback only. The Comments group has no fuzzy fallback — comment matching is exact at the word level, so a typo in a comment search returns nothing.

Exact key lookup

Typing a record key (for example PT-653) pins that exact task or issue at the top of its group, ahead of any ranked matches. Other results still render below it.

Key number lookup

Typing just the number part of a key (for example 653) pins the tasks and issues whose key ends in that number — PT-653, INF-653, and so on — at the top of their groups, ahead of any ranked matches. Like every group, this is capped at 10 results per group, most recently updated first. Zero-padded keys are matched too, and padding is irrelevant on both sides: 250 and 0250 both find PT-250 and TSA-0250.

The number must be the whole key number to be treated as an identifier: neither 25 nor 2500 pins PT-250. (A near-miss number can still appear further down as an ordinary typo-tolerance similarity match — it just is not treated as naming that record.) Only a bare number triggers this — a number embedded in a longer query (fix 653) is treated as an ordinary search.

This exists because ranked text matching alone cannot find a key by its number. The text index reads PT-653 as two tokens — pt and a signed integer -653 (the hyphen is parsed as a minus sign) — and it never stores a bare 653, so an unsigned 653 query has nothing to match. Without this lookup, typing 653 would find PT-653 only by coincidence.

Pull-request number lookup

Typing a GitHub pull-request number pins the task that PR is linked to at the top of the Tasks group, the same way an exact key does. All of these forms work (case-insensitive): a bare number (1360), a hash prefix (#1360), or a PR prefix (PR 1360, PR#1360). The match is against the task's pr_link field, so it only finds a task whose linked PR URL contains the /pull/1360 path segment (…/pull/1360 and …/pull/1360/files both count) — 1360 never matches PR 13600. A key (PT-1360) or a number embedded in a longer query (fix 1360) is treated as an ordinary search instead.

A bare number is ambiguous — it could be a key number or a PR number — so both lookups run and both sets of matches are pinned. Key-number matches are listed first, because in a project tracker the ticket number is the more literal reading of a bare number. The #1360 and PR 1360 forms are explicit PR references and only run the PR lookup.

Comment results and visibility

Project Tracker search includes a Comments group covering task and issue comments. Comment search never widens what you can see — it applies exactly the same visibility rules as the activity feed and the comment threads themselves:

  • Task comments appear only if you hold full task-read permission (tasks.read). A scoped .own grant is not enough, because a comment hit reveals its parent task's title and key.
  • Internal issue comments appear only if you can manage issues (projects.issues.manage). Everyone else sees only non-internal issue comments.
  • Guest members only see comments from projects they actively collaborate on.
  • Deleted comments are never returned.
  • Results show a short snippet (not the full body) and deep-link to the parent task or issue.
  • Only comments attached to a task or an issue are searchable; project-level and initiative-level comments are not covered.

Cross-app search is a future capability

Today, no search bar returns results from another module — searching in Project Tracker will not surface wiki pages, and searching the wiki will not surface tasks. This is deliberate, not a gap in your permissions.

Cross-app (federated) search is a planned future capability with a strict security model: it will be opt-in and entitlement-gated — a module is only queried for you if your tenant has that module enabled and you are entitled to use it — and fail-closed, meaning a module that cannot be positively resolved is silently omitted rather than searched. Queries will always run with your own identity, so row-level tenancy and classification rules keep applying. No delivery timeline is committed; until it ships, expect every search bar to remain app-local.