$ sudo science
~/projects/webpoke

Webpoke

prototype

aka “Restoring Truth and Sanity to Webhooks

# a poke with a hint, then a ranged pull

Webhooks should not deliver truth in flight. A signed, content-free poke plus a cursor-owned ranged pull turns every delivery failure into latency instead of corruption.

The doctrine is named for the 2025 executive order that promised to restore truth and sanity to history; this one settles for event delivery. Truth lives in a pullable ledger; sanity is a cursor you own.

webpoke.sudoscience.dev

problem

Payload-bearing webhooks make delivery the correctness mechanism, which means providers owe signatures, ordering, retry queues, idempotency, dead-letter handling, and replay consoles — then disclaim it all with "don't rely on webhooks," transferring the reconciliation engineering to every consumer independently.

thesis

Move the contract from delivery to cursor. The provider keeps an append-only ledger and sends best-effort pokes; the consumer owns one durable checkpoint and reads ranges from it. Monotone facts can be lost, duplicated, or reordered harmlessly — so the channel gets to be cheap and the data gets to be correct.

the contract

four parts, none clever

signed content-free poke

"Something changed for this stream, frontier ≥ X." Nothing in it is load-bearing; every poke subsumes all earlier ones.

GET /changes?since=<cursor>

Ordered, bounded pages over an append-only ledger, with opaque cursors and a stated replay window.

heartbeat floor

Consumers poll anyway every N minutes. A consumer that missed every poke self-heals; nobody operates a replay console.

consumer-owned checkpoint

One durable row. At-least-once, duplication, reordering, and gap recovery all collapse into "read from my checkpoint."

vendor-shipped consumer

the integration is code the vendor writes

Every provider ships the stateless client — the easy 20% — and abandons consumers at the part that breaks in production. Webpoke inverts it: the vendor ships the stateful half, as deployable infrastructure, and the consumer writes one function.

reference stacks

Terraform / CDK / CloudFormation modules per cloud: poke receiver → cursor row → ranged-pull worker → fan-out → DLQ. ~200 lines of IaC, three flavors (AWS, GCP, plain Postgres-in-a-container).

the handler stub

The consumer's entire obligation is handle(events): everything around it — checkpointing, ordering, retries, fan-out by stream or type — arrives already provisioned and already correct.

day-2 included

Replay is "rewind the cursor." Shadow-running a new consumer version is "same stream, second checkpoint, diff the outputs." These ship as runbook commands, not aspirations.

one design, internal and external

The module the vendor hands partners is the same converger pattern it runs internally. Integration stops being a spec PDF and becomes "deploy this, write your function."

agent-operated onboarding

authorize an integration agent on rails that already exist

The last mile — wiring the vendor's consumer runtime into your stack — is itself delegable. Not by inventing a new trust ceremony, but by granting a vendor integration agent exactly the permissions that existing consent mechanisms already know how to scope, display, and revoke.

one-click provision

An AWS CloudFormation quick-create link (or Marketplace listing, or Terraform Cloud run) stands up the poke receiver, cursor table, and pull worker under a stack-scoped IAM role. The consent screen is the cloud's own — reviewed, logged, revocable.

scoped agent grant

The integration agent assumes only the role the stack created: this queue, this table, this log group. Cloud-side permissioning already solved least-privilege delegation; the agent just rides it.

code integration as a PR

Granted a GitHub App installation with the standard permission prompt, the agent wires the handler stub into your codebase following your conventions and opens a pull request — review remains yours.

verification before cutover

The agent replays a sample range from cursor zero through your handler in shadow mode and attaches the output diff to the PR as evidence. The cursor makes the rehearsal free.

revocation is boring

Delete the stack, uninstall the app, rotate the grant. Because the consumer owns the checkpoint, tearing the agent out never threatens the data.

dividends

offset pull is multi-consumer by construction

permissionless consumers

A new consumer is a reader with credentials and a cursor at zero. Producer cost is O(1) in consumer count — immutable history is the most cacheable workload there is.

consumer isolation

A slow consumer is just behind. No provider retry queues backing up, no "we deregistered your endpoint for failing too often."

history through the same channel

Bootstrap by starting at zero — same channel, same code path, no backfill API, no seam.

replay as an operation

Rewind, re-read, shadow-run, diff. There is no webhook-shaped version of blue-green consumption.

field card: the ledger is already a product

Filed by Rhett's ethos agent (by hand, for now): s2.dev — "the API for unlimited, durable, real-time streams." Durable, ordered, append-only streams readable from any retained point by sequence number or timestamp, with tailing, fencing tokens, and a self-hostable lite build. Relation: credible_actor, implementation_reference; impact: supports — the changes endpoint can be a thin shim over a stream store, and the lab has receipts: desh's stream-in/stream-out POC already replays through S2.

the rubric

when the hybrid is wrong

no versioned store to pull from?

Push — durable and acked for imperatives (a lost command is lost intent), fire-and-forget for samples nobody re-reads.

not reducible to a monotone fact?

Then the lattice tricks don't apply; you need delivery semantics and should pay for them knowingly.

floor latency intolerable?

Still build poke + pull — then harden only the poke channel, the half whose failures can't corrupt anything.

artifacts

status, honestly

doctrinelive

webpoke.sudoscience.dev

changes-endpoint RFCsketch

opaque cursors, bounded pages, replay window, signed poke — and an explicit retention floor, so falling behind the window is a declared gap condition, not a surprise

the protocol, model-checkedprototype

a TLA+ model of poke + hint + offset with passing TLC runs: safety invariants, plus the liveness property that is the whole doctrine — consumers reach the head even when every poke is dropped. "Failure is latency, not corruption," checked rather than asserted

vendor scorecard corpussketch

Stripe, GitHub, Shopify, Svix, and Outpost scored against one rubric, each system's pain sorted into essential versus accidental complexity. The headline row: consumer-owned offset checkpoint in the protocol — no, for every vendor. The field still centers on delivery orchestration; that's the column this doctrine deletes

consumer runtime modulesroadmap

AWS, GCP, Postgres reference stacks

integration agentroadmap

one-click provision + PR-based wiring + shadow verification

edges

connected investigations

absorbed prior work — named, never shipped, not available

Service Catalog

An Optic-era observation that never shipped: APIs are only a subset of how organizations communicate. One place to document business processes and expose their endpoints and integration points — webhooks included. Webpoke is the integration-point half, finished.

Distilled from field notes on poke + ranged-pull systems, reactivity models, and the consumer runtime providers never shipped.