Written 17 August 2026 by ellsworth (PM). Engineering owned by howard and ralston-eng. Every number below is either measured on the live service today or pulled from the Yandex Wordstat API today; provenance is listed at the foot.
The binding constraint is not product depth. It is liquidity and discoverability.
Дурак and Russian checkers are both built, server-authoritative and live. In 18 hours of uptime the service recorded 0 connections, 0 rooms, 0 completed matches and 0 human matches, ever. Meanwhile «дурак онлайн» is searched roughly 474,000 times a month in Russia. Nothing is wrong with the games. Nobody can find them, and a stranger who did find them would arrive at an empty lobby with no one to play.
So the plan through December spends its first six weeks on being findable and being playable alone, and only then on depth. A third game is deliberately gated behind a retention number, not scheduled.
Verified by reading the repository at 625afe2 and probing the live services, not from
the docs:
| Fact | How it was verified |
|---|---|
Web client live at svoi-game-platform.vercel.app | HTTP 200 |
| Realtime worker healthy, uptime 18.5 h | /svoi/health → ok:true |
| 0 online, 0 rooms, 0 matches completed today, 0 human matches | same health payload |
No route rendered any body text. / and /games/checkers served an identical 1,669-byte shell with the same title; the two rules pages already had their own head and JSON-LD but an empty <body>. Corrected 17 Aug: my first pass said all four were identical — I had probed three paths that do not exist and read the SPA fallback as the real page. The no-text finding held; the "identical" part was mine and wrong. | curl per URL from sitemap.xml, re-checked against git show 625afe2 |
| Sitemap advertised 4 URLs, none of which rendered text — now 5, all rendering | /sitemap.xml + fetch of each, before and after |
| No analytics of any kind on the client — closed 17 Aug (Metrika 111682754, in the static HTML of all five pages) | no Metrika / Umami / gtag in apps/web |
No own domain; WebSocket borrows duel.sudoky.net/svoi/* | repo CLAUDE.md calls this temporary sharing |
| Fairness promise unimplemented — no commitment, seed or proof in the protocol | grep across packages/game-protocol and both gateways |
| Deck derives from a 31-bit seed through xorshift32 | shuffleDeck(), randomInt(1,0x7fffffff) |
| Matches live in worker memory; a restart ends them | docs/MULTIPLAYER.md, stated |
| Engine and gateway tests exist; no CI runs them | no .github/workflows |
| 22 commits, all dated 15–16 August 2026 | git log |
Monthly, Russia (GeoID 225), pulled from the Wordstat API today. These are broad-match and nested figures: sub-phrases are counted inside their head term, so they must never be summed. Read each as the size of an intent, and compare them to each other.
| Query | Monthly | What it tells us |
|---|---|---|
| дурак онлайн | 474,404 | The anchor. Nothing else in the category is close. |
| дурак играть бесплатно | 268,739 | Free-and-instant is the expectation, not a feature. |
| играть в дурака | 224,086 | Play intent, not rules intent. |
| шашки онлайн | 176,111 | The second game was the right pick. |
| нарды онлайн | 113,231 | Strongest candidate for a third game. |
| тысяча онлайн | 74,051 | Fourth. A card game, so it reuses card UI. |
| шашки играть с компьютером | 69,229 | Solo-vs-bot demand is real and large. |
| домино онлайн | 66,918 | Fifth. |
| играть в шашки | 55,302 | — |
| дурак подкидной | 50,209 | The variant we actually implement. |
| карточные игры онлайн | 31,637 | Category-level intent; a platform can own this. |
| морской бой онлайн | 24,983 | Cheap to build, weak retention. Not scheduled. |
| игры на двоих онлайн | 24,152 | Invite-a-friend framing has its own demand. |
| настольные игры онлайн | 9,618 | — |
| правила игры в дурака | 8,139 | 58× smaller than play intent. |
| поддавки | 3,686 | — |
| дурак онлайн с друзьями | 1,203 | Small as a query; large as a mechanic. |
| русские шашки правила | 894 | — |
| шахматы онлайн | 668,318 | Bigger than Дурак — and deliberately out of scope. |
The correction this forces. An obvious first instinct is to prerender the rules pages, because rules pages are static text and easy to publish. The data says that is the small prize: «правила игры в дурака» is 8,139 against 474,404 for «дурак онлайн». The page that has to rank is the page you play on. That is harder — it is the interactive surface — and it is where the work belongs.
The second correction is about bots. «шашки играть с компьютером» at 69,229 is not a rounding error next to «шашки онлайн» at 176,111. A large share of this audience wants to play now, against whatever is available. That is the only product that functions at zero liquidity, and we already have three labelled bot levels in checkers and honest bot training in Дурак.
The category is not empty and it is not weakly held. Live competitors for «дурак онлайн играть бесплатно без регистрации»: minigames.mail.ru/durak, durakgames.ru, logic-games.spb.ru, playnet.club, sdelayhod.ru, and Yandex Games, which hosts its own Дурак app.
I read durakgames.ru as the sharpest of them. It requires no registration, offers humans
and computer opponents, runs three variants (классический, переводной, подкидной), has
configurable 2–6 seat lobbies with passwords, a dedicated /pravila page, substantial
on-page text, and it states mobile support. In other words the incumbent already does the obvious
things — we do not currently beat it on content, variants, or discoverability, only on
architecture, which no visitor can see.
SEO against six established sites is a two-quarter fight. Yandex Games is an archive upload with 3–5 working days of moderation and a catalogue that already sends traffic to a Дурак app. Its requirements, from the developer documentation: the SDK is mandatory and a game cannot be published without it; player progress must persist between sessions; the game must auto-detect the user's language through the SDK; no JavaScript errors or performance problems; sound must stop when the tab is switched or an ad plays. Monetization (ads and in-app purchases) runs through a Yandex Advertising Network account.
All of those are cheap to satisfy if designed in and expensive to retrofit — which is the argument for deciding now that this channel is in scope for Q4, rather than discovering the constraints in December.
Nineteen weeks, five phases, each with an exit condition someone else can check. Dates are targets; the exit conditions are the contract.
vercel.app and off duel.sudoky.net.typecheck and test on every push.Exit: curl on /, /games/durak and
/games/checkers each return ≥1,500 characters of body text with distinct titles; the
domain serves the client over HTTPS and the socket over WSS; Metrika reports a nonzero session count;
a red test blocks a push.
Exit: from a cold visit, first move against a bot inside 10 seconds; an invite link opened in a second browser seats that player; killing the socket mid-match and reconnecting restores the seat with the position intact — demonstrated, not asserted.
Corrected 17 Aug, after reading the client instead of the health endpoint.
Most of this phase is already built: App.tsx offers practice, private and quick modes,
private tables already mint an invite link with a copy button and a room code read from the query
string, and useRealtime.ts already persists a resume token and rejoins an active match.
I had scoped this phase from the docs and the health payload, and it was wrong to assume the
mechanics were missing.
What the real gap turned out to be: the prominent button on the lobby is «Играть с людьми»,
which at zero liquidity is a queue nobody will ever fill, while the one action that works today —
the labelled bot — is the quieter one below it. So this phase is not "build bot play"; it is making
the path that functions the default, and giving the queue an honest exit that offers a bot
explicitly rather than substituting one silently. Briefed 17 Aug.
Exit: a third party, given only what the match published, can confirm the deal was fixed before play began; a test asserts commitment and reveal agree; the claim «играем по-честному» links to the verifier. If this slips, the claim comes off the page until it ships.
Shipped 17 Aug, ahead of schedule — and the scope is narrower than this
phase assumed. The server side is done and verified (commits 8a073d8,
817a5f0): a 128-bit CSPRNG seed, a deal_commitment published before any
hand state, a deal_reveal released only once the match phase is over, and a
test that re-derives every hand, the remaining deck and the trump from the revealed seed. It fails
if the server deals from a seed it did not commit to — verified independently by mutation, not
taken on report.
What that does and does not let a player claim. From the wire, a player can verify
their own hand and the trump after the reveal. Nobody can yet audit a whole match from
outside, because no end-of-match transcript publishes every initial hand and the draw order. That
is acceptable for the promise we actually want to make — «проверьте свою раздачу», verify the deal
you were dealt — and the full transcript is deferred to P5. The copy must say the narrower
thing. Claiming auditability we do not have would be the same failure as the unbacked title tag
this phase existed to fix.
Exit: both games reachable from their own Yandex Games catalogue URLs, and the first session from that channel visible in Metrika.
Re-planned 17 Aug and pulled forward — checkers first, and without an external
host. Yandex Games declares external hosts separately, reviews them, refuses a host that carries
most of the game data, and will not accept a bare IP or a port. Our socket lives on
duel.sudoky.net, which belongs to another product and which the repo already wants to
leave. So a submission that depends on it is gated on the domain.
It does not have to be. packages/checkers-engine exports
chooseBotMove(state, playerId, difficulty, random) with all three levels, so
Russian checkers runs entirely in the browser — rules, bot, mandatory capture,
promotion — with no socket, no declared host and no review of someone else's hostname. Дурак cannot
follow yet: its bot lives in realtime.gateway.ts, server side, so an offline Дурак
needs that logic lifted into durak-engine first. That is a later task, not a blocker.
So the channel opens on checkers alone, and it is blocked on nothing. Briefed 17 Aug: an
offline checkers build with the SDK, progress persistence, language auto-detection and the sound
rules, packaged by a reproducible command. Submission itself needs the operator's Developer Console
account.
Two candidates, and the choice is made by data rather than by preference:
Exit: the decision is recorded with the number that drove it, and the chosen work ships.
Exit: the load test's actual figures are published in
docs/MULTIPLAYER.md, and the year-end read exists as a document.
| Gap | Evidence | Phase |
|---|---|---|
| five pages, 1,631–1,898 chars of text, distinct titles, all in the sitemap | P0 ✓ | |
| No analytics | counter 111682754 present in raw HTML; API reports 0 visits today | P0 — needs one real browser visit |
| No domain of its own; socket borrows another product's host | CLAUDE.md: "temporary infrastructure sharing" | P0 |
| Tests exist but nothing runs them | no .github/workflows | P0 |
| Cold visitor has nobody to play | 0 human matches, ever | P1 |
| commit-reveal shipped; mutation-tested | P2 ✓ | |
128-bit CSPRNG seed, sfc32-v1 | P2 ✓ | |
deal_reveal now carries initialHands, deckOrder, trumpCardId, captured from the real deal; 1,167 bytes at six seats against a 2,048 ceiling; mutation-tested | P5 ✓ (early) | |
CI cannot be read from the box — no gh, no token | private repo returns 404 unauthenticated | needs operator |
| No distribution channel beyond a direct link | research lists five; none integrated | P3 |
| One Дурак variant against the incumbent's three | durakgames.ru offers 3 | P4 (alt) |
| Restart ends live matches | docs/MULTIPLAYER.md | P5 |
| Capacity limits documented but never load-tested | ceilings stated, no measurement | P5 |
| No monetization posture | nothing in the product | deferred — see below |
None of these can be read today, which is why Metrika in P0 is not housekeeping: