The Egg
The egg is Yoshi's identity primitive — and its mascot. One key → one egg, forever; every distinct
key → a visibly different egg. It's the same category as SSH randomart, GitHub identicons, or Ethereum
blockies: a picture of a key, not the key itself. The brand mark yoshi·site puts an egg where the dot
goes: YOSHI › 🥚 › SITE (input → egg → output).
Play with it: the egg-studio (
assets/egg-studio/) —python3 -m http.server 8731→ type a name, watch its egg. Canonical algorithm:egg.js(zero-dep ES module).
How an egg is generated
seedString ──fnv64──▶ 8 bytes b0..b7 ──byte-map──▶ traits ──▶ OKLCH SVG
The key's bytes literally paint the egg:
| bytes | trait | range |
|---|---|---|
| b0,b1 | hue (body) | full wheel |
| b2 | chroma | muted OKLCH (sophisticated, not kiddish) |
| b3 | lightness | soft |
| b4 | spot count | 3–9 |
| b5 | density | 10–22% |
| b6 | shape | radius jitter |
| b7 | harmony | the second (spot) hue relationship |
Colour is OKLCH with two real hues — body = hue1, spots = hue2 at a keyed harmony offset (split-comp / comp / triadic / analogous). Perceptually-uniform + muted chroma is what keeps it elegant.
It's a fingerprint of a real key, not the key
Authentication is done by a real keypair (Ed25519 / did:key) behind the egg; the egg just makes that
identity human-recognisable. Minimal disclosure: show the egg (the picture) freely; reveal the
did/pubkey only where verification is actually needed. Full reasoning: EGG-IDENTITY-SECURITY.md.
The demo above is picture-only — by design. Rendering an egg from a name is a public identicon (zero-dep
egg.js, safe to run in any browser). The sensitive half — generating real keypairs, custody of private keys, signing, and challenge-response verification (“does this person control this identity? → true/false”) — lives behind an API, never in the runtime bundle. Private keys come from a CSPRNG (or a passkey), never from a name. Verifying needs only the public key, so the verify-API holds no secrets. See the security-boundary decision (D34) +EGG-IDENTITY-SECURITY.md.
Two key-holders, stable by design
- Visitor (anonymous) —
hash(browser fingerprint), daily-salted, never raw IP → a guest egg that promotes to a real key on signup. - User — anchored to an immutable
userId(P1: a realdid:key). - Project —
derive(userKey, projectName). The URL/domain is excluded on purpose: it arrives late and can change, and identity must be stable (otherwise the favicon would mutate).
The lifecycle
The egg has a traced 7-state break-apart sequence — the same egg, hatching:
sealed → cracking → fracturing → breaking → splitting → opening → hatched
This is what powers "watch it hatch": the build progress is the egg cracking open.
One algorithm, two implementations (kept identical)
Two surfaces genuinely need it, so it's ported and locked byte-for-byte by test vectors:
egg.js— canonical; browser/runtime theming + the studio.yoshi-generator/src/egg.rs— native Rust port, byte-identical for all output; emits each site'spublic/icon.svg, powersyoshi egg, and exportsegg_palette/egg_css_varsfor build-time theming. Re-run_compare.mjsvsegg_dumpafter any algorithm change.
Where the egg shows up
Per-site favicons · user avatars · project marks · the "Built with Yoshi" badge · CLI/webhook fingerprints · and — per the persona decision (D31) — Yoshi's conversational face: the egg shakes and speaks in chat bubbles during intake. No dinosaur, no creature; the egg is the character.
🌳 Open question — one egg, or three?
The egg plays three roles, and we should decide whether they're the same egg or siblings:
- Identity egg — keyed, stable, per-user/per-project (this page).
- Site egg — the "watch it hatch" build-progress metaphor (a site-in-progress).
- Avatar egg — Yoshi the character (shakes, chat bubbles).
Leaning: one egg, three contexts — the project's identity egg is the one that fills with assets (the site egg) and is animated as the avatar during that project's intake. That makes the favicon, the build animation, and the chat face the same recognisable egg — a strong, coherent identity. Needs a decision; cross-ref cycle 33 + D31.