schema overhaul, test consolidation, type cleanup - #43
Merged
Kristof Roomp (mcroomp) merged 1 commit intoMay 16, 2026
Merged
Conversation
Schema migration (requires `ts recreate` on existing indexes):
- Every text field switches to the `raw` tokenizer. No more 40-char
drop, no underscore splitting — `add_text_field` is one token, not
three; `InitializeNotificationHistoryAcrossDataCentersUSA` (49 chars)
stays whole.
- New `path_tokens` field stores per-directory + filename components,
so a search for `billing` finds files under any `billing/` directory
at any depth. Replaces `filename` as the path-side query_by fallback.
- `namespace` is now multi-value: `Acme.Billing.Service` indexes as
three separate searchable tokens.
- Minimal stored set — only `{id, relative_path, mtime, filename,
extension, language, path_segments}` are `stored=True`. Every other
field is indexed-for-search but not retrievable; AST stage carries
line-level output.
- New `member_sig_tokens` field: every identifier inside a member's
signature (attribute names, parameter names, default-value
identifiers) extracted by walking the member AST minus the body.
- Listing modes (`methods` / `classes` / `fields`) now return line
ranges. Output renders `path:start-end: text` so callers can
`Read(file, offset=start, limit=end-start+1)` precisely.
Shared modules:
- `indexserver/search_modes.py` holds `resolve_query_params` and
`build_filter_by`. Daemon `/query-codebase` and `scripts/search.py`
share the same mode→query_by mapping — new modes reach both paths.
- `mcp_server.py` switched to `indexserver.config.load_config()`
instead of its own JSON-reading copy. Roots are typed `Root` objects.
Test architecture:
- Killed `_FakeBackend`. ~30 unit tests migrated to real Tantivy on
`tempfile.mkdtemp()` via a new `make_test_backend()` helper. Catches
schema drift the fake silently hid.
- New `TestSemanticFieldDiscrim` + `TestPySemanticFieldDiscrim`:
orthogonal fixtures where one identifier appears in exactly one
structural role per file. Each test asserts search-by-field returns
only the right files — verifies indexer→Tantivy round-trip instead
of re-running the parser.
- New `test_path_tokens.py` (24 tests) and `test_long_identifiers.py`
(10 tests) covering subpath search, namespace components, and the
long-identifier round-trip.
- Test consolidation via LSP cross-reference: deleted 18 redundant
per-mode test files (~267 tests) covered by canonical homes
(`test_indexer_query_consistency.py`, `query/tests/test_query_cs.py`,
discrimination tests). Pruned 34 of 49 dead fixtures in
`tests/fixtures.py`. Removed `LiveTestBase` (no longer used).
- Sample E2E tests: `_get_doc → doc.get(field)` pattern replaced with
`_search(coll, value, query_by=field)` → file-in-hits assertions.
Removed back-compat shims:
- `X-TYPESENSE-API-KEY` header → `X-API-KEY` across daemon, MCP server,
CLI, VS Code extension, tests, and docs. Added rationale doc
explaining why a localhost service still needs an API key.
- `Root.to_external` alias deleted (WSL-era leftover).
- `_build_filter_by` / `_resolve_query_params` shims in
`tsquery_server.py` deleted; test imports from
`indexserver.search_modes` directly.
- `_OpenFailure` unused dataclass + `dataclasses` import.
- `_expand_type_refs`, `_q_all_call_sites_data`, `_collect_all_refs`
dead functions in `query/cs.py` (LSP confirmed no callers).
- Unused `coll_name` parameter on `index_file_list` (12 call sites
updated).
Type cleanup (pyright):
- `Backend._reopen_writer` now None-guards `wait_merging_threads`.
- `BackendResolver = Callable[[str], Backend | None]` (production
legitimately returns None for unknown collections; downstream code
already handled it).
- `_CsIndex` factory function correctly typed as returning
`TreeIndex` — 17 annotation sites in `query/cs.py` were treating it
as a class.
- `build_document` typed `-> dict | None`.
- `tsquery_server._backends: dict[str, Backend]` (was `object`,
which hid every `Backend.method` access).
- `_Fence` added to the `OrderedDict` value union in `IndexQueue`;
`payload: object` widened to `dict | str` with runtime narrowing.
- `_Handler.log_message` matches `BaseHTTPRequestHandler` signature.
- Watcher narrows `coll`, `native_root`, `root_exts` together.
Tooling:
- `pyrightconfig.json` for full workspace background analysis.
Test suite: 1253 → 986 tests (267 deleted, 41 new) — strictly better
signal, ~6s faster.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Kristof Roomp (mcroomp)
deleted the
schema-overhaul-and-test-consolidation
branch
September 24, 2026 07:51
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.
Schema migration (requires
ts recreateon existing indexes):rawtokenizer. No more 40-char drop, no underscore splitting —add_text_fieldis one token, not three;InitializeNotificationHistoryAcrossDataCentersUSA(49 chars) stays whole.path_tokensfield stores per-directory + filename components, so a search forbillingfinds files under anybilling/directory at any depth. Replacesfilenameas the path-side query_by fallback.namespaceis now multi-value:Acme.Billing.Serviceindexes as three separate searchable tokens.{id, relative_path, mtime, filename, extension, language, path_segments}arestored=True. Every other field is indexed-for-search but not retrievable; AST stage carries line-level output.member_sig_tokensfield: every identifier inside a member's signature (attribute names, parameter names, default-value identifiers) extracted by walking the member AST minus the body.methods/classes/fields) now return line ranges. Output renderspath:start-end: textso callers canRead(file, offset=start, limit=end-start+1)precisely.Shared modules:
indexserver/search_modes.pyholdsresolve_query_paramsandbuild_filter_by. Daemon/query-codebaseandscripts/search.pyshare the same mode→query_by mapping — new modes reach both paths.mcp_server.pyswitched toindexserver.config.load_config()instead of its own JSON-reading copy. Roots are typedRootobjects.Test architecture:
_FakeBackend. ~30 unit tests migrated to real Tantivy ontempfile.mkdtemp()via a newmake_test_backend()helper. Catches schema drift the fake silently hid.TestSemanticFieldDiscrim+TestPySemanticFieldDiscrim: orthogonal fixtures where one identifier appears in exactly one structural role per file. Each test asserts search-by-field returns only the right files — verifies indexer→Tantivy round-trip instead of re-running the parser.test_path_tokens.py(24 tests) andtest_long_identifiers.py(10 tests) covering subpath search, namespace components, and the long-identifier round-trip.test_indexer_query_consistency.py,query/tests/test_query_cs.py, discrimination tests). Pruned 34 of 49 dead fixtures intests/fixtures.py. RemovedLiveTestBase(no longer used)._get_doc → doc.get(field)pattern replaced with_search(coll, value, query_by=field)→ file-in-hits assertions.Removed back-compat shims:
X-TYPESENSE-API-KEYheader →X-API-KEYacross daemon, MCP server, CLI, VS Code extension, tests, and docs. Added rationale doc explaining why a localhost service still needs an API key.Root.to_externalalias deleted (WSL-era leftover)._build_filter_by/_resolve_query_paramsshims intsquery_server.pydeleted; test imports fromindexserver.search_modesdirectly._OpenFailureunused dataclass +dataclassesimport._expand_type_refs,_q_all_call_sites_data,_collect_all_refsdead functions inquery/cs.py(LSP confirmed no callers).coll_nameparameter onindex_file_list(12 call sites updated).Type cleanup (pyright):
Backend._reopen_writernow None-guardswait_merging_threads.BackendResolver = Callable[[str], Backend | None](production legitimately returns None for unknown collections; downstream code already handled it)._CsIndexfactory function correctly typed as returningTreeIndex— 17 annotation sites inquery/cs.pywere treating it as a class.build_documenttyped-> dict | None.tsquery_server._backends: dict[str, Backend](wasobject, which hid everyBackend.methodaccess)._Fenceadded to theOrderedDictvalue union inIndexQueue;payload: objectwidened todict | strwith runtime narrowing._Handler.log_messagematchesBaseHTTPRequestHandlersignature.coll,native_root,root_extstogether.Tooling:
pyrightconfig.jsonfor full workspace background analysis.Test suite: 1253 → 986 tests (267 deleted, 41 new) — strictly better signal, ~6s faster.