How to add a scheduled Buffaly process
Use a scheduled process when Buffaly should run trusted work on a clock or when an external scheduler should trigger a stored Buffaly process row.
Safety first: keep scheduled work narrow, auditable, disabled until verified, and tied to a specific session/prompt context.
1. Choose the trigger model and execution category
Use an internal interval process when Buffaly should own the clock. Use an external scheduled task when Windows Task Scheduler or cron should own the clock. External schedulers trigger a stored Processes row through Buffaly; they should not call lower-level ProtoScript endpoints directly.
Set Processes.Action to a broad category such as IntervalSystemProcess or ExternalScheduledTask, not to a concrete switch key.
2. Choose or create a handler
Prefer a generic handler when possible. For prompt-driven scheduled work, use a handler shape such as Buffaly.Agent.ScheduledProcesses.PromptScheduledTaskHandler. Only create new C# when deterministic work is genuinely needed before the agent is called.
If new code is needed, implement IScheduledProcessHandler and let the trusted resolver find it through DI or assembly scanning. Do not add one-off central switch statements.
3. Define the process row
ProcessName: Daily Email Summary
Action: ExternalScheduledTask
RunEvery: NULL
MaximumRunTime: 10
IsEnabled: trueUse RunEvery = NULL for external prompt-driven tasks so the internal interval loop does not run them automatically.
4. Define lightweight RunData
{
"TriggerMode": "External",
"HandlerType": "PromptScheduledTaskHandler",
"SessionKey": "Scheduled-EmailSummary",
"CreateChildSession": true,
"PromptContext": "EmailSummaryHandler",
"Instruction": "Check and summarize emails for the last day."
}PromptContext is the context prompt name. Instruction is the run-specific request. CreateChildSession is the reuse-vs-child-session decision.
5. Add the prompt context
Create or register the context prompt used by PromptContext. Keep it specific to the scheduled job and include safety, evidence, output, and escalation expectations.
6. Add external trigger support when needed
An external trigger should resolve exactly one enabled process row, validate the trigger key, verify Action = ExternalScheduledTask and TriggerMode = External, reject already-running non-timed-out rows, call the process runner, and return status plus session metadata.
Verify
- The process row resolves to one enabled process.
- The handler type is trusted and loadable.
- Invalid trigger keys and already-running rows are rejected.
- A test run creates expected session metadata and durable evidence.