acme/api and one open bug on
GitHub, a #general channel on Slack, an empty ledger on Stripe. That world is
there so the first command works. It is not there because it looks like yours.
A seed is how you replace it. Write your repositories, your threads, your
customers, and the twin serves them to your agent as though they were real —
same routes, same status codes, same recorded tape. This page is the whole job,
from generating the file to proving every field of it landed.
A seed replaces the world. It does not merge into it.
This is the single most costly thing to get wrong, so it comes first. Measured on a local twin booted from the file further down this page:labels boots a
repository with no labels, not a repository with ours.
Generate the file; do not write it
pome twin new-seed prints the twin’s own
starting state, computed from the twin’s declared world and normalised through
the same parseSeed the twin runs at boot. Whatever it prints, the twin loads.
Start from that and edit; do not compose one from the field names in a reference
table.
This is not a style preference. On 2026-08-26 three of the five seed examples
published on this site could not boot the twin they were written for —
repositories.0.owner missing on GitHub, primaryMailbox typed as a string on
Gmail, issues.0.assignee null on Linear. Every one of them was correct the day
it merged, and each was hand-typed. Copying one produced a 503 Failed to spawn twin pod twelve seconds later. Every seed block on this site is now generated
and re-parsed in CI against its own twin.
The generated file is a starting point with real bulk to it — with
@pome-sh/cli@0.42.1: 82 lines for GitHub, 89 for Slack, 136 for Gmail, 270
for Linear, 14 for Stripe’s deliberately empty ledger. Cutting it down is the
normal next step.
Seed file
Here is the GitHub file above, cut to one organisation, one repository and the one issue a triage task needs. It is whatpome twin new-seed github printed,
with the sample world’s names and rows replaced:
--seed doors below take the
twin’s name as well. Add a second twin and the file grows the envelope, one key
each:
_meta block, which
pome compile-seeds writes into a task’s sidecar, is
dropped before the twin sees it.
Each twin’s own generated block, and the field names behind it, live on that
twin’s page: github,
stripe,
slack,
gmail,
linear.
One file, both doors
The sameworld.seed.json boots a twin on your laptop and a hosted sandbox. No
conversion, no second copy.
- Local — no account
- Hosted
- REST
The seed is parsed before a hosted sandbox is provisioned, so an unbootable
world costs a
422 in well under a second rather than a spawn that fails.
POST /v1/seeds/validate runs the
same check and provisions nothing at all.Check that every field landed
A twin that boots is not proof that your whole world arrived — until 2026-08-29 a typo’d field name could be silently dropped on three of the five twins. No longer, on your machine. Measured 2026-08-30 against@pome-sh/cli@0.42.1, a GitHub seed carrying isuses instead of issues
refuses to boot, naming the key and its path:
twin start --seed since
F-1689 landed. A wrong type was
always refused everywhere — expected string, received undefined — so a local
boot now vouches for every field name and type in your file.
Seed file, or task sidecar
One file, two destinations.pome twin new-seed <twin> writes it either way, and
the shape follows the twin count rather than where it is going.
Both are flat for one twin and the per-twin envelope from two up, so a file
written for one destination works at the other. What differs is only the last
row: a sidecar has the task’s
## Config beside it, while a seed file travels
alone and so has to be handed the name. Replace-not-merge applies to both, and
both accept JSON or YAML.
A task is not required to seed a world. A hosted sandbox created with twins
and seed and no task records no task at all, which is what a
bring-your-own-eval harness wants: you drive the agent, and you score the tape
from the twin’s own /_pome/events.
Next
Write a task
Turn the world you just built into a graded exam — criteria,
[code] checks,
and why a criterion the seed already satisfies leaves the denominator.pome twin
Every flag on
twin new-seed, twin start and twin status.Seeds over REST
The wire shape,
POST /v1/seeds/validate, and the error vocabulary a client
branches on.Digital twins
Each twin’s generated starting state, its declared checks, and what it serves.