Automation Manager
Automations have two representations that must stay in sync:
- YAML file in
.ona/automations/<name>.yaml— version-controlled source of truth. - Live registration in Ona — the runtime configuration that actually triggers executions.
Editing only the YAML does nothing. Registering only via CLI loses version history. Every change must update both.
Authentication
The environment principal cannot manage automations. Authenticate with the user PAT:
ona login --token "$ONA_PAT"
Restore the environment context when done:
ona config context use environment
Creating a new automation
Generate the example syntax for reference:
ona ai automation create --exampleCreate the YAML file at
.ona/automations/<name>.yaml. Follow the structure of existing automations in that directory. Required fields:name,description,triggers,action.limits,action.steps.Register it:
ona login --token "$ONA_PAT" ona ai automation create .ona/automations/<name>.yamlThe CLI prints the new automation ID.
Add the new entry to
references/registry.mdwith the YAML filename, name, and ID.Restore context:
ona config context use environmentCommit both the YAML file and the updated registry.
Updating an existing automation
Look up the automation ID in
references/registry.md.Edit the YAML file.
Push the update to Ona:
ona login --token "$ONA_PAT" ona ai automation update <automation-id> .ona/automations/<name>.yamlVerify the update took effect:
ona ai automation get <automation-id> -o json | jq '.[0].spec.triggers'Restore context:
ona config context use environmentCommit the YAML change.
Deleting an automation
Look up the automation ID in
references/registry.md.Delete from Ona:
ona login --token "$ONA_PAT" ona ai automation delete <automation-id>Delete the YAML file.
Remove the row from
references/registry.md.Restore context and commit.
Auditing drift
Compare YAML files against live registrations to find mismatches.
List live automations:
ona login --token "$ONA_PAT" ona ai automation list -o json | jq '[.[] | {id: .id, name: .metadata.name}]'List YAML files:
ls .ona/automations/*.yamlCheck for:
- YAML files with no matching live automation (unregistered).
- Live automations with no matching YAML file (untracked).
- Name mismatches between YAML
name:field and livemetadata.name.
For each unregistered YAML: run
ona ai automation create.For each untracked live automation: either create the YAML or delete the live registration.
Update
references/registry.mdwith any changes.
Trigger design rules
These rules prevent the race conditions that caused duplicate PRs (#45/#46, #40/#41):
- One trigger type per automation. Use either cron OR webhook, not both. The cron alone is sufficient — a 10-minute delay after a merge is acceptable.
maxParallel: 1on all automations. This is necessary but not sufficient (the platform has a TOCTOU window during environment startup).- Prompt-level guards are defense-in-depth, not primary protection. The prompt should check for existing work (open PRs, in-progress labels) but cannot guarantee mutual exclusion.
YAML structure reference
name: Human-readable name
description: One-line description of what the automation does.
triggers:
- context:
projects:
projectIds:
- 019d8bf4-1ded-7317-be2f-555e8fb55ff9
time:
cronExpression: "*/10 * * * *"
- context:
projects:
projectIds:
- 019d8bf4-1ded-7317-be2f-555e8fb55ff9
manual: {}
action:
limits:
maxParallel: 1
maxTotal: 50
steps:
- agent:
prompt: |
Your prompt here.
Trigger types (use only one per automation, plus manual):
time.cronExpression— cron schedulepullRequest.events— webhook events (avoid combining with cron)manual— always include for manual runs
Reference files
references/registry.md— Read when you need to look up an automation ID or check which automations are registered.