Skip to content

[Automation] Scheduled rules can run more than once on the same day #96

Description

@Jackkp0t

Summary

The automation scheduler's once-per-day guard is in-memory only and is set after the complete automation finishes. This permits duplicate execution both after an app restart and when an execution lasts longer than the one-minute scheduler interval.

Evidence

  • tickAutomations() runs every 60 seconds in apps/electron/src/main/kernelHost.ts.
  • runDue() returns an enabled scheduled rule for the entire remainder of its scheduled day once its scheduled time has passed.
  • The only dedupe state is lastAutomationRunByRule: Map<string, string>; it is constructed empty when AgentKernelHost is created.
  • The map is updated only after both executeAutomation(rule) and automationRuns.record(run) resolve. No persisted AutomationRun is consulted before starting a job, and there is no in-flight lock.

Reproduction

Restart path

  1. Enable a daily automation and let it finish after its scheduled time.
  2. Restart Folio before local midnight.
  3. Wait for the next scheduler tick (up to 60 seconds).

The new host has an empty map, while runDue() still considers the rule due. The same daily automation runs again, even though its earlier run is present in automation-runs.json.

Overlap path

  1. Enable a scheduled automation whose execution takes longer than 60 seconds (a material-change path can start research).
  2. Let the first scheduled tick enter executeAutomation().
  3. Before it resolves, let the next interval tick fire.

Because the map is not populated until the first run completes, both ticks pass the guard and can execute the same rule concurrently. This can duplicate research, notifications, and provider calls.

Expected

At most one scheduled run per rule and scheduled occurrence, across restarts and overlapping ticks. Failed-run retry behavior should be explicit and bounded rather than an accidental one-minute re-run.

Suggested direction

Persist a per-occurrence state/claim before executing (or atomically derive it from persisted run records), recover it at startup, and add an in-flight per-rule guard. Add tests covering:

  • successful execution followed by a same-day host recreation;
  • an execution held past the next tick;
  • a failure/retry policy that does not create duplicates.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

claimedClaimed by a contributor and currently in progress

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions