Manifest (meta)

Every workflow exports a meta literal. Boardwalk derives the workflow's manifest from it at deploy time without executing your code, so meta must be a pure literal: no computed values, no inlined imports. The schema is strict: an unknown field is a validation error (boardwalk check catches it before deploy), so it can never silently drift.

export const meta = {
  slug: "morning-digest",
  title: "Morning Digest",
  description: "Summarize open issues every weekday at 9am.",
  triggers: [{ kind: "cron", expr: "0 9 * * 1-5", timezone: "America/New_York" }],
  permissions: { secrets: [{ name: "GITHUB_TOKEN" }] },
  budget: { max_usd: 1 },
};

Fields

FieldRequiredWhat it declares
slugyesThe workflow's identity: lowercase letters, digits, and hyphens, stable across versions.
titlenoA human-readable display label for the dashboard.
descriptionnoOne line for the dashboard and your teammates.
triggersyesAt least one trigger: manual, cron, or webhook. See Triggers.
envnoEnvironment variables for the run. Values are plaintext or a whole-value secret reference, ${{ secrets.NAME }}.
input_schemanoJSON Schema validating the trigger payload.
output_schemanoJSON Schema validating the value passed to output().
workspaceno{ persist: true }(or a list of directories) keeps the run's working directory between runs; omitted, it's scratch.
budgetnoCaps that fail the run when breached (never silent truncation). See below.
concurrencynoHow many runs of this workflow may run at once. Default: unlimited. See below.
runs_onnoThe machine. Default boardwalk/linux. See Runners.
notificationsnoEmail or webhook on completion, failure, cancelled, or budget_exceeded.
permissionsnoWhat a run may do: its API token scope, OIDC, artifacts, and the secret allowlist. See below.
callable_bynoWho may invoke this workflow (e.g. other workflows in the org). Default: anyone in the org.
egressnoOutbound network policy on hosted runners: none, trusted, full, or a custom host allowlist.
containernoA custom OCI image to run the workflow's tools inside (hosted).

runs_on

Almost every workflow uses the default, boardwalk/linux: a Linux machine with Node, Python, git, and common CLIs preinstalled. For more CPU and memory, ask for a larger machine:

runs_on: "boardwalk/linux-large",
// or, equivalently, with an explicit size:
runs_on: { label: "boardwalk/linux", size: "large" },

budget

Any cap that's exceeded ends the run with a budget error. All three are optional:

budget: {
  max_usd: 5,                  // stop if the run's inference cost passes $5
  max_tokens: 2_000_000,       // ...or this many tokens
  max_duration_seconds: 3600,  // ...or this long
},

concurrency

By default runs overlap freely. Serialize them when a workflow mutates shared state, either globally or per key (so one user, repo, or tenant runs one at a time):

concurrency: { mode: "serial" },
// or keyed:
concurrency: { mode: "serial_by_key", key: "repo" },

permissions

A run executes with a least-privilege token. permissions raises or lowers what it can do, modeled on GitHub Actions:

permissions: {
  contents: "read",          // the run's API token: "read" (default), "write", or "none"
  artifacts: "write",        // read/write/none for run artifacts
  id_token: "write",         // mint an OIDC token (for cloud federation)
  secrets: [{ name: "GITHUB_TOKEN" }],  // allowlist of names the program may secrets.get()
},

permissions.secrets is the allowlist of secret names the program may secrets.get(): see Secrets. The injected token is always ceilinged below admin, so a workflow can never escalate past member-level access to your org.