Skip to content

Automations are Harbor's: the record, the pages, starting one and the tick (0.22.0) - #27

Merged
adamfortuna merged 1 commit into
mainfrom
automations
Nov 14, 2026
Merged

adamfortuna merged 1 commit into
mainfrom
automations

Conversation

@adamfortuna

Copy link
Copy Markdown
Contributor

Step 6a of moving the Factory's sections into Harbor: Automations and the tick. Version 0.22.0.

What a site with no code of its own gets

  • The Automations pages at /factory/automations: the list, the form that makes and edits an automation, the switch, "Run now" and Delete.
  • Agent automations: an agent with instructions or a slash command, started by a schedule or by hand. When one fires it becomes a queued run and Harbor::Automations::AgentRunJob runs it as an agent session of its agent. While the agent or every runtime is full, or no model is available, the run waits and the job looks again.
  • The tick: Harbor::Automations::TickJob, the one entry a site gives its scheduler, every minute. Harbor requires no scheduler in particular; the README shows sidekiq-scheduler, Solid Queue and a plain call.

What Harbor owns now

  • Harbor::Automation on the automations table. The migration creates the table only when it is missing, and adds the index and foreign key on runs.automation_id only when they are missing, so it changes nothing in a host that already has them.
  • The schedule: cron parsing with fugit, next_run_at, due_at, the trigger in words, and the marker that makes a schedule count from when it was set.
  • Harbor::Automations::Dispatch: starts an automation however it was triggered, as a tracked run or a stated reason not to.
  • Harbor::Automations::Tick: starts each due automation exactly once (a compare-and-set on last_scheduled_at), once for the latest time missed after an outage, and hands a due time back when the start raises.
  • Job automations (kind: "job", with job_dispatch loader, skill or self). They are made in code. The page never saves job_class, job_dispatch, job_input or kind, so a name typed in a browser is never turned into a constant.

What a host declares, configures and adds

  • Harbor::Automations.category, .working_folder, .identity, .label and .trigger (a trigger kind the host fires itself).
  • config.automation_class, config.automation_params, config.automation_edited and config.automation_agent_run (for a host that runs agent automations its own way).
  • Partials in the host's app/views/harbor/automations/: _name_extras, _agent_fields, _trigger_fields and _hint.
  • A new setting, "Where slash commands are read from" (automation_command_ref, origin/main by default).

Tests

test/automations_test.rb (the record, the declarations, starting one, the session job, the tick) and test/automations_pages_test.rb (the pages, with and without a host's additions). They include a site with no host code making an automation on the page, the tick starting a due one exactly once, and a disabled or not-due one being left alone. The dummy app's placeholder page for "a page still in the host" is Workflows now, since Automations is Harbor's.

669 runs, 0 failures; rubocop clean.

Upgrading

See "Upgrading from 0.21" in the CHANGELOG. The one thing every site does is schedule the tick.

… tick

Harbor::Automation is the record, on the automations table (the migration
creates it when it is missing, and adds the index and foreign key on
runs.automation_id). Harbor::AutomationsController serves
/factory/automations: the list, the form that makes and edits one, the
switch, "Run now" and Delete. The menu's Automations entry is the engine's
own route.

Harbor::Automations::Dispatch starts one however it was triggered, always as
a tracked run or a stated reason not to. Harbor::Automations::Tick starts
every scheduled automation that came due, exactly once: a compare-and-set on
last_scheduled_at, once for the latest time missed after an outage, and a
start that raises is handed back for the next tick.
Harbor::Automations::TickJob is the one entry a site gives its scheduler;
Harbor requires none in particular.

A site with no code of its own makes an agent automation on the page, its
schedule fires it, and Harbor::Automations::AgentRunJob runs it as an agent
session of its agent, waiting while the agent or every runtime is full. A
slash command is read from the ref in the new automation_command_ref
setting.

A job automation enqueues one of the site's own job classes (loader, skill
or self). They are made in code: the page never saves job_class,
job_dispatch, job_input or kind.

A host declares categories, working folders, identities, field labels and
trigger kinds of its own (Harbor::Automations), names its subclass
(automation_class), says which of its attributes the form saves
(automation_params), reads the rest of the form (automation_edited), and
may run agent automations its own way (automation_agent_run). It adds to the
pages with partials in its own app/views/harbor/automations/: _name_extras,
_agent_fields, _trigger_fields and _hint.

fugit is a dependency. 0.22.0.
@adamfortuna
adamfortuna merged commit 341eefd into main Nov 14, 2026
2 checks passed
@adamfortuna
adamfortuna deleted the automations branch November 14, 2026 23:18
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