Skip to content

feat(berdctl): expose automations as a gated automation noun - #63

Closed
NickTitle wants to merge 4 commits into
mainfrom
nesposito/berdctl-automations
Closed

feat(berdctl): expose automations as a gated automation noun#63
NickTitle wants to merge 4 commits into
mainfrom
nesposito/berdctl-automations

Conversation

@NickTitle

@NickTitle NickTitle commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

What

Adds a berdctl automation noun (registry group automations) with four verbs:

verb effect / visibility what it does
automation list read / none Summaries (id, title, schedule, status, pause state, last success), --query title filter
automation get read / none One automation's full detail, including instructions and latest-run wiring
automation create create / immediate Create a scheduled automation (generic summary tile type)
automation run update / discoverable Trigger one immediate run, off schedule
$ berdctl automation --help
Manage scheduled automations: list, get, create, run

Why

Agents running inside Berd can already manage sessions/projects/skills via berdctl, but automations were UI-only. This lets an agent set up and operate recurring jobs (for example a scheduled PR-review sweep) through the app instead of ad-hoc local cron/schedulers.

How it is gated

Follows the feedback precedent for gated distribution surfaces, since Automations depend on a backing service:

  • Renderer registry (the trust boundary) includes the group only when VITE_AUTOMATIONS === "1".
  • Every action also refuses at execute() via the automations profile capability (automations_disabled), mirroring how the Automations view is gated at runtime.
  • Contract artifacts: one variant per gate combination (public / feedback / automations / block), selected by matching cargo features (block-feedback, block-automations). The embedded CLI can never advertise a noun its renderer build filters out of TOOL_GROUPS, in any flag combination. Public artifacts are byte-identical to before.
  • Every berdctl build path maps VITE_AUTOMATIONSblock-automations: dev justfile, dev-e2e.sh, prepare-berdctl-sidecar.sh, Stage-Sidecar-Windows.ps1, and the macOS release build. Release-script tests pin each seam.

Scope decisions

  • No delete / pause verbs. Delete is destructive and outside the v1 no-auth model; pause/resume is not currently a first-class single mutation in the UI API surface (schedulePaused is read-only on the tile). Both stay in the UI for now.
  • create pins the generic summary tile type (4, same as the Automations builder); dashboard/Builderbot tile types are deliberately out of scope, matching the view's own filtering.
  • run resolves the automation first so a bad id reads as automation_not_found rather than a backend refresh failure.

Tests

  • Behavior tests for all four commands: capability refusal before any backend call, not-found with the fixing command named, backend rejections surfaced as stable command errors, run session id passthrough.
  • Schema-bounds coverage plus valid-args fixtures (strict-parse totality).
  • Rust: wire-mapping minimal invocations for the new verbs; top-level help asserts automation appears iff block-automations (independent of feedback).
  • just check green; cargo test -p berdctl green on all four feature combinations; clippy/fmt green; contracts regenerated byte-stable; release-script seam tests green (85).

Review

Builderbot local review loop: round 1 flagged variant coupling + a missed release-build gate (both fixed: per-combination artifacts, full build-path propagation); round 2 asked for seam test coverage (added); final round: 0 findings, "patch is correct."

🤖 Authored by Nick's AI agent; built against the berdctl-new-command SKILL and docs/berdctl-architecture.md.

Adds a berdctl `automation` noun (group `automations`) with four verbs:

  automation list    read-only summaries, --query title filter
  automation get     one automation's full detail incl. instructions
  automation create  create a scheduled automation (summary tile type)
  automation run     trigger one immediate run, off schedule

The group follows the feedback precedent for Block-only surfaces:

- Renderer registry gates it on VITE_AUTOMATIONS === "1" (trust boundary);
  every action also refuses at execute() via the automations profile
  capability (automations_disabled), matching how the Automations view
  is gated.
- The generated contract keeps two variants. The former feedback-only
  variant artifacts now carry BOTH gated groups (feedback + automations),
  and either VITE flag selects the block-feedback cargo feature for the
  sidecar; the renderer filter still controls what actually dispatches.
- New error codes: automations_disabled, automation_not_found,
  automation_create_failed, automation_run_failed.
- Commands go through the existing KGoose automations API
  (kgooseAutomations.ts) — list/get reuse the view's generic-tile
  filtering; create pins the generic summary tile type (4); run resolves
  the id first so bad ids read as automation_not_found.

Safety: list/get are read/none; create is create/immediate (visible in
the Automations view); run is update/discoverable (run + output appear
in the view). No delete/pause verbs — deletion is destructive and stays
in the UI per the no-auth safety model.

Tests: behavior tests for all four commands (capability refusal,
not-found, backend rejection, run session id), schema-bounds coverage,
valid-args fixtures, wire-mapping minimal invocations, and a top-level
help variant assertion that automation appears iff block-feedback.

Co-authored-by: Goose <opensource@block.xyz>
@NickTitle
NickTitle requested a review from a team August 17, 2026 14:48
NickTitle and others added 3 commits August 17, 2026 10:58
Addresses both review findings:

1. One contract variant per gate combination (public / feedback /
   automations / block) instead of overloading the feedback variant
   with both gated groups. A feedback-only or automations-only build's
   CLI can no longer advertise a noun its renderer registry filters
   out of TOOL_GROUPS.

2. The macOS release build now passes VITE_AUTOMATIONS through to
   prepare-berdctl-sidecar.sh, so an automations-enabled custom
   release bundles a berdctl that actually carries the automation
   noun. The sidecar script and dev justfile map each flag to its own
   cargo feature (block-feedback / block-automations); the release
   test pin is updated to match.

cargo test -p berdctl passes on all four feature combinations, and the
top-level help variant assertion now tracks block-automations
independently of block-feedback.

Co-authored-by: Goose <opensource@block.xyz>
…paths

The e2e dev script and the Windows sidecar stage built berdctl with only
the feedback mapping, so an automations-enabled build on those paths
would bundle a CLI without the automation noun. Both now map
VITE_AUTOMATIONS to block-automations exactly like the dev justfile,
sidecar script, and macOS release path.

Co-authored-by: Goose <opensource@block.xyz>
Covers the two drift-prone seams the review named: the dev
justfile/dev-e2e standalone-CLI feature mapping now asserts the
block-automations line alongside block-feedback, and a new Windows
staging seam test pins the direct $cargoArgs feature propagation in
Stage-Sidecar-Windows.ps1 for both gated families.

Co-authored-by: Goose <opensource@block.xyz>
@NickTitle

Copy link
Copy Markdown
Contributor Author

Closing — the workflow this was built for ended up not needing a CLI surface for automations. The branch is complete and green (all four feature-gate variants tested) if anyone wants to pick it up later.

@NickTitle NickTitle closed this Aug 17, 2026
@NickTitle
NickTitle deleted the nesposito/berdctl-automations branch August 17, 2026 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant