fix(playtest): stop rejecting real Steam keys on a guessed alphabet #245

Merged
sionzee merged 1 commit from fix/steam-key-alphabet into main 2026-08-11 01:24:16 +02:00
Owner

A 100-key batch downloaded from the Steam partner site imported as 38 imported / 62 invalid. The keys were fine — STEAM_KEY_RE was not.

It excluded I, O, S and 0, documented as "those are excluded by Valve to avoid confusion". That is folklore from the old retail CD keys. The rejected keys in that batch visibly contain both I and 0:

*****-*****-GII65   *****-*****-I4G20   *****-*****-460RG   *****-*****-CG0PL

Interestingly the batch also rules out the opposite extreme: with a full 36-character alphabet only ~17% of keys would survive a 4-character exclusion, and 38% did. So Valve does omit something — plausibly O and S, of which the batch shows no instance. Guessing which characters is exactly what caused this, so the fix does not guess again.

Change

/^[A-HJ-NP-RT-Z1-9]{15}$/ → /^[A-Z0-9]{15}$/. Structure only: 15 alphanumerics after normalisation.

Valve is the authority on whether a key is real, and it says so at redemption. The two failure modes are not symmetric — a false reject silently discards paid inventory and keeps no record of what it dropped (rejected candidates are skipped, never stored, and only a masked form is echoed back), while a false accept surfaces the moment a tester tries the key.

Blast radius

Nothing was lost in the failed import, and re-uploading the same file is idempotent: duplicates collapse in-batch and again on the keyFingerprint unique index, so the 62 import and the 38 return as duplicates.

Tests

Both specs encoded the wrong assumption and now assert the opposite, including the exact shapes from the real batch. 707 pass / 0 fail, tsgo clean, oxlint unchanged against baseline (16 pre-existing warnings on the touched files, before and after).

🤖 Generated with Claude Code

A 100-key batch downloaded from the Steam partner site imported as **38 imported / 62 invalid**. The keys were fine — `STEAM_KEY_RE` was not. It excluded `I`, `O`, `S` and `0`, documented as *"those are excluded by Valve to avoid confusion"*. That is folklore from the old retail CD keys. The rejected keys in that batch visibly contain both `I` and `0`: ``` *****-*****-GII65 *****-*****-I4G20 *****-*****-460RG *****-*****-CG0PL ``` Interestingly the batch also rules out the opposite extreme: with a full 36-character alphabet only ~17% of keys would survive a 4-character exclusion, and 38% did. So Valve does omit *something* — plausibly `O` and `S`, of which the batch shows no instance. Guessing which characters is exactly what caused this, so the fix does not guess again. ### Change `/^[A-HJ-NP-RT-Z1-9]{15}$/` → `/^[A-Z0-9]{15}$/`. Structure only: 15 alphanumerics after normalisation. Valve is the authority on whether a key is real, and it says so at redemption. The two failure modes are not symmetric — a false reject silently discards paid inventory and keeps **no record of what it dropped** (rejected candidates are skipped, never stored, and only a masked form is echoed back), while a false accept surfaces the moment a tester tries the key. ### Blast radius Nothing was lost in the failed import, and re-uploading the same file is idempotent: duplicates collapse in-batch and again on the `keyFingerprint` unique index, so the 62 import and the 38 return as `duplicates`. ### Tests Both specs encoded the wrong assumption and now assert the opposite, including the exact shapes from the real batch. 707 pass / 0 fail, tsgo clean, oxlint unchanged against baseline (16 pre-existing warnings on the touched files, before and after). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(playtest): stop rejecting real Steam keys on a guessed alphabet
Some checks failed
OpenCodeReview / review (deepseek) (pull_request) Failing after 4s
OpenCodeReview / review (luna) (pull_request) Has been cancelled
Tests / test (pull_request) Successful in 59s
96383df68a
STEAM_KEY_RE excluded I, O, S and 0 "because Valve excludes them to avoid
confusion". That is folklore from the old retail CD keys and does not hold for
keys generated on the partner site: a real 100-key batch imported on 2026-08-11
was rejected 62 times over, with I and 0 plainly present in the failures
(...-GII65, ...-I4G20, ...-460RG). The batch's pass rate also rules out a full
36-character alphabet, so Valve does exclude something - but guessing which
characters is precisely what broke this.

Validate structure only: 15 characters of A-Z0-9 after normalisation. Valve is
the authority on whether a key is real and says so at redemption. A false
reject silently discards paid inventory and keeps no record of what it dropped;
a false accept surfaces the moment a tester tries the key.

Nothing was lost in that import - rejected candidates are skipped, never
stored - and re-uploading the same file is idempotent via the fingerprint
index, so the 62 import and the 38 come back as duplicates.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
sionzee deleted branch fix/steam-key-alphabet 2026-08-11 01:24:16 +02:00
Sign in to join this conversation.
No description provided.