Ask the host's clock to start work nobody will be present for
Records a schedule: a repository, a prompt, a rule saying when it fires, and what one fire may spend. The host’s own clock fires it into a new session that runs unattended — every fire opens its own session and nothing is ever appended to an earlier one.
Everything this host could not honour is refused HERE, because creation is the only moment somebody is present to answer. A rule under the five-minute floor, an instant already behind the clock, and a repository nobody has vouched for are all 422: a schedule accepted into an untrusted directory would wake at three in the morning, be refused at everything it tried, and leave an empty morning behind.
A hosted home runs every session inside a container. A schedule there that names no environment fires each time into a container of the fired session’s own, made at its first turn as a conversation’s is, holding a fresh clone of the repository it names in clone; a clone or setup that fails ends that turn, and the session’s next turn clones again. A named environment is read again at every fire: one destroyed since, or no longer the owner’s, makes that fire open no session, and the reason is written on the schedule’s lastError.
The clock itself is not on this surface. Due-ness, the sweep’s cadence and how a ceiling is spent are the host’s own facts; a client asks for a schedule and reads what the host decided.
Authorizations
Enforced on every transport, with no exempt operation. A person's request must carry a JWT issued by the configured identity provider, which the host verifies itself against that issuer's key set: signature, issuer, expiry, and the person and organisation it names. Requests without a valid one receive 401 NRY-0011 — except a request with no token on a laptop's socket from the OS user the kernel names as the host's own, which is that machine's user.
Body
A schedule being asked for, in the words the caller has: the rule arrives as the strings a person typed and one parser reads them, so every surface refuses --every whenever in the same sentence.
There is no owner field and its absence is the rule rather than an omission — the host writes the owner from its own identity.
What the fired session is asked to do. Required: a schedule with nothing to do starts a session at three in the morning and does nothing in it.
Absolute path of the directory a fire runs in, required unless clone is given and refused (422) beside it. Somebody must have vouched for it already; one nobody has is refused with the sentence that names the gesture.
4096The agent recipe a fire runs under. Empty runs the host's default.
An interval — "15m", "2h", "24h", "7d". Exactly one of every and at is given. The shortest a schedule may fire on is five minutes, and anything under it is refused naming the floor: an agent turn takes minutes and spends money, so a schedule measured in seconds is an incident rather than an aggressive setting. An interval's first fire is one interval away, never immediately.
One absolute RFC3339 instant, fired once, after which the schedule is completed. An instant already behind the clock is refused rather than fired late.
What one fire may spend. Absent takes the operator's configured default, which is why the spend ceiling is on whether or not anybody thought about it. Zero is not absent and is never promoted: it is a schedule that does not fire, which is how one is parked until somebody prices it.
x >= 0Run every fire inside this environment, which must already exist (createEnvironment) and is read again at each fire. Absent means the host's own machine on a person's own home, whose repository must exist there, and a container of each fire's own on a hosted home (createSession).
1 - 64^[A-Za-z0-9][A-Za-z0-9._-]*$A repository cloned afresh into each fire's own container, exactly as createSession's clone: on a hosted home, without environment, and the schedule's repository, which reads back as owner/name.
200^[A-Za-z0-9][A-Za-z0-9._-]*/[A-Za-z0-9][A-Za-z0-9._-]*$Run once at each fire in place of the clone's own .narya/setup.sh, as createSession's setupScript. Only with clone (422 otherwise).
1 - 65536A key the client chooses for this schedule, so a create whose answer was lost can be repeated safely. A create carrying a key its caller already created a schedule under records nothing: it is answered 201 with that schedule, whatever else this body says. Absent, every create records a schedule.
1 - 255Response
The schedule as stored, with the first instant it is owed.
Work the host's own clock starts, with nobody present. A schedule is durable configuration, never swept: what a fire produces is a session, governed by the rules sessions already have, while the schedule itself stays until somebody cancels it. The owner is never something a caller names — a fire has to be attributable to somebody who is not there, and an attribution the reader cannot check reads exactly like a true one.
Who this schedule's fires are billed to and attributed to: the person who created it, as the host authenticated them. A fire runs with nobody present, so this is read from the row rather than from whoever is signed in at the time — which is what lets a schedule outlive its author being away.
The directory a fired session runs in, relative to the workspace on a hosted home. Somebody has vouched for it — creation refuses one nobody has — and the host reads that answer again at every fire, because trust is revocable.
What the fired session is asked to do.
When a schedule fires: a kind and the one parameter that kind takes. Exactly one parameter is ever set. There is no cron expression here and the absence is a decision, not a gap: a cron expression drags a timezone, a daylight-saving policy and a no-match semantics behind it, and an agent turn costs money and takes minutes, so the units that matter are hours and days.
active fires; completed is what a single-instant schedule becomes once that instant is spent; cancelled is what a person does to one, and it stops the fires without removing the record; paused keeps the row and stops the fires, which is the difference between changing your mind and changing it back.
active, paused, completed, cancelled What ONE fire may spend. A hard stop on the turn rather than a price — see setScheduleBudget for what it does and does not bound. Zero means this schedule does not fire. A fire on a model this host has no price for runs without it, and notice says so.
x >= 0How many instants this schedule has CLAIMED, including fires that never reached a session. The count is incremented inside the same transaction that spends the instant, which is what makes a fire unrepeatable across a crash — so a fire refused after the claim, or a host that died in the gap before the session existed, is counted here and explained in lastError. A consumer counting SESSIONS wants the sessions themselves, not this.
x >= 0The agent recipe a fire runs under. Absent runs the host's default.
The environment every fire runs inside, read again at each fire. Absent is a schedule whose fires run on the host's own machine, or on a hosted home in a container of each fire's own.
1 - 64^[A-Za-z0-9][A-Za-z0-9._-]*$The repository cloned afresh into each fire's own container on a hosted home, which is also the schedule's repository.
The instant a fire is owed at. Absent once a single instant has been spent. A cancelled schedule KEEPS the instant it was going to run at — its status is what stops the fire, and the instant is what somebody reads when they wonder whether they stopped the right one. It is advanced from the moment of the fire rather than from the instant that was missed, which is why a host that was off for three days fires once rather than three times.
When this schedule last CLAIMED an instant. Absent until it has. It is stamped at the claim, before the fire's session exists, so it says when the host last acted on this schedule rather than when work last started: a fire refused for a missing repository or a missing key moves it too, and lastError says which.
The session the last fire created, which is where the morning's reading starts. It may name a session that has since been purged.
When a due fire was refused, with lastSkipReason saying which refusal it was. Recorded rather than silent: a skip nobody can read is indistinguishable from a scheduler that stopped working. Written once while the refusal lasts, so it answers "since when", and cleared by any fire that gets through.
How a fire that had already claimed its instant failed to reach a session. The instant stays spent, so this is what the morning reads instead of an unexplained gap.
What the last fire that opened a session says about how this schedule's fires run, absent when it says nothing. Two facts earn it: the model the fires run on has no price on this host, so they run with no spend ceiling until a fire on a priced model clears it; or the agent they run comes from the repository each fire's turn clones, so its price is judged when the turn clones and a priced model keeps the ceiling.

