Harden it

The running jobjob_7Hq2 · accepted · document.fr-CA.pdf · $49.00 final

Add a review step that attacks every translation before the buyer sees it, and watch the redo it sends back.

A review step attacks the work before the buyer sees it: one AI reviewer per lens flags what's wrong, and the work goes back for a redo. It's how a draft is hardened before anyone signs it. This is Grow 1. Each page adds one key to the four-line Translation from your first paid job, shows the whole file, runs check, runs one job on the four buyer surfaces, and ends on what changed across all seven.

Write each step as its own file under grow/, so diff can compare them. check counts 8 lines, the ones inside Service({ … }):

grow/review.ts
import { Service } from 'services.dev'

// Grow 1, harden it: two AI reviewers attack every translation at once, one for meaning and one for
// terms, and flag it back for a redo until it holds, at most twice, inside the AI budget.
export default Service({
  name: 'Translation',
  input: { document: 'file', to: 'language: a BCP 47 tag, such as fr-CA' },
  output: { document: 'file' },
  deliver: {
    translate: 'ai',
    harden: { review: 'adversarial', lenses: ['meaning', 'terms'], rounds: 2 },
  },
  price: 49,
})

translate is the AI doing the work. harden is a review step of it.

KeyWhat it doesDefault
review'adversarial' attacks the step it reviews; 'affirmative' extends it, "yes, and", for creative workrequired
ofThe step it reviewsthe step before
lensesOne AI reviewer per lens, all at onceone reviewer
roundsHow many times it may flag the work back and review again, inside the AI budget3
exhaustedWhere work still flagged after the last round goes: a step, such as a person's second look, or an endthe job stops at $0
byA role whose member reviews instead of AI, for work only a credential may passAI

check reads services/, so put the step there:

Run
npx services.dev check
magic values: metadata.sandbox.review = flag_once
services/translation.ts · 8 lines · $49 per job, within 48 hours, charged on delivery.
  who     AI delivers every job.
  steps   translate · ai → harden · ai · adversarial · 2 lenses
  agent   order_translation · 24 of 30 words · bought job_7Hq2 · $49.00 · no person
  ledger  +$49.00 · AI $1.26 (example) · you $47.74
  margin  at least $39.20 a job (80%) · a job that stops costs you at most $9.80
  apps    customer portal · owner console

mcp     13 buyer tools · 4,486 of 8,000 tokens · 9 more with ?toolset=sandbox
✓ ready to sell · 1 Service · AI delivers it alone · it keeps at least 80% of every job
  next    npx services.dev dev

AI and money are simulated until you wire them. $0.42 a call is an example.

The steps line reads the graph back. AI still delivers every job alone, and the floor holds at 80%: every round spends from one AI budget, capped at a fifth of the price.

The magic value metadata.sandbox.review = flag_once makes the first round flag the work, so the redo runs without waiting for a real miss:

npx services.dev translation document=https://example.com/lease.pdf to=fr-CA --max 49 --key grow --metadata sandbox.review=flag_once
job_7Hq2 · working · $49.00 held
job_7Hq2 · delivered · lease.fr-CA.pdf · $49.00 charged
  record  translate · ai | harden · ai · adversarial · 2 lenses · flagged | translate · ai · redo | harden · ai · adversarial · 2 lenses · pass
  ledger  +$49.00 · AI $2.52 · you $46.48
  next    npx services.dev accept job_7Hq2
curl -X POST http://localhost:8787/jobs -H 'content-type: application/json' -d '{"service":"translation","document":{"url":"https://example.com/lease.pdf","name":"lease.pdf"},"to":"fr-CA","key":"grow","max_usd":49,"metadata":{"sandbox":{"review":"flag_once"}}}'
  next    get_job {"id":"job_7Hq2"}

$ curl http://localhost:8787/jobs/job_7Hq2?wait=50
← 200 · job_7Hq2 · delivered · lease.fr-CA.pdf · $49.00 charged
→ tools/call order_translation {"document":{"url":"https://example.com/lease.pdf","name":"lease.pdf"},"to":"fr-CA","key":"grow","max_usd":49,"metadata":{"sandbox":{"review":"flag_once"}}}
← job_7Hq2 · working · $49.00 held
  next    get_job {"id":"job_7Hq2"}

→ resources/read job://job_7Hq2?wait=50
← job_7Hq2 · delivered · lease.fr-CA.pdf · $49.00 charged
await lingua.translation.order({"document":{"url":"https://example.com/lease.pdf","name":"lease.pdf"},"to":"fr-CA","key":"grow","max_usd":49,"metadata":{"sandbox":{"review":"flag_once"}}})
← job_7Hq2 · working · $49.00 held
  next    get_job {"id":"job_7Hq2"}

await lingua.jobs.wait("job_7Hq2")
← job_7Hq2 · delivered · lease.fr-CA.pdf · $49.00 charged

The record keeps both rounds, the flag and the redo:

Call
→ POST /translation {"document":"lease.pdf","to":"fr-CA","key":"grow","max_usd":49,"metadata":{"sandbox":{"review":"flag_once"}}}
magic values: metadata.sandbox.review = flag_once
← job_7Hq2 · delivered · lease.fr-CA.pdf · $49.00 charged
  record  translate · ai | harden · ai · adversarial · 2 lenses · flagged | translate · ai · redo | harden · ai · adversarial · 2 lenses · pass
  ledger  +$49.00 · AI $2.52 · you $46.48

The redo cost a second pass: $2.52 of AI, where check priced a clean run at $1.26. Both sit under the $9.80 cap, and you kept $46.48.

Run
npx services.dev diff services/translation.ts grow/review.ts
magic values: metadata.sandbox.review = flag_once
services/translation.ts (4 lines) → grow/review.ts (8 lines)
Translation · changed deliver

API   ~ operation service.quote.translation  GET /translation.json  answers.deliver
      ~ operation brand.manifest             GET /manifest.json  answers.services
CLI   no change
MCP   no change
SDK   ~ object job_ (translation)            Job<"translation">  + stage: "translate" | "harden"
Site  ~ operation service.quote.translation  /translation.json  deliver
Docs  no change
App   no change

Only the steps moved: the quote's deliver, the manifest and the SDK's stage union. No call is new, so the CLI, MCP, Docs and App don't change. The step graph adds branches, loops and joins.

In a brand, the legal example reviews a draft through four lenses, three rounds, and its exhausted sends what's still flagged to a credentialed second look.

Ask the buyer: a question the buyer answers before the AI starts.