Skip to content

feat(schedules): B2 — scheduler dispatcher + worker#565

Merged
philmerrell merged 1 commit into
developfrom
feature/scheduled-runs-b2-engine
Jul 6, 2026
Merged

feat(schedules): B2 — scheduler dispatcher + worker#565
philmerrell merged 1 commit into
developfrom
feature/scheduled-runs-b2-engine

Conversation

@philmerrell

Copy link
Copy Markdown
Contributor

What

The scheduler engine (Phase B, F3): an EventBridge rate rule fires due schedules through the Phase A headless harness. Completes end-to-end scheduled runs behind the SCHEDULED_RUNS_ENABLED flag + scheduled-runs capability.

  • Dispatcher (backend/src/lambdas/scheduled_runs_dispatcher/): rate(5m) → sweeps the sparse DueScheduleIndex → per schedule: runaway guard (runs_today vs max_runs_per_day, UTC-rollover-aware) → conditional re-arm before invoking (a double-tick is idempotent) → async-invoke the worker (InvocationType=Event).
  • Worker (backend/src/lambdas/scheduled_runs_worker/): mints a per-owner Cognito bearer via CognitoRefreshBearerAuthrun_agent_headless(trigger="schedule") as the owner → records the outcome. Pauses cleanly (never retry-spams) on reauth_required (expired grant), oauth_required (connector needs consent), or repeated_failures.
  • CDK (scheduled-runs-construct.ts): two Docker Lambdas sharing one image via ImageConfig.Command, bootstrap-stub + out-of-band deploy mirroring KB-sync. EventBridge rule gated by config.scheduledRuns.enabled; IAM scoped to sessions-metadata RW + BFF-grant table RW + app-client secret read + AgentCore vault token/oauth-secret read. No InvokeAgentRuntime/SigV4 — the minted bearer is the front door (matches the Run-now path).

Delivery flows straight through — governance is role/auth-based (run-as-user, deliver-to-self), no content gate.

Orchestrator note (this was finished + reviewed on Opus)

The Sonnet build stalled before committing; I finished it and reviewed the code directly. The CDK/IAM is tightly scoped and correct as built. I fixed one real defect I found in review: the failure breaker used a last-run-status proxy that caps the streak at 2, so with the production default SCHEDULED_RUNS_MAX_FAILURES=3 the repeated_failures pause could never fire (the existing test only passed because it set the threshold to 2). Fixed with a persistent consecutive_failures counter (model + record_run_result, mirroring sync_policies), unified the worker's two error paths, and added regression tests at the default threshold.

Tests

  • Backend full suite: 4302 passed, 3 skipped (incl. 2 new breaker regression tests).
  • Infra: tsc --noEmit clean; jest 429 passed.
  • No new packages.

Part of #559.

🤖 Generated with Claude Code

EventBridge rate(5m) -> dispatcher (sweeps the sparse DueScheduleIndex,
runaway guard, conditional re-arm before fire-and-forget) -> worker (mints a
per-owner Cognito bearer, run_agent_headless(trigger="schedule"), records the
outcome, pauses on reauth_required / oauth_required / repeated_failures).
Two Docker Lambdas share one image (Dockerfile.scheduled-runs) via
ImageConfig.Command; bootstrap-stub + out-of-band image deploy mirroring
kb-sync. IAM scoped to sessions-metadata RW, BFF-grant table RW, app-client
secret read, and AgentCore vault token + oauth-secret read; no
SigV4/InvokeAgentRuntime (the minted bearer is the front door, matching the
Run-now path). Delivery flows straight through — governance is role/auth-based.

Fixes the failure breaker: added a persistent consecutive_failures counter
(model + record_run_result, mirroring sync_policies) so repeated_failures
pauses at the production default of 3. The original last-status proxy capped
the streak at 2 and could never trip at the default; unified the worker's two
error paths on the returned streak and added regression tests at the default
threshold.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@philmerrell philmerrell marked this pull request as ready for review July 6, 2026 03:21
@philmerrell philmerrell merged commit 02e6e02 into develop Jul 6, 2026
4 checks passed
@philmerrell philmerrell deleted the feature/scheduled-runs-b2-engine branch July 6, 2026 03:21
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