Skip to content

apiary-routines

Scheduled routines for Apiary, as an out-of-process source plugin.

A routine is work that starts from a clock instead of a ticket: a nightly dependency audit, a weekly backlog sweep, an hourly flaky-test check. This plugin turns each due cron occurrence into an Apiary work item. From there nothing is special — Apiary binds the item to an internal task and the router matches it against workflow triggers exactly as it does a GitHub issue.

There are no changes to Apiary itself. A routine is just a work item that happens to be born from a schedule.

cron occurrence ──► plugin ──► work item ──► trigger ──► workflow ──► agent

Install

Build it and drop it into one of your hive's plugin_dirs:

make install DIR=/path/to/your/project/.apiary/plugins

That places the executable and its manifest in <DIR>/dev.apiary.routines/. Optionally pin the binary's checksum so Apiary detects a swap-out:

make checksum DIR=/path/to/your/project/.apiary/plugins

Then verify Apiary sees it:

apiary plugins list
apiary validate

Configure

plugins:
  - id: dev.apiary.routines
    config:
      state_file: /abs/path/to/.apiary/routines-state.json
      timezone: America/Sao_Paulo
      routines:
        - id: nightly-dep-audit
          schedule: "0 3 * * *"
          title: "Nightly dependency audit"

sources:
  - id: routines
    type: plugin
    poll_interval: 60s
    config: {plugin: dev.apiary.routines}

workflows:
  - id: dependency-audit
    trigger:
      once: true
      match: {source: routines, labels: ["routine:nightly-dep-audit"]}
    steps:
      - id: audit
        agent: engineer
        prompt: Audit dependencies for known vulnerabilities.

A full example is in examples/apiary.yaml; every option is documented in docs/configuration.md.

Four things to know

Pair every routine workflow with trigger.once: true. The plugin never re-emits an occurrence it has recorded, but once is the second lock. Apiary's pre-dispatch guards do not stop a completed workflow from running again if its item reappears, so a restored state file would otherwise re-run the job.

state_file must be absolute. A plugin runs with its own install directory as the working directory, not the project root.

Name the repository path in the routine's prompt. Apiary starts every agent in / and a routine carries no checkout, so an agent that is not told where the code lives will search for it — see docs/limits.md.

Routine items are read-only, so pin source: in the trigger. Plugin sources implement none of the write capabilities: a routine workflow cannot set states, add labels, wait for CI, or use a source-signalled approval. Apiary rejects those at apiary validate — but only when the trigger pins match.source. Leave it out in a hive that also runs GitHub and the same workflow validates clean, then silently no-ops at runtime. A routine that needs to produce a ticket does it from inside the workflow, with APIARY_SPAWN and a materialize: sub_issue step. (An operator-gate approval — a message, no approvers — is fine.) See docs/limits.md.

Documentation

Development

make check     # vet + test + build

License

BSD 3-Clause — see LICENSE. Commercial use is covered in COMMERCIAL.md.