WaitFor
A platform for turning asynchronous, unreliable external signals into correlated, validated results with a single accepted resolution. An application declares the external result it needs; WaitFor correlates each arriving signal with the expectation waiting for it, extracts and validates structured data, accepts one resolution, and returns it through a synchronous API. Built on Cloudflare Workers with a per-channel Durable Object state machine. Email over AWS SES is the first transport, not the product.
Problem
Agents and automated workflows routinely block on an external result — a one-time code, a confirmation link, a reply — that arrives asynchronously, out of order, duplicated, or not at all. Ad-hoc solutions poll mailboxes, race between sending a request and registering a listener, and re-process the same message twice, with nothing that authoritatively decides what the awaited result actually was.
Solution
Designed and implemented an expectation-resolution model around three primitives — `wait`, `ask`, and `deadline` — on a per-channel Durable Object state machine. `ask` registers the `wait` before transmitting, so a reply cannot beat its own listener; a backlog scan makes registration order irrelevant; and serialized resolution with layered message-identity deduplication yields a single accepted result per expectation.
Role
Founder, system architect, and lead engineer
Technologies
Impact
- Designed and implemented an expectation-resolution API around three primitives — `wait`, `ask`, and `deadline` — letting an application declare the external result it needs and receive it as a validated value
- Eliminated the reply-before-registration race by having `ask` register the `wait` before the outbound request is transmitted, so a response can never arrive before anything is listening for it
- Made signal arrival order irrelevant by resolving new registrations against a scanned backlog, so a matching signal that arrived before the `wait` existed still resolves it
- Enforced a single accepted resolution per expectation through per-channel Durable Object serialization, with layered message-identity deduplication using Message-ID where present and a content hash where it is absent
- Designed versioned SQLite schemas with foreign-key constraints, cascading deletes, query-path indexes, and partial unique indexes that constrain only the rows where an optional key is present, plus an atomic per-channel UID allocator that claims each value with `UPDATE ... RETURNING` rather than `SELECT MAX + 1`, so concurrent assignment cannot race
- Built deterministic extractors for one-time codes, links, patterns, and metadata, with typed schema-constrained extraction that cascades organization, project, and channel schemas
- Added a model-assisted extraction fallback that runs off the request hot path and is non-fatal by design, re-matching pending expectations when it completes so extraction latency never blocks ingestion
- Built a correctness harness running the real Worker and Durable Object inside workerd — 260 unit and 90 integration tests green at the release candidate — covering resolution races, deduplication in both directions, timeout outcomes, abandoned long-poll reconnect, and tenant isolation
- Cut WaitFor over to Stemwall — a self-authored shared identity and tenancy platform — as its second consumer, chosen because its identity model had been designed independently, so the abstraction was tested by divergence rather than confirmed by similarity
- Validated a clean separation between immutable evidence storage and application semantics as the second consumer of a shared Record Store, which owns exact inbound bytes, content identity, and atomic publication while WaitFor retains correlation, extraction, and resolution semantics
- Closed an unauthenticated internal control-plane surface before launch, replacing a Durable Object proxy and six internal routes with least-privilege named RPC entrypoints, verified by 68 production probes and route-enumeration regression tests
- Designed and implemented WaitFor's platform surface: a TypeScript SDK, an OpenAPI-described HTTP API, usage metering, an append-only audit log, and hibernation-safe WebSocket streaming with event replay