Repository navigation
Releases: sadkinglabs/sorcery-registry
Release list
v3.4.0
Schema 12. Additive: no identifier changed and no existing value changed.
Notes. Cards and printings carry notes: facts the official API does not say, each with its source and the date it was recorded. The first is on P001640, the Frank Frazetta Sorcerer: prize support in the Arthurian Legends store kit.
Records kept by hand. The registry can now record cards and printings the official API does not serve, such as store-kit prizes, Kickstarter pledge cards and curios, with the same fields as every other record and ids from the same counters. Every card, printing and set says who stands behind it: origin is api or manual, and manual gives the source and date. A manual record keeps its id when the API later serves it and a person confirms the match. This release holds none yet.
Sets. A set code is a label, never a number. Each set now carries kind: release, promo (999) or registry (a set of the registry's own, such as CUR). Every printing carries released_with, the set release it belongs to. P001640 is recorded as released with Arthurian Legends.
Release diffs. changes.json reports notes and records kept by hand in sections of their own, and a field a release adds counts as a change only where it holds more than its default. This release: 1 printing changed, 1 note added, 0 identifiers removed.
Migration guide: docs/migrating-to-v2.md, section v3.3 to v3.4 (schema 12).
v3.3.3
No data changes since v3.3.2. This release adds types.d.ts to every release root: TypeScript declarations generated from schema.json, so a TypeScript project gets typed records with one import and nothing to install (import type { Registry, Card } from "./types"). Every field carries the schema's description as JSDoc; Card and CardHistoryRow extend Face. index.json lists the new endpoint. CI now checks the committed declarations match the schema and type-checks a slice of the export against them.
See the API documentation: https://kairosarchive.net/docs/data
v3.3.2
No data changes since v3.3.1. This release adds changes.json to every release root: what a release changed against the one before it, as counts and the ids behind them, with identifiers_removed always 0 within a major. The release workflow now refuses a release that removes an identifier within a major, so the promise that ids are permanent is checked at release time. index.json lists the new endpoint; the file is also attached to this release.
See the API documentation: https://kairosarchive.net/docs/endpoints
v3.3.1
Druid's two faces, corrected by hand.
The official API serves this card's faces wrong: the front carries the back's text ("Nearby allied sites have ...") while the back still reads the wording it replaced ("Whenever an enemy enters a nearby site ..."), and the front's Tawny clause is not the card's current wording either. Upstream issued no errata for any of it, so the registry corrects it the way it corrects every upstream data error - an override in data/overrides.json, with its reason.
C000459 now reads:
- front: Tap -> Play or draw a site. If this is your first turn, summon Tawny here. / Tap -> Summon Bruin here. Flip this card.
- back: Tap -> Play or draw a site. / Nearby allied sites have "Whenever an enemy enters here, it takes 1 damage."
Its card_history keeps two rows: the printed face, transcribed from P001762 and valid 2024-10-04 to 2026-09-15, and the corrected face from 2026-09-15. errata stays true and both text-bearing printings still report printed_as_current false; the textless promo P001764 stays null.
Data only: no schema change (still 11), no new or retired records, 1,100 cards and 1,873 printings as in v3.3.0.
Mechanism, for anyone reading the repository: data/overrides.json and data/errata.json now accept back., which corrects one field of a back face and leaves the rest of that face as upstream serves it, rather than freezing the whole face in a hand-written file. A field name the registry does not have is now an error in both files instead of a line that silently corrects nothing.
v3.3.0
Schema 11. Additive to consumers: one new field on card_history rows, and corrected values in printed_as_current.
28 cards were changed by the publisher after they were printed. The official API serves only their current text (it used to mark it UPDATED; the 2026 re-import dropped the marker), so the registry had never seen the earlier face and every printing of those cards claimed printed_as_current: true - which is false when the card in your hand says something else.
card_historyrows carrysource:apiwhen the registry observed the face in the official API,cardwhen it was transcribed by hand from the printed card. 28 rows of the second kind are new; they run from the day the first printing carrying the printed face reached the public until 2026-09-15, when the current face takes over.printed_as_currentis now false for 101 printings (98 of them printings of these 28 cards), andnullfor the two textless OP promos that show no rules text at all (Deathspeaker P001611, Druid P001764): no date can say what a card shows when it shows nothing.- Because none of these cards has a printing that shows its current values, each one's
default_printing_idis now a printing withprinted_as_current: false. That is the selection rule working as documented, not a regression. - The transcriptions live in
data/errata.jsonwith the printing each face was read from and why.python -m registry.errata checkruns in CI: the file, the history and the release dates must agree.
Nothing breaks. Read source if you want to distinguish an observed face from a transcribed one; docs/api.md and docs/migrating-to-v2.md (v3.2 to v3.3) describe both. Pin https://api.kairosarchive.net/v3.3.0/ for immutable bytes, or follow /v3/ for the current release.
v3.2.1
Card images for every card.
Additive; v3.2 consumers keep working. Every record keeps its ids, slugs and histories; only the image fields filled in.
- 3,087 faces held from the publisher's public folder: 1,411 printings at full size (
image_status: ok), 1,673 upscaled from the publisher's 380x531 files and flaggedlowres, 4 printings without a file in the folder remainmissing. - Every one of the 1,100 cards carries
image_urls(its default printing's); the 3 double-faced printings carryback.image_urls. - Renditions:
small146x204,normal488x680,large672x936 WebP, plus the untouchedoriginalPNG, athttps://api.kairosarchive.net/images/, content-addressed and permanent. Suggested CSS for the printed corner:border-radius: 4.75% / 3.5%; the publisher's files already carry transparent rounded corners.
Intake notes: downloads are signed by a service account in the archive's Google Cloud project (it reads only what is public); a run killed after uploading is recovered by adopting the bucket's renditions rather than downloading again; CDN verification is paced under the zone's own rate rule. Automated clients must send a User-Agent. Terms: docs/usage.md.
v3.2.0
Schema 10: derived power, self-hosted images, lowres.
Additive; v3.1 consumers keep working. Every record keeps its ids, slugs and histories.
poweron cards, back faces andcard_historyrows: equalsattackwhen attack and defense are equal, otherwise floor((attack + defense) / 2);nullwhen either stat is null. Derived, never stored; the search keypow:on kairosarchive.net reads it.- Images, self-hosted per the publisher's guidance, from their public folder: printings carry
image_hash,image_statusandimage_urls(small146x204,normal488x680,large672x936 WebP, plus the untouchedoriginal); a back face carries its ownimage_urls; cards carry their default printing's. Object names are content-addressed underhttps://api.kairosarchive.net/images/and never change bytes. image_statusgainslowres: the publisher's file is below 672 px wide and was upscaled to the standard sizes.missingis still the value for a printing with no file.- This release holds 12 faces (a trial batch, all Alpha, all
lowres); the remaining printings aremissingand fill in on the next releases as the folder is processed. index/cards.jsonaddsattack,defense,power,life,image_status;index/printings.jsonaddsimage_hash,image_status.- Data files:
data/images.json(per face: source file, MD5, dimensions, art key, rendered sizes) anddata/image-decisions.json(hand decisions for files the naming rule cannot place, each with a reason). - Automated clients must send a
User-Agent; anonymous requests to api.kairosarchive.net are refused at the edge. Terms: docs/usage.md.
Migration notes: docs/migrating-to-v2.md, section v3.1 to v3.2.
v3.1.0
Kairos Archive v3.1.0: the registry is now served from api.kairosarchive.net.
Schema 9, additive. No identifier changed; every codex_id and printing_id from v3.0.0 is present and refers to the same card or printing.
New on every record
- api_url: the record's own JSON object on api.kairosarchive.net, under the moving /v3/ alias (always the newest verified v3.x release).
- kairos_url: the record's page on kairosarchive.net.
- image_urls and image_status on printings, their back faces, and cards (through the default printing): null / "missing" in this release; the image pipeline fills them in a later minor release without changing the shape.
- Sets carry api_url and kairos_url too. Slug objects carry the resolved printing's addresses.
Hosting
- Immutable release roots: https://api.kairosarchive.net/v3.1.0/ (registry.json, schema.json, manifest.json, cards/, printings/, slugs/, sets/, index/, history/). Bytes at a published path never change; cache forever.
- Moving alias: https://api.kairosarchive.net/v3/ redirects (302) to the newest verified v3.x root.
- Discovery: https://api.kairosarchive.net/versions.json lists every hosted release with the digest of its registry.json; a release is listed only after the CDN has been verified serving it.
- CORS allows GET/HEAD from any origin. No keys, no signup. Usage terms: docs/usage.md (linked from index.json as "terms").
- The GitHub release remains a full mirror.
Pipeline
- Every upstream payload is checked against the publisher's published CardAPIDTO contract before it is read; every upstream request identifies itself with a User-Agent.
- The MCP server reads the newest verified release through versions.json, falling back to the same tag on GitHub.
Migration notes: docs/migrating-to-v2.md (v3.0 to v3.1 section).
v3.0.0
Schema v8: the registry records every state of a card's gameplay face, not just its text. No identifier changed - CI proved append-only against v2.0.0.
Why: upstream announced reprints that change existing cards' cost and power. v2.0 recorded rewordings only; a stat change would have overwritten the old values silently. Now a reprint that changes a card's numbers is recorded exactly like a rewording.
Breaking: the rules_history section is replaced by card_history - one row per state of the whole face (type, category, rarity, slot, subtypes, elements, keywords, umbrellas, cost, attack, defense, life, thr_*, rules_text, back) with valid_from / valid_to. The 1101 v2.0 rows carry over exactly; every card has one open row equal to its record. header.rules_history is header.card_history.
errata widened: true once any gameplay field has changed since printing - type, elements, cost, attack, defense, life, thresholds, rules text, back face. A change to rarity, slot, subtypes, keywords or umbrellas is history but not errata. Same 29 cards today.
Added, default_printing_id on every card: a representative printing chosen by a fixed rule so every consumer picks the same one - not retired, showing the card's current face, Booster over other products, Standard over other finishes, most recently released, lowest id. A reprint that changed a card's stats becomes its default even as a promo; otherwise a promo never outranks a Booster. Maintainers can pin a different printing through data/overrides.json.
Added, printed_as_current on every printing: whether the values physically printed on it equal the card's current face, derived from its release date and card_history. 3085 true, 3 false (Sir Lancelot's printings, all released before its reword).
Published objects: history/cards.json replaces history/rules.json; card objects carry card_history; both new fields appear in the indexes. See docs/migrating-to-v2.md for the v2.0 -> v3.0 field map. 107 tests.
Pin this release's export at:
https://raw.githubusercontent.com/sadkinglabs/sorcery-registry/v3.0.0/export/registry.json
v2.0.0
Schema v7: the registry now mirrors the rebuilt official API. No existing identifier changed - CI proved append-only against v1.5.0 - but the shape of every record did, hence the major version.
Why: the official API was rebuilt on a new backend in August 2026 with a completely different payload. All 1100 card names and 3088 slugs survived the rebuild unchanged, so every codex_id and printing_id from v1.x is intact. The registry's own identifiers remain the only stable ones: upstream's new per-card and per-printing ids are database minting ids, regenerated on every re-import (confirmed by its developers), and are not stored.
Breaking, cards: defence is defense; subtypes and elements are arrays in upstream's order (["None"] = colourless); set_numbers is set_codes. New: category (Spell, Site, Avatar, Token), slot (the rarity slot a card is distributed in), keywords, umbrellas (Evil, Knight, Royalty), and back - the full gameplay data of the reverse face for the two double-faced cards (Druid, Foot Soldier), null otherwise.
Breaking, printings: physical facts only. set_number is set_code (a code, not a number - 003 is deliberately unused); type_text is typeline; artist gains artist_slug; released_at is the printing's own release date; product names are spelled as upstream spells them (BoxTopper, OrganizedPlay, PreconstructedDeck, ...). The per-printing copies of type, rarity, rules text and stats are gone: a card plays by its current text wherever it was printed, and that text lives on the card record.
Sets: set_code; released_at is the earliest printing date in the set.
Added, rules_history: every text a card has played by, as observed by syncs. When a card is reworded the previous text is closed with a valid_to date and the new text opens a row. Sir Lancelot's reword is the first entry.
Kept, errata: upstream no longer marks updated cards (the old UPDATED: text prefix is gone and nothing replaces it), so the flag is now the registry's own: seeded from the old marker, set whenever a sync observes a card's text change, corrected through data/overrides.json. 29 cards.
Kept, flavour_text: upstream serves it as null for every printing since the rebuild; the registry keeps the 1015 values it holds and treats an upstream null as no information.
Data changes applied in the same release, all upstream-sourced: set 999 is now named "Promo"; Alpha and Beta release dates follow upstream's printing dates (2023-06-22, 2023-10-06); 39 multi-element cards reordered to upstream's order; five Avatars and tokens lost a printed rarity they never had.
MCP server: set_code throughout, keyword and category filters on search_cards, product matching that accepts "Box Topper" / box_topper / BoxTopper. Same seven tools. 93 tests. The committed database was migrated by registry/migrate_v7.py, which proves every id and history row survived.
Pin this release's export at:
https://raw.githubusercontent.com/sadkinglabs/sorcery-registry/v2.0.0/export/registry.json