Skip to content
Behind the build4 min read

The ranking firewall is a lint rule

We promise that paying us cannot move a product up the leaderboard. Here is the mechanism that makes it true, and why it lives in the linter rather than in a policy document.

Every directory in this category says some version of the same sentence: sponsorship does not influence rankings. It is an easy thing to say and an almost impossible thing for a reader to check. The claim and the code live in different places, one of them is public, and it is not the code.

So the interesting question is not whether a site makes the promise. It is what would have to happen, mechanically, for the promise to break, and how much work that would be.

Here, it is this much work: you would have to delete a lint rule, and the deletion would appear in the diff.

What the rule says

Ranking lives in lib/ranking. Payments live in lib/payments. The ESLint config contains a no-restricted-imports block scoped to lib/ranking/** that forbids importing anything under lib/payments, by three patterns at once, the aliased path, the bare alias, and any relative route that ends up in the same directory.

The failure message is not "restricted import". It names what is being protected:

The ranking firewall: lib/ranking/** may never import payments code. /pricing, /about and /how-ranking-works publish this guarantee.

That wording is deliberate. A rule that fires with a generic message gets suppressed by whoever hits it at 6pm on a Friday. A rule that names the three public pages it is holding up is harder to wave through.

Why an import, and not something cleverer

The rule does not check whether a paid product actually ranks higher. That would be a better test and it is not one you can write: ranking is a scoring function over votes, recency and quality, and proving a negative about its output means enumerating inputs.

What you can check cheaply and completely is reachability. A scoring function cannot use a subscription status it has no way to read. So the rule does not ask "did money affect this score". It asks "could it have", and answers no by making the data structurally unavailable at the point the score is computed.

That is a weaker guarantee in theory and a much stronger one in practice, because it holds regardless of what the scoring function does next year.

The database half

The same rule is expressed a second time in the schema, by omission. There is no foreign key from products to subscriptions, to orders, or to placements. None of the commercial tables is reachable from a product row by following relationships.

This matters more than it sounds. Given a join path from a subscription to a rank, somebody eventually uses it, not maliciously, but because it is there and because a query that needs "paid customers, sorted by position" is a reasonable thing for a growth dashboard to want. The absence of the path is what stops that query from being easy to write.

Commercial data reaches products in one direction only: from the commerce side, looking outward. Never the reverse.

What is not protected

Placements are advertising, and advertising is not ranking. A sponsored slot on a category page is a placement, it is labelled, and placements.is_labelled is NOT NULL DEFAULT true with a CHECK constraint pinning it to true. It is not a boolean anyone can flip during a large sale; changing it requires a migration, which is exactly the amount of friction intended.

So: a company can pay to appear in a slot that says it paid to appear there. A company cannot pay to appear at position three of a list that does not say so. Those are different products and we sell exactly one of them.

The honest limitation

None of this constrains what we choose to feature. There is an is_featured column on products, an editor can set it, and a featured product sorts to the top of the homepage's first shelf. That is editorial judgement, it is not sold, and it is not a ranking, the leaderboard ignores it entirely.

But it is a lever, and a page about mechanisms that omitted it would be doing the thing this post is complaining about.

Why write this down

A guarantee that only exists in prose degrades quietly. Someone adds a feature, the prose stays, and the two drift apart over eighteen months until the page says something that is no longer true and nobody involved remembers deciding otherwise.

A guarantee that fails the build cannot drift. It can be removed (deliberately, visibly, in a commit with an author on it), but it cannot rot.

That is the whole argument for putting it in the linter.

All writing