Play an environment

Train or test an agent on an environment whose every episode can be checked. env hosts deterministic puzzles over HTTP: reset opens an episode of baba (Baba-Is-You rules on a tiny board, eleven levels with certified solution lengths), step plays one action and answers the observation, the reward, done, the legal actions and a chained digest, and the last step seals the episode as a signed record — the env version, the core’s sha, the seed, the level, every action and reward — that anyone replays to the same digest. One price per episode; the steps are free. Here an agent opens the first level, walks right twice, wins, and seals a scorecard over two such episodes.

10calls answered
2receipts re-hashed
4records verified
$0.04list price for a stranger
1,414ms end to end
pass · 4 records verified

Run 2026-10-11 05:26 UTC against api.s2ar.dev 0.1.1 · 10 calls · 1,414 ms · list price $0.04 for a stranger (these ran on the operator's key and cost nothing) · every number on this page re-derived by tools/walkthrough.py before it was written

1. The catalogue, free

The environments, their versions and core shas, the levels with certified lengths, the price per episode, the windows, and the baselines.

curl -s -X GET 'https://api.s2ar.dev/v1/env'

→ HTTP 200 · 308 ms

price_usd0.02
unitper episode; steps are free
free_per_day10
envs.baba.versionbaba/1
envs.baba.levels.0{"name": "route_to_win", "height": 5, "width": 3, "cert_len": 2}
envs.baba.levels.1{"name": "push_rock", "height": 6, "width": 5, "cert_len": 2}
envs.sokoban.bands{"easy": {"optimal_pushes": [1, 3]}, "medium": {"optimal_pushes": [4, 6]}, "hard": {"optimal_pushes": [7, 14]}}
window_s{"credits_or_key": 600, "x402": 50, "note": "an episode left open past its window is sealed abandoned and never charged"}
baselines.baba/1.policies{"first_legal": {"mean_plies": 29.45, "mean_return": 0.0, "n": 11, "win_rate": 0.0}, "greedy": {"mean_plies": 17.55, "mean_return": 0.6364, "n": 11, "win_rate":
the answer, as JSON
{
  "price_usd": 0.02,
  "unit": "per episode; steps are free",
  "free_per_day": 10,
  "envs.baba.version": "baba/1",
  "envs.baba.levels.0": {
    "name": "route_to_win",
    "height": 5,
    "width": 3,
    "cert_len": 2
  },
  "envs.baba.levels.1": {
    "name": "push_rock",
    "height": 6,
    "width": 5,
    "cert_len": 2
  },
  "envs.sokoban.bands": {
    "easy": {
      "optimal_pushes": [
        1,
        3
      ]
    },
    "medium": {
      "optimal_pushes": [
        4,
        6
      ]
    },
    "hard": {
      "optimal_pushes": [
        7,
        14
      ]
    }
  },
  "window_s": {
    "credits_or_key": 600,
    "x402": 50,
    "note": "an episode left open past its window is sealed abandoned and never charged"
  },
  "baselines.baba/1.policies": {
    "first_legal": {
      "mean_plies": 29.45,
      "mean_return": 0.0,
      "n": 11,
      "win_rate": 0.0
    },
    "greedy": {
      "mean_plies": 17.55,
      "mean_return": 0.6364,
      "n": 11,
      "win_rate": 0.6364
    },
    "random": {
      "mean_plies": 25.18,
      "mean_return": 0.5455,
      "n": 11,
      "win_rate": 0.5455
    },
    "solver": {
      "mean_plies": 5.36,
      "mean_return": 1.0,
      "n": 11,
      "win_rate": 1.0
    }
  }
}

2. The quote: HTTP 402

The price of an episode, the rails and the witness. The quote costs nothing.

curl -s -X GET 'https://api.s2ar.dev/v1/env/reset?env=baba&seed=0' \
  -H 'X-Assay-Quote: 1'

→ HTTP 402 · 122 ms

price_usd0.02
rails["x402", "credits"]
determinismreplayable
witnesses["core"]
free.per_day_keyless10
the answer, as JSON
{
  "price_usd": 0.02,
  "rails": [
    "x402",
    "credits"
  ],
  "determinism": "replayable",
  "witnesses": [
    "core"
  ],
  "free.per_day_keyless": 10
}

3. Open an episode: seed 0 is the first level

The board as text (B baba, I is, Y you, F flag, N win; lowercase b and f are the objects), the legal actions, the horizon, the starting digest. Nothing is charged until the episode ends.

curl -s -X POST 'https://api.s2ar.dev/v1/env/reset' \
  -H "Authorization: Bearer $S2AR_KEY" \
  -H 'content-type: application/json' \
  -d '{"env": "baba", "seed": 0}'

→ HTTP 200 · 106 ms · list price $0.02

episode_idep_9ed12eb5a58f6e43
envbaba
versionbaba/1
levelroute_to_win
horizon16
ply0
obs.asciiBIY ... b.f ... FIN
legal["U", "D", "R"]
digestfcc896ccab521a1d…
expires_in_s600
charged_usd0.0
the answer, as JSON
{
  "episode_id": "ep_9ed12eb5a58f6e43",
  "env": "baba",
  "version": "baba/1",
  "level": "route_to_win",
  "horizon": 16,
  "ply": 0,
  "obs.ascii": "BIY\n...\nb.f\n...\nFIN",
  "legal": [
    "U",
    "D",
    "R"
  ],
  "digest": "fcc896ccab521a1d6ee3288632dd80431cae7cded524adad50e72737caecf519",
  "expires_in_s": 600,
  "charged_usd": 0.0
}
re-derived by the generator
✓as the prose says: env = "baba" · level = "route_to_win" · ply = 0 · charged_usd = 0.0

4. Step right: no reward yet

curl -s -X POST 'https://api.s2ar.dev/v1/env/step' \
  -H "Authorization: Bearer $S2AR_KEY" \
  -H 'content-type: application/json' \
  -d '{"episode_id": "ep_9ed12eb5a58f6e43", "action": "R", "ply": 0}'

→ HTTP 200 · 112 ms

ply1
actionR
reward0.0
donefalse
obs.asciiBIY ... .bf ... FIN
legal["U", "D", "L", "R"]
digest3a32633103ac436a…
the answer, as JSON
{
  "ply": 1,
  "action": "R",
  "reward": 0.0,
  "done": false,
  "obs.ascii": "BIY\n...\n.bf\n...\nFIN",
  "legal": [
    "U",
    "D",
    "L",
    "R"
  ],
  "digest": "3a32633103ac436a9f754a3f621ee091528b81c2dabd0e95358e88cf630fff9b"
}
re-derived by the generator
✓as the prose says: ply = 1 · reward = 0.0 · done = false

5. Step right again: the win, the seal, the receipt

The reward is 1.0, the verdict win; the record (kind env-episode, no expiry, replayable) carries the seed, the level, both actions, both rewards, the final board and the chained digest; the receipt books the one charge of the episode.

curl -s -X POST 'https://api.s2ar.dev/v1/env/step' \
  -H "Authorization: Bearer $S2AR_KEY" \
  -H 'content-type: application/json' \
  -d '{"episode_id": "ep_9ed12eb5a58f6e43", "action": "R", "ply": 1}'

PASS → HTTP 200 · 111 ms · receipt sha256:79036ba4569b9bad…

ply2
reward1.0
donetrue
verdictwin
outcomepass
return1.0
digestb2485755d47b31f1…
record.kindenv-episode
record.replayabletrue
record.subject.0.core_sha3a67867a0b8e5a82…
record.payload.actions["R", "R"]
record.payload.rewards[0.0, 1.0]
record.payload.final_stateBIY ... ..f ... FIN
record_sha256603e1c03c5a255c7…
charged_usd0.0
x-assay-record603e1c03c5a255c7…
the answer, as JSON
{
  "ply": 2,
  "reward": 1.0,
  "done": true,
  "verdict": "win",
  "outcome": "pass",
  "return": 1.0,
  "digest": "b2485755d47b31f18018788719065602dbf8d6f47c4ef11bf8920f5ac3ed9273",
  "record.kind": "env-episode",
  "record.replayable": true,
  "record.subject.0.core_sha": "3a67867a0b8e5a821a79c8daefc32532f79bca7b6c37f59e7c71b458aa319e6a",
  "record.payload.actions": [
    "R",
    "R"
  ],
  "record.payload.rewards": [
    0.0,
    1.0
  ],
  "record.payload.final_state": "BIY\n...\n..f\n...\nFIN",
  "record_sha256": "603e1c03c5a255c7e041d0cce49c87b8cb2f250c7531a8c1d3f5f53effe1534f",
  "charged_usd": 0.0,
  "x-assay-record": "603e1c03c5a255c7e041d0cce49c87b8cb2f250c7531a8c1d3f5f53effe1534f"
}

Assay badge for record 603e1c03c5a255c7

re-derived by the generator
✓receipt sha256:79036ba4569b9bad… re-derived: sha256 over the canonical answer, header and body agree
✓record 603e1c03c5a255c7… fetched back from /v1/verify: sealed, signed, and signed by assay-1 (the key at /.well-known/assay.json)
✓as the prose says: done = true · verdict = "win" · outcome = "pass" · reward = 1.0 · record.kind = "env-episode" · record.payload.actions.0 = "R" · record.payload.actions.1 = "R"

6. A second episode, the same two moves

Opened and played in two calls; its digest equals the first episode’s: the same seed and actions give the same trajectory, measured, not promised.

curl -s -X POST 'https://api.s2ar.dev/v1/env/reset' \
  -H "Authorization: Bearer $S2AR_KEY" \
  -H 'content-type: application/json' \
  -d '{"env": "baba", "seed": 0}'

→ HTTP 200 · 194 ms · list price $0.02

episode_idep_34025c099b2f5a32
levelroute_to_win
digestfcc896ccab521a1d…
the answer, as JSON
{
  "episode_id": "ep_34025c099b2f5a32",
  "level": "route_to_win",
  "digest": "fcc896ccab521a1d6ee3288632dd80431cae7cded524adad50e72737caecf519"
}
re-derived by the generator
✓as the prose says: level = "route_to_win"

7. …stepped to the same win

curl -s -X POST 'https://api.s2ar.dev/v1/env/step' \
  -H "Authorization: Bearer $S2AR_KEY" \
  -H 'content-type: application/json' \
  -d '{"episode_id": "ep_34025c099b2f5a32", "action": "R"}'

→ HTTP 200 · 79 ms

ply1
donefalse
the answer, as JSON
{
  "ply": 1,
  "done": false
}
re-derived by the generator
✓as the prose says: ply = 1 · done = false

8. …and sealed with the same digest

curl -s -X POST 'https://api.s2ar.dev/v1/env/step' \
  -H "Authorization: Bearer $S2AR_KEY" \
  -H 'content-type: application/json' \
  -d '{"episode_id": "ep_34025c099b2f5a32", "action": "R"}'

PASS → HTTP 200 · 122 ms · receipt sha256:ffd9786a3acfb19a…

verdictwin
digestb2485755d47b31f1…
record.payload.digestb2485755d47b31f1…
record_sha256894a8865ec5f80f1…
the answer, as JSON
{
  "verdict": "win",
  "digest": "b2485755d47b31f18018788719065602dbf8d6f47c4ef11bf8920f5ac3ed9273",
  "record.payload.digest": "b2485755d47b31f18018788719065602dbf8d6f47c4ef11bf8920f5ac3ed9273",
  "record_sha256": "894a8865ec5f80f17783786b84c83ff206bd64ec7980725b57f0c2fcbe22d742"
}

Assay badge for record 894a8865ec5f80f1

re-derived by the generator
✓receipt sha256:ffd9786a3acfb19a… re-derived: sha256 over the canonical answer, header and body agree
✓record 894a8865ec5f80f1… fetched back from /v1/verify: sealed, signed, and signed by assay-1 (the key at /.well-known/assay.json)
✓as the prose says: verdict = "win"

9. A scorecard over the two episodes, free

Under the policy label the caller gives: episodes, wins, win rate, mean return, every episode’s digest; a signed record of kind env-scorecard.

curl -s -X POST 'https://api.s2ar.dev/v1/env/scorecard' \
  -H "Authorization: Bearer $S2AR_KEY" \
  -H 'content-type: application/json' \
  -d '{"policy": "walk right twice", "episodes": ["603e1c03c5a255c7e041d0cce49c87b8cb2f250c7531a8c1d3f5f53effe1534f", "894a8865ec5f80f17783786b84c83ff206bd64ec7980725b57f0c2fcbe22d742"]}'

→ HTTP 200 · 134 ms

policywalk right twice
n2
win_rate1.0
mean_return1.0
envbaba/1
record.kindenv-scorecard
record.payload.episodes.0.digestb2485755d47b31f1…
record.payload.episodes.1.digestb2485755d47b31f1…
record_sha256286c6863d5f09264…
the answer, as JSON
{
  "policy": "walk right twice",
  "n": 2,
  "win_rate": 1.0,
  "mean_return": 1.0,
  "env": "baba/1",
  "record.kind": "env-scorecard",
  "record.payload.episodes.0.digest": "b2485755d47b31f18018788719065602dbf8d6f47c4ef11bf8920f5ac3ed9273",
  "record.payload.episodes.1.digest": "b2485755d47b31f18018788719065602dbf8d6f47c4ef11bf8920f5ac3ed9273",
  "record_sha256": "286c6863d5f0926473a26fc5a45561b7b8722c9549f743c77edf78d314bfeacc"
}

Assay badge for record 286c6863d5f09264

re-derived by the generator
✓record 286c6863d5f09264… fetched back from /v1/verify: sealed, signed, and signed by assay-1 (the key at /.well-known/assay.json)
✓as the prose says: n = 2 · win_rate = 1.0 · mean_return = 1.0 · record.kind = "env-scorecard"

10. Anyone verifies the scorecard, free

curl -s -X GET 'https://api.s2ar.dev/v1/verify/286c6863d5f0926473a26fc5a45561b7b8722c9549f743c77edf78d314bfeacc'

PASS → HTTP 200 · 127 ms

foundtrue
seal_oktrue
signature_oktrue
key_pinnedtrue
certificate.kindenv-scorecard
certificate.verdictscored
certificate.replayabletrue
certificate.payload.win_rate1.0
certificate.payload.n2
the answer, as JSON
{
  "found": true,
  "seal_ok": true,
  "signature_ok": true,
  "key_pinned": true,
  "certificate.kind": "env-scorecard",
  "certificate.verdict": "scored",
  "certificate.replayable": true,
  "certificate.payload.win_rate": 1.0,
  "certificate.payload.n": 2
}
re-derived by the generator
✓seal recomputed ✓ · signature ✓ · key pinned to assay-1 ✓

The record is the trajectory, not a claim about it: the core at core_sha replays seed and actions to the same digest, so a third party checks a score without trusting the scorer. The catalogue (GET /v1/env) lists every level with its certified length and the house baselines — first legal, random, greedy, the solver’s ceiling — so a scorecard reads against something on day one. An episode left open past its window is sealed abandoned and never charged.

What this cannot buy

From the signed proceedings (/.well-known/proceedings.json), verbatim:

Failed calls are never charged. Nothing about a caller is kept. The rules: the charter.