A date the world sets

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

Give the filing a date the registry sets and the buyer answers for. Three days out, a rung asks the registry for more time; at the date, unfiled, the buyer chooses what happens.

within is your deadline: how long the work may take. Some dates belong to the world: a registry takes a filing until the day it names. A clock holds that date, names who answers for it, acts before it comes, and at the date asks its owner what happens. This is Grow 5: Grow 4's filing gains a date.

check counts 26 lines. translators() is Grow 4's, unchanged:

grow/clock.ts
import { Pool, Rules, Service } from 'services.dev'

// Grow 5, a date the world sets: the registry takes the filing until a date the buyer names, and the buyer answers
// for it. Three days out, the clock asks the registry for two more weeks, and the extension moves the date. The clock
// is named for the filing, so the filing satisfies it; at the date, unfiled, the buyer chooses to file late or withdraw.
export default Service({
  name: 'Translation',
  description: 'A document, translated, signed and filed by its date.',
  input: { document: 'file', to: 'language: a BCP 47 tag, such as fr-CA', file_by: 'date: the registry deadline, such as 2026-11-04' },
  output: { document: 'file', filing: 'text', extension: 'text' },
  rules: rules(),
  roles: { translator: { pool: translators(), pay: 30 } },
  deliver: {
    glossary: { ask: 'buyer', to: 'answer', items: () => [{ id: 'terms', label: 'Which terms stay in English?' }] },
    translate: 'ai',
    harden: { review: 'adversarial', lenses: ['meaning', 'terms'], rounds: 2 },
    sign: { by: 'translator', stamp: true, est: '20min' },
    extend: { submit: 'https://registry.example.test/extensions', to: 'the registry', receipt: 'extension', routed: true },
    file: {
      submit: 'https://registry.example.test/filings',

Asking for more time is an act, so rules() gains one row:

grow/clock.ts
        extend: { open: true, position: 'Asking a registry for more time needs no credential.' },

file_by is the buyer's date. extend is routed: it runs only when the clock sends the job there.

KeyWhat it doesDefault
dueThe date: a function of the job returning a civil date, which closes at the calendar's minute, or a span after a step, an input, an event or another clock, such as '365d after file'. A function that throws, or returns what isn't a date, fails check with clock_due_unreadablerequired
ownerWho answers for it: 'buyer', 'brand', a role, or of_record, the member of record on the subject. An owner that can never resolve fails check with clock_unownedrequired
rungsWhat happens before the date, in civil days back: 'notice 30d' and 'escalate 3d' tell the owner, 'ack daily 2d' asks them to acknowledge each of the last two days, and 'run extend 3d' proposes the routed step through the gate. A proposal the gate holds proposes again each day, and escalatesnone
movesSteps whose committed output moves the date, and to when: '14d after due', or a function of the job. It moves this clock only, so two dates that move differently are two clocksnone
lapseWhat the owner chooses at the date, unsatisfied, through clock.choose. A step's name runs that step through the gate; any other option closes the clock with the choice on the recordnone
satisfied_bySteps whose commit closes itthe step it's named for

Clocks covers every, each, lives_on, hard, exposure and the calendar.

Run
npx services.dev check
magic values: none
services/translation.ts · 26 lines · $89 per job, within 48 hours, charged on file's receipt.
  who     A translator signs every document before it is filed. (rules 2026-10) The buyer answers at glossary.
  roles   translator · sworn translator · from sworn-translators · $30 an act
  steps   glossary · buyer · answer → translate · ai → harden · ai · adversarial · 2 lenses → sign · translator · * · stamped → extend · the registry · routed → file · the registry → hand_off · buyer · answer · routed
  clocks  file · a date your code decides · the buyer
  bounds  reserved sign to sworn translator · open extend and file
  agent   order_translation · 30 of 30 words · job_7Hq2 waits on party
  ledger  +$89.00 · AI $1.26 (example) · translator $30.00 · you $57.74
  margin  at least $41.20 when the first translator signs ($89.00 − $30.00 translator − $17.80 AI cap) · $26.20 at the ladder's cap, the lower of 50% and what the floor leaves · $11.20 after a decline and a second translator
          a job that stops costs you at most $47.80
  apps    customer portal · delivery portal · owner console

mcp     13 buyer tools · 4,555 of 8,000 tokens · 9 more with ?toolset=sandbox
✓ ready to sell · 1 Service · it keeps at least 46% 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 clocks line names the date and its owner. The margin is Grow 4's.

No magic value is needed. The order opens the clock:

Call
→ POST /translation {"document":"lease.pdf","to":"fr-CA","file_by":"2026-11-04","key":"grow","max_usd":89}
magic values: none
← job_7Hq2 · waiting · on party · $89.00 held
  clock   clk_7Hq2 · file · due 2026-11-04 · buyer · open

Every surface reads it alike, its rung armed, its lapse listed:

npx services.dev clocks get clk_7Hq2 --json
{
  "id": "clk_7Hq2",
  "object": "clock",
  "livemode": false,
  "name": "file",
  "service": "translation",
  "job": "job_7Hq2",
  "subject": null,
  "lives_on": "job",
  "status": "open",
  "due_at": "2026-11-04T23:59:00.000Z",
  "due_on": "2026-11-04",
  "zone": "UTC",
  "original_due_at": "2026-11-04T23:59:00.000Z",
  "moves": [],
  "occurrence": 0,
  "owner": {
    "type": "buyer",
    "member": null
  },
  "rungs": [
    {
      "rung": "run extend 3d",
      "rings_at": "2026-11-01T00:00:00.000Z",
      "fired": false
    }
  ],
  "lapse": [
    "file",
    "withdraw, in writing"
  ],
  "choice": null,
curl http://localhost:8787/clocks/clk_7Hq2
{
  "id": "clk_7Hq2",
  "object": "clock",
  "livemode": false,
  "name": "file",
  "service": "translation",
  "job": "job_7Hq2",
  "subject": null,
  "lives_on": "job",
  "status": "open",
  "due_at": "2026-11-04T23:59:00.000Z",
  "due_on": "2026-11-04",
  "zone": "UTC",
  "original_due_at": "2026-11-04T23:59:00.000Z",
  "moves": [],
  "occurrence": 0,
  "owner": {
    "type": "buyer",
    "member": null
  },
  "rungs": [
    {
      "rung": "run extend 3d",
      "rings_at": "2026-11-01T00:00:00.000Z",
      "fired": false
    }
  ],
  "lapse": [
    "file",
    "withdraw, in writing"
  ],
  "choice": null,
→ tools/call get_clock {"id":"clk_7Hq2"}
{
  "id": "clk_7Hq2",
  "object": "clock",
  "livemode": false,
  "name": "file",
  "service": "translation",
  "job": "job_7Hq2",
  "subject": null,
  "lives_on": "job",
  "status": "open",
  "due_at": "2026-11-04T23:59:00.000Z",
  "due_on": "2026-11-04",
  "zone": "UTC",
  "original_due_at": "2026-11-04T23:59:00.000Z",
  "moves": [],
  "occurrence": 0,
  "owner": {
    "type": "buyer",
    "member": null
  },
  "rungs": [
    {
      "rung": "run extend 3d",
      "rings_at": "2026-11-01T00:00:00.000Z",
      "fired": false
    }
  ],
  "lapse": [
    "file",
    "withdraw, in writing"
  ],
  "choice": null,
await lingua.clocks.get("clk_7Hq2")
{
  "id": "clk_7Hq2",
  "object": "clock",
  "livemode": false,
  "name": "file",
  "service": "translation",
  "job": "job_7Hq2",
  "subject": null,
  "lives_on": "job",
  "status": "open",
  "due_at": "2026-11-04T23:59:00.000Z",
  "due_on": "2026-11-04",
  "zone": "UTC",
  "original_due_at": "2026-11-04T23:59:00.000Z",
  "moves": [],
  "occurrence": 0,
  "owner": {
    "type": "buyer",
    "member": null
  },
  "rungs": [
    {
      "rung": "run extend 3d",
      "rings_at": "2026-11-01T00:00:00.000Z",
      "fired": false
    }
  ],
  "lapse": [
    "file",
    "withdraw, in writing"
  ],
  "choice": null,

A test clock runs to 2 November, the glossary unanswered:

Call
→ POST /test_clocks/default/advance {"to":"2026-11-02T00:00:00Z"}
magic values: none
  2026-10-31 14:02:11  ask.reminded · glossary · 1d before expiry
  2026-11-01 00:00:00  clock file · rung run extend 3d → extend proposed · committed
  2026-11-01 00:00:00  extend · rcp_7Hq2 accepted
  2026-11-01 00:00:00  clock file · moved 2026-11-04 → 2026-11-18
  2026-11-01 00:00:00  waits on party at glossary
  2026-11-01 14:02:11  ask.expired · glossary
  2026-11-01 14:02:11  ask glossary · buyer · 1 item · 1 open (terms)

Three days out, the rung proposed extend, the registry's receipt committed it, and moves carried the date to 18 November. The glossary's link expired and reopened as ask_7Hq3. The buyer answers, the translator signs, and the filing satisfies the clock:

Call
→ POST /asks/ask_7Hq3?t=rE5VINsEvPPB93bDQLooDc {"items":{"terms":{"answer":"Lessee, Lessor, Premises"}}}
magic values: none

# 20 minutes later, mbr_7Hq2, the sworn translator, claims tsk_7Hq2 in the delivery portal and signs, in their own session
→ POST /tasks/tsk_7Hq2/claim · POST /tasks/tsk_7Hq2/clear · POST /tasks/tsk_7Hq2/attest

← job_7Hq2 · delivered · lease.fr-CA.pdf · $89.00 charged
  record  glossary · reminded 1d before expiry | file clock · run extend 3d · goto extend | extend · the registry · accepted · rcp_7Hq2 | file clock · moved 2026-11-04 → 2026-11-18 | glossary · expired | glossary.terms · answered | glossary · buyer · answer · clock paused 7d 9h | translate · ai | harden · ai · adversarial · 2 lenses · pass | sign · person · sworn translator · * · mbr_7Hq2 | file · the registry · accepted · rcp_7Hq3
  clock   clk_7Hq2 · file · due 2026-11-18 · buyer · satisfied · moved from 2026-11-04
  closed  file · satisfied when file committed

The glossary's wait paused the job's own deadline, clock paused 7d 9h; the registry's date kept running.

Had the filing missed 18 November, the clock would turn due and wait for the buyer's clock.choose: file runs the filing late, through the gate, and withdraw, in writing closes the clock with that choice on the record, leaving the job for the buyer to cancel. The clock calls shows one.

Run
npx services.dev diff grow/submit.ts grow/clock.ts
magic values: none
grow/submit.ts (22 lines) → grow/clock.ts (26 lines)
Translation · changed description, input, output, deliver, rules, clocks · adds clocks: dates the world sets, who answers for each, its rungs and what moves it

API   ~ operation service.order.translation  POST /translation  item.description, item.requestBody.content.application/json.schema.properties.file_by, item.requestBody.content.application/json.schema.required  · breaking
      ~ operation service.quote.translation  GET /translation.json  answers.description, answers.input.properties.file_by, answers.input.required  · breaking
      + operation clock.list                 GET /clocks
      + operation clock.get                  GET /clocks/{id}
      + operation clock.ack                  POST /clocks/{id}/ack
      + operation clock.satisfy              POST /clocks/{id}/satisfy
      + operation clock.choose               POST /clocks/{id}/choose
      + operation clock.assign               POST /owner/clocks/{id}/assign
      ~ operation brand.manifest             GET /manifest.json  answers.services
      + object clk_                          clock
      + 15 events                            clock.opened, clock.noticed, clock.escalated, clock.ack_due, clock.ack_missed, clock.ran, clock.moved, clock.due, clock.satisfied, clock.rolled, clock.recurred, clock.acked, clock.chosen, clock.assigned, clock.outlived
      + 6 errors                             needs_the_owner, evidence_required, evidence_used, clock_closed, clock_not_due, clock_moved_on
CLI   ~ operation service.order.translation  services.dev translation document=… to=… file_by=…  input.properties.file_by, input.required  · breaking
      + operation clock.list                 services.dev clocks list
      + operation clock.get                  services.dev clocks get <clock>
      + operation clock.ack                  services.dev clocks ack <clock>
      + operation clock.satisfy              services.dev clocks satisfy <clock>

The input gains file_by, breaking for clients that type it. The clock brings its own calls, the clk_ object, fifteen events and six errors; MCP only reads clocks.

In a brand, the tax example runs two clocks on one job, because its extension moves one date and never the other.

Paid on the close: a Service that charges only when its buyer's own customer pays.