# AGENTS.md — Build guide for Svix

## Project scope
Accept an authenticated event, fan it out to approved HTTPS endpoints and sign each attempt with a documented timestamped HMAC format. Show attempt logs, backoff, disabled endpoints and manual replay with clear semantics.

Catalogue verdict: kinda. The core loop here is genuinely small: accept an event, look up subscribed endpoints, sign the payload, POST it, retry on failure with backoff, log the attempt. An agent will produce that in a session, and for a single product sending a few thousand events a day it will work fine. What does not fall out of a one-shot is the boring half: a queue that survives restarts, per-endpoint rate limiting and circuit breaking so one dead customer does not poison your worker pool, replay and manual retry tooling, a portal your customers can log into, and signature schemes that third-party libraries already understand. Svix is also open source, which means the honest DIY move is often self-hosting theirs rather than writing your own. Call it a weekend for something you would actually put in front of paying users, and understand that you are now on call for it.
Use the implementation prompt below to define the deliverable. Complete each phase's acceptance checks before extending the scope.

## Working agreement
- Inspect the repository and its existing instructions before choosing paths, dependencies or commands. Keep one coherent stack and explain changes to the proposed architecture.
- Plan a vertical slice that accepts a real input and produces the useful output described below. Persist only the state the prompt calls for; respect memory-only and upstream-managed workflows. Use fixtures only when they are clearly labelled.
- After scaffolding, document the actual install, development, check and build commands in README and keep them synchronized with the package or project manifest. Do not report commands as successful unless they ran.
- Work in small steps. At handoff, list implemented flows, checks actually performed, remaining blockers, and any credentials or provider setup the owner must supply.
- Do not publish, spend money, contact customers, delete source data or run irreversible migrations without the project owner's authorization.

## Prerequisites
- Node, PostgreSQL, Redis, owner-managed signing secrets and explicitly approved public HTTPS receiver endpoints. Configure queue persistence, network egress policy and request timeouts.
- Implementation components: Node.js, TypeScript and Fastify for authenticated webhook management and message ingestion. PostgreSQL/Drizzle for events and attempt receipts, BullMQ/Redis for delivery scheduling and Node crypto for documented HMAC signatures.
- Scope boundary: Global delivery infrastructure and exactly-once receiver processing are not promised.

## Stack and architecture
- Node.js, TypeScript and Fastify for authenticated webhook management and message ingestion.
- PostgreSQL/Drizzle for events and attempt receipts, BullMQ/Redis for delivery scheduling and Node crypto for documented HMAC signatures.
- Domain model: applications, endpoints, signing keys, immutable events, delivery attempts and retry schedules

## Security and data integrity
- Authorize management and ingestion with separate scoped credentials; protect cookie-authenticated administration against CSRF. Validate destinations on resolution and redirects, reject private-network targets and sign exact payload bytes with timestamped endpoint keys. Redact payloads, keys and response excerpts before diagnostics.
- Correctness boundary: Protect against SSRF on every resolution/redirect; retries preserve event identity and signatures bind the exact payload bytes and timestamp.
- Commit the immutable event, approved endpoint snapshot and pending delivery outbox in one PostgreSQL transaction before acknowledging intake. A dispatcher enqueues stable delivery IDs into BullMQ and records the handoff; reconcile a crash between enqueue and marking dispatched without creating a new logical delivery. Lease attempts, save receipts, back off bounded transient failures and retain ambiguous receiver outcomes for explicit review. Failed Redis access leaves authoritative pending deliveries in PostgreSQL for later dispatch.
- Back up authoritative PostgreSQL event/attempt/endpoint records with separately protected signing keys. Rebuild pending queue jobs from durable delivery state after Redis loss and reconcile in-flight attempts; never treat a recovered queue as proof of exactly-once receiver processing.

## Agent implementation rules
- Project rule — data model: applications, endpoints, signing keys, immutable events, delivery attempts and retry schedules
- Project rule — preserve this invariant: Protect against SSRF on every resolution/redirect; retries preserve event identity and signatures bind the exact payload bytes and timestamp.
- Project rule — acceptance evidence: An endpoint returning 500 retries with backoff while a successful endpoint is not resent; key rotation accepts a documented overlap window and blocks private-network targets.

## Optional agent skills and references
- Optional external skill: [supabase-postgres-best-practices](https://github.com/supabase/agent-skills/blob/main/skills/supabase-postgres-best-practices/SKILL.md) — Review PostgreSQL schemas, queries, indexes, pooling, concurrency and row-level security. Review its instructions and compatibility before use; it does not grant deployment, data-access or publication permission.
- Optional external skill: [sharp-edges](https://github.com/trailofbits/skills/blob/main/plugins/sharp-edges/skills/sharp-edges/SKILL.md) — Review security-sensitive APIs and configuration for dangerous defaults and easy-to-misuse interfaces. Review its instructions and compatibility before use; it does not grant deployment, data-access or publication permission.

Read the linked SKILL.md and its dependencies before adding a skill. Select only the skills matching this project's runtime and task; their documentation does not supply API access, credentials or approval to perform external actions. Pin the reviewed revision where the tool supports it. Follow the chosen agent's documented project-level installation mechanism.

## Distribution ideas
These are optional planning notes. Obtain the owner's approval before publishing or contacting anyone.
- Demonstrate the actual Svix-inspired workflow with owned or clearly labeled sample data: Accept an authenticated event, fan it out to approved HTTPS endpoints and sign each attempt with a documented timestamped HMAC format. Show attempt logs, backoff, disabled endpoints and manual replay with clear semantics.
- Publish a reproducible walkthrough with this observable result: An endpoint returning 500 retries with backoff while a successful endpoint is not resent; key rotation accepts a documented overlap window and blocks private-network targets.
- Explain who can operate this scoped tool, its setup and ongoing costs, and these remaining product gaps: Global delivery infrastructure and exactly-once receiver processing are not promised. Avoid guaranteed savings, performance scores or implied endorsement.

## Engineering roadmap
1. Phase 1 — Scope and fixtures. Implement this bounded workflow: Accept an authenticated event, fan it out to approved HTTPS endpoints and sign each attempt with a documented timestamped HMAC format. Show attempt logs, backoff, disabled endpoints and manual replay with clear semantics. Record prerequisites, select representative user-owned fixtures and document the unsupported features: Global delivery infrastructure and exactly-once receiver processing are not promised.
2. Phase 2 — Durable model. Model applications, endpoints, signing keys, immutable events, delivery attempts and retry schedules Add migrations or a versioned document format, explicit validation, stable IDs and a visible import-error report. Preserve this rule: Protect against SSRF on every resolution/redirect; retries preserve event identity and signatures bind the exact payload bytes and timestamp.
3. Phase 3 — Complete the first useful path. Implement the workflow's input, review and output interface, with clear controls and explicit empty/error states. Commit the immutable event, approved endpoint snapshot and pending delivery outbox in one PostgreSQL transaction before acknowledging intake. A dispatcher enqueues stable delivery IDs into BullMQ and records the handoff; reconcile a crash between enqueue and marking dispatched without creating a new logical delivery. Lease attempts, save receipts, back off bounded transient failures and retain ambiguous receiver outcomes for explicit review. Failed Redis access leaves authoritative pending deliveries in PostgreSQL for later dispatch.
4. Phase 4 — Permissions and integration failure. Authorize management and ingestion with separate scoped credentials; protect cookie-authenticated administration against CSRF. Validate destinations on resolution and redirects, reject private-network targets and sign exact payload bytes with timestamped endpoint keys. Redact payloads, keys and response excerpts before diagnostics. Request integration credentials and permissions only for the enabled feature; show a disconnected state instead of mock results.
5. Phase 5 — Portable handoff. Back up authoritative PostgreSQL event/attempt/endpoint records with separately protected signing keys. Rebuild pending queue jobs from durable delivery state after Redis loss and reconcile in-flight attempts; never treat a recovered queue as proof of exactly-once receiver processing. Include setup, operating limits, fixture walkthrough and shutdown/restart instructions in the README.
6. Phase 6 — Acceptance scenarios. An endpoint returning 500 retries with backoff while a successful endpoint is not resent; key rotation accepts a documented overlap window and blocks private-network targets. Repeat the workflow after restart and with a denied permission or unavailable dependency; show recoverable failure rather than a success placeholder.

## Paid-product capabilities outside this build
- A customer-facing portal where your users manage their own endpoints and see failures
- Battle-tested signature format that existing verification libraries accept out of the box
- Per-endpoint circuit breaking and rate limiting so one slow consumer does not stall everyone
- Operational maturity: dead-letter handling, replay windows, throughput under a spike
- Someone else being paged when delivery breaks at 3am

## Implementation prompt
WORKING SLICE
Accept an authenticated event, fan it out to approved HTTPS endpoints and sign each attempt with a documented timestamped HMAC format. Show attempt logs, backoff, disabled endpoints and manual replay with clear semantics.

Build this scoped Svix-inspired workflow with a documented data model and visible failure states.

Architecture
- Node.js, TypeScript and Fastify for authenticated webhook management and message ingestion.
- PostgreSQL/Drizzle for events and attempt receipts, BullMQ/Redis for delivery scheduling and Node crypto for documented HMAC signatures.

Prerequisites and limits
Node, PostgreSQL, Redis, owner-managed signing secrets and explicitly approved public HTTPS receiver endpoints. Configure queue persistence, network egress policy and request timeouts.
Outside this release: Global delivery infrastructure and exactly-once receiver processing are not promised.

Data model and correctness
applications, endpoints, signing keys, immutable events, delivery attempts and retry schedules
Invariant: Protect against SSRF on every resolution/redirect; retries preserve event identity and signatures bind the exact payload bytes and timestamp.
Commit the immutable event, approved endpoint snapshot and pending delivery outbox in one PostgreSQL transaction before acknowledging intake. A dispatcher enqueues stable delivery IDs into BullMQ and records the handoff; reconcile a crash between enqueue and marking dispatched without creating a new logical delivery. Lease attempts, save receipts, back off bounded transient failures and retain ambiguous receiver outcomes for explicit review. Failed Redis access leaves authoritative pending deliveries in PostgreSQL for later dispatch.

Security and privacy
Authorize management and ingestion with separate scoped credentials; protect cookie-authenticated administration against CSRF. Validate destinations on resolution and redirects, reject private-network targets and sign exact payload bytes with timestamped endpoint keys. Redact payloads, keys and response excerpts before diagnostics.

Recovery and export
Back up authoritative PostgreSQL event/attempt/endpoint records with separately protected signing keys. Rebuild pending queue jobs from durable delivery state after Redis loss and reconcile in-flight attempts; never treat a recovered queue as proof of exactly-once receiver processing.

Implementation order
1. Phase 1 — Scope and fixtures. Implement this bounded workflow: Accept an authenticated event, fan it out to approved HTTPS endpoints and sign each attempt with a documented timestamped HMAC format. Show attempt logs, backoff, disabled endpoints and manual replay with clear semantics. Record prerequisites, select representative user-owned fixtures and document the unsupported features: Global delivery infrastructure and exactly-once receiver processing are not promised.
2. Phase 2 — Durable model. Model applications, endpoints, signing keys, immutable events, delivery attempts and retry schedules Add migrations or a versioned document format, explicit validation, stable IDs and a visible import-error report. Preserve this rule: Protect against SSRF on every resolution/redirect; retries preserve event identity and signatures bind the exact payload bytes and timestamp.
3. Phase 3 — Complete the first useful path. Implement the workflow's input, review and output interface, with clear controls and explicit empty/error states. Commit the immutable event, approved endpoint snapshot and pending delivery outbox in one PostgreSQL transaction before acknowledging intake. A dispatcher enqueues stable delivery IDs into BullMQ and records the handoff; reconcile a crash between enqueue and marking dispatched without creating a new logical delivery. Lease attempts, save receipts, back off bounded transient failures and retain ambiguous receiver outcomes for explicit review. Failed Redis access leaves authoritative pending deliveries in PostgreSQL for later dispatch.
4. Phase 4 — Permissions and integration failure. Authorize management and ingestion with separate scoped credentials; protect cookie-authenticated administration against CSRF. Validate destinations on resolution and redirects, reject private-network targets and sign exact payload bytes with timestamped endpoint keys. Redact payloads, keys and response excerpts before diagnostics. Request integration credentials and permissions only for the enabled feature; show a disconnected state instead of mock results.
5. Phase 5 — Portable handoff. Back up authoritative PostgreSQL event/attempt/endpoint records with separately protected signing keys. Rebuild pending queue jobs from durable delivery state after Redis loss and reconcile in-flight attempts; never treat a recovered queue as proof of exactly-once receiver processing. Include setup, operating limits, fixture walkthrough and shutdown/restart instructions in the README.
6. Phase 6 — Acceptance scenarios. An endpoint returning 500 retries with backoff while a successful endpoint is not resent; key rotation accepts a documented overlap window and blocks private-network targets. Repeat the workflow after restart and with a denied permission or unavailable dependency; show recoverable failure rather than a success placeholder.

Acceptance
An endpoint returning 500 retries with backoff while a successful endpoint is not resent; key rotation accepts a documented overlap window and blocks private-network targets.
Use real source data or clearly labeled fixtures. Explain unsupported input and provider failures; do not fabricate analytics, delivery receipts, accuracy claims or security guarantees.

Optional agent guidance
Optional external skill: [supabase-postgres-best-practices](https://github.com/supabase/agent-skills/blob/main/skills/supabase-postgres-best-practices/SKILL.md) — Review PostgreSQL schemas, queries, indexes, pooling, concurrency and row-level security. Review its instructions and compatibility before use; it does not grant deployment, data-access or publication permission.
Optional external skill: [sharp-edges](https://github.com/trailofbits/skills/blob/main/plugins/sharp-edges/skills/sharp-edges/SKILL.md) — Review security-sensitive APIs and configuration for dangerous defaults and easy-to-misuse interfaces. Review its instructions and compatibility before use; it does not grant deployment, data-access or publication permission.
Project rule — data model: applications, endpoints, signing keys, immutable events, delivery attempts and retry schedules
Project rule — preserve this invariant: Protect against SSRF on every resolution/redirect; retries preserve event identity and signatures bind the exact payload bytes and timestamp.
Project rule — acceptance evidence: An endpoint returning 500 retries with backoff while a successful endpoint is not resent; key rotation accepts a documented overlap window and blocks private-network targets.

## Completion evidence
Demonstrate the prompt's acceptance scenarios against the scoped workflow. Include setup from a clean checkout and failure recovery. Check persistence across restart and export/restore only for the state the prompt says to store; for memory-only tools, confirm that temporary content is discarded as specified. Record actual results and remaining limitations. A detailed plan alone does not establish a working replacement.
