Create a Ceremony
A ceremony is a scheduled skill invocation — a recurring fleet ritual defined in YAML, fired by a cron expression, and dispatched through the standard skill routing pipeline.
Ceremonies are distinct from GOAP actions. Actions react to world-state violations. Ceremonies run on a fixed schedule regardless of world state, like a daily standup or a weekly retrospective.
How ceremonies work
Section titled “How ceremonies work”SchedulerPluginfires acron.<id>bus event at the scheduled timeRouterPluginreceives it, identifies it as a ceremony, and publishesceremony.<id>.executeCeremonyPluginsubscribes toceremony.#.execute, loads the ceremony definition, and dispatchesagent.skill.requestwith the configured skill and targetsSkillDispatcherPluginroutes the request to the matching executor
The ceremony YAML is the only configuration required.
Ceremony YAML schema
Section titled “Ceremony YAML schema”Create a file in workspace/ceremonies/<id>.yaml:
# Must match the file name (without .yaml).id: daily-standup
# Human-readable name.name: "Daily Fleet Standup"
# Optional description — shown in /api/ceremonies.description: "Morning ceremony: board summary, active ceremonies, open PRs"
# Cron expression (UTC). Standard 5-field cron.schedule: "0 9 * * 1-5"
# Skill name to dispatch. Must be registered by an agent.skill: board_audit
# Agent names to route this skill to. If multiple, all receive it.# Leave empty to use default routing (skill-match or default executor).targets: - protomaker
# Discord channel ID for the response. Leave empty to suppress Discord posting.notifyChannel: "1469195643590541353"
# Set to false to disable without deleting the file.enabled: trueField reference
Section titled “Field reference”| Field | Required | Description |
|---|---|---|
id | Yes | Unique ceremony ID. Must match the filename (without .yaml). |
name | Yes | Human-readable name shown in the API and logs. |
description | No | Explains the purpose of the ceremony. |
schedule | Yes | 5-field cron expression (UTC). Examples below. |
skill | Yes | Skill name dispatched via agent.skill.request. |
targets | No | Agent names for explicit routing. Empty = default routing. |
notifyChannel | No | Discord channel ID for delivery. Empty = no Discord post. |
enabled | No | true (default) or false to suspend without deleting. |
Cron expression examples
Section titled “Cron expression examples”| Schedule | Expression |
|---|---|
| Weekdays at 9:00 UTC | 0 9 * * 1-5 |
| Every 30 minutes | */30 * * * * |
| Every 3 hours | 0 */3 * * * |
| Mondays at 9:00 UTC | 0 9 * * 1 |
| Daily at midnight | 0 0 * * * |
Triggering a ceremony manually
Section titled “Triggering a ceremony manually”Ceremonies can be triggered outside their schedule via the HTTP API:
curl -X POST http://localhost:3000/api/ceremonies/daily-standup/run \ -H "X-API-Key: $WORKSTACEAN_API_KEY"Or by publishing to the bus:
curl -X POST http://localhost:3000/publish \ -H "X-API-Key: $WORKSTACEAN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"topic": "ceremony.daily-standup.execute", "payload": {}}'Listing ceremonies
Section titled “Listing ceremonies”curl http://localhost:3000/api/ceremoniesResponse:
[ { "id": "daily-standup", "name": "Daily Fleet Standup", "schedule": "0 9 * * 1-5", "skill": "board_audit", "enabled": true, "nextRun": "2026-04-09T09:00:00.000Z" }]Example: security triage ceremony
Section titled “Example: security triage ceremony”This ceremony runs hourly and is also triggered by a GOAP action (see workspace/actions.yaml):
id: security-triagename: "Security Incident Triage"description: "Investigates open security incidents and reports resolution status."schedule: "0 * * * *"skill: bug_triagetargets: []notifyChannel: ""enabled: trueWhen ActionDispatcherPlugin fires the ceremony.security_triage GOAP action, it publishes ceremony.security-triage.execute, which triggers this ceremony immediately — using the same code path as the cron schedule.
Example: weekly retrospective
Section titled “Example: weekly retrospective”id: weekly-retroname: "Weekly Retrospective"schedule: "0 9 * * 1"skill: pattern_analysistargets: - protomakernotifyChannel: "1469195643590541355"enabled: trueThe protoMaker team receives the pattern_analysis skill request every Monday at 9:00 UTC and posts its output to the configured Discord channel.
Adding a ceremony
Section titled “Adding a ceremony”- Create the file
workspace/ceremonies/<id>.yamlwith the schema above - Restart the server (ceremonies are loaded at startup)
- Confirm it appears in
GET /api/ceremonies - Optionally trigger it manually to verify the skill routes correctly
Related
Section titled “Related”- Add an agent — register the agent that will run the ceremony’s skill
- Bus topics reference —
ceremony.<id>.execute,cron.<id> - Workspace files reference