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 real did:key).
  • Projectderive(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's public/icon.svg, powers yoshi egg, and exports egg_palette/egg_css_vars for build-time theming. Re-run _compare.mjs vs egg_dump after 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:

  1. Identity egg — keyed, stable, per-user/per-project (this page).
  2. Site egg — the "watch it hatch" build-progress metaphor (a site-in-progress).
  3. 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.

Deterministic: the same name always makes the same egg, and every distinct name a visibly different one. This is the very algorithm that bakes each site's favicon.