All 21 checks with why-it-matters prose, severity, and cross-references to related audits.
Without a state machine model, sequence position exists only as an implicit calculation derived from send timestamps — and that calculation breaks the moment history is incomplete. A cron loop that re-derives step index on every run will duplicate sends when emails are delayed, skip steps when records are missing, and produce divergent behavior across contacts that should be in identical states. CWE-372 (Incomplete Internal State) captures the class of defect: the system behaves correctly in the happy path but enters an undefined state under any pressure — process restart, partial failure, manual intervention. The business impact is concrete: contacts receive redundant outreach, or fall silent mid-sequence, with no audit trail to diagnose either.
Why this severity: Critical because missing per-contact state causes duplicate sends and irreversible data loss on any process restart or partial failure.
campaign-orchestration-sequencing.sequence-architecture.state-machine-modelSee full patternSequence state held only in memory — a JavaScript Map, a module-level object, or a BullMQ job payload with no database mirror — is erased by any process restart, deployment, or crash. CWE-400 and CWE-693 both apply: the system is neither protected against state loss nor recoverable after failure (iso-25010:2011 reliability.recoverability). The concrete outcome: contacts re-enter sequences from step 0, receive duplicate emails, or disappear from sequences entirely. At scale, a single deployment during a live campaign can corrupt thousands of enrollment records with no recovery path short of manually reconstructing state from email send logs — if those logs even exist.
Why this severity: Critical because in-memory state is permanently lost on any restart, causing duplicate sends or silent contact abandonment with no recovery path.
campaign-orchestration-sequencing.sequence-architecture.state-persistenceSee full patternA linear sequence sends the same follow-up to a contact who clicked your demo link and a contact who never opened the first email. That equivalence wastes the engaged contact's attention — they receive content calibrated for cold prospects — and misses the conversion window when intent is highest. iso-25010:2011 functional-suitability.functional-completeness treats this as a completeness failure: the system claims to run campaigns but cannot differentiate its behavior based on the core input it tracks. At the business level, a branching gap means every click and reply is detected but never acted on, turning your engagement data into a vanity metric.
Why this severity: High because linear-only sequences ignore real-time engagement signals, wasting conversion opportunities when contact intent is measurably highest.
campaign-orchestration-sequencing.sequence-architecture.branching-logicSee full patternDuplicate enrollment — calling `enrollContact()` twice for the same contact and sequence — creates two active send threads. Both threads advance independently and both send on their own schedules, so a single contact can receive every sequence email twice. CWE-841 (Improper Enforcement of Behavioral Workflow) applies directly: the system fails to enforce that a contact occupies exactly one position in a sequence at a time. The exit-conditions gap is equally damaging: contacts who unsubscribe mid-sequence continue receiving steps because no exit path was wired to the opt-out signal, creating CAN-SPAM and GDPR Art-6 exposure for marketing emails sent after a withdrawal of consent.
Why this severity: High because missing deduplication causes duplicate send threads, and missing exit conditions continue sending to contacts who have unsubscribed — both are legally and reputationally damaging.
campaign-orchestration-sequencing.sequence-architecture.entry-exit-conditionsSee full patternWhen a sequence is edited in place — steps added, removed, or reordered on the same mutable record — every active enrollment instantly changes behavior. A contact on step 3 of a 5-step sequence wakes up to find step 3 is now something completely different, or that step 5 was removed and the sequence loops. CWE-440 (Expected Behavior Violation) and iso-25010:2011 reliability.recoverability apply: the system makes no guarantee about what a contact in-flight will experience once a sequence is modified. Beyond the technical defect, this creates unpredictable outreach — contacts who opted into a specific message cadence receive a different one — and debugging post-send complaints becomes impossible without version history.
Why this severity: High because in-place edits silently corrupt in-flight enrollments, potentially skipping or repeating content for contacts mid-sequence with no way to audit what changed.
campaign-orchestration-sequencing.sequence-architecture.sequence-versioningSee full patternWhen sequence steps live as a JSON blob inside a campaign record, every campaign that wants the same nurture cadence requires its own copy. Copies diverge — a fix to step 2 is applied to Campaign A but not Campaign B, the mistake is caught in production, and there is no authoritative source to determine which version is correct. iso-25010:2011 maintainability.reusability grades this failure mode: the architecture forces copy-paste duplication of business logic, making future changes error-prone and audit trails inconsistent. This is a low-severity architectural debt issue, not a runtime defect — the harm accrues gradually as sequences accumulate.
Why this severity: Low because the defect is an architectural coupling issue that causes maintenance burden and drift, not an immediate runtime failure or data loss.
campaign-orchestration-sequencing.sequence-architecture.reusable-templatesSee full patternWithout a minimum-spacing guard enforced at send time, a contact enrolled in two simultaneous sequences can receive back-to-back emails minutes apart. CAN-SPAM Act Sec. 5 does not set a specific inter-email minimum, but sending frequency that a recipient experiences as abusive constitutes a material compliance risk under GDPR Art. 6 (lawful basis) and ePrivacy Art. 13, both of which require that commercial communications reflect the consent and reasonable expectations of the recipient. Beyond regulatory exposure, rapid-fire emails generate spam complaints, damage sender reputation, and suppress deliverability across the entire sending domain — affecting all customers, not just the one who complained.
Why this severity: Critical because absent send-time spacing enforcement, overlapping sequences produce back-to-back emails that trigger spam complaints, degrade sender reputation, and create GDPR Art-6 exposure.
campaign-orchestration-sequencing.cadence-spacing.minimum-spacingSee full patternMinimum spacing prevents back-to-back emails within a single send pair; frequency capping prevents runaway volume over a rolling window. A contact enrolled in four simultaneous sequences, each with a 24-hour minimum spacing, can still receive four emails per day — 28 per week — without violating any per-pair spacing rule. CWE-770 (Allocation of Resources Without Limits) applies at the application layer: the system places no global bound on how many times it contacts a single recipient. Under CAN-SPAM Act Sec. 5 and GDPR Art. 6, the volume of commercial email must reflect the reasonable expectations of the subscriber — not the maximum throughput the queue can sustain.
Why this severity: High because without a cross-campaign cap, contacts enrolled in multiple sequences receive unlimited email volume — a CAN-SPAM and GDPR Art-6 compliance risk at scale.
campaign-orchestration-sequencing.cadence-spacing.frequency-capSee full patternScheduling all sends in server UTC means a "send at 9am" step reaches a contact in Tokyo at 9pm and a contact in London at 8am in summer, 9am in winter. Open rates for email campaigns vary by as much as 30% based on local time of delivery — sending into the wrong timezone is a measurable conversion loss, not a cosmetic issue. iso-25010:2011 functional-suitability.functional-correctness treats this as a functional accuracy defect: the system executes the correct action (sends the email) at the wrong time (server timezone rather than recipient timezone), producing a systematically degraded outcome for any globally distributed contact list.
Why this severity: Medium because server-timezone scheduling consistently delivers emails at suboptimal local times for non-local contacts, producing measurable open-rate and conversion losses.
campaign-orchestration-sequencing.cadence-spacing.timezone-aware-sendingSee full patternB2B sequences that fire at 3am local time or Saturday afternoon land in the recipient's inbox alongside spam and weekend cleanup, tanking open rates and conversion. Without a business-hours gate in the scheduler, computed send timestamps push cold outreach outside the 9-5 Monday-Friday window when decision-makers actually read email, degrading user experience for both senders configuring campaigns and recipients receiving off-hours pings that signal low-effort automation.
Why this severity: Low because the impact is reduced engagement and sender reputation drift, not data loss or outages.
campaign-orchestration-sequencing.cadence-spacing.business-hoursSee full patternA 2-day follow-up configured Friday lands Sunday when `exclude_weekends` is missing, so the prospect sees your nurture step buried under Monday morning inbox triage instead of arriving mid-Tuesday when it was meant to reinforce the initial touch. Campaigns that add calendar days instead of business days collapse sequence cadence across weekends, breaking the carefully-spaced rhythm sales and lifecycle teams designed and reducing the user experience quality of the automation tool itself.
Why this severity: Low because weekend sends degrade engagement timing but do not break delivery, billing, or data integrity.
campaign-orchestration-sequencing.cadence-spacing.weekend-exclusionSee full patternA sequence that cannot detect replies is operationally blind — it continues sending follow-ups to contacts who have already engaged, replied, or expressed interest. The next scheduled step lands in the inbox of a prospect who replied two days ago asking for a demo, with no human having seen the reply and no system action taken. iso-25010:2011 reliability.fault-tolerance marks this as a reliability gap: the system lacks a mechanism to adapt its behavior to the most important signal a sequence can receive. In practice, the absence of reply detection turns outreach sequences into one-way blast channels that actively frustrate engaged prospects.
Why this severity: High because no reply detection means engaged contacts continue receiving automated outreach after responding, damaging the relationship at the highest-intent moment.
campaign-orchestration-sequencing.reply-engagement.reply-detectionSee full patternDetecting a reply and not acting on it is worse than not detecting it at all — the system now has evidence that a human responded and chose to continue sending anyway. CWE-841 (Improper Enforcement of Behavioral Workflow) applies: the reply event is received but the workflow does not enforce the expected state transition (active → replied). Pending BullMQ or Sidekiq jobs scheduled before the reply are the specific failure vector: updating the enrollment status in the database does not cancel jobs already enqueued. The contact receives the next step at the scheduled time despite the status update, because the job handler may not re-check enrollment status before sending.
Why this severity: High because detecting a reply without cancelling pending send jobs means the next scheduled step delivers regardless of enrollment status, continuing automated outreach after human engagement.
campaign-orchestration-sequencing.reply-engagement.reply-pauses-sequenceSee full patternAn OOO auto-responder and a genuine human reply are structurally identical inbound emails. Without explicit OOO detection, the system treats every `Auto-Submitted: auto-replied` as a real engagement signal — permanently pausing sequences, creating rep notifications, and potentially marking the contact as 'replied' when they are simply on vacation. The inverse failure is equally bad: some implementations silently discard all inbound emails to avoid OOO noise, missing genuine replies in the process. iso-25010:2011 reliability.fault-tolerance requires that the system handle this expected abnormal input class explicitly, not by accident.
Why this severity: Medium because undetected OOO messages either incorrectly terminate sequences (false-positive reply) or create spurious rep notifications, degrading signal quality and operational trust.
campaign-orchestration-sequencing.reply-engagement.ooo-detectionSee full patternApple Mail Privacy Protection (MPP), launched in iOS 15, pre-fetches email content through a proxy — generating open events for emails that were never read by a human. Systems that branch or score exclusively on open events are routing contacts based on machine-generated signals, not human intent. A contact's sequence may advance to the "engaged" branch because Apple's privacy proxy opened the email — no human action required. iso-25010:2011 functional-suitability.functional-correctness classifies this as a functional accuracy defect: the system computes engagement from unreliable inputs, producing systematically incorrect routing for a large portion of Apple Mail users.
Why this severity: Low because open-only engagement scoring produces incorrect branching for Apple Mail users without causing immediate data loss — the harm is gradual misdirection of sequence logic.
campaign-orchestration-sequencing.reply-engagement.multi-signal-engagementSee full patternGDPR Art. 21 grants the right to object to processing; GDPR Art. 17 grants the right to erasure; CAN-SPAM Act Sec. 5 requires honoring opt-out requests within 10 business days; CCPA Sec. 1798.120 provides the right to opt out of sale. Each of these rights is violated when an unsubscribe updates only the `contacts` table while active sequence enrollments continue executing. The enrollment record is a separate processing instruction — the system knows it should send the next email and will do so unless the enrollment is explicitly terminated. Updating a contact field is not enough: pending queue jobs already scheduled will execute regardless of any contact-level flag unless the jobs themselves are cancelled.
Why this severity: High because continuing sequence sends after an unsubscribe, hard bounce, or spam complaint violates GDPR Art-21, CAN-SPAM Act Sec-5, and CCPA Sec-1798.120 — legal obligations with direct regulatory exposure.
campaign-orchestration-sequencing.reply-engagement.negative-engagement-exitSee full patternA scoring model that lives as scattered `contact.score += 10` calls across twelve event handlers cannot be audited, cannot be versioned, and cannot be changed without grepping the entire codebase for every increment site. iso-25010:2011 maintainability.analysability formalizes the problem: the system is not analyzable without exhaustive code review. In practice, this means sales teams receive qualified leads whose score no one can explain, scoring bugs are introduced by developers who miss a call site, and there is no record of what the model was when a particular lead was scored — critical when a lead disputes their classification or when an audit demands a scoring rationale.
Why this severity: High because an undocumented scoring model cannot be audited, versioned, or safely changed — scoring bugs propagate silently and lead qualification decisions lack traceable rationale.
campaign-orchestration-sequencing.lead-scoring.model-documentedSee full patternA nightly batch score recalculation means a contact who crosses the SQL threshold at 9am on a Tuesday does not trigger the sales notification until 2am Wednesday — a 17-hour delay on the highest-intent moment in the lead lifecycle. iso-25010:2011 performance-efficiency.time-behaviour captures the failure: the system's response time for a threshold-crossing event is measured in hours, not minutes. In B2B SaaS where intent signals decay rapidly, delayed scoring translates directly to missed pipeline: the contact who booked a competitor demo at 10am was already gone before the batch ran.
Why this severity: Low because batch-only scoring delays threshold actions by hours — a significant conversion impact but not a data integrity failure or compliance risk.
campaign-orchestration-sequencing.lead-scoring.realtime-updatesSee full patternLead scores that accumulate without triggering any action are a vanity metric. The system faithfully increments a number, the number crosses 100, and nothing happens — no CRM task, no Slack notification, no lifecycle stage change. CWE-691 (Insufficient Control Flow Management) applies: the application collects state (score) but fails to enforce the behavioral transitions that state is supposed to trigger. iso-25010:2011 functional-suitability.functional-completeness rates the scoring system as incomplete when threshold actions are missing. In practice, sales-ready leads sit uncontacted because the handoff mechanism was never wired.
Why this severity: High because scores without threshold actions mean qualified leads are never routed to sales, producing invisible pipeline leakage from a system that appears to be working correctly.
campaign-orchestration-sequencing.lead-scoring.threshold-actionsSee full patternWithout score decay, a contact who was highly engaged 18 months ago — opened five emails, clicked twice, visited the pricing page — retains a high score and continues surfacing as a hot lead. Sales receives contacts who have not interacted in over a year, the pipeline confidence drops, and the scoring model loses calibration. iso-25010:2011 functional-suitability.functional-correctness categorizes this as an accuracy defect: the score no longer reflects the contact's current engagement probability. Score decay is also an anti-sycophancy mechanism in the scoring model itself — it resists inflating lead quality based on historical activity that no longer predicts current intent.
Why this severity: Low because missing decay accumulates stale high scores over months — a gradual calibration failure that degrades sales pipeline quality, not an immediate runtime error.
campaign-orchestration-sequencing.lead-scoring.score-decaySee full patternA lead scoring system with no CRM integration produces qualified leads that exist only in the application database — invisible to the sales team until someone manually exports and imports them. iso-25010:2011 reliability.fault-tolerance applies because the lead handoff is a single-point-of-human-failure: if no one runs the export, the lead is never worked. Beyond operational risk, missing bidirectional sync means the CRM's deal stage and rep assignment cannot inform sequence behavior — a contact who has already progressed to negotiation continues receiving top-of-funnel nurture emails because the sequencing system has no visibility into CRM state.
Why this severity: Low because missing CRM integration requires manual export for every qualified lead — an operational failure point but not a data corruption or compliance risk.
campaign-orchestration-sequencing.lead-scoring.crm-integrationSee full patternRun this audit in your AI coding tool (Claude Code, Cursor, Bolt, etc.) and submit results here for scoring and benchmarks.
Open Campaign Orchestration & Sequencing Audit