Durable Objects
Notewright’s stateful work runs in Cloudflare Durable Objects. Each one is an agent: it owns its own SQLite-backed state, registers its own cron schedule on start, and exposes a uniform status contract that the CLI reads.
The Durable Objects
Section titled “The Durable Objects”| Binding | Class | Contributed by | Role |
|---|---|---|---|
FOLLOW_UP_AGENT | FollowUpAgent | core | Runs the follow-up extraction pipeline; records runs, task mappings, and failures. |
SPEAKER_CONTEXT_AGENT | SpeakerContextAgent | core | Resolves and caches per-meeting speaker identities. |
GRANOLA_SYNC_AGENT | GranolaSyncAgent | Granola provider | Runs notes sync on a schedule and on demand. |
The two core bindings and their migrations (v2 for FollowUpAgent, v3 for
SpeakerContextAgent) are already declared in wrangler.jsonc. The Granola
provider contributes its own binding and the granola-v1 migration through its
runtime fragment.
Each agent is driven by its own cron schedule and on-demand HTTP routes;
SpeakerContextAgent has no cron and is invoked only by the pipeline:
flowchart LR
CRON[Cron schedules] --> GSA[GranolaSyncAgent]
CRON --> FUA[FollowUpAgent]
HTTP[On-demand HTTP<br/>/sync · /follow-ups/run · /follow-ups/backfill] --> GSA
HTTP --> FUA
FUA -.->|resolve speakers| SCA[SpeakerContextAgent]
GSA --> D1[(D1)]
FUA --> SINK[Follow-up sink]
class SINK external
Schedules register on first start
Section titled “Schedules register on first start”A Durable Object only registers its cron schedule the first time it starts. After
a fresh deploy, an agent has not started yet, so its schedule is not registered.
Run notewright start to wake every DO at once and see the schedules each
registered. (A /health call does not work here: /health is a core-owned
Worker route and never reaches the provider Durable Objects.)
- Granola sync registers the cron
0 0 * * 2-6(weekday evenings). - Follow-up extraction registers a backstop cron that re-scans recent meetings so nothing is missed between on-demand runs.
- Speaker context registers no cron; it is invoked on demand by the pipeline.
See Monitoring health for inspecting the registered
schedules with notewright schedules.
The status contract
Section titled “The status contract”Every Notewright agent extends a shared base class that exposes a plain,
Promise-returning status method. The Worker’s /status and /start routes
enumerate every DO binding and call that method, which is how the CLI reports
per-DO health and registered schedules. The base class is part of the public API,
so a third-party DO host that extends it participates in /status and /start
automatically. See Writing a provider.