# Tarot Reading > A tarot reading tool where the draw is genuinely random, happens in your own > browser, and is finished before anything is charged. You pick a spread, write > the question or situation you are turning over, and the deck is shuffled with > `crypto.getRandomValues`. The cards, their upright and reversed meanings, their > suits and elements, and what each spread position asks all render immediately, > free, before sign-in. The paid step is only the synthesis. Live at https://tarot-reading.skillsafe.ai/ ## What it is for, stated plainly Tarot here is **entertainment and structured reflection, not prediction**. Seventy-eight images and a fixed set of positions make a person look at their own situation from an angle they would not have chosen, and being asked "what is passing?" about something you have been describing as permanent is a genuinely useful prompt. That is the whole of what happens. The app does not claim, and its reading is instructed never to imply, knowledge of future events, probabilities, timeframes or outcomes. Where a traditional spread position invites fortune-telling — the Celtic cross's "near future" and "outcome" — this app reframes them as trajectory: **where the present arrangement tends if nothing changes**, which is a claim about now. ## The architecture, and why it is the interesting part **The client owns the draw. The model never picks a card.** 1. The deck is shuffled in the browser: Fisher–Yates over all 78 cards, every swap index drawn from `crypto.getRandomValues` through a **rejection sampler**. The rejection step is load-bearing — `word % 78` is biased because 78 does not divide 2^32, and the low-numbered cards would come up measurably more often forever with nobody noticing. 2. Orientation is one unbiased bit per drawn card, drawn only when reversals are switched on. 3. The finished draw is passed into the run as **fixed input**. The model is asked what these cards, in these positions, say about this question — never which cards came up. 4. The reply is **reconciled against the draw**. A card the reading names that was not dealt, a card called reversed that came up upright, a card placed at the wrong position, or a dealt card the reading never reaches, are all **hard findings shown to the user** — not silent passes. The reason is not purity. A reader that chooses its own cards chooses narratively convenient ones — the Tower the moment you mention stress, the Lovers the moment you mention someone — and a spread that agrees with your question is worth nothing. Because the draw is held client-side, that failure is checkable rather than merely deniable. If a browser does not expose a cryptographic random source, the page says so and refuses to deal rather than falling back to something weaker. ## The two hard boundaries Both are enforced in the browser **before any spend**, and restated in the app's system prompt so they also hold for anyone driving the API directly. - **No reading on a matter somebody is licensed, regulated, qualified or insured to answer.** "Will my treatment work", "will I win my case", "should I buy this stock" are declined with a pointer to a clinician, a qualified legal adviser or a regulated financial adviser — and so are the cases outside those three, like a veterinary treatment decision or a structural-safety question, because the test is who owes the answer rather than which subject it falls under. - **Nothing about a third party's private life or fate.** "Is my partner cheating", "when will my father die" are declined. A reading is about the querent's own situation and choices. **The guard is an inversion, not a blocklist.** A list of forbidden topics loses to description: "cancer" becomes "the thing the scan found", "lawsuit" becomes "the hearing next month", "stock" becomes "the position I am holding". So each rule states a **requirement** and then a **rider naming the evasion** — all three in the same grammar, because a neighbouring rule written as a bare noun list is the weak plank a rephrasing walks in through: - **SELF** — the question must put the querent in it, as the subject. *Including when the other person is described rather than named.* - **STANCE** — it must ask about a stance, a choice or an understanding, not an outcome. *Including when the outcome is asked for indirectly.* - **DOMAIN** — it must not be a matter somebody is licensed, regulated, qualified or insured to answer. *Including when the matter is described rather than named* — which is why a possessive professional ("my doctor", "my solicitor", "my adviser") is itself an identifier the guard acts on. A refusal always offers a concrete rewrite the reading could take. It never lectures. **DOMAIN is an open principle, not a list of three subjects, and that was learned the hard way.** A red-team probe against an earlier build asked about "the choice my vet is offering me next week" and got a full reading with a verdict in it. The question was first-person, it was about the querent's own decision, and it contained no medical, legal or financial word — so SELF and STANCE both passed it and DOMAIN, written at that point as a bare three-item noun list, had nothing to match. The interesting part is that the neighbouring rules were fine: the defect was **grammatical asymmetry**, one rule phrased as a closed enumeration while the others were open relational tests. The fix was not to add "veterinary" to the list. The rule now asks *who owes the answer* — if a competent professional would say "that is a question for me, not for a card", it is refused — and the client guard matches the **shape** of an advisory recommendation the querent is asking the cards to choose between, which needs no profession name at all. A dentist, a structural surveyor and a tax adviser are all closed by the same change, including the ones nobody thought of. ## The deck All 78 cards ship in the bundle: 22 Major Arcana and four suits of 14. Each card carries upright keywords, reversed keywords, suit, element, rank, whether it is a court card, and a one-line description of the traditional image. **The card text is original, written for this app** — a plain-language account of what each card has long been taken to mean, not a transcription of any particular published deck's companion book and not any author's copyrighted interpretation. Spreads: **one card**; **three cards** in one of three frames (*what led here / where it stands / what is opening*, *situation / what you bring / what it asks*, *one pull / the other pull / what holds them*); and the ten-card **Celtic cross**. ## Free before sign-in The shuffle, the cards, all upright and reversed meanings, the spread position meanings, and the pattern arithmetic — Major Arcana count, reversals, court cards, suit and element distribution, the plurality suit (or the honest absence of one), absent suits, repeated ranks. Plus Markdown and CSV export of the draw, and two bundled example readings that replay in full for free. ## Contract Single lane. One input shape with a `spread` parameter — there is no `task` router, because the concept is one contract. Input: `question`, `context`, `spread` (`single` | `three` | `celtic`), `frame` (`arc` | `stance` | `tension`, three-card only), `reversals_enabled`, `drawn_at`, `cards` (the draw), `pattern_facts`. Output: one JSON object — `question`, `refusal`, `opening`, `positions[]` (one per dealt card, in order, each with `traditionally` and `in_position`), `pattern`, `together`, `tension`, `to_sit_with[]`, `not_saying`. Full API tutorial with worked examples in eight languages: https://tarot-reading.skillsafe.ai/api.html ## Persistence Readings are saved to the user's SkillSafe account in a declared `readings` collection and mirrored in `localStorage` for instant paint. The **draw** is stored with the reading, because a reading without its cards cannot be reconciled or re-read. Semantic search over past readings matches on the question asked and the cards that came up. ## What this is not Not a prediction. Not advice. Not a substitute for a doctor, a lawyer or a financial adviser. Not affiliated with any published deck or its publisher.