Skip to content

chore(deps): bump fast-uri from 3.1.4 to 3.1.5 - #2

Merged
Mikhus merged 1 commit into
masterfrom
dependabot/npm_and_yarn/fast-uri-3.1.5
Aug 3, 2026
Merged

chore(deps): bump fast-uri from 3.1.4 to 3.1.5#2
Mikhus merged 1 commit into
masterfrom
dependabot/npm_and_yarn/fast-uri-3.1.5

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 3, 2026

Copy link
Copy Markdown
Contributor

Bumps fast-uri from 3.1.4 to 3.1.5.

Release notes

Sourced from fast-uri's releases.

v3.1.5

⚠️ Security Warning

Fix for GHSA-7p8r-x3mc-p8w7

Full Changelog: fastify/fast-uri@v3.1.4...v3.1.5

Commits

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    You can disable automated security fix PRs for this repo from the Security Alerts page.

Bumps [fast-uri](https://github.com/fastify/fast-uri) from 3.1.4 to 3.1.5.
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](fastify/fast-uri@v3.1.4...v3.1.5)

---
updated-dependencies:
- dependency-name: fast-uri
  dependency-version: 3.1.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Aug 3, 2026
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying imqueue-org with  Cloudflare Pages  Cloudflare Pages

Latest commit: 656e5cc
Status: ✅  Deploy successful!
Preview URL: https://6a8dacb1.imqueue-org.pages.dev
Branch Preview URL: https://dependabot-npm-and-yarn-fast.imqueue-org.pages.dev

View logs

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying imqueue-com with  Cloudflare Pages  Cloudflare Pages

Latest commit: 656e5cc
Status: ✅  Deploy successful!
Preview URL: https://4941f019.imqueue-com.pages.dev
Branch Preview URL: https://dependabot-npm-and-yarn-fast.imqueue-com.pages.dev

View logs

@Mikhus
Mikhus merged commit dadc6d0 into master Aug 3, 2026
4 checks passed
@dependabot
dependabot Bot deleted the dependabot/npm_and_yarn/fast-uri-3.1.5 branch August 3, 2026 20:00
Mikhus added a commit that referenced this pull request Aug 5, 2026
The corpus is built from the markdown mirrors, and the mirrors carry `# Title` plus a
Source/Published/Author block and nothing else — front matter is not in them by design. So
the two most deliberately curated relevance signals on this site were absent from its own
search: `description` was ignored in favour of each page's first paragraph, and `keywords`
was unused entirely. 186 curated phrases across 29 posts, 140 of which appear nowhere in
the indexed text.

The consequence, measured as the rank of the page each phrase was WRITTEN for:

  handle traffic spikes microservices   absent of 32  ->  #1
  nodejs backpressure microservices     absent of 32  ->  #5
  overload resilience                   absent        ->  #1
  message queue throughput              #32 of 134    ->  #3
  nodejs job queue                      #36 of 93     ->  #3
  imqueue benchmark                     #2 of 140     ->  #1

Weighted at 300 — BELOW emphasis — and scored on coverage alone: no density, no position,
no phrase bonus. A keyword list is a handful of comma-separated phrases, so
occurrences-per-token sits near 1.0 for anything that matches at all, and density would
rank by brevity while rewarding padding; order in a comma list means nothing, so position
would be noise.

That placement is the point rather than caution for its own sake. Google has ignored
<meta name="keywords"> since 2009 and Bing treats a stuffed one as a spam signal — because
neither can trust the author. A first-party index can: the author is the site. What does
not change is that a self-declared list is cheap to pad, so it sits under the signals that
cost something to fake, and check:search-ranking asserts "safeDelivery" still ranks the
symbol first — the failure mode meta keywords earned its reputation for is an identifier
query returning articles that merely list the identifier.

Plumbed through a build intermediate: src/search-frontmatter.11ty.js emits url ->
{description, keywords} and the generator reads it and DELETES it, so it never ships. A
template rather than a front-matter parse because mapping a source file back to its URL
means re-deriving permalink resolution, which Eleventy owns and which this repo has already
been bitten by duplicating; `item.url` cannot drift from what Eleventy published. Keyword
text also feeds the vocabulary, so inflections in a keyword list get lemmas like any other
word.

Tier 1 grows 65.2 -> 67.5 KB gz on org, 0.9 -> 1.1 on com.

One defect worth recording: the new record was first named `entry`, inside a loop whose
variable is the directory entry. Shadowing it in the same block is a temporal-dead-zone
error reported at the line ABOVE, which reads as readdir having failed.
Mikhus added a commit that referenced this pull request Aug 5, 2026
Element order is now URL > keywords > title > header > emphasis > body.

The URL leads because a path is two to four words and a human chose every one —
the argument that makes a title strong, applied to something terser. But only for
the words it ADDS. A blog slug is generated from the title, so
/blog/imqueue-vs-moleculer/ matching "imqueue" is the title matching twice; at the
top weight that would quietly mean "titles count double" and demote every other
element to pay for it. So urlScore splits: a term in the path AND the title is an
echo worth less than the title it repeats (110), a term in the path and NOT in the
title takes the top weight (480). /mcp/installation/ is titled "Add the MCP server
to Claude, Cursor & VS Code" — "installation" exists nowhere on that page but its
path, which is the case worth leading with.

The reported symptom had nothing to do with weight, though. urlScore required a
query term to EQUAL a path segment, so "installation mcp" ranked that page #1 and
"install mcp" could not find it at all — one element doing exact string equality
while every other element in the ranker matches substrings. A term is now credited
when it equals a segment, is its lemma, or is a prefix of it from 5 characters up.

keywords moves from 300 to 450, above title. At that weight the difference between
"one of my declared phrases IS what you typed" and "your words appear somewhere in
my list" is the whole value of the element, and without it the promotion did real
damage: four blog comparison pages whose lists merely contain "imqueue" pushed the
home page's own "What @imqueue is" heading from #1 to #9. A declared phrase now
takes the full 450, word overlap takes 270 — near where the element sat before.

/intro/ replaces / as the expected #1 for "what is imqueue", and it is a decision
rather than a drift: /intro/ declares that literal phrase in its keywords and its
title answers the question in a sentence. The home page is #2. The failure that
case was written for is guarded by the stopword and bagScore checks, not by which
of those two pages comes first.

covers() now sees the path for exactly the records urlScore will score, and not
for the API records it returns 0 on. Yesterday's bug was a floor rejecting what
the scorer would have ranked first; crediting a path the scorer ignores is the
same bug mirrored.

  how to install mcp     #5 -> #1
  install mcp            absent from the top -> #1
  what is imqueue        /intro/ #1, / #2 (was / #1, /intro/ #2)
  imqueue vs moleculer   its own article still #1 — no slug double count

Also fixes a stale comment: the keywords element claimed to sit "BELOW emphasis
deliberately" while its value was 300 and emphasis was 200.

Full suite green on both editions; six new ranking checks.
Mikhus added a commit that referenced this pull request Aug 5, 2026
imqueue.com reaches the ranker only through the peer feeds, so with x1/x2
unloaded "pricing commercial license" answered from imqueue.org's own /license/ —
a plausible page, the wrong edition, and nothing anywhere reporting a problem.
The MCP server's docs.ts went out of its way to fix that ("the commercial
question was the single thing this server could not answer") and nothing here
asserted it stayed fixed. This is the last open item of the plan's Phase 0.3.

Three cases, each answerable only by the commercial edition, asserted as "an
imqueue.com result is in the visible set" rather than "it is first": which
commercial page wins is a ranking judgement that may change, that the answer
comes from the edition documenting licensing at all is not. Plus the reverse — a
framework query must still lead with imqueue.org — so the peer feed cannot swamp
the docs it sits beside.

  pricing                      -> imqueue.com at #2
  commercial license           -> #8
  pricing commercial license   -> #5   the phrasing the plan recorded as broken

"support" was tried and dropped: imqueue.org has its own page titled Support,
which correctly takes #1, so the query is not commercial-only and asserting
otherwise asserted a false premise. Better to delete the case than to weaken what
the others mean.

Skipped rather than failed when the peer feed is absent, since `npm run
build:org` alone does not produce one. Verified the guard fails when it should by
swapping in an org-only topic: "graceful shutdown sigterm" reports no imqueue.com
result and exits non-zero.
Mikhus added a commit that referenced this pull request Aug 6, 2026
…s ranker

TWO CHANGES, both from building a real app against the MCP server and recording where
search failed.

1. THE PACKAGE FRONT PAGES WERE INVISIBLE. search-corpus.js excluded everything under
   /api/, correctly for the 1,152 symbol pages — the feed already carries each symbol's
   name, kind, package and summary, and deriving that twice once produced 52% junk. But
   the rule matches on URL, and /api/<pkg>/latest/ is a different kind of page: an
   overview naming the entry points, a Remarks section stating the behaviours no
   signature shows, and worked examples.

   Those 16 URLs got ONE record whose entire searchable text was a title and a
   one-liner — 98 characters for @imqueue/http-protect, against 123 for a single one of
   its properties. So "protect an HTTP gateway from too many requests per IP" returned
   four HttpProtect PROPERTY pages, each with a summary mentioning requests and IPs,
   while the page holding `app.use(new HttpProtect().jsonMiddleware())` never appeared.
   A property page outscored the front page of the package because it had more indexed
   text than the front page did. The `hardening` topic of the question KPI scored 0% on
   BOTH rankers for the same reason: what answers it was not in the corpus.

   Sections only, not a page record — the feed already contributes a `package` record
   for each of those exact URLs, and a second record would leave the ranker's URL dedupe
   choosing between two spellings of one page.

   Cost: 719 -> 836 sections, search-text.json 206.9 -> 241.4 KB gz, on a feed fetched in
   the background after the first query rather than on load. check:search-index now
   validates 700 section ranges against the real mirrors, up from 599, and those pages
   are dense with code fences.

2. THE RANKER NOW JUDGES A SECTION BY ITS PAGE (submodule -> 3a43ea0). Natural micro
   94.1 -> 94.2 and macro 88.9 -> 89.0 with 19 better against 7 worse; question accuracy
   64.0 -> 64.5, macro 60.9 -> 61.5, #1-exactly 47.8 -> 48.7; artificial 91.1 -> 90.8.
   See that commit for the mechanism and for the two experiments rejected on the way.

Honest note on (1): measured alone it moved no aggregate — natural, artificial and
question all within 0.2 either way. It is kept because the content genuinely belongs in
the index and individual answers do improve (/api/validation/latest/#remarks went from
absent to #2 for "how do I reject bad input before it reaches my method?"), and because
nothing can rank a page whose text was never indexed. The aggregate needs the weights,
which is what (2) starts on.
Mikhus added a commit that referenced this pull request Aug 6, 2026
The harness was being asked to resolve differences it could not. Decisions have
rested on natural-macro moves of 0.1–0.5 points, and its own README records a
change that moved the mean by +0.0 while 260 queries churned. "19 better / 7
worse" is a better signal than the mean and still not an answer.

lib/stats.js reports the same per-query deltas three ways: a seeded paired
bootstrap 95% CI, a Wilcoxon signed-rank p-value (non-parametric because the
per-query metric is discrete, bounded and mostly exactly zero — where a t-test
misbehaves), and the same test over TOPIC MEANS, because the headline is a macro
average and a claim about a macro has to be tested over topics. Paired
throughout: both rankers see the same queries, so the variance that matters is
the variance of the differences.

It also calibrates the evidence already in use. 19 better / 7 worse of 2,281 at
equal magnitudes is p = 0.019 — significant, so the churn count was worth more
than it looked. 12 better / 10 worse is p = 0.68 and means nothing.

lib/split.js cuts each set in two and both halves print by default, because
every constant in the ranker was chosen by sweeping it against these sets and a
training score that reads as a measurement is the failure this prevents. The cut
is BY TOPIC, never by query: the natural harvest expands each seed a–z, so
`imqueue rpc` and `imqueue rpc example` are near-twins on the same page, and
splitting by query would put twins on both sides and make the holdout agree with
the fit by construction. Artificial is cut by TARGET PAGE — its `bucket` is a
query SHAPE, and cutting on shape produced halves made of different populations
and read the difference as a 5.6-point fitting gap on a ranker nobody had tuned
against that set at all.

The result is good news that was not guaranteed:

  natural      fit 87.8%  holdout 90.3%   (-2.5, holdout BETTER)
  artificial   fit 98.5%  holdout 98.5%   (+0.0)
  question     fit 62.4%  holdout 60.6%   (+1.8, inside the noise of 56 queries)

No detectable overfitting after twenty rounds of hand-tuning.

nDCG@10 is reported beside the linear metric rather than replacing it. The -10
per position rule says something true — nobody scrolls to row eleven — but it
overstates #5 against #7 and understates #1 against #2; the two together say
more than either. One relevant document per query, because `expect` lists
ALTERNATIVES, and textbook DCG summing over them would reward returning three
spellings of the same answer. `grades` is honoured where a query carries one, so
a graded label set needs no further harness change.

compare.js gains the question set. It measured two of the three populations, and
the missing one is the only set that has ever caught a regression the other two
could not see.

check-search-ranking.js gains three cases for the ranker's new relaxation pass,
including the gate itself — a query that returns results must never be rewritten.
The safety argument for spelling correction is worth exactly as much as that
assertion.

Pins search-ranker 6fc2ca8.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant