---
title: "A simulated market"
url: https://services.dev/docs/people/pool/simulate
captured: [legal-fill.txt, market.txt]
---
# A simulated market

URL: https://services.dev/docs/people/pool/simulate

> Seed simulated members in every Pool, set how hard work is to fill, and watch the market run through the real gate before anyone joins. Every act they take is labeled simulated.

How do you see your marketplace work before anyone has joined it?

## Seed a market

`dev` takes two flags. `--members N` seeds N simulated members in each Pool, from the Pool's own `join` shape. `--market` sets how hard work is to fill:

| `--market` | The members it seeds |
|---|---|
| `tight` | ask more than Tasks post at, so the fill ladder climbs before a claim |
| `normal`, the default | ask what Tasks post at, and pass, decline, send back and contest at set rates |
| `flush` | ask less than Tasks post at, so a Task fills at the first rung |

```bash
npx services.dev dev --members 12 --market tight --no-try
```

```txt title="magic values: client.email = signs@example.test"
  attorneys           http://localhost:8787/attorneys · join at /attorneys/join, or npx services.dev signers add attorneys <email>
  verifier            vt_test_7Hq2 · the only writer of verified facts, at POST /<network>/signers/:id/verify
  market              tight · 12 simulated signers in attorneys, each act labeled simulated · the fill ladder climbs before a review is claimed
```

Simulated members claim, pass, send back, decline and contest through the same gate a person's act goes through, so every branch your Service has runs without a person. Each act they take is labeled `simulated: true` on the record, in its events and on every answer. Every roll is fixed by the member, the Task and the act, so a market writes the same record, act for act, every run, and a captured walk never drifts.

## One job, three markets

One job from the legal example, ordered into each market, then six hours on the clock. `tight` climbs two rungs before a member claims it:

```txt
→ POST /matters {"service":"contract-review","contract":"lease.pdf","client":{"name":"Ada Lovelace","email":"signs@example.test"},"client_region":"US-CA","max_usd":99,"key":"tight"}, then six hours
```

```txt title="magic values: client.email = signs@example.test"
  14:02 · task.posted · tsk_7Hq2 · $50.00 · dispatch cascade
  16:02 · task.raised · tsk_7Hq2 · $55.00 · raise 10% 2h · funded by the brand
  16:02 · task.offered · tsk_7Hq2 · mbr_7Hq3 · cascade
  18:02 · task.widened · tsk_7Hq2 · opened reviewer · widen 4h
  18:02 · task.offered · tsk_7Hq2 · mbr_7Hq4 · cascade
  18:02 · task.claimed · tsk_7Hq2 · mbr_7Hq4 · simulated
  18:02 · step.committed · advise · person · bar admission · US-CA · mbr_7Hq4 · simulated
  18:02 · pay.accrued · mbr_7Hq4 · attest · $55.00 · $5.00 of it the brand's raise · simulated
← job_7Hq2 · delivered · flags.pdf · memo.pdf · $99.00 held
```

`normal` raises once, then widens:

```txt
→ POST /matters {"service":"contract-review","contract":"lease.pdf","client":{"name":"Ada Lovelace","email":"signs@example.test"},"client_region":"US-CA","max_usd":99,"key":"normal"}, then six hours
```

```txt title="magic values: client.email = signs@example.test"
  14:02 · task.posted · tsk_7Hq2 · $50.00 · dispatch cascade
  14:02 · task.offered · tsk_7Hq2 · mbr_7Hq2 · cascade
  16:02 · task.raised · tsk_7Hq2 · $55.00 · raise 10% 2h · funded by the brand
  16:02 · task.offered · tsk_7Hq2 · mbr_7Hq2 · cascade
  18:02 · task.widened · tsk_7Hq2 · opened signer · widen 4h
  18:02 · task.offered · tsk_7Hq2 · mbr_7Hq3 · cascade
  18:02 · task.claimed · tsk_7Hq2 · mbr_7Hq3 · simulated
  18:02 · step.committed · advise · person · bar admission · US-CA · mbr_7Hq3 · simulated
  18:02 · pay.accrued · mbr_7Hq3 · attest · $55.00 · $5.00 of it the brand's raise · simulated
← job_7Hq2 · delivered · flags.pdf · memo.pdf · $99.00 held
```

`flush` fills at the posted fee:

```txt
→ POST /matters {"service":"contract-review","contract":"lease.pdf","client":{"name":"Ada Lovelace","email":"signs@example.test"},"client_region":"US-CA","max_usd":99,"key":"flush"}, then six hours
```

```txt title="magic values: client.email = signs@example.test"
  14:02 · task.posted · tsk_7Hq2 · $50.00 · dispatch cascade
  14:02 · task.offered · tsk_7Hq2 · mbr_7Hq2 · cascade
  14:02 · task.claimed · tsk_7Hq2 · mbr_7Hq2 · simulated
  14:02 · step.committed · advise · person · bar admission · US-CA · mbr_7Hq2 · simulated
  14:02 · pay.accrued · mbr_7Hq2 · attest · $50.00 · simulated
← job_7Hq2 · delivered · flags.pdf · memo.pdf · $99.00 held
```

## Four members that never change

Beside the seeded market, every Pool on localhost has the sandbox's four magic members: one eligible for every Task, and three that each fail one predicate. [Eligibility](https://services.dev/docs/people/pool/eligibility.md) lists them, and [the magic values](https://services.dev/docs/reference/magic-values.md) list every branch the sandbox can run.

## Time

A test clock moves every job, Task, hold and rung on it in order. `POST /test_clocks/:id/advance` fires each rung as it falls due, so a ladder that takes twelve hours runs in one call, as [When no one claims](https://services.dev/docs/people/pool/fill.md) shows.

---

- Up: [Pool(): your marketplace](https://services.dev/docs/people/pool.md)
- Previous: [One Pool, several brands](https://services.dev/docs/people/pool/share.md)
- Next: [Tenants](https://services.dev/docs/people/tenants.md)
