Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Moving Cryptonym Desk’s word lists out of a single HTML file and into a Sanity dataset exposed two defects that the old version had hidden. The first was a noun that appeared twice, so it was drawn twice as often as every other noun. The second was an alias splitter whose code did not match its own README example. Christian Anderson’s September 24, 2026 write-up, with a September 25 update, describes both bugs, the fixes, and the workflow changes that followed. This article walks through what he reports, what he changed, and what the case means for anyone storing generator data in a CMS.

What Cryptonym Desk does

Cryptonym Desk is a name generator for people naming AI agents, bots, side projects, or D&D characters. A user enters films, anime, and characters they like, and the tool returns three outputs: a CIA-style cryptonym built from an office digraph and an unrelated word, a working alias made by joining input names at vowel boundaries, and an adjective-noun field codename.

The original version was one 29 KB HTML file with the word lists embedded in a script, according to Anderson. In the rebuild, those lists became documents in a public Sanity dataset, and an Astro site reads that dataset at build time. Text the user types is handled in the browser; Anderson states that it never leaves the page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Bug one: a duplicate noun that the new data model made visible

The noun MERIDIAN appeared twice in the original list. Because the generator picks from the list uniformly, the duplicate meant MERIDIAN was drawn twice as often as any other noun. The flaw was invisible inside one long array. When each word became its own document with a name, a bank, and a weight, the repeat stood out.

The fix addressed the cause rather than the single entry. Later in the project, the word-proposal workflow described below checks for an existing bank entry before it creates a new one, so the same word cannot be added to a bank twice through that path.

Bug two: a splitter that contradicted its README

The README gave two examples of how the alias splitter should divide names at vowel boundaries. Spiegel should split as Spie·gel, and Kusanagi as Ku·sa·na·gi, which joins into Spienagi. The regular expression in the code did something different. It kept one consonant after each vowel group, producing Spieg·el and Kus·an·ag·i.

Input Output documented in the README Output from the old regular expression
Spiegel Spie·gel Spieg·el
Kusanagi Ku·sa·na·gi Kus·an·ag·i
Combined alias Spienagi Spiegagi (the only result Anderson reports across 200 seeds for this pair)

Anderson’s decision was to treat the README as the intended design and change the regular expression to match it. He did not edit the test to fit the existing code. A new test checks that the README example can occur. The trade-off is that the tool now produces different aliases for the same inputs than the original version did.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

This is a useful pattern to borrow. When documentation and code disagree, a test written from the documented example forces a decision about which one is correct. Writing the test to pass against whatever the code currently does would have locked the defect in.

Other findings from the migration

Weights only matter when the data uses them

The schema and generator already supported weighted picks, but every entry had weight 1, so the feature changed nothing. Anderson reports setting the plain SECRET entry to weight 5 and CODE WORD to 0.5. He also describes a 10,000-draw distribution test in the original build section. These are his reported figures from his own tests, not independent measurements.

Seeded output changes when the corpus changes

The tool generates seeded records, so identical inputs with the same salt return the same result. Once the words lived in an editable dataset, a change to any word could alter the record for inputs that had not changed. To make that visible, the site hashes the document _rev values into a seven-character corpus revision. That revision appears on each record and in the “Copy record” output.

Anderson’s example: after an edit with no code changes, the corpus page’s displayed revision moved from 211eb8a to 4ca7fee on the next build. A reader who saved a record can now see whether the word data behind it has changed since.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Validation at build time and in the Studio

Anderson reports that astro build fails when a bank is empty, a bank name is unknown, a weight is zero, or no digraphs are active. The Sanity Studio also enforces rules: weights must be positive, codes must be uppercase and two or three characters, and each preset needs at least two seeds.

Keeping user input away from the CMS

The corpus is fetched at build time, not on each interaction. Anderson argues this keeps the promise that what a user types does not leave the page, because the generator never sends that text to Sanity at runtime. Dataset edits reach the live site through a GitHub Action that runs on push, can be triggered manually, and runs nightly. He chose not to configure a Sanity webhook, because that would require storing a GitHub token in Sanity.

The later reviewed word-proposal workflow

The September 25 update adds a way to propose new words. Proposals are wordProposal documents in the same public dataset. Each contains the word, a target bank, a weight, a rationale, a status, and a history. Anderson describes these states:

  • Proposed: submitted and waiting for review.
  • In review: a reviewer is evaluating it.
  • Approved: accepted and ready to merge.
  • Merged: written into the bank.
  • Rejected: declined, and can be reopened later.

Anderson reports several rules in the implementation. A proposal cannot move directly from proposed to merged. Rejection requires a reviewer note. Merges run as a deterministic transaction pinned to a specific document revision. The review board is an App SDK application, the Studio has its own actions, and a command-line tool all share one rules module, so the three entry points enforce the same transitions.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

He also reports two test outcomes. When two merges raced and one was stale, the stale request returned HTTP 409 and wrote nothing. The word CISTERN completed the full flow and was merged into the noun bank, which went from 14 nouns to 15. He reports that a CLI workflow update appeared on the live board in 2.6 seconds. These are his reported results for his setup, not benchmarks.

The trade-off of a public dataset

Because proposals share the public dataset, proposal text, rationales, and reviewer notes are world-readable. The review board itself requires organization membership, but the underlying documents are not hidden by that gate. Anyone designing a similar workflow should decide before launch whether reviewer comments should be public.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Architecture choices compared

The project changed four design axes at once. The table below sets out each one, with what the author reports about each side.

Axis Before After What the author reports
Where words live Embedded arrays in a script Documents in a public Sanity dataset Editing is easier; a duplicate entry becomes visible
When data is fetched Not applicable (data is in the page) Build time only Keeps user input off CMS requests; data is only as fresh as the last build
How behavior changes Code change Dataset edit (weights, banks, digraphs) Output can shift without a code change, so a corpus revision is shown
How words are added Code change Proposal, review, and merge Automated transitions and deterministic merges; reviewer notes are public

What to take from this case

  • Splitting data into records can expose duplicates that a single array hides. Check counts after any migration.
  • When a README and the code disagree, write the test from the documented example, then decide which one is correct.
  • If output is seeded and the data is editable, show a revision identifier so saved results can be traced.
  • Fail the build on invalid data rather than shipping a broken corpus.
  • Decide early whether a public dataset should contain review comments.

Limits of the source

All figures, test results, and revision identifiers in this article come from Anderson’s own write-up. The live demo, the corpus page, the repository, and the public dataset are not independently verified here. The write-up also says that each digraph’s provenance note is generic, reading “real digraph from declassified material,” rather than citing a specific source for each. The origin of any particular digraph therefore is not established by this article.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

This is one developer’s project account, not a comparison of Sanity with other content platforms. The lessons apply to any editable data store that feeds a deterministic generator.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.