Daily Workflow with Approval
Status: Preview
CRON scheduling requires a full Supabase instance and Supabase pg_cron configured for workflow dispatch. See Known Preview Surfaces.
This tutorial sets up a workflow that runs every morning at 08:00 but waits for your explicit approval before executing. Nothing runs unattended. You remain in control of every invocation.
This is the recommended starting point for anyone new to LenserFight automation.
Prerequisites:
- A workflow already created and tested manually (see Create a Workflow)
- An agent assigned to that workflow (see Create Your First Agent)
- CRON scheduling enabled (see CRON Scheduling)
Step 1 — Create the schedule with approval required
lf schedule create \
--workflow <workflow-id> \
--cron "0 8 * * *" \
--timezone Europe/Istanbul \
--require-approvalThis creates a row in lenses.workflow_schedules with:
{
"approval_policy": { "requiresApproval": true },
"cron_expr": "0 8 * * *",
"timezone": "Europe/Istanbul",
"is_active": true
}Confirm it was created:
lf schedule listExpected output:
ID WORKFLOW CRON TIMEZONE APPROVAL ACTIVE
<uuid> My Daily Summary 0 8 * * * Europe/Istanbul required yesStep 2 — Wait for the first dispatch
At 08:00 Istanbul time, pg_cron fires fn_dispatch_scheduled_workflows_with_approval(). Because requiresApproval is true, the dispatch creates a team_run with approval_status='pending' and stops. The workflow does not run yet.
You will see the pending run in the Approvals tab of your agent workspace, or via CLI:
lf approval listExpected output:
ID AGENT WORKFLOW CREATED AT
<uuid> my-agent My Daily Summary 2026-05-09 08:00:01 UTCStep 3 — Review and approve
Inspect what the run would do:
lf approval inspect <approval-id>This shows the workflow graph, the resolved inputs, and the assigned agent.
Approve when ready:
lf approval decide <approval-id> approveThe run is immediately claimed by the execution engine. Track it:
lf run inspect <run-id>Expected output:
STATUS STARTED AT COMPLETED AT
completed 2026-05-09 08:00:45 UTC 2026-05-09 08:01:12 UTCStep 4 — Reject or modify inputs (optional)
Reject if the run should not proceed:
lf approval decide <approval-id> reject --reason "Holiday — skip today"The team_run moves to status='failed' with the rejection reason recorded in metadata.decision_reason.
Modify inputs and approve to adjust what the workflow receives before it runs:
lf approval decide <approval-id> approve \
--modifications '{"inputs": {"topic": "revised topic for today"}}'The run executes with the overridden inputs instead of the original schedule inputs.
Step 5 — Pause and resume
If you want to suspend the schedule temporarily:
lf schedule pause <schedule-id>Resume later:
lf schedule resume <schedule-id>Paused schedules set is_active=false. The dispatch function skips them and records last_dispatch_status='paused'.
What this setup guarantees
- The workflow never runs unattended. Every dispatch requires a human decision.
- CRON cannot bypass the approval gate. This is a non-negotiable platform invariant.
- If you miss the approval window, the run stays
pendinguntil you decide. It does not auto-expire or auto-run. - You can delete the schedule at any time:
lf schedule delete <schedule-id>
Next steps
- Agent Team + Gated Tool Schedule — add a write-class tool with its own approval gate
- Audit Trail Examples — inspect the approval decision audit record
- Scheduling Reference — full policy bundle documentation