Work in progress should not be readable by anyone who wanders in. CURTAIN=<secret> puts a
contentless "Coming soon" card in front of every request — pages, APIs, the rotator, the
link domains — with noindex headers and nothing that names the product or what it does.
Opening the site once with ?k=<secret> drops a cookie that lifts it for that browser.
Unsetting CURTAIN opens the site again, so this never has to be picked back out of the code.
It sits at the very top of the request handler, ahead of the rotator and the link-domain
sites, so there is no path around it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This is a test area on a testnet contract, but it was seeded on 15 Sep with a copy of
InstantAdPay's live member list and it carried a working SendGrid key. On 18 Sep the
coach's stall nudges fired on schedule and emailed 95 real people from it. One of them
clicked through and opened a fresh account two hours later.
Nothing was misconfigured. Every send site checked mailer.hasKey(), the key was there,
so every send site got a yes. The default was wrong, not the plumbing.
OUTBOUND=on is now required before anything can leave: hasKey() is false without it,
send() rejects outright, and the two mailing loops (coach nudges, lead drip) never start.
SIGNUPS=closed shuts the three registration doors and reports signupsOpen:false, which
also drops the email-code card from the UI. Members already here keep their dashboards.
A missing env var means silence now, not delivery.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>