Skip to content

feat(automations): every-few-hours and before/after-meeting triggers - #6546

Open
benjaminshafii wants to merge 11 commits into
devfrom
feat/automation-calendar-trigger
Open

benjaminshafii wants to merge 11 commits into
devfrom
feat/automation-calendar-trigger

Conversation

@benjaminshafii

@benjaminshafii benjaminshafii commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

What is this about?

Automations can now run every few hours, or before or after each meeting on the owner's Google Calendar. This one PR holds both: interval commits first, then calendar triggers.

What problem does it solve?

"Every 3 hours" or "after each customer meeting, write up the action items" were impossible. People made eight daily Automations instead.

What was the situation before?

The Schedule menu offered Once, Daily and Weekly only, and agents were told there is no interval.

How is this implemented?

  • schedule gains interval (everyHours, daysOfWeek, startHour/endHour) and calendar (edge, offsetMinutes ±120, rule). Still one field per revision, so a revision always has exactly one trigger.
  • Pure: interval math in automation-schedule.ts. calendarTriggerOccurrences turns calendar events into occurrences with stable keys.
  • Den's CalendarTriggerSource reads readMemberGoogleCalendar at most every 5 minutes per owner and claims each occurrence once, using its key as the nonce. The run gets the meeting's time, invitee domains and link, but never anything the invite's sender wrote. Cloud only.
  • Released desktops parse schedules strictly, so Den omits kinds a desktop does not name in x-openwork-automation-schedule-kinds. The agent index lists them in moreAutomations.
  • Behind automationIntervalSchedules and automationCalendarTriggers (cloud and self-hosted, off). Turning one off keeps existing Automations. See docs/features/automation-*.

What else changed?

  • One shared formatAutomationSchedule replaces the duplicate labels in the app and Den web.
  • Schedule choices use the shared Select.

Release note

Automations can run every few hours, or before or after each meeting on your Google Calendar.

Evidence

evals/proofs/automation-schedule-triggers.proof.test.ts: before, the Schedule menu offers Once, Daily and Weekly. After, it also offers Every few hours and Around my meetings.

Design: P4, P5, C5

Every-few-hours Automation schedules ship behind their own flag, cloud and
self-hosted, default off. The internal doc says what changes, how older
desktops are kept safe and what turning it off does.

Signed-off-by: Benjamin Shafii <ben@prologe.io>
{ kind: "interval", timezone, everyHours 1-24, daysOfWeek, startHour,
endHour } runs every N hours on the hour, counted from the window start each
listed day. Parsing fills the days and window so stored schedules carry every
field. The resolver now walks each local day's wall times, so DST gaps that
shift one time onto the next count once.

Also adds the one shared schedule label (formatAutomationSchedule) and the
schedule-kinds capability header released desktops are narrowed by.

Signed-off-by: Benjamin Shafii <ben@prologe.io>
- schedule_kind gains 'interval' (migration 0160).
- Creating or changing to an interval needs automationIntervalSchedules;
  keeping an Automation's current interval does not, so editors that send
  the whole definition still save.
- While the feature is off the scheduler records each due occurrence as
  skipped and the schedule moves on; nothing is deleted.
- First-party desktops that do not name 'interval' in
  x-openwork-automation-schedule-kinds never receive interval Automations
  (list omits them, detail answers 404); Den web, agents and API clients see
  everything. The agent index carries them in moreAutomations with a summary.

Signed-off-by: Benjamin Shafii <ben@prologe.io>
- The editor and Calendar schedule fields offer Every few hours (every N
  hours, a from/until window and days) when the feature is on.
- The desktop names the schedule kinds it reads on every Automation request.
- One shared label replaces the duplicate formatters in the app and Den web;
  the Calendar describes intervals in words.
- The agent listing reads every schedule kind leniently and lists
  moreAutomations; automation.propose and the capability knowledge describe
  interval schedules.

Signed-off-by: Benjamin Shafii <ben@prologe.io>
Cloud Automations that run before or after each meeting on the owner's
Google Calendar ship behind their own flag, cloud and self-hosted, default
off. The internal doc says how Den reads calendars, what a run receives and
what turning it off does.

Signed-off-by: Benjamin Shafii <ben@prologe.io>
- schedule gains { kind: "calendar", timezone, edge, offsetMinutes ±120,
  rule: { withExternalAttendees, titleIncludes } }: one field per revision,
  no clock occurrences.
- calendarTriggerOccurrences (pure) turns projected Google Calendar events
  and a window into occurrences with a stable key per meeting edge; only
  timed, accepted, non-cancelled meetings with someone else invited count.
- projectGoogleCalendarEvents also reports accepted, the title and a safe
  Meet/Calendar link; the agent's wake prompt is unchanged.
- calendarTriggerPrompt frames the meeting as JSON data the invite's sender
  wrote; a title cannot close the frame.
- A claim nonce now identifies a scheduled occurrence on its own, so two
  meetings at one instant are two runs; existing keys are unchanged.
- runs may carry triggerContext (the meeting) for calendar runs.

Signed-off-by: Benjamin Shafii <ben@prologe.io>
…endar

- schedule_kind gains 'calendar'; runs gain an encrypted trigger_context
  (migration 0161).
- A calendar trigger needs automationCalendarTriggers and Cloud placement;
  keeping the current trigger through an edit does not need the feature.
- The scheduler's calendar source reads each owner's primary Google
  Calendar (readMemberGoogleCalendar) at most every 5 minutes, only for
  owners with an active calendar-triggered Automation and the feature, and
  claims each due occurrence with its stable key as the claim nonce. Moments
  older than 10 minutes, or from before the trigger was saved, never run.
- The run's prompt carries the meeting as framed JSON data after the
  person's instructions.
- An unconnected calendar puts the Automation in needs attention; a Google
  API error is retried on the next read.
- The tick's claim-and-dispatch is shared by clock and calendar occurrences.
- Schedule kinds describe themselves in the API schema for agents.

Signed-off-by: Benjamin Shafii <ben@prologe.io>
- The schedule fields offer Around my meetings (before a meeting starts or
  after it ends, and outside-attendees only) when automationCalendarTriggers
  is on; the editor saves it only for a cloud placement and says why.
- Proposals with a meeting trigger explain when the organization lacks the
  feature or the desktop cannot create Cloud placement.
- automation.propose and the capability knowledge describe calendar
  schedules, with the meeting reaching the run as data.
- The agent listing renders calendar entries; Workbot's Calendar describes
  them.
- The proof now covers both new schedule choices, and the feature docs show
  the editor.

Signed-off-by: Benjamin Shafii <ben@prologe.io>
The schedule menu and the new interval and meeting choices use the shared
Select instead of native selects (DESIGN.md P5), which also retires this
file's UI guardrail baseline entry. The proof picks options the way a
person does, and the feature docs show the updated editor.

Signed-off-by: Benjamin Shafii <ben@prologe.io>
@vercel

vercel Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
openwork-app Ready Ready Preview Oct 27, 2026 6:20am UTC
openwork-den Ready Ready Preview Oct 27, 2026 6:20am UTC
openwork-diagnostics Ready Ready Preview Oct 27, 2026 6:20am UTC
1 Skipped Deployment
Project Deployment Actions Updated
openwork-landing Ignored Ignored Preview Oct 27, 2026 6:20am UTC

Request Review

@github-actions

github-actions Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

OpenWork evidence

Status Commit Preview Updated
🟢 Ready · evidence passed 3ec30a7 Open preview 2026-10-27 06:28:02 UTC

Run details · Open the preview to inspect evidence and sandbox options.

@diff-warden

diff-warden Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Warden: approved

No high or medium security findings and no confidentiality findings.

Reviewed 3ec30a7d8ab7 · Warden run · Updates after every Warden run.

The packaged desktop loads the server's compiled output from app.asar, where
Node cannot strip types from @openwork/types' source-only schedule module.
The Automation listing renders Den's summary and keeps a small fallback for
the schedule kinds older Dens send, instead of importing the shared label.

Signed-off-by: Benjamin Shafii <ben@prologe.io>
…prompts

A meeting's title, description and invitee names are written by whoever
sent the invite, and a calendar-triggered run is unattended. The run's
prompt now carries only facts Google or the owner control (times, invitee
domains checked as hostnames, a Google link) and never points the agent at
the event to read it. The event id and title stay on the stored run for the
owner, and the title still serves titleIncludes rules.

Signed-off-by: Benjamin Shafii <ben@prologe.io>
@benjaminshafii
benjaminshafii force-pushed the feat/automation-calendar-trigger branch from df5ae13 to 3ec30a7 Compare October 27, 2026 06:18

@diff-warden diff-warden Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warden clearance. Complete security and confidentiality review of 3ec30a7d8ab74774e60a761f073331bea8b95fb3 found no high or medium security findings and no confidentiality findings. Any new push dismisses this approval. Analysis run

This branch was successfully deployed

5 active and 1 inactive (outdated) deployments
Evidence / PR 6546 — 3ec30a7d Deployed Oct 27, 2026 by github-actions[bot]
Preview – openwork-app — 3ec30a7d Deployed Oct 27, 2026 by vercel[bot]
Preview – openwork-den — 3ec30a7d Deployed Oct 27, 2026 by vercel[bot]
Preview – openwork-diagnostics — 3ec30a7d Deployed Oct 27, 2026 by vercel[bot]
Preview – openwork-landing — 9442a3c7 Deployed Oct 27, 2026 by vercel[bot]
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