Skip to content

fix(search): rank results by page title, path, and heading - #212

Merged
KayleeWilliams merged 6 commits into
mainfrom
search-page-match-ranking
Oct 15, 2026
Merged

KayleeWilliams merged 6 commits into
mainfrom
search-page-match-ranking

Conversation

@KayleeWilliams

@KayleeWilliams KayleeWilliams commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Search on c15t.com ranks poorly now that the docs have one copy of most guides per framework (11 trees, ~28 pages each). The causes are in searchDocs:

  • Title matches barely counted. A title hit saturated into one more BM25 occurrence, so consent categories ranked the page with that exact title 47th, behind changelogs that repeat both words.
  • The framework lived only in the URL. Ten pages are titled "Quickstart", and URL paths weren't searched.
  • ConsentBanner, DevTools and Next.js were single tokens, so consent banner, dev tools and nextjs missed them.
  • Every chunk repeated the page description, so pages with long descriptions won broad queries.
  • One page could fill every result. posthog returned 8 sections of one page. NLWeb removed duplicate pages after cutting to limit, so it returned fewer results than asked for.

Changes

  • A chunk's BM25 score is multiplied by how much of the query its page title, URL path and own heading cover. Title coverage is weighted by precision, so a short "Translations" title beats "v1.3.0 — Translations Package, SSR Consent, CLI Telemetry…".
  • Camel-case names also index their parts (ConsentBanner → consentbanner, consent, banner). Short dotted or hyphenated names also index their joined form (Next.js → next, js, nextjs).
  • The page description is indexed with the first chunk only. The c15t index shrinks from 9.8 MB to 9.0 MB.
  • New maxResultsPerPage option (default 2), applied before limit. NLWeb /ask passes 1 and drops its own post-limit dedupe.
  • Queries with two or more words skip phrase matching for chunks whose best possible score can't reach the results. On the c15t index, consent banner drops from 148 ms to 18 ms. Pruned and exhaustive results matched on 918 query/option combinations.

The index format moves to version 4. Sites must regenerate their search artifacts, and v3 artifacts fail validation.

Results

I rebuilt the c15t.com index from its 438 live Markdown mirrors and scored 46 queries, each with the page that should come first:

Right page 1st In top 3 MRR@8 Pages in top 8
main 17/46 29/46 0.49 5.2
This PR 32/46 37/46 0.75 5.8

I chose the queries and the correct pages myself, so treat these numbers as a guide. The weights are round numbers and none are specific to c15t.

Tests

Four regression tests cover camel-case and dotted tokens, a title beating a release note that repeats it, URL-only words, and the per-page cap. All four fail on main.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

Docs sites with one copy of each guide per framework got poor results:
title matches saturated into one more BM25 occurrence, the framework only
lived in the URL, camel-case names were single tokens, every chunk repeated
the page description, and one page could fill every result.

- Multiply each chunk's score by how much of the query its page title,
  URL path, and heading cover, weighted by title precision.
- Index camel-case parts and joined dotted/hyphenated compounds.
- Index the page description with its first chunk only.
- Add maxResultsPerPage (default 2), applied before limit; NLWeb uses 1.
- Skip phrase matching for chunks that cannot reach the results.

Bumps the search index format to version 4.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T22:59:12.206813Z 14f4e3a New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

Next included review available in 20 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 90 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Team
  • Run ID: 764b24f9-4eae-4d7f-8719-88eaa488846d
📥 Commits

Reviewing files that changed from the base of the PR and between 214f17d and 14f4e3a.

📒 Files selected for processing: 9
  • .changeset/search-ranking-page-match.md
  • docs/reference/search.mdx
  • packages/leadtype/src/mcp/artifacts.ts
  • packages/leadtype/src/mcp/mcp.test.ts
  • packages/leadtype/src/next/client.test.ts
  • packages/leadtype/src/nlweb/ask.ts
  • packages/leadtype/src/search/client.ts
  • packages/leadtype/src/search/search.test.ts
  • packages/leadtype/src/search/search.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Team
  • Run ID: cc9fb6e4-ae8c-4c5d-9626-977ec23cc43a
📥 Commits

Reviewing files that changed from the base of the PR and between 69b90bf and 214f17d.

📒 Files selected for processing: 7
  • .changeset/search-ranking-page-match.md
  • docs/reference/search.mdx
  • docs/search/add-search.mdx
  • docs/search/ai-answers.mdx
  • packages/leadtype/src/nlweb/ask.ts
  • packages/leadtype/src/search/search.test.ts
  • packages/leadtype/src/search/search.ts

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

📜 Recent review details
⏰ Context from checks skipped due to timeout: 6
  • GitHub Check: pullfrog
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Validate & test on Windows
  • GitHub Check: Validate & test
  • GitHub Check: Build examples
  • GitHub Check: Convert + LLM pipeline
🧰 Additional context used
🪛 markdownlint-cli2 (0.23.3)
.changeset/search-ranking-page-match.md

[warning] 5-5: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

🔇 Additional comments: 7
packages/leadtype/src/search/search.ts: 1

17-23: LGTM!

Also applies to: 37-61, 237-241, 364-404, 462-590, 872-994, 1208-1211, 1229-1229, 1271-1271, 1288-1288, 1355-1356, 1405-1431, 1739-1739

docs/search/add-search.mdx: 1

52-52: LGTM!

Also applies to: 64-64

docs/search/ai-answers.mdx: 1

137-137: LGTM!

Also applies to: 144-144

packages/leadtype/src/search/search.test.ts: 1

20-20: LGTM!

Also applies to: 103-103, 114-114, 313-422

docs/reference/search.mdx: 1

23-24: LGTM!

Also applies to: 51-58, 144-144

.changeset/search-ranking-page-match.md: 1

1-11: LGTM!

packages/leadtype/src/nlweb/ask.ts: 1

601-601: LGTM!

Also applies to: 828-832

📝 Summary

Summary by CodeRabbit

  • New Features
    • Search results now rank pages more effectively using matches in page titles, URL paths, and headings, with improved recognition of camel-case and compound terms.
    • Results are limited to two chunks per page by default, with an option to configure the cap. The /ask endpoint returns at most one result per page.
  • Compatibility
    • Search indexes now use version 4; version 3 indexes fail validation and must be regenerated.
  • Documentation
    • Updated search guidance and examples to reflect the new ranking, result limits, and index version.

Search indexing and ranking now use index version 4, recognize additional token forms, and score matches from page titles, URL paths, and headings. Search results support a configurable per-page cap. NLWeb /ask requests one result per page.

Changes: Search indexing and results

Layer / File(s) Summary
Tokenization and index generation
packages/leadtype/src/search/search.ts, packages/leadtype/src/search/search.test.ts, docs/reference/search.mdx, docs/search/add-search.mdx, docs/search/ai-answers.mdx
Index version advances to 4. Tokenization adds camel-case parts and joined dotted, hyphenated, and underscored forms. Page descriptions are included in searchable text and body postings only for the first chunk. Tests cover tokenization, and documentation examples use version 4.
Page scoring and result limits
packages/leadtype/src/search/search.ts, packages/leadtype/src/search/search.test.ts, docs/reference/search.mdx, .changeset/search-ranking-page-match.md
Search scores query matches in titles, URL paths, and final headings. It applies content-match boosts and limits results per page before applying the overall limit. Tests cover ranking and per-page limits. The reference documents the option and default.
NLWeb validation and search integration
packages/leadtype/src/nlweb/ask.ts
Artifact validation checks body postings against chunk content alone. /ask requests one result per page instead of deduplicating search results afterward.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 214f1

The search changes are mergeable after normal checks; no concrete issue requiring a pre-merge fix was identified.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 40.91% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 22 functions across 3 files. (4 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly summarizes the main search-ranking change by identifying page title, path, and heading as ranking signals.
Description check Passed The description directly explains the search-ranking problems, implemented fixes, index-version change, performance results, and regression tests.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 40.91% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 22 functions across 3 files. (4 skipped: 4 unsupported.)

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

I’m a rabbit with queries to try,
I follow page titles and paths as they fly.
New tokens hop into the index with care,
Two chunks per page make a tidy result pair.
I nibble the changelog, then bound through the night.

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 214f17d724

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/leadtype/src/search/search.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues. Two ranking and performance rough edges are inline.

Reviewed changes

I reviewed the whole PR: the new compound tokenizer, the page-match multiplier, the per-page result cap, the pruned phrase boosting, and the index v4 bump.

  • Compound tokens — ConsentBanner and Next.js now index their parts and their joined form. Case is lowered per token so camel-case boundaries survive.
  • Page-match multiplier — BM25 plus the phrase boost is scaled by title coverage × precision, title∪path coverage, and last-heading coverage, up to 5×.
  • Description in the first chunk only — this also fixes the old double count, because chunk text already contained the description. assertNlwebArtifacts is updated to match.
  • maxResultsPerPage — defaults to 2 and is applied before limit. NLWeb /ask passes 1, and dedupeByPage is removed.
  • Pruned content boosts — phrase and proximity matching run in score order and stop once no remaining chunk can reach the results. I checked the bound: boost ≤ 1.4 × 5, and the k-th selected score never drops when chunks are added, even with the per-page cap.

The search and NLWeb test suites pass (160 tests).

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

Comment thread packages/leadtype/src/search/search.ts Outdated
Comment thread packages/leadtype/src/search/search.ts
Comment thread packages/leadtype/src/nlweb/ask.ts
…cost

- Count title precision per written word, so TypeScript is fully matched
  by typescript instead of scoring 1/3 for its camel-case parts.
- Also compare phrases on the words as written, so the joined nextjs
  token in Next.js app no longer breaks the phrase next js app.
- Refresh the pruning bound at doubling checkpoints, so refreshing stays
  O(n log n) when scores are flat and nothing is pruned.
- Drop the dedupeByPage JSDoc left above sseEvent.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No new issues. All three earlier comments are fixed, and I left one small efficiency suggestion inline.

Reviewed changes

I reviewed b056553, the commit that responds to the earlier review.

  • Title precision counts written words — fieldPrecision now gets one token group per word from tokenizeWordGroups. TypeScript is a single word, so a typescript query covers the whole title. The new test checks that "TypeScript" ranks above "Typescript setup".
  • Phrase matching on written words — when the query has two or more written words, the phrase boost also compares written words without the derived tokens. The joined nextjs no longer breaks next js app. The largest possible boost is still PHRASE_MATCH_BOOST, so the pruning bound still holds.
  • Doubling checkpoints for the pruning bound — the bound is now recomputed at 32, 64, 128 and so on, which keeps the total recompute cost at O(n log n). Between checkpoints the bound can be out of date, but that only means fewer chunks get skipped. Results are unchanged.
  • Removed the orphaned JSDoc in ask.ts, and moved the shared filler docs into one fillerDocs fixture.

The search and NLWeb suites pass on this head: 187 tests, 0 failures.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

Comment thread packages/leadtype/src/search/search.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b05655322d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/leadtype/src/search/search.ts
Reuse the phrase tokens for the proximity check, and test that a phrase
match lifted only by the content boost survives pruning.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found. The efficiency suggestion is fixed, and the new test closes the pruning coverage gap.

Reviewed changes

I reviewed d27d100, the commit added since the last review.

  • Chunk text tokenized once for phrase and proximity — scoreContentMatchBoost now builds textTokens once and uses it for both the phrase check and hasOrderedProximityMatch. normalizeForPhraseMatch is gone. Boosted chunks are tokenized at most twice now, down from three times. Behavior is unchanged.
  • Regression test for the pruning bound — 61 matching chunks take applyContentMatchBoosts past its first checkpoint at 32. Only the phrase boost lifts the target page into the top 5. I checked that the test bites: with + maxBoost removed from the skip condition, it fails and guide-0 ranks first.

The search and NLWeb suites pass on this head (188 tests, 0 failures), and tsc --noEmit is clean.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d27d100d7e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/leadtype/src/search/search.ts
The browser search client and MCP artifact loading only checked that the
index and content matched each other, so a cached v3 pair loaded and was
searched with the v4 tokenizer, quietly missing matches. Both now reject an
index whose version differs from DOCS_SEARCH_INDEX_VERSION, with the same
regenerate message NLWeb uses.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found. Both loaders that read a shipped index now reject a v3 index with a clear error telling the user to regenerate.

Reviewed changes

I reviewed df2c484, the only commit since the last review.

  • Shared version check — the new docsSearchIndexVersionError in search.ts returns an error unless index.version equals DOCS_SEARCH_INDEX_VERSION. The message names the source path or URL.
  • Browser search client — loadArtifacts throws inside the cached promise, so the existing catch drops the cache entry and a redeployed index can load on the next call.
  • MCP artifact loading — loadDocsArtifacts runs the check right after the missing-file check, before it reads the manifest. NLWeb /ask already rejected old versions in assertNlwebArtifacts, so the changeset wording matches the code.
  • Tests — mcp.test.ts and next/client.test.ts each serve a version 3 index and expect the rejection. Only these two code paths parse a generated index from outside; the project and source paths build the index in-process.

The search, NLWeb, MCP and Next client suites pass on this head (222 tests), and tsc --noEmit is clean.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: df2c484d7c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/leadtype/src/search/search.ts
The page-match boost read the URL path, but only chunks with a posting
could be scored, so a page whose only match was its URL never appeared:
`vue` missed a page titled Quickstart at /docs/frameworks/vue/quickstart.

Path words now count once as body text when the chunk lacks them, using
the words as written so hyphenated segments add no joined prefix terms.
countDocsSearchChunkTerms keeps the indexer and NLWeb validation on one rule.
A query such as nextjs matched Next.js through its joined token, but the
excerpt looked for nextjs in text that still had the dot and fell back to
the first 220 characters. Excerpts now also search the text with compound
separators removed, mapped back to the original offsets.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found. A page that matches only through its URL path is now found, and the indexer and NLWeb validation use the same counting rule.

Reviewed changes

I reviewed b2c0358, the only commit since the last review.

  • URL path words become postings — the new countDocsSearchChunkTerms adds each URL path word that a chunk doesn't already contain to its body counts, once. It uses only the words as written, so typescript-setup doesn't add a joined typescriptsetup that every typescript query would prefix-match. vue now finds the page titled "Quickstart" at /docs/frameworks/vue/quickstart.
  • One counting rule — createDocsSearchIndex and NLWeb's assertNlwebArtifacts both call countDocsSearchChunkTerms, so the posting validation can't drift from the indexer. NLWeb reads the URL path from document[3], the same slot createDocsSearchIndex writes it to. Chunk length (chunk[4]) still counts only the text tokens, so NLWeb's length and average-length checks still pass.
  • Docs and test — the changeset and docs/reference/search.mdx now describe the path postings, and the new test "finds a page whose only match is its URL" covers the case Codex raised.

The search, NLWeb, MCP and Next client suites pass on this head (223 tests).

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found. When a query matches only through a joined compound like nextjs, the excerpt now centers on the match in the original text.

Reviewed changes

I reviewed 14f4e3a, the only commit since the last review.

  • Joined-compound fallback for excerpts — the new findOriginalMatchIndex tries each excerpt token against the normalized text first. If that misses, it tries the same token against a copy that drops ., - and _ between two word characters, so nextjs finds Next.js. joinCompoundsWithOffsets builds that copy lazily and only once per excerpt, and its offsets still point into the original text, so the slice window is unchanged.
  • Regression test — "centers the excerpt on a dotted name matched through its joined form" puts Next.js about 340 characters into a chunk, past the 220-character fallback excerpt. I checked that it fails when the joined match is disabled.

The search and NLWeb suites pass on this head (165 tests).

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 14f4e3afc2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

};
// Written words only: a joined `typescriptsetup` from `typescript-setup`
// would become a prefix match for every `typescript` query.
for (const token of tokenizeWrittenWords(chunk.urlPath)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Index joined URL compounds as search candidates

When a dotted or hyphenated name appears only in the URL, using tokenizeWrittenWords omits the joined token that the new tokenizer advertises. For example, a generic Quickstart page at /docs/frameworks/tanstack-start/quickstart returns no result for tanstackstart: the index contains only tanstack and start, so the page never becomes a candidate for its path multiplier. Fresh evidence after the earlier URL-indexing fix is this new written-only call; joined compounds need an exact-candidate path that does not also make typescriptsetup a prefix match for typescript.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving this as is for now. I tried indexing the joined URL compounds (swapping tokenizeWrittenWords for tokenizeDocsSearchText on the path). Every hyphenated slug then becomes a prefix-expansion target for its first word: /docs/typescript-setup adds typescriptsetup, which the query typescript prefix-matches at 0.55, so "Typescript setup" outranks the page titled "TypeScript" again and that regression test fails. On the c15t.com eval, right-page-first drops from 32/46 to 31/46 and MRR@8 from 0.752 to 0.741.

The miss is limited to queries that type a hyphenated slug run together, such as tanstackstart, for a page whose title and text never say "TanStack Start". Fixing it without the prefix problem needs postings that match exactly and never expand by prefix, which is another index format change. The c15t site already maps tanstackstart to tanstack start with query synonyms (inthhq/monorepo#2316), which covers the real case. Happy to do the exact-only postings as a follow-up if maintainers want it.

@KayleeWilliams
KayleeWilliams merged commit 993a4af into main Oct 15, 2026
8 checks passed
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