Define account setup service email as its own narrow category - #170
Define account setup service email as its own narrow category#170TommyBez wants to merge 2 commits into
Conversation
Q31a, option b restricted, approved by the founder. The first two activation emails need a basis that gives them recipients: opt-in consent to product_communications is 0 of 8, so the sequence would send nothing. .agents/product-marketing.md drops "activation guidance" from the product_communications topic and defines account setup service email: welcome and first skill only, to the team creator, inside 14 days of team creation, 3 proactive emails per person ever, visible unsubscribe, every suppression honored. The founder-voice sender rule now says the opt-in check is replaced by qualification under that category for service email only, and that suppression, unsubscribe, identity, provider, a real public postal identity, and explicit send authorization stay mandatory for it too. docs/email-compliance.md documents the operational contract: perimeter, window, legal basis, frequency caps, permanent exit conditions, suppression precedence, reuse of the existing one-click unsubscribe, emailSubscriber exclusion, no retroactive send, and the two preconditions on the first send. No code changes. No send is enabled. The product_communications disclosure and its notice version are untouched.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3abdac3c4c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| - The `emailSubscriber` list is out of scope. Those rows are visitor captures with no account and no team, so they never receive an activation email. | ||
| - No retroactive send. Users and teams created before the sequence ships are not backfilled into it, and doing so would need its own recorded decision. | ||
|
|
||
| Two preconditions gate the first send of the sequence. The footer must carry a real public postal identity: the value in `lib/site.ts`, quoted above, is a placeholder and has to be replaced with the operator's real address before any activation email leaves. And the founder has to authorize that first send explicitly, as with every other proactive category. |
There was a problem hiding this comment.
Require a privacy-notice update before the first send
When this category is enabled, the two listed preconditions are insufficient: the current public privacy notice says Skills Board sends requested transactional messages such as sign-in codes and invitations, and sends practical guides or other product communications only after opt-in (app/privacy/page.tsx lines 84-124). Allowing activation_welcome and activation_first_skill under legitimate interest without first updating that notice would begin using Resend for a purpose users have not been told about. Add privacy-notice alignment and publication as a precondition to the first activation send.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Founded, and fixed in 4d951ef.
The precondition list in docs/email-compliance.md now opens with the privacy notice: it has to describe this category and the basis it relies on before the category is switched on, because the notice published today says product communications go out only after opt-in. The explicit send authorization stays as the second precondition. Publishing the notice and enabling the send both remain manual steps.
The other precondition you quoted is gone, on a separate maintainer decision. A public postal address is not required for this category: CAN SPAM asks for a postal address on commercial messages, and account setup service email is a relationship message. The placeholder address it pointed at was invented, so it was removed from lib/site.ts in the same commit rather than replaced, and every surface omits the address while none is configured. A real postal address stays required before a marketing broadcast.
…to marketing Q31d, approved by the maintainer. The CAN SPAM postal address requirement covers commercial messages. Account setup service email and transactional email are relationship messages, so they do not need one, and the address that was in `lib/site.ts` was invented: "15 Giuseppe Verdi Avenue, Suite 150, Capraia Innovation Park, CA 50050" is not a real place. A fabricated address in an email footer, on the terms and privacy pages, and inside the Organization JSON-LD is worse than no address at all. `postalAddress` and its structured twin `address` are now nullable and set to null. Every surface that printed them omits the block while they are unset: the legal page footer, the marketing email footer, the terms and privacy contact paragraphs, the contact page card, and the Organization JSON-LD, which now emits `address` only when there is a real one. Setting the two fields together, with a real address, restores every surface at once. No address was invented to replace the old one. docs/email-compliance.md now states that a marketing broadcast carries the public postal address and that service and transactional email do not, and that the address is required before the first broadcast to the opt-in list rather than before the first activation email. `.agents/product-marketing.md` is aligned on the same point for the service category. The Codex P2 on this PR is addressed in the same paragraph: the first send of the sequence is now gated on the public privacy notice describing this category and its basis, plus the explicit send authorization that was already there. Publishing a notice and enabling a send both stay manual. The organization node test asserts the address is absent while the two spellings are unset, that neither is ever set alone, and keeps the agreement check for when a real address exists. tsc --noEmit clean. 562 unit tests pass. No send is enabled.
|
Pushed 4d951ef after the maintainer approved the postal address question. The category this PR defines is account setup service email. The CAN SPAM postal address requirement applies to commercial messages, and service and relationship email are not commercial messages, so a physical postal address is not a precondition for the first send of this sequence. A real postal address stays required before any future marketing broadcast to the opt-in list, such as a newsletter or a product update. Approved by maintainer. What changed:
This also picks up the Codex P2 on this PR. Privacy notice alignment is now one of the two preconditions on the first send, next to the explicit send authorization. Note that this PR is no longer docs only. It now touches
PR #172 branches from |
Hypothesis
The first two activation emails need a basis that gives them recipients. Opt-in consent to
product_communicationscurrently stands at 0 of 8 accounts, so an activation sequence built on that topic would send nothing to nobody. Classifying only the welcome message and the first skill reminder as account setup service email gives the sequence a narrow, defensible set of recipients: the person who just created a team, inside the window where setting up that account is still the thing they are doing.What changes
Documents only. Two files.
.agents/product-marketing.mdproduct_communicationsconsent topic.product_communicationsand still require opt-in consent.docs/email-compliance.mdactivation_welcomeandactivation_first_skillonly), the 14 day window from team creation, the legal basis (legitimate interest toward a registered user limited to completing the setup of the account they just created in the EU, CAN SPAM footer with a working opt out in the United States), the frequency caps (at most one per user per day, at least 24 hours between two emails of the sequence, no more than 3 activation emails per person ever), the permanent exit conditions (withdrawn consent, any suppression, the completed action, the end of the window, or 3 emails sent), the absolute precedence of suppression, reuse of the existing one-click unsubscribe and its RFC 8058 headers, exclusion of theemailSubscriberlist, no retroactive send to existing users without a separate decision, and the two preconditions on the very first send.What does not change
product_communicationsopt-in disclosure is identical andPRODUCT_COMMUNICATIONS_NOTICE_VERSIONis untouched. The invite and connect emails stay under the opt-in topic, so the disclosure users already answered stays accurate.lib/site.tsstill carries a placeholder postal address. Replacing it with the operator's real address is written into the doc as a precondition for the first send, not done here.The metric that has to move
Share of newly created teams that save their first skill within 14 days of team creation.
Read it directionally over months, not weekly. At current volume a single team swings the number, so any short window reading is noise rather than signal.
Guard metric: spam complaints. One complaint stops the sequence.
How we will know it worked
The sequence does not exist yet, so this PR cannot be judged on outcome. It can be judged on whether the classification is narrow enough to survive review: two messages, one recipient, one window, one hard cap, five independent exit conditions, and no route by which a newsletter, a digest, or a re-engagement message could later claim the same basis. If a reviewer can name a message that would slip into this category and should not, the definition is wrong and this should not merge.
Once the sequence ships and sends, the check is the activation share above against its pre-sequence baseline, with complaints at zero.
Approval
The classification is approved by the founder: decision Q31a, option b restricted, over Slack. The contract itself requires that a material change to the durable communication policy be delivered through the normal repository review process, which is why this PR lands before any sending code is written.
Verification
tsc --noEmitclean.node --test tests/*.test.mjsgreen, 562 of 562. No test reads either document, and no test regressed.