Outreach Wave 3 — Send-Queue Audit Notes (2026-07-25)

This note records the Wave 3 outreach send queue as it stands on 2026-07-25. The queue itself is persisted in the database (see migrations/010_create_outreach_wave3_queue.js and the inspection endpoint GET /api/admin/outreach/queue). The draft copy and the founder-pain source material both live outside this repository — in the agent harness / copy library. This article is the in-repo audit trail only.

It does not change any application behavior in this repository. It is a pointer, not duplication.

Acceptance contract — referenced, not duplicated

From the Wave 3 brief:

> Acceptance: queue is persisted as a structured send-ready artifact (per-recipient record: prospect, archetype, subject, body, status=queued-not-sent); founder-pain library and 4-archetype library are referenced, not duplicated; ready to fire in one operation the moment POL-1492 comes back, with zero additional drafting.

The contract has two halves:

1. The 16 per-recipient records (4 prospects × 4 archetypes) ARE persisted here — in outreach_wave3_queue. Subject lines, body copy, and HTML versions are rendered at seed time (migration 010). 2. The 4-archetype library and the founder-pain library are NOT persisted here. They are referenced by id and library_ref only. A future maintainer who needs to evolve the copy should edit the external library, then re-render this seed if they want the new wording to land in the next batch's queued records.

Wave 3 prospects (4)

| Handle | Display name | Company | Source platform | |---|---|---|---| | spencer-claydon-foundra | Spencer Claydon | Foundra.ai | Hacker News | | mehphp | mehphp | mehphp | IndieHackers | | alexandru-dodon | Alexandru Dodon | dodon.dev | Hashnode | | shahed-khalidi | Shahed Khalidi | khalidi.io | Medium |

Each prospect row's last_post_hook column points at the canonical founder-pain library id — a record in an external library, not a re-embedded quote. The personalization token is substituted into each of the 4 archetype drafts so the seeded subject / body fields show the live name and the live hook reference text. No {{tokens}} are left in the rows.

Wave 3 archetypes (4, pointer-only)

| Archetype id | Display label | Library reference (external) | |---|---|---| | speed_pressure | speed_pressure | outreach-copy-library@/archetypes/speed_pressure.md | | build_vs_buy | build_vs_buy | outreach-copy-library@/archetypes/build_vs_buy.md | | spec_clarity | spec_clarity | outreach-copy-library@/archetypes/spec_clarity.md | | client_validation | client_validation | outreach-copy-library@/archetypes/client_validation.md |

The outreach_wave3_archetypes table in this repo carries only the link (library_ref) and the label. Full archetype copy lives in the external library. If the AC is ever violated by adding a description or body column here, that violates the "referenced, not duplicated" contract — revert it.

Fire trigger

When the Polsia email proxy (https://polsia.com/api/proxy/email/send) recovers from POL-1492, the operator fires the queued batch in one admin call:

POST /api/admin/outreach/send-wave3

Authorization: Bearer <admin-jwt>

The route:

Re-running the same call after a drain returns total: 0 because the status='queued-not-sent' filter prevents re-firing. Inspect progress with GET /api/admin/outreach/fire-status.

Why the queue is persisted, not deferred

The send queue is persisted in the DB so that: