feat(finder): make the publisher host free-text searchable - #94
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds the agent’s publisher host (verified domain / URN <publisher> segment) to the Finder’s FTS5 index so free-text queries can match host tokens (e.g., translator → translator.example.com), and documents the Finder’s exact text-matching semantics in the OpenAPI spec(s).
Changes:
- Rebuilds the Finder FTS5 virtual table to include a
publishercolumn and repopulates it from existing ACTIVE rows via a new SQLite migration. - Threads the derived
publishervalue through the runtime FTS insert path and adds tests covering host-token matching and tombstone suppression. - Documents the Finder’s text-matching contract in both spec copies and improves
scripts/demo/register.shdisplay/description text derived from host (with length truncation).
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| spec/api-spec-finder-v1.yaml | Documents the Finder text-matching contract and clarifies query.text/score semantics. |
| internal/adapter/docsui/openapi/finder.yaml | Syncs the same spec changes for the docs UI copy. |
| internal/adapter/store/sqlitefinder/migrations/002_fts_publisher.sql | Drops/recreates the FTS table to add publisher and repopulates it from base/side tables for ACTIVE rows only. |
| internal/adapter/store/sqlitefinder/apply.go | Adds publisher threading so runtime inserts keep base and FTS publisher values consistent. |
| internal/adapter/store/sqlitefinder/sqlite.go | Tracks and exposes applied migrations so startup can log in-place schema upgrades. |
| cmd/ans-finder/main.go | Logs applied index migrations at startup for operational observability. |
| internal/adapter/store/sqlitefinder/search_publisher_test.go | Adds tests ensuring host tokens are searchable and tombstones remove host discoverability. |
| internal/adapter/store/sqlitefinder/migrate_internal_test.go | Tests upgrade behavior from schema 001 → 002 including repopulation and non-resurrection of revoked rows. |
| scripts/demo/register.sh | Derives display name/description from host and truncates to RA field limits. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // database, in application order. Empty means the schema was already | ||
| // current. Callers log this at startup so schema upgrades are | ||
| // diagnosable from logs alone. | ||
| func (s *Store) AppliedMigrations() []string { return s.appliedMigrations } |
Member
Author
There was a problem hiding this comment.
Fixed in 3e7454e — AppliedMigrations now returns slices.Clone(...).
Free-text search previously covered displayName, description, capabilities, and tags — but not the one text every entry reliably carries, the publisher host. A quickstart user who registered translator.example.com and searched "translator" got zero results unless the display fields happened to repeat the word. Add publisher as a fifth FTS5 column. FTS5 has no ALTER TABLE, so migration 002 drops and recreates the table and repopulates it from the base and side tables — self-contained, no feed replay, ACTIVE rows only so tombstoned agents are not resurrected. insertFTS threads the same publisher value the base-row insert derives, so the two columns agree by construction. Open now records applied migrations and ans-finder logs them at startup, making the first in-place schema upgrade diagnosable from logs alone. Document the text-matching contract in the finder spec (exact-token AND, case/diacritic-insensitive, dotted terms match as phrases, FTS operators are literal, ranking informational) and align the Query.text description, its example, and the score description with it. register.sh now derives demo display text from the host — presentation, not a search requirement — truncated to the RA's field limits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: kperry <kperry@godaddy.com>
kperry-godaddy
force-pushed
the
feat/finder-publisher-fts
branch
from
July 23, 2026 18:32
867cfa7 to
2373f9a
Compare
Returning the internal slice let a caller's sort or in-place append reach the store's own record. slices.Clone removes the sharing; the getter runs once at startup, so the copy costs nothing. Addresses Copilot review feedback on #94. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: kperry <kperry@godaddy.com>
csnitker-godaddy
approved these changes
Jul 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds the publisher host (the URN
<publisher>segment — the agent's verified domain) as a searchable column in the Finder's FTS5 index, so free-text queries match host words:"translator"now findstranslator.example.comeven when the display fields share no tokens with the host.002_fts_publisher.sql— FTS5 has noALTER TABLE, so the FTS table is dropped, recreated with thepublishercolumn, and repopulated from the base + side tables (group_concat … ORDER BY rowid). Self-contained: no feed replay needed. ACTIVE rows only, so tombstoned agents are not resurrected — pinned by tests on both the migration path and the runtime tombstone path.insertFTSthreads the same publisher value the base-row insert derives, so base and FTS columns agree by construction.Openrecords applied migrations (Store.AppliedMigrations) andans-finderlogs them at startup, so the first in-place schema upgrade a deployed DB performs is diagnosable from logs alone.translator.com≠translator.example.com), FTS-operators-as-literals, and ranking as informational. TheQuery.textdescription, its example (flight booking— the oldfind me a flight booking agentcannot match under all-terms-must-match), thescorenormalization note, and the explore description are aligned with it. Both spec copies synced (make docs-sync; byte-equality test enforces).Upgrade & rollback notes
applied index migrationslog line.Review
Six-perspective review (security, architect, skeptic, systems, go, api): 0 critical, 0 high findings. Consensus MEDIUM/LOW items fixed in this PR: phrase-vs-AND semantics documented correctly (empirically verified against modernc.org/sqlite v1.54.0), spec self-contradiction on
Query.textresolved, bm25 softened to informational, migration logging added,group_concatordering pinned, register.sh length overflow fixed, tags repopulation now tested with data. Deferred (noted, not blocking): centralizing URN parsing ininternal/ard, per-column bm25 weights,maxLengthonquery.text(pre-existing surface).Verification
make build✅go vet✅make lint: 0 issues ✅go test ./...: all packages pass; race detector clean ✅make test-cover: 90.7% ≥ 90% gate ✅DCO
Signed off by the submitter per CONTRIBUTING.md; the DCO certification is the human submitter's, made at their direction.
AI assistance
Assisted-by: Claude Code (claude-fable-5)
🤖 Generated with Claude Code