Open the app

Language

For players

Explanation Live

Security model

The address for security reports isn't published yet.

Open llms.txt

Every place on HatchWorld runs code somebody else wrote. So the platform treats all place code as hostile, including yours. This page explains what that protects, and what's left to you.

The rule: walls, not judgement

An AI reviews every push. But a model can be talked into things, so the review isn't the wall. The wall is deterministic:

  • The sandbox. Code runs in QuickJS with a fresh runtime per event, 50 ms of CPU and 16 MB of memory. No network, no files, no eval, no imports except the API module.
  • The type check. Each push goes through strict tsc against the published types, then a compile run. A call the types don't declare doesn't publish.
  • The manifest. Rights come only from static capabilities, checked by the server. A comment or a string in your code can't add a right.
  • The key's rights. A personal key can upload drafts. It enables versions only if the owner said so when issuing it.

The AI review sits on top and can only refuse. Anything that isn't a clean answer is a refusal. If the model were fooled, an attacker would get nothing the walls don't already allow.

Who could attack whom

ThreatWhat stops it
A place's code tries to reach the network, the phone, or another placeThe sandbox has no network, files or DOM; each part imports only its API module
A place's code tries to learn where players are or what they're calledScripts get player ids only: no names, no positions, no street distances
A place's code shows abusive text to guestsText a player sees is declared in static texts or comes from a checked source: player answers, LLM answers and pushes pass a text judge first
A script loops or hogs the server50 ms per event; a script that keeps failing or is slow is switched off, and the owner sees why
Someone steals your personal keyIt expires (7 days by default), can only upload drafts unless you allowed more, opens only the places you chose, and you revoke it in the app
A guest sends a forged action from their phoneNothing from a phone is trusted. Your server part checks who acts and its own state (that part is yours, see below)
Text inside code tries to talk the AI reviewer into "ok"Code reaches the reviewer inside a frame with a random marker per call, as data. Text in code addressed to the reviewer counts as an attack and blocks the publish
A tampered setup file tells your coding agent to run somethinginstall.md contains only our package's commands at a pinned version: no curl | sh, no downloads outside npm, nothing outside the project folder

What's on you

The walls protect players and the platform from your code. They can't make your code correct.

  • Check every input. Payloads come from phones. Narrow before use: typeof x === 'string', Number(x ?? 0), x && typeof x === 'object' && !Array.isArray(x).
  • Check who acts. Owner-only actions test e.isOwner. Answers to a sheet: check the id is one you asked, and keep "already answered" in e.player.state.
  • Be idempotent. A handler may run twice for one event. Check state before acting.
  • Keep no personal data. You only have ids. Keep it that way.
  • Keep the key out of files. Only in the HATCHWORLD_PLACE_KEY environment variable: no .env, no config, no commit, no output. place-kit never prints it or writes it to disk.
  • Don't write to the reviewer. No comments or strings telling the AI what to answer.

Handing a key to a coding agent

The text you paste to Claude Code or Codex lands in the agent's chat and in its provider's logs. That's why the defaults are short and narrow:

  • one place per key, 7 days, drafts only;
  • you enable versions yourself, on your phone;
  • Revoke sits in the same sheet you issued it from.

If your agent's session is shared or leaks, revoke the key. Issuing a new one takes three taps.

Reporting a problem

Found a way around any of the walls above? Tell us before you tell anyone else: security@….

Docs