# Fortune Cookie Generator > A fortune cookie generator that writes its own lines, checks every one of them > in your browser against a corpus of anonymous traditional proverbs and fixed > idioms, and publishes the rate at which that check misses. Live at https://fortune-cookie-generator.skillsafe.ai/ - a metered SkillSafe app. The generator runs a language model and costs credits; the two checking lanes are free, need no account, and never send anything anywhere. ## What it does You choose four things and get back that many one-sentence fortunes plus a set of lucky numbers. - **Tone** - `dry`, `warm`, `ominous`, `absurd`. - **Mode**, deciding what kind of sentence it is - `aphorism` (a standing fact), `prophecy` (an event in your future), `advice` (do one thing, or stop). - **Count** - 3, 5 or 7. - **Subject** - optional; omit it for an unaimed batch. All twelve tone x mode combinations are offered and all twelve are verified reachable: each is measured against the four tones and lands nearest its own. ## The two promises, and exactly what backs them **Nothing carries a name.** No philosopher, no national tradition, no "as the saying goes". A fortune signed with a source manufactures a historical record that outlives the tool, so the app does not produce one and refuses to pass one through. 11 grammatical shapes of attribution are detected: a signed name, `attributed to`, `in the words of`, an invented national proverb, an appeal to "the ancients", a dash-signed line, and a quoted phrase. **Nothing should be a saying that already exists.** Every field of every reply is matched in the browser against a shipped corpus, across two independent channels. ## The numbers, including the one that is not flattering | measure | rate | |---|---| | lines the corpus holds, word for word | 100% (474/474) | | lines the corpus holds, lightly reworded | 92.8% | | a corpus line embedded in a longer sentence | 97.0% | | **held out - 160 traditional sayings the corpus does NOT hold** | **4.4%** | **The held-out figure is the one that means anything.** It says this is a CORPUS-MEMBERSHIP TEST, NOT AN ORIGINALITY TEST. A clean result means no known match was found in a corpus of 474 lines; it does not mean a line is original, and no surface of this app claims otherwise. The held-out set was deliberately *not* folded back into the corpus afterwards - doing so would have raised the headline number and destroyed its meaning. Expanding the corpus is the only thing that moves that figure; better matching does not. ## Why two matching channels The first channel strips function words and stems what is left. It is strong on proverbs with real nouns in them and **structurally blind** to phrases built almost entirely from function words. Measured on this bundle: of 172 fixed idioms, the stem channel catches 159 and the verbatim word-window channel catches 172. The **13 it cannot see have exactly zero content words** - "It is what it is.", "So be it.", "Up to you.", "What will be, will be." Those are the most memorable short shapes in English and therefore the most likely to be reproduced by accident, which is why a verbatim channel runs alongside rather than instead. ## What is in the corpus, and what deliberately is not 474 entries: 306 anonymous traditional proverbs and 172 fixed idioms (4 duplicates folded). The admission test is that a saying must be **anonymous traditional material** - common property of English for generations, with no identifiable author and no first publication that could hold a term. Deliberately absent, and the absence is the point: - No named-author maxims. A line by a known writer is that writer's expression, and the translation you would actually quote is usually newer than the original and separately owned. - No mass-produced fortune-slip text. That is recent commercial writing. - No scripture, and no modern translation of a classical fable - both are routinely still in copyright even where the underlying work is ancient. ## The register check is not a corpus Separately from originality, 13 **grammatical shapes** that the mass-produced slip is built on are detected: opening on a second-person promise, opening on an abstract noun, stating one abstraction as the key to another, making a reward accrue to a class of person defined by their conduct, assigning the reader a lucky attribute, and so on. This check holds **shapes, never specimens**. There is no stock-slip text in this bundle in any form, so the check cannot reproduce a line because there is no line in it to reproduce. A hit means the sentence is *ordinary*, not that it was copied - the app reports the two under different headings and in different words, because merging them would accuse a merely-generic sentence of being a plagiarised one. ## The craft report A third free lane measures what the batch actually did, and reports rather than grades: - **Leakage** - whether a phrase from the brief came back inside a fortune. The most diagnostic check available, because "ignored the brief" and "transcribed the brief" look identical from outside and need opposite fixes. - **Tone, discriminatively** - not "does this look dry" but "does it look more dry than warm, ominous or absurd". Four tones that are one temperament in four hats is the characteristic failure of this form, and a non-discriminative check passes happily on exactly that. - **Mode, from grammar** - tense and mood are nearly perfectly checkable, which makes this the cheapest honest evidence that the dial did anything. - **Shapes used** - each sentence's frame classified from the sentence itself and compared with the device the model claimed; openings compared two content words deep; repeated observations detected. Repeating a device inside a batch is explicitly fine and is stated as fine. What must not repeat is the **observation** - a new frame around an old noticing is one fortune written twice. Five house rules are checked mechanically (length, no verdict, no hedge, one breath, no flattery). Three are not (concreteness, plain diction, plausible world) and the app names them as unchecked rather than implying coverage it does not have. **And the craft measurements have a limit of their own, found by a cold reader rather than by an assertion.** Openings are compared two content words deep and frames are counted inside the mode's own set, so a batch that reuses either is reported. Neither catches SENTENCE ARCHITECTURE: five lines with five different openings, several different frames and no repeated observation can still be one skeleton with five sets of nouns dropped into it. The system prompt instructs against it directly, because that is the only place it can be addressed - and the craft panel says plainly that this is what it cannot see. ## Output contract Labelled lines, not JSON - each line completes on its own, so a stream cut anywhere yields every whole record before the cut: ``` FORTUNE: The kettle arrives on Thursday, before the beds do. TURN: dated_arrival ANGLE: a_place NUMBERS: 3 14 22 29 41 57 ``` A short batch is rendered short and labelled short. It is never padded to the requested count, because padding makes a truncated run indistinguishable from a complete one. ## Free lanes - **Check lines you wrote yourself** - paste your own fortunes and run the same corpus, attribution and register checks. No account, nothing transmitted. - **See a finished batch** - a saved model run bundled with the app, rendered through the real parser, the real checks and the real renderer. One of its five fortunes deliberately trips the register check and is left in, so the check is visibly doing something. ## API Full tutorial at https://fortune-cookie-generator.skillsafe.ai/api.html - base URL `https://api.skillsafe.ai/v1/app-api`, bearer token, the `{data}`/`{error}` envelope, and worked examples in cURL, Python, JavaScript, Go, Java, Ruby, PHP and C#. Two things worth knowing before you call it: - **There is no `X-App-Slug` header on any endpoint.** `POST /guest` is the one call that names the app, and it does so in the body as `{"slug":"fortune-cookie-generator"}`. - **`/estimate` validates nothing.** A bare string returns `ok: true` with a well-formed estimate and an identical `hold_credits`, so a passing estimate proves the model binding and says nothing about your input shape. Guard it client-side. The SSE wire format is `event:` plus `data:` with frames separated by a blank line, and a delta's text is at `.text`. There is no `{"type":"delta"}` envelope. ## What this app is not It is not a prediction of anything. Fortunes are written by a language model on request. Nothing here is medical, financial or legal advice, and the ominous tone is a matter of arrangement rather than content - everything named in an ominous fortune is harmless.