CovenDocs

Coven automations

Durable Coven-owned routine definitions, scheduling, execution, health, and run history.

18 min read

Coven automations are durable routine definitions owned by the Coven daemon and its local store. A routine binds a schedule to a validated runtime launch, optional familiar identity, project working directory, prompt, and delivery settings. The scheduler and run ledger live in Coven rather than in a harness home directory.

Automations are exposed through the coven.automations capability and the versioned POST /api/v1/actions router. Always call GET /api/v1/capabilities first and use only action ids advertised by the live daemon. This page describes the current source contract; an older installed daemon advertises fewer actions.

The coven.automations capability may include an optional variantNegotiation object describing supported, experimental, and refused contract variants. This is negotiation metadata; it does not authorize a refused variant. See versioned definition commands.

Owner-local access

Send automation actions to the owner-local IPC endpoint: the Unix socket or the Windows named pipe. If you run the optional loopback TCP listener, only these diagnostic reads answer over it: coven.automations.health, coven.automations.definition.health.v1, coven.automations.scheduler.status.v1, coven.automations.occurrence.list.v1, and coven.automations.occurrence.history.v1. Every other coven.automations.* action, including reads that return prompts, run logs, receipts, or event checkpoints, returns HTTP 403 with error code AUTHORITY_REQUIRED before the daemon opens its store. origin, intentId, and other caller-supplied identity fields never grant access.

AUTHORITY_REQUIRED sets retryable: false. Refusal happens before reserving an adoption key, replaying a saved result, emitting an action event, or dispatching runtime work. A refused request does not consume the adoption key; a later owner-local request can use that key, subject to normal validation.

Clients should stop and report the transport error. Have the owner explicitly configure a supported owner-local connection. Do not silently retry through a more privileged connection or expose the IPC endpoint through an unauthenticated bridge. Passing this transport check does not provide a trusted Runtime Authority adapter or enable a refused execution command or SDK mutation phase.

Capability discovery alone does not prove that an older installed daemon enforces this boundary. Check its build identity and release evidence before relying on TCP refusal.

Safety defaults

  • coven.automations.import creates legacy routines as PAUSED and coven.automations.legacy.import.v1 creates them as drafts; import never opts them into execution. See Automations migration.
  • Unsupported recurrence values fail validation rather than being approximated.
  • Overlap policy is forbid and misfire recovery is latest in the v1 definition shape.
  • A run without an explicit cwd fails instead of guessing a project.
  • Scheduled and manual runs use the same validated session-launch path.
  • The daemon runs a scheduler pass at startup, every 60 seconds, and right after most successful definition changes, cancellations, recoveries, retries, manual runs, tick, or unquarantine. Disabling a definition, a rich command.v1 change, and imports wait for the next 60-second pass. It records occurrence and run state durably. See Automations scheduling.
  • One scheduler at a time claims and dispatches work for a COVEN_HOME, fenced by $COVEN_HOME/automations-scheduler.lock and a generation stored in SQLite. Keep the lock file and the SQLite store on one local filesystem; network filesystems are not supported.
  • outputTarget is refused until atomic delivery is certified.
  • An authority declaration is refused until the daemon advertises Runtime Authority.
  • A routine that exhausts its retry policy is quarantined: it stops planning and refuses manual runs until you call coven.automations.unquarantine.

Review a definition before changing its status to ACTIVE. Provider credentials remain owned by the selected runtime or harness and must not be embedded in the automation definition or action envelope.

Action envelope

Automation arguments are top-level fields in the action request. origin and intentId are optional correlation fields. On coven.automations.create, .update, and .delete, intentId is also an idempotency key: repeating the same request with the same intentId returns the first result, and a different request with a reused intentId is rejected. Use a new intentId for each intended change. coven.automations.run.cancel.v1, coven.automations.occurrence.cancel.v1, coven.automations.attempt.cancel.v1, coven.automations.attempt.retry.v1, coven.automations.occurrence.recover.v1, and coven.automations.occurrence.runNow.v1 accept only their own fields, so leave origin and intentId off those requests.

{
  "action": "coven.automations.health",
  "origin": "local-maintainer-tool",
  "intentId": "inspect-daily-notes-1",
  "id": "daily-notes"
}

The router returns an event-shaped response when it recognized and routed the action:

{
  "ok": true,
  "accepted": true,
  "action": "coven.automations.health",
  "status": "completed",
  "event": {
    "kind": "automations.changed",
    "action": "coven.automations.health",
    "origin": "local-maintainer-tool",
    "intentId": "inspect-daily-notes-1",
    "payload": {
      "health": {
        "automationId": "daily-notes"
      }
    }
  }
}

A successful action returns ok: true, accepted: true, and status: "completed". A failed action returns ok: false, accepted: false, status: "rejected", and the cause in reason. Unversioned actions report failures with HTTP 400. Versioned actions (ids ending in .v1) and the owner-local check also return a typed error with code, httpStatus, message, and retryable, and the HTTP status matches error.httpStatus: for example VALIDATION_FAILED (400), AUTHORITY_REQUIRED (403), NOT_FOUND (404), REVISION_CONFLICT and ADOPTION_REPLAY_MISMATCH (409), CANCEL_PENDING (409), GONE_TOMBSTONED and CURSOR_EXPIRED (410), and CAPABILITY_UNSUPPORTED, ILLEGAL_TRANSITION, RETRY_DISPOSITION_INVALID, or AMBIGUOUS_RETRY_FORBIDDEN (422), and DEADLINE_EXCEEDED (504). Branch on error.code, not reason. Malformed JSON and missing action ids return 400. An unknown coven.automations.* action over TCP is refused with 403 before action validation; other unknown action ids return 400.

accepted: true on coven.automations.run means Coven started or scheduled the run, not that it finished; see Manual runs and health.

Supported actions

The daemon advertises 37 coven.automations.* action ids. Unversioned actions and the definition, run, occurrence, health, and scheduler reads return their data in event.payload. Versioned commands, event pages, and receipt reads return it in a top-level result; a versioned command that commits also returns an event.

Unversioned actions

ActionRequired fieldsResult
coven.automations.listnoneroutines
coven.automations.getidroutine or null
coven.automations.createdefinitioncreated routine and timestamp
coven.automations.updatedefinitionupdated routine and timestamp
coven.automations.deleteidid and deleted
coven.automations.ticknoneplanning report; it plans due slots and wakes the scheduler but never claims or recovers work, so recovered is 0 and claimed is empty
coven.automations.runsid; optional limitrecent runs with their attempts and the latest attempt's cancellation; default limit 20
coven.automations.runidrun id, status, session id, and error
coven.automations.importnoneimported, skipped, and failure lists
coven.automations.healthidnext due time, recent outcomes, lease, retry, quarantine, and staleness state
coven.automations.unquarantineidautomationId and released

Versioned commands

ActionRequired fieldsResult
coven.automations.definition.create.v1definition, adoptionKeyoutcome, revision, and the routine
coven.automations.definition.revise.v1definition, adoptionKey, expectedRevisionoutcome, revision, and the routine
coven.automations.definition.activate.v1id, adoptionKey, expectedRevision; optional reasonpaused to active as a new revision
coven.automations.definition.pause.v1id, adoptionKey, expectedRevision; optional reasonactive to paused as a new revision
coven.automations.definition.disable.v1id, adoptionKey, expectedRevision; optional reasondisabled as a new revision
coven.automations.definition.tombstone.v1id, adoptionKey, expectedRevisiontombstone revision; history is kept
coven.automations.legacy.import.v1adoptionKey, source: "codex-automation-toml"; optional dryRunimported, skipped, and failure lists
coven.automations.run.cancel.v1adoptionKey, runId, attemptId, runtimeCorrelation.sessionId, scope: "run", reason, requestedBy.principalIdcancellation record
coven.automations.occurrence.cancel.v1adoptionKey, occurrenceId; optional reasonthe occurrence cancelled, or the run cancellation it started
coven.automations.attempt.cancel.v1adoptionKey, attemptId; optional reasonthe attempt cancelled, or the run cancellation it started
coven.automations.attempt.retry.v1adoptionKey, runId, priorAttemptNumber, priorDisposition; optional notethe new attempt, with the occurrence planned
coven.automations.occurrence.recover.v1adoptionKey, occurrenceId, evidenceDetermination; optional statementthe determination: the occurrence settled failed, or planned for a new attempt
coven.automations.occurrence.runNow.v1adoptionKey, automationId; optional note, bypassEligibilitythe manual occurrence and, once dispatched, its run
coven.automations.command.v1envelopea coven.automations.v1 command response

Reads, history, and events

ActionRequired fieldsResult
coven.automations.definition.list.v1none; optional includeTombstonedroutines, revisionById, and tombstonedAtById
coven.automations.definition.get.v1idroutine or null, revision, tombstonedAt, and the rich definition when one was authored through command.v1
coven.automations.definition.health.v1idthe same health as coven.automations.health; typed NOT_FOUND or GONE_TOMBSTONED
coven.automations.run.history.v1automationId; optional occurrenceId, limit, cursorruns newest first and a cursor
coven.automations.run.get.v1idone run with its attempts, or null
coven.automations.occurrence.list.v1view; optional automationId, limitoccurrences
coven.automations.occurrence.get.v1idone occurrence with up to 20 runs, or null
coven.automations.occurrence.history.v1automationId; optional limit, cursoroccurrences in every state, newest first, and a cursor
coven.automations.scheduler.status.v1nonescheduler owner, generation, last pass, and queue counts
coven.automations.receipt.get.v1idreceipt and verification
coven.automations.events.read.v1stream; optional after or from, limitan event page with nextAfter and a checkpoint
coven.automations.events.subscribe.v1stream; optional after or checkpointup to 100 events and a new checkpoint

view is due, eligible, claimed, running, or recovery_required. due lists every planned slot whose time has arrived; eligible applies the scheduler's own claim rules. History and occurrence reads accept limit from 1 to 100 (default 20). Pass the previous page's cursor.next as cursor until cursor.hasMore is false. These reads never renew leases or change state.

stream is an object with kind (automation, occurrence, run, or feed) and id; use feed with id all for every automation event in commit order. events.read.v1 takes an exclusive sequence in after or a UTC timestamp in from, and limit from 1 to 1,000 (default 100). Checkpoints expire after 24 hours and then return CURSOR_EXPIRED instead of rewinding.

Occurrence, run, and attempt state changes publish occurrence.transitioned, run.transitioned, and attempt.transitioned events in the same transaction as the change: occurrence events on the occurrence stream, run and attempt events on the run stream. Creating a row publishes from: "none". History from before these events existed is not backfilled, so a stream can begin mid-lifecycle; treat its first prior state as unknown.

coven.automations.receipt.get.v1 returns the stored receipt with a verification summary. Current builds cannot authenticate the receipt producer, so verification.status is unverifiable; treat a receipt as integrity-checked, not as proof of what ran.

Versioned definition commands

Versioned mutations take an adoptionKey: 8 to 200 characters, starting with a letter or digit, then letters, digits, ., _, :, or -. Coven stores the first outcome for each key in the same transaction as the change. Repeating the exact request returns the stored result with outcome: "replayed" and no second event. Reusing a key for a different request returns ADOPTION_REPLAY_MISMATCH. Rejections are stored too, so use a new key after you fix a rejected request.

Revise, activate, pause, disable, and tombstone also take expectedRevision. Read the current value from coven.automations.definition.get.v1. A stale value returns REVISION_CONFLICT with currentRevision and changes nothing.

{
  "action": "coven.automations.definition.activate.v1",
  "id": "daily-notes",
  "adoptionKey": "activate-daily-notes-0001",
  "expectedRevision": 1,
  "reason": "Reviewed prompt, cwd, and schedule."
}
  • Activate moves a paused definition to active and re-validates it; pause moves active to paused. Any other starting state is ILLEGAL_TRANSITION.
  • A disabled definition cannot be activated, revised, or updated.
  • A draft from legacy.import.v1, or an invalid definition, can only be revised to status: "PAUSED" before you activate it.
  • create.v1 and revise.v1 reject unknown definition fields, and refuse any variant that the variantNegotiation object on the coven.automations capability does not list as supported, such as outputTarget, with CAPABILITY_UNSUPPORTED naming the variant.
  • After any versioned mutation, coven.automations.update refuses the definition and coven.automations.delete returns deleted: false and leaves it in place. Use definition.tombstone.v1 instead.
  • Every versioned command in the coven.automations.v1 command envelope is implemented and advertised. A versioned action name the daemon does not advertise returns CAPABILITY_UNSUPPORTED.

coven.automations.command.v1 accepts a coven.automations.v1 command envelope in envelope and answers with a command response in result. Envelope definition.create.v1 and definition.revise.v1 commands carry a rich AutomationDefinition with its JCS integrity digest. Create must be revision: 1 in lifecycleState: "draft"; revise must be expectedRevision + 1. Coven runs the rich body through the same validation and transactions as a routine body, keeps the rich form, and returns it as definition from coven.automations.definition.get.v1. Delivery policies and activation windows are refused with CAPABILITY_UNSUPPORTED rather than dropped, and a rich request and a routine request never share an adoption key. The envelope also refuses run.cancel.v1, occurrence.cancel.v1, attempt.cancel.v1, attempt.retry.v1, and payload fields it does not implement with CAPABILITY_UNSUPPORTED; send cancellation as the flat action instead.

For a richly authored revision, definition lifecycle events, occurrence list/history/get projections, coven.automations.run.get.v1, and Runtime Authority execution bindings publish the recorded document's integrity digest. The compatibility coven.automations.runs and coven.automations.run.history.v1 projections do not expose a digest. Receipts produced from those bindings carry the published digest. Scheduling and dispatch continue to fence execution with the digest of the projected routine JSON; these two digests serve different purposes. Revisions without a rich document publish the routine digest. Historical rows without a stored digest remain unattributed.

This behavior is present in source beginning with eb3273e. Existing events are immutable: v0.4.7 events retain their original routine digest. Receipts from older execution bindings may also name the routine digest of the same revision; the signed binding still determines the exact value to verify.

Definition shape

A create or update request supplies a top-level definition object:

{
  "action": "coven.automations.create",
  "origin": "local-maintainer-tool",
  "definition": {
    "schemaVersion": 1,
    "id": "daily-notes",
    "name": "Daily notes",
    "status": "PAUSED",
    "rrule": "FREQ=DAILY;BYHOUR=9",
    "timezone": "local",
    "misfire": "latest",
    "overlap": "forbid",
    "timeoutMinutes": 30,
    "runtime": "coven-code",
    "familiarId": "charm",
    "cwd": "/absolute/path/to/project",
    "prompt": "Write the daily reflection.",
    "tags": ["notes"]
  }
}

The v1 implementation validates:

  • schemaVersion is exactly 1;
  • id is 1–96 ASCII letters, digits, ., _, or -;
  • name is 1–160 characters;
  • status is ACTIVE or PAUSED; reads can also return DISABLED after coven.automations.definition.disable.v1;
  • rrule uses FREQ=DAILY or FREQ=WEEKLY with supported BYHOUR values, and BYDAY only for weekly rules; empty or repeated parts and repeated weekdays fail;
  • timezone is utc or an exact IANA zone name such as America/New_York; local is accepted as input only, and Coven resolves it to the host's IANA zone before storing the definition or refuses the request (on Unix, a TZ override must itself be utc or an IANA name);
  • misfire is latest and overlap is forbid;
  • timeoutMinutes is 1–44,640;
  • optional retry sets maxAttempts (1–10), backoffPolicy (none, fixed, or exponential), backoffSeconds (1–86,400, required for fixed), and retryableClasses from transient_dispatch, lease_expired, and runtime_unavailable;
  • runtime is non-empty and at most 64 characters;
  • prompt is non-empty;
  • optional familiarId is non-empty and at most 64 characters.

Optional fields also include model and tags. outputTarget fails validation until atomic delivery is certified, and an authority block (a Runtime Authority declaration) fails validation until the daemon advertises Runtime Authority. In an IANA zone, a wall-clock slot removed by a spring-forward change does not run, and a slot repeated by a fall-back change runs once, at the earlier instant; see Automations scheduling for the recurrence subset, time zones, missed slots, retries, and timeouts with their conformance cases. Treat all filesystem paths as host-local values. Do not copy a definition between hosts without reviewing its cwd and timezone.

Manual runs and health

An immediate run uses:

{
  "action": "coven.automations.run",
  "id": "daily-notes"
}

A successful dispatch returns a run id and session id with status running. That status proves durable correlation and runtime ownership, not completion. The automation run remains nonterminal until the correlated session ledger contains authoritative terminal evidence. Launch acknowledgement, process output, or a dropped client connection must not be reported as success. If a running response also carries error, Coven kept runtime ownership but could not confirm the launch; treat that run as unresolved.

If the launch fails before any process starts and the failure class is in the routine's retry.retryableClasses, the response has status retry_scheduled, a run id, no session id, and the launch error. The scheduler starts the next attempt after its backoff.

A missing routine, missing cwd, quarantined routine, unsettled earlier run, or launch refusal returns a rejected response: HTTP 400, accepted: false, and the cause in reason. coven.automations.run does not check the routine's status, so it also runs a paused routine; coven.automations.occurrence.runNow.v1 requires an active one. A refused launch still leaves its run: an ordinary run is held for an operator retry until its deadline rather than failed. Deadline and restart recovery settle conservatively: timeout handling requires strict process-tree containment, and an interrupted run stays nonterminal until Coven can prove a terminal disposition.

To run a routine now with replay protection, send coven.automations.occurrence.runNow.v1 instead. It plans a manual occurrence, claims it, and dispatches it through the same path as a scheduled one, so the routine's timeout, overlap, and retry policies still apply:

{
  "action": "coven.automations.occurrence.runNow.v1",
  "adoptionKey": "run-now-daily-notes-0001",
  "automationId": "daily-notes",
  "note": "Rerun after fixing the notes template."
}

The result has occurrenceId, automationId, and occurrenceState, plus runId, status, and sessionId once a run exists, and echoes note (at most 500 characters). Read status as for coven.automations.run. If the launch is refused before a session starts, the result has no sessionId: the status is retry_scheduled when an automatic retry applies, an ordinary run is otherwise held for an operator retry (occurrenceState: "claimed", status: "running"), and any other refusal settles it failed. An unexpected dispatch error is returned in error and settles the occurrence failed. bypassEligibility is accepted but changes nothing in v1, which has no eligibility conditions.

The occurrence id derives from the adoptionKey, and the claim commits before the launch, so an exact replay returns the same occurrence and its run with reason: "replayed previously adopted run" and never launches a second time. Reusing the key for a different request returns ADOPTION_REPLAY_MISMATCH. The command is refused with NOT_FOUND, GONE_TOMBSTONED for a tombstoned routine, ILLEGAL_TRANSITION when the routine is not active or is quarantined, VALIDATION_FAILED when it has no cwd, and OVERLAP_FORBIDDEN (409) while it already has a nonterminal run.

Automatic retries cover only transient_dispatch, lease_expired, and runtime_unavailable failures with evidence that no process started. Each retry is a new attempt inside the same run and its original timeout. Backoff none retries immediately, fixed waits backoffSeconds, and exponential uses deterministic jitter capped at one day. When a routine exhausts maxAttempts, Coven quarantines the routine until you call coven.automations.unquarantine, and the run is held for an operator retry like any other failed ordinary run.

Operator retry

When an attempt of an ordinary run fails and no automatic retry follows, Coven holds the run running until its deadline instead of failing it. The failed attempt stays failed, the run has no live session, the occurrence stays claimed (failed before launch) or running (failed after start), and its failure reason ends with held for an operator retry until the run's deadline. If no retry is opened by the deadline, the run and occurrence settle failed with the reason no operator retry was opened before the run's deadline. Runtime Authority runs are not held.

To retry a held run, name its latest attempt and that attempt's disposition, so a retry never lands on an attempt you did not mean:

{
  "action": "coven.automations.attempt.retry.v1",
  "adoptionKey": "retry-daily-notes-0001",
  "runId": "RUN_ID",
  "priorAttemptNumber": 1,
  "priorDisposition": "failed",
  "note": "Fixed the missing template."
}

The retry opens the next attempt in the same run, classified operator_retry, and returns the occurrence to planned for the scheduler to dispatch. The result has runId, occurrenceId, attemptId, attemptNumber, priorDisposition, status: "planned", and retriedAt; note is optional and at most 500 characters. It is refused with:

  • RETRY_DISPOSITION_INVALID when the attempt number or disposition does not match the run's latest attempt;
  • AMBIGUOUS_RETRY_FORBIDDEN for ambiguous work, which only coven.automations.occurrence.recover.v1 resolves;
  • ILLEGAL_TRANSITION when the run is not held: it is settled, its latest attempt is still in flight, it has used all 10 attempts, or its routine is not active or is still quarantined (call coven.automations.unquarantine first);
  • CANCEL_PENDING while a cancellation or stop is unresolved;
  • DEADLINE_EXCEEDED once the run's deadline has passed;
  • AUTHORITY_REQUIRED for a Runtime Authority run.

An exact replay returns reason: "replayed previously adopted retry" and opens nothing new, and reusing the key for anything else returns ADOPTION_REPLAY_MISMATCH. To give up on a held run before its deadline, cancel its occurrence with coven.automations.occurrence.cancel.v1: the run and occurrence settle cancelled and the failed attempt stays failed. attempt.cancel.v1 refuses the held attempt, because it has already settled.

Cancellation and recovery

To cancel a run, send coven.automations.run.cancel.v1 with the run id, the current attempt id from the run's attempts, and its session id. Cancellation stays a request until Coven confirms the session stopped; read the run's cancellation record for its state.

To cancel by occurrence or attempt instead, without a session id, send coven.automations.occurrence.cancel.v1 with occurrenceId or coven.automations.attempt.cancel.v1 with attemptId, plus an adoptionKey and an optional reason of at most 500 characters (default "cancelled by the owner"):

  • Work that has not been dispatched, an occurrence still planned or claimed or an attempt still adopted and waiting for its retry, is cancelled at once. The occurrence settles cancelled, and so do a waiting attempt and its run, with no session to stop. The result has occurrenceId, status: "cancelled", reason, and cancelledAt, plus runId and attemptId when a waiting attempt was cancelled.
  • Work that is dispatching or running is handed to coven.automations.run.cancel.v1 under a key derived from yours, and the result is that run cancellation. It can answer CANCEL_PENDING (409) while the session's stop is unconfirmed; retry when retryable is true.

attempt.cancel.v1 accepts only the current attempt of a running run. Both commands refuse an occurrence in recovery_required (resolve it with coven.automations.occurrence.recover.v1), work that has already settled (except that occurrence.cancel.v1 releases a run held for an operator retry), and a waiting attempt whose run deadline has passed, with ILLEGAL_TRANSITION; that last case first settles the attempt timed_out. An exact replay returns reason: "replayed previously adopted cancellation" and changes nothing, and reusing the key for anything else returns ADOPTION_REPLAY_MISMATCH.

When Coven cannot settle an occurrence on its own, because a stop could not be confirmed or a launch was abandoned, the occurrence waits in recovery_required. Coven never retries ambiguous work by itself. List these with coven.automations.occurrence.list.v1 and view: "recovery_required", then resolve each one with coven.automations.occurrence.recover.v1 and one evidenceDetermination:

  • failed_deterministic settles the occurrence and its run failed. The result has status: "failed", and runId when there was a run.
  • retry_with_new_attempt opens the next attempt in the same run, recording the earlier attempt as ambiguous, and plans the occurrence for dispatch. The result has status: "planned", runId, attemptId, and attemptNumber. The latest attempt must be ambiguous, the run must have attempts left (at most 10) and an open deadline, and the routine must be active.
{
  "action": "coven.automations.occurrence.recover.v1",
  "adoptionKey": "recover-daily-notes-0001",
  "occurrenceId": "OCCURRENCE_ID",
  "evidenceDetermination": "failed_deterministic",
  "statement": "Checked the worktree; the run wrote nothing."
}

statement is optional, 1 to 1,000 characters, and is recorded with the determination. Both determinations are refused with ILLEGAL_TRANSITION while the latest attempt's session is still created or running; cancel it first, so a retry never runs beside it. A retry after the run's deadline returns DEADLINE_EXCEEDED; settle it failed_deterministic instead. A Runtime Authority run returns AUTHORITY_REQUIRED, because settling it needs authority-evidenced receipts. The adoptionKey works as it does for the versioned definition commands: an exact replay returns the first answer, with reason: "replayed previously adopted recovery" and no second change, and reusing the key for anything else returns ADOPTION_REPLAY_MISMATCH.

Health

Use coven.automations.health for the next due time, recent planning and run timestamps, consecutive failure count, live lease owner/expiry, the current retry attempt (currentAttempt, maxAttempts, retryNotBefore), quarantine state (quarantinedAt, quarantineFailureClass, quarantineReason, consecutiveExhaustions), and a staleness reason. nextDueAt is null while a routine is quarantined. Use coven.automations.runs, or coven.automations.run.history.v1 to page by cursor, for persisted run history rather than inferring completion from process output.

See Automations lifecycle for the contract's state machines and how the daemon's recorded states relate to them, Automations scheduling for how schedules, retries, and timeouts resolve, Automations conformance for what the contract is tested against and the exact revisions it depends on, Automations migration for importing Codex automations, Coven local API for transport and trust rules, and Safety for the broader authority model.

Was this page helpful?No

Last updated on

On this page