Repository navigation
Phase 3: consent, inbound keywords, quiet hours, rate limits - #3
Merged
Merged
Conversation
Add smswire_consents and smswire_inbound_messages. Consent is kept per phone number and scope, where a sender's consent_scope picks the scope for both outbound checks and inbound keywords. Inbound webhooks are verified, stored once per provider message id, and STOP / START / HELP keywords update consent and send a configurable reply through the built-in compliance category, unless the provider already replied. Category rules merge over shipped defaults: transactional and otp send unless opted out, marketing requires opt-in and observes 9pm-8am quiet hours in the recipient's time zone. Rate limits are counted from the deliveries table. Quiet-hour and rate-limit deferrals re-enqueue the action for when it may send. Carrier opt-out errors record an opt-out with source carrier. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L5SuBiSMN4r9qr5CXbKkHV
This was referenced Oct 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements Phase 3 of
docs/SPEC.md. Stacked on #2, which is stacked on #1. Merge in order.What's included
Smswire::Consentstores status per phone number and scope, with source, timestamps, last keyword, and evidence metadata. A sender'sconsent_scopedecides which scope applies, so two programs on two numbers keep separate consent.POST <mount>/inbound/:providerverifies the signature, storesSmswire::InboundMessageonce per provider message id, and answers Twilio with empty TwiML. Observers can implementsms_receivedfor two-way messaging.compliancecategory that skips consent checks, so the opt-out confirmation reaches the number that just opted out. When Twilio Advanced Opt-Out already replied, signalled byOptOutType, consent is recorded without a second reply.transactionalandotpsend unless opted out.marketingrequires opt-in and observes 9pm to 8am quiet hours in the recipient's time zone.deliver_nowand the background job.carrier.Decisions and deviations, recorded in the spec
Rails.cache, so they survive restarts and are shared across processes.OPTOUTandREVOKEwere added to the opt-out keywords.Verification
:rejected_no_consent.🤖 Generated with Claude Code
https://claude.ai/code/session_01L5SuBiSMN4r9qr5CXbKkHV