Skip to content

Flexible task search with prefix matching, slug search, and ranked results - #40

Merged
pufit merged 1 commit into
mainfrom
pufit/flexible-task-search
Apr 9, 2026
Merged

pufit merged 1 commit into
mainfrom
pufit/flexible-task-search

Conversation

@pufit

@pufit pufit commented Apr 9, 2026

Copy link
Copy Markdown
Member

Summary

Replaces the rigid FTS5 exact-word search with a multi-strategy approach that actually finds things:

  • Prefix matching — distrib now finds "distribution documentation" (FTS5 word* syntax instead of "word")
  • Slug search — 2026-03-10-distribution finds the task by ID substring. Task IDs are now indexed as searchable FTS columns (were UNINDEXED)
  • BM25 relevance ranking — results ordered by relevance instead of updated_at DESC
  • Cascading fallbacks — exact ID → FTS prefix + BM25 → slug LIKE → title LIKE, merged and deduplicated

Also fixes two content-wipe bugs:

  • task_update title rename called upsert_task() without content=, nuking the FTS content index
  • Gateway PATCH route had the same bug — req.content available but not passed through

Changes

File What
nerve/db/tasks.py Rewritten _build_fts_query (prefix), new search_tasks (multi-strategy), extracted _tokenize_query, _apply_status_filter, _apply_tag_filter, _row_matches_filters helpers
nerve/db/migrations/v023_tasks_fts_slug.py Rebuild tasks_fts with task_id as searchable column
nerve/agent/tools.py Fix content wipe bug on title rename, update tool description
nerve/gateway/routes/tasks.py Fix content+tags wipe on PATCH save
tests/test_db.py 6 new tests + updated test_rebuild_fts for fallback behavior

Test plan

  • All 332 tests pass (17 search-specific, 6 new)
  • Manual test: search by partial word
  • Manual test: search by task slug
  • Manual test: verify content search still works after title rename
  • Verify migration runs cleanly on existing DB (triggers reindex)

Generated by Nerve

…sults

Multi-strategy search replaces the single FTS5 query:
1. Exact task ID match
2. FTS5 prefix search ranked by BM25
3. Task ID substring match (LIKE)
4. Title substring fallback (LIKE)

Key changes:
- FTS query builder uses prefix syntax (word*) instead of exact ("word")
- Task ID now indexed as searchable FTS column (was UNINDEXED)
- Results ranked by BM25 relevance instead of updated_at
- Fix: task_update title rename no longer wipes FTS content index
- Fix: gateway PATCH route now preserves content+tags in FTS on save
- Migration v023 rebuilds tasks_fts with searchable task_id column
- 6 new tests for prefix, slug, dedup, and relevance ordering
@pufit
pufit merged commit cc9e7c1 into main Apr 9, 2026
@pufit
pufit deleted the pufit/flexible-task-search branch April 9, 2026 07:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant