You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Production cutover completed on 2026-08-27. send.growthpath.systems serves the Plunk dashboard and api.send.growthpath.systems serves the split API; both are DNS-only Cloudflare CNAMEs to Railway production targets with valid TLS. Signups remain disabled.
The production gate and first-brand support patches are landed. #12 fixed the first-contact race at 576bc1408f06bcf662f7dfeb9fbfe778e21cf59c (upstream useplunk#469); #14 fixed Railway-domain session cookies at 380dcafb9021fc6c3f7b3efa790d95731f8988a4 (upstream useplunk#470); #17 added create-only subscription state at a09ac1c193122fe3a4216496bd090ce80c8382a9 (upstream useplunk#471); #19 fixed workflow email execution from the relational template binding at 62ee1a1480e61b8fb52f56617f555ba57f037d18, closing #18 (upstream useplunk#472).
The domain error-handling patch #25 landed at e6315a575e68867b47f0a1d116799ed8a297fe6d; unexpected provider failures now use the safe global 500 boundary and the dashboard understands legacy string and structured errors. Production IAM now grants Plunk's region-limited SES v1 identity lifecycle. The Bookling project contains bookling.dev; all three DKIM CNAMEs and the custom MAIL FROM MX and SPF TXT resolve publicly, while SES verification is still processing.
Current Railway deployments are API fe0d1bdb-bc54-401c-a155-24aaeb9f15cf, worker 59738f20-e9f9-4f94-af59-ec17fd27c1b2, and dashboard 9e3f7809-7c78-4469-9e2f-3daf24acf0d4. All three report SUCCESS, one running replica, and the exact immutable image ghcr.io/vladbisceanu/plunk@sha256:a2d0a15a705fb69dfa45b5cfd8249e4f8d3852d74e0a00406784b6b5b44cc14f, built from production merge e6315a575e68867b47f0a1d116799ed8a297fe6d. API health and the dashboard both return 200. PostgreSQL 18 and Redis 8.2 retain 50 GB volumes; Redis uses AOF with appendfsync everysec.
The bisceanu.com first-brand migration completed on 2026-08-28 in vladbisceanu/bisceanu-com#87 at site SHA cca5b29c25fbc9f53af20bd58e9e268b25d5c9a7. The site now sends repo-rendered inline HTML through /v1/send and starts double opt-in through one /v1/track call with subscribed:false and preserveExistingSubscription:true. Its post-retirement Vercel production redeploy is Ready and the named production proof succeeded again on that exact SHA.
The live Bisceanu confirmation workflow ec12c9ff-1f4e-4764-95b3-8a98b107277f and welcome workflow 7ce1660c-71ff-4fec-acc4-5ef30076b2d1 are enabled and unchanged. Production proof covered real English and Romanian form submissions, both owner notifications and localized confirmations, pending-before-confirm state, hosted confirmation, contact.subscribed welcome, RFC 8058 one-click headers, hosted unsubscribe, marketing rejection for a migrated-unsubscribed record, and SES-simulator bounce suppression. All synthetic proof contacts were deleted; no live workflow was edited.
Contact and suppression state were reconciled without resubscribing suppressed contacts. USESEND_API_KEY and USESEND_CONTACT_BOOK_ID were removed from Vercel Production and the bisceanu Infisical project only after received-mail proof; store readback confirms they are absent. The useSend Railway project was deleted on 2026-08-28 (#20); Vlad waived the final backup since its contact and suppression state were already reconciled into Plunk. The vladbisceanu/useSend fork repository remains as code history. Delayed Easy DKIM selector rotation and removal of the legacy usesend._domainkey TXT after its seven-day overlap are tracked in vladbisceanu/bisceanu-com#88.
Production backup protection remains active. PITR completed base backup set 20260827-202416F; manual backup 8a9fa50c-8dde-4c8c-a3c0-aeb907492c03 (pre-cutover-2026-08-27) is retained with daily and weekly schedules. An isolated point-in-time restore replayed WAL, reached its recovery target, completed archive recovery, and accepted connections without touching primary.
AWS remains healthy: SES production sending is enabled with HEALTHY enforcement; bisceanu.com and mail.bisceanu.com MAIL FROM report success. Configuration set growthpath-plunk-production publishes to the isolated SNS topic with exactly one confirmed HTTPS subscription at https://api.send.growthpath.systems/webhooks/sns.
Final verification: the Bisceanu repository pnpm verify passed lint, typecheck, build, 150 unit tests, and 18 browser tests. Platform build and functional suites passed for #19; its production behavior was then re-proved on the pinned image. The immutable image labels and all running service sources were independently read back.
Outcome
Promote the maintained Plunk fork from disposable evaluation to the shared multi-brand email platform. Plunk owns campaigns, contact state, templates, and nurture workflows. Product backends keep domain events and money, auth, and recovery decisions.
Scope
Fix the first-contact /v1/track upsert race before production traffic.
Build production API, worker, and dashboard services from an immutable digest. Keep PostgreSQL and AOF Redis on persistent volumes. Do not use the all-in-one template.
Production hostname is send.growthpath.systems, permanent from day one (tracking links and hosted unsubscribe pages embed it in delivered mail, so it can never move; decided 2026-08-27). Cutover order: provision and verify production Plunk on its Railway-generated domain first, then flip the DNS record from useSend to Plunk and migrate the bisceanu contact form in a separate follow-up. bisceanu.com is useSend's only live consumer and has negligible traffic, so temporary form downtime and broken useSend SNS callbacks during the flip are accepted. useSend stays reachable on its Railway-generated domain for data reference until retirement. mail.growthpath.systems stays reserved for SES custom MAIL FROM.
Put agency customers behind a scoped ingest proxy. Never issue raw Plunk project keys.
Enforce workflow changes by duplicate, drain, and switch. Never edit a live workflow.
Migrate sending domains, templates, contacts, unsubscribe state, campaigns, and active nurture definitions with per-brand proof. bisceanu.com is the first migration (POC): contact form, double opt-in, SNS feedback, one-click unsubscribe.
The GrowthPath migration is reshaped and sliced: growthpath-ai/growthpath#1218 is now an epic around Plunk workflows, a thin internal client and repo-owned templates, with four sub-issues. Two platform constraints it surfaced land here rather than there: per-brand hosted unsubscribe and preference URLs are instance-wide (DASHBOARD_URI / API_URI), so Heralded mail carries a growthpath.systems opt-out link; and a WEBHOOK step completes on a non-2xx response, so no workflow can treat an application 5xx as a failure.
Retire useSend after its contact and suppression state are copied into Plunk and the bisceanu POC has production proof for send, engagement, unsubscribe, and bounce handling. Remaining brands migrate from Loops directly to Plunk.
Done when
The first-contact race is fixed and the nine-check suite is repeatable against the production candidate.
Each brand has exact production proof for transactional mail, marketing mail, suppression, and any migrated nurture flow.
PostgreSQL backup and restore are proved before the first upgrade and documented for later upgrades.
useSend is removed only after all consumers and suppression data have moved.
The adoption ADR and all affected product issues point here as the owning program.
References
Evaluation: vladbisceanu/setup-works#131
Disposable deployment and evidence: vladbisceanu/setup-works#146
Current state
Production cutover completed on 2026-08-27.
send.growthpath.systemsserves the Plunk dashboard andapi.send.growthpath.systemsserves the split API; both are DNS-only Cloudflare CNAMEs to Railway production targets with valid TLS. Signups remain disabled.The production gate and first-brand support patches are landed. #12 fixed the first-contact race at
576bc1408f06bcf662f7dfeb9fbfe778e21cf59c(upstream useplunk#469); #14 fixed Railway-domain session cookies at380dcafb9021fc6c3f7b3efa790d95731f8988a4(upstream useplunk#470); #17 added create-only subscription state ata09ac1c193122fe3a4216496bd090ce80c8382a9(upstream useplunk#471); #19 fixed workflow email execution from the relational template binding at62ee1a1480e61b8fb52f56617f555ba57f037d18, closing #18 (upstream useplunk#472).The domain error-handling patch #25 landed at
e6315a575e68867b47f0a1d116799ed8a297fe6d; unexpected provider failures now use the safe global 500 boundary and the dashboard understands legacy string and structured errors. Production IAM now grants Plunk's region-limited SES v1 identity lifecycle. The Bookling project containsbookling.dev; all three DKIM CNAMEs and the custom MAIL FROM MX and SPF TXT resolve publicly, while SES verification is still processing.Current Railway deployments are API
fe0d1bdb-bc54-401c-a155-24aaeb9f15cf, worker59738f20-e9f9-4f94-af59-ec17fd27c1b2, and dashboard9e3f7809-7c78-4469-9e2f-3daf24acf0d4. All three reportSUCCESS, one running replica, and the exact immutable imageghcr.io/vladbisceanu/plunk@sha256:a2d0a15a705fb69dfa45b5cfd8249e4f8d3852d74e0a00406784b6b5b44cc14f, built from production mergee6315a575e68867b47f0a1d116799ed8a297fe6d. API health and the dashboard both return 200. PostgreSQL 18 and Redis 8.2 retain 50 GB volumes; Redis uses AOF withappendfsync everysec.The bisceanu.com first-brand migration completed on 2026-08-28 in vladbisceanu/bisceanu-com#87 at site SHA
cca5b29c25fbc9f53af20bd58e9e268b25d5c9a7. The site now sends repo-rendered inline HTML through/v1/sendand starts double opt-in through one/v1/trackcall withsubscribed:falseandpreserveExistingSubscription:true. Its post-retirement Vercel production redeploy is Ready and the named production proof succeeded again on that exact SHA.The live Bisceanu confirmation workflow
ec12c9ff-1f4e-4764-95b3-8a98b107277fand welcome workflow7ce1660c-71ff-4fec-acc4-5ef30076b2d1are enabled and unchanged. Production proof covered real English and Romanian form submissions, both owner notifications and localized confirmations, pending-before-confirm state, hosted confirmation,contact.subscribedwelcome, RFC 8058 one-click headers, hosted unsubscribe, marketing rejection for a migrated-unsubscribed record, and SES-simulator bounce suppression. All synthetic proof contacts were deleted; no live workflow was edited.Contact and suppression state were reconciled without resubscribing suppressed contacts.
USESEND_API_KEYandUSESEND_CONTACT_BOOK_IDwere removed from Vercel Production and the bisceanu Infisical project only after received-mail proof; store readback confirms they are absent. The useSend Railway project was deleted on 2026-08-28 (#20); Vlad waived the final backup since its contact and suppression state were already reconciled into Plunk. The vladbisceanu/useSend fork repository remains as code history. Delayed Easy DKIM selector rotation and removal of the legacyusesend._domainkeyTXT after its seven-day overlap are tracked in vladbisceanu/bisceanu-com#88.Production backup protection remains active. PITR completed base backup set
20260827-202416F; manual backup8a9fa50c-8dde-4c8c-a3c0-aeb907492c03(pre-cutover-2026-08-27) is retained with daily and weekly schedules. An isolated point-in-time restore replayed WAL, reached its recovery target, completed archive recovery, and accepted connections without touching primary.AWS remains healthy: SES production sending is enabled with
HEALTHYenforcement;bisceanu.comandmail.bisceanu.comMAIL FROM report success. Configuration setgrowthpath-plunk-productionpublishes to the isolated SNS topic with exactly one confirmed HTTPS subscription athttps://api.send.growthpath.systems/webhooks/sns.Final verification: the Bisceanu repository
pnpm verifypassed lint, typecheck, build, 150 unit tests, and 18 browser tests. Platform build and functional suites passed for #19; its production behavior was then re-proved on the pinned image. The immutable image labels and all running service sources were independently read back.Outcome
Promote the maintained Plunk fork from disposable evaluation to the shared multi-brand email platform. Plunk owns campaigns, contact state, templates, and nurture workflows. Product backends keep domain events and money, auth, and recovery decisions.
Scope
/v1/trackupsert race before production traffic.mainas an upstream mirror and production patches on the maintained fork branch. Track upstream response to fix: re-check subscription before SES submission useplunk/plunk#462 through fix(contacts): make concurrent first-contact upserts safe useplunk/plunk#469.send.growthpath.systems, permanent from day one (tracking links and hosted unsubscribe pages embed it in delivered mail, so it can never move; decided 2026-08-27). Cutover order: provision and verify production Plunk on its Railway-generated domain first, then flip the DNS record from useSend to Plunk and migrate the bisceanu contact form in a separate follow-up. bisceanu.com is useSend's only live consumer and has negligible traffic, so temporary form downtime and broken useSend SNS callbacks during the flip are accepted. useSend stays reachable on its Railway-generated domain for data reference until retirement.mail.growthpath.systemsstays reserved for SES custom MAIL FROM.DASHBOARD_URI/API_URI), so Heralded mail carries agrowthpath.systemsopt-out link; and aWEBHOOKstep completes on a non-2xx response, so no workflow can treat an application 5xx as a failure.Done when
References