Skip to content

How a sentence becomes an automation

Ops Canvas turns one sentence into a routine that runs every day. This is what happens in between: what reads your sentence, what is left for you, and what leaves your device.

· 7 min read · Ops Canvas

On this page
  1. The short version
  2. Step by step
  3. Why rules come first
  4. Why Claude fills the rest
  5. Why you confirm
  6. What is sent to Claude
  7. Real examples
  8. Under the hood

The short version

Rules read what is certain. Anything they can’t read stays open. When the rules leave a gap, your sentence goes to Claude to fill it. Claude fills only the open fields, and every value it fills is marked as a guess that waits for you to confirm. Your logins, cards and data never leave your device. Then the routine runs on your own device and reports on Telegram. Anything that costs money is held, not paid, unless you set a limit.

Step by step

  1. You write a sentence

    In English or Korean, the way you would text a friend: “Seoul to Pohang on the 25th, 9 to 12, two seats.” One sentence describes one routine.

  2. Rules read what’s certain

    A rule parser decides what kind of routine it is (train seat watch, facility booking, dorm request or daily briefing) and reads only the fields it can read with certainty:

    • Dates: “tomorrow”, “next Tuesday”, “the 25th”, “Oct 20 to 22”, “25일”.
    • Times and time windows: “9 to 12”, “9pm to 11pm”, “at 7am”.
    • Routes: “Seoul to Pohang”, from a fixed list of stations.
    • People: “two seats”, “for 3 people”.
    • Rooms and facilities: “any study room”, “the turf field”, “basketball court 2”.
    • Dorm requests: overnight stay-out or late return, and for which days.
    • Briefing time: “every morning at 8”, “daily briefing at 7am”.
  3. Anything else stays open

    If a field isn’t stated clearly, the rules leave it empty instead of guessing, and list it under missing. “2 to 4” could mean 2 a.m., so both times stay open. “This weekend” isn’t a date the rules know, so the dates stay open.

  4. Claude fills only the gaps, as guesses

    When fields are missing, or the rules can’t tell which routine you mean, your whole sentence goes to Claude, together with today’s date and the rules’ draft. Claude is asked to fill those gaps and nothing else. The server checks every value it returns again, drops anything invalid, and marks the rest as guesses. Each guess shows a Check this field → confirm? badge and waits for you to confirm.

  5. It runs on your own device

    Once every field is filled and confirmed, the routine runs on your device, not on our servers. It reports on Telegram: a seat held, a slot booked, a request that went through, the morning briefing.

  6. Payments: it holds by default

    For anything that costs money, it only holds the seat or slot and tells you how long you have to pay. If you want, switch on auto-pay with a limit; it never goes above it.

Why rules come first

  • Predictable. The same sentence gives the same result every time. Relative dates resolve against today in Korea time, so “tomorrow” always means the next calendar day.
  • Nothing is sent anywhere. Rules need no model call. A sentence the rules read completely never goes to Claude; in Ops Canvas, it never leaves your device. (The website preview runs the rules on our server, so there your sentence does reach our parser.)
  • A blank is cheap; a wrong guess isn’t. A wrong guess books the wrong train. An empty field costs you one tap.

Why Claude fills the rest

People write the same thing many ways: “this weekend”, “after class on Friday”, “the usual time”. A rule for every phrasing doesn’t scale, and the phrases rules can’t read are exactly the ones a language model reads well. Claude sees your whole sentence, but it fills only what the rules left open. It can’t change a field the rules already filled, and it can’t change the kind of routine the rules chose.

Why you confirm

These routines touch real accounts and real money: a train seat, a facility booking, a dorm request. A guess you never saw could book the wrong day. So every field Claude fills waits for one tap from you, and nothing runs on an unconfirmed guess. You stay in control of what is booked and when.

What is sent to Claude

When the rules leave a gap, your sentence goes to Claude to fill it. Your logins, cards and data never leave your device. Claude is called only when the rules left something open, and the request contains:

  • the whole sentence you wrote, not just the unclear part,
  • today’s date,
  • the rules’ draft: the kind of routine, the fields they filled, and the list of missing fields.

Nothing else: no logins, no card details, no booking history, no other routines. Claude is asked to return values for the missing fields only. A sentence the rules read completely is not sent at all.

Real examples

These are real requests to the parser behind the Try it box, with the responses pasted unchanged. Run the same command and you get the same shape back.

1. Everything stated: nothing left open

Route, date, time window and seats are all in the sentence, so missing is empty.

Train seat watch

“Seoul to Pohang on the 25th, 9 to 12, two seats”

Request

curl -s -X POST https://dirini.com/api/parse \
  -H 'Content-Type: application/json' \
  --data '{"text":"Seoul to Pohang on the 25th, 9 to 12, two seats"}'

Response

{
  "kind": "train-watch",
  "fields": {
    "dep": "서울",
    "arr": "포항",
    "date": "2026-10-25",
    "fromTime": "09:00",
    "toTime": "12:00",
    "passengers": 2,
    "room": null
  },
  "missing": [],
  "echo": "Seoul to Pohang on the 25th, 9 to 12, two seats",
  "source": "rules"
}

Reads as Train seat watch · Seoul → Pohang · Sun, Oct 25 · 09:00–12:00 · 2 seats

2. Missing fields: the rules don’t guess

No date and no time window, so date, fromTime and toTime come back empty and listed in missing. On the website these become three Needs you chips.

Train seat watch, with gaps

“Seoul to Busan by train, two seats”

Request

curl -s -X POST https://dirini.com/api/parse \
  -H 'Content-Type: application/json' \
  --data '{"text":"Seoul to Busan by train, two seats"}'

Response

{
  "kind": "train-watch",
  "fields": {
    "dep": "서울",
    "arr": "부산",
    "date": null,
    "fromTime": null,
    "toTime": null,
    "passengers": 2,
    "room": null
  },
  "missing": ["date", "fromTime", "toTime"],
  "echo": "Seoul to Busan by train, two seats",
  "source": "rules"
}

Reads as Train seat watch · Seoul → Busan · 2 seats · Needs you: date, departs after, departs before

3. An ambiguous phrase: where Claude would help

The rules know this is an overnight stay-out, but “this weekend” could be Friday night or Saturday night. Both dates stay open. With Claude on, it would propose dates and mark them as guesses for you to confirm. On this website, you pick the dates.

Dorm request, dates open

“Overnight stay-out this weekend”

Request

curl -s -X POST https://dirini.com/api/parse \
  -H 'Content-Type: application/json' \
  --data '{"text":"Overnight stay-out this weekend"}'

Response

{
  "kind": "rc-stay",
  "fields": {
    "stayKind": "overnight",
    "start": null,
    "end": null
  },
  "missing": ["start", "end"],
  "echo": "Overnight stay-out this weekend",
  "source": "rules"
}

Reads as Dorm request · Overnight stay-out · Needs you: from, until

4. Not something it automates

A reminder isn’t one of the four routines, so kind is null and the answer is “Couldn’t tell what to automate”. Nothing is guessed. With Claude on, it would pick a routine only if the sentence clearly asked for one of the four.

Unknown request

“Remind me to call mom”

Request

curl -s -X POST https://dirini.com/api/parse \
  -H 'Content-Type: application/json' \
  --data '{"text":"Remind me to call mom"}'

Response

{
  "kind": null,
  "fields": {},
  "missing": [],
  "echo": "Remind me to call mom",
  "reason": "Couldn't tell what to automate",
  "source": "rules"
}

Reads as Couldn't tell what to automate

Under the hood

Claude gap-fill

Model
Claude Sonnet (default claude-sonnet-5-5), called through the Messages API.
Output
JSON-schema structured output. The answer has to match a fixed schema: routine kind, stations from a fixed list, dates, times, facility ids.
Re-validation
The server re-checks every value with the same criteria as the rules: a known station, a date from today up to 400 days ahead, a valid 24-hour time, a known facility, 1–4 seats, an end after the start. Anything invalid is dropped and the field stays open.
Scope
Only fields in missing. Rule-filled fields and the routine kind never change. Filled fields are listed in inferred, and source becomes "rules+claude".
Timeout
8 seconds, no retries. A timeout, a refusal or any error returns the rules’ result unchanged.
Status
Implemented in Ops Canvas and in testing. On dirini.com no API key is set, so every response is "source": "rules".

Try it now

Write one routine in a sentence on dirini.com and see what the rules read. Nothing is booked.