Test queued email against consent at send time
Test AI-generated email code by enqueueing a message while consent is active, revoking consent, then asserting that the worker makes zero transport calls and returns an explicit suppression result. For this example, the chosen requirement is to check authoritative consent immediately before handoff, rather than trust consent captured when the message entered the queue.
Imagine a marketing email queued at time 10. The recipient unsubscribes at time 20, and the worker processes the message at time 30. An enqueue-only check approves the message; a send-time check suppresses it. That difference is the behavior your contract must make observable.
OpenAI describes its updated Model Spec as outlining five core values intended to guide more capable AI toward sound judgment, human agency, and faithfulness to human intent. That is behavioral guidance, not evidence that generated application code satisfies an unsubscribe requirement. Developers accepting an AI-assisted change still need an application-level check. See OpenAI’s updated Model Spec announcement.
Choose the consent boundary before writing the test
“Respect unsubscribes” leaves several implementation choices unresolved. Does consent matter when the message is queued, when a worker processes it, or when a transport accepts it?
For this example, choose the following contract. It is an engineering requirement for this workflow, not a universal policy or legal interpretation.
| Contract element | Chosen behavior |
|---|---|
| Scope | A queued marketing email processed by this worker |
| Authority | The consent store, keyed by recipient and marketing purpose |
| Decision boundary | The worker’s final eligibility check before transport handoff |
| Revoked consent | Return suppressed:consent_revoked; make no transport call |
| Consent unavailable | Return deferred:consent_unavailable; make no transport call |
| Active consent | Permit transport handoff, subject to other applicable checks |
The core requirement is precise:
If authoritative consent is revoked before the worker’s final pre-send eligibility check, the worker must not hand the queued marketing email to the transport.
Queued consent is historical evidence, not current permission under this contract.
That sentence also tells a coding agent what not to implement: treating a saved consent_at_enqueue value as sufficient authorization to send.
Use the queued snapshot as the counterexample
An implementation can look reasonable and still violate the requirement:
if message["consent_at_enqueue"]:
transport.send(message)
This checks a real value, but at the wrong boundary. In the example timeline, the value remains true after the authoritative store changes to false.
A useful acceptance test must distinguish this implementation from one that reads current consent. Testing only recipients who remain subscribed would let both implementations pass.
A test needs a case where the competing implementations disagree.
Make the acceptance test deterministic
The following Python example uses only in-memory resources: a fake clock, a consent store, and a transport spy. It illustrates the contract and test structure; it has not been executed here.
The worker is a small reference implementation. To evaluate an AI-generated change, preserve the scenario and assertions but exercise the actual worker through its dependency adapters.
class FakeClock:
def __init__(self):
self.now = 10
def advance(self, seconds):
self.now += seconds
class ConsentStore:
def __init__(self):
self.records = {}
def set(self, recipient, purpose, active):
self.records[(recipient, purpose)] = active
def read(self, recipient, purpose):
# None represents unavailable consent in this test model.
return self.records.get((recipient, purpose))
class TransportSpy:
def __init__(self):
self.calls = []
def send(self, message):
self.calls.append(dict(message))
def process(message, consent, transport, clock):
active = consent.read(message["recipient"], "marketing")
checked_at = clock.now
if active is None:
return "deferred:consent_unavailable", checked_at
if not active:
return "suppressed:consent_revoked", checked_at
transport.send(message)
return "handed_off", checked_at
def test_unsubscribe_after_enqueue_blocks_handoff():
clock = FakeClock()
consent = ConsentStore()
transport = TransportSpy()
recipient = "reader@example.invalid"
consent.set(recipient, "marketing", True)
queue = [{
"recipient": recipient,
"queued_at": clock.now,
"consent_at_enqueue": True,
}]
clock.advance(10)
consent.set(recipient, "marketing", False)
clock.advance(10)
result, checked_at = process(
queue.pop(0), consent, transport, clock
)
assert checked_at == 30
assert result == "suppressed:consent_revoked"
assert transport.calls == []
The fake clock makes the timeline explicit without sleeping. The store changes after enqueueing but before processing. The spy observes the boundary the contract controls: transport handoff.
Both outcome assertions matter. Zero transport calls alone could also mean the worker silently dropped the message or never processed it. The suppression result records the intended decision.
Add an active-consent control that expects one transport call. Otherwise, a worker that suppresses every message could pass the unsubscribe test. Add a separate unavailable-consent case to check the declared deferral behavior; the example’s None value does not exercise a real adapter’s timeout or error handling.
A passing test leaves one important race open
Suppose the worker reads active consent, the recipient then unsubscribes, and the worker hands the message to the transport. The acceptance test above says nothing about that interleaving.
The contract deliberately draws its boundary at the final eligibility check. If the intended requirement instead says that every revocation before transport handoff must block sending, a read followed by a send leaves a gap. That stronger requirement needs a coordination design and additional interleaving tests. Another read can narrow the gap without eliminating it.
A passing test covers the exercised boundary, not every possible interleaving.
It also does not establish that other email paths consult consent, that the production consent adapter reads sufficiently fresh data, or that a downstream provider will stop an already accepted message. Those are separate obligations with different observation points.
For this narrow change, I would gate acceptance on the revoked-consent case, the active-consent control, and the unavailable-consent case. I would not describe those checks as complete conformance across the email system.
Keep this send-boundary checklist with the change
Before accepting the generated diff, record four decisions:
- Authority: Which store and consent purpose determine eligibility? Does the real adapter satisfy the required freshness?
- Boundary: Where is the last eligibility check, and is the test observing the actual transport handoff?
- Failure behavior: Does unavailable consent prevent handoff, with an explicit result and a defined retry path?
- Concurrency: What happens if revocation occurs after the check but before handoff?
Keep the requirement, counterexample, test result, and unresolved boundary together. That gives later reviewers something concrete to compare when either the specification or implementation changes. A refactor that starts trusting the queued snapshot is then a detectable change in behavior, rather than an argument about what “respect unsubscribes” meant.
For a five-minute first pass, write the four checklist answers beside one existing worker test and add the enqueue-then-revoke scenario. This checks one processing path, not the whole delivery system. To carry that requirement and acceptance check into an intent-checking workflow, start with ThunderLang’s getting-started guide.