Skip to content

Runtime-level triggered schedules (demand-driven cron) #133

@c-h-

Description

@c-h-

Summary

Add a first-class on_demand scheduling mode to the OrgLoop runtime, where schedules fire based on activity from other sources rather than fixed cron intervals.

Motivation

Fixed cron schedules (e.g., patrol every 30 min) are wasteful overnight when nothing is happening, and potentially too infrequent during heavy activity. Since OrgLoop already receives all the events that would trigger a need for patrol, the runtime should support demand-driven scheduling natively.

Proposed Design

New schedule config in the cron connector (or a new scheduler primitive):

sources:
  - id: patrol-trigger
    connector: "@orgloop/connector-cron"
    config:
      schedules:
        - name: patrol
          trigger_on:
            sources: [github, linear]  # Listen for events from these sources
          delay: 30m      # Fire this long after the last demand signal
          throttle: 30m   # Never fire more frequently than this

Behavior:

  1. When any event arrives from a listed source, the scheduler records a demand signal timestamp
  2. After delay has elapsed since the last demand signal AND at least throttle has passed since the last fire, emit the scheduled event
  3. If no demand signals arrive (e.g., overnight), no events are emitted — the schedule is dormant
  4. When activity resumes (e.g., morning), the first event triggers the delay countdown

Implementation Notes

This requires the scheduler/runtime to observe events from other sources, which is a cross-cutting concern. Two possible approaches:

A) Connector-level (dual actor+source): A new connector that registers as both source and actor. Activity routes deliver to the actor side (recording demand), and the source side polls for trigger conditions. Works with existing primitives but requires extra route wiring.

B) Runtime-level (preferred): The runtime natively supports trigger_on in schedule config. The scheduler subscribes to the event bus and tracks demand signals internally. Cleaner config, no extra routes needed.

Option B is preferred as the long-term solution since it keeps the config declarative and avoids routing boilerplate.

Context

Discussion originated from patrol SOP optimization — currently running every 30 min via */30 * * * * cron, which is wasteful overnight. Interim fix: reduced to every 3 hours. This feature would enable the ideal behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions