Automation
Sequences with reply-exit, workflows on domain events, rules conditioned on the audit log. Why automation reads from the event log rather than firing as side-effects on the writer's path, what that costs in latency, and what it gives back in recoverability.

The question that determined the shape of the automation engine: should rules run as side-effects on the writer's path, or as subscribers to a durable event log. A naive automation engine fires rules inline. The operator marks a deal closed-won, the inline handler runs immediately, the proof-of-craft email goes out, the follow-up task gets created, the audit-log entry is written last. This is the path of fewest moving parts and the lowest latency, and it is also the path where every rule misfire is invisible because the audit log was written after the side-effect, not before. The rule fired, the email sent, the customer received it; the only record of why it fired is in the rule's own configuration at the moment of firing, which the operator may have changed since. Inline automation is fast and brittle. I chose the second path: every meaningful mutation in Canopy writes to the audit log first. Rules read from the log and act. That is slower by a few hundred milliseconds than firing rules inline; it is also the reason a rule that fires wrong is recoverable. The mutation records the actor and the change. The action records the rule that fired it and the input it was reading. The audit log holds both. So the question 'why did this email send' has a query, not a debugging session against an inline handler's stack trace and a rule configuration that may have changed since. I considered the no-code automation-builder pattern: drag-and-drop conditions, multi-path branches, A/B-tested templates, the works. I rejected it for the same reason I reject most product additions. Buyers who genuinely need lifecycle marketing software are well served by the established players in that category and have already chosen one. Buyers who have not chosen yet need the next ten operational steps to happen without anyone remembering them, not a sprawling lifecycle program that nobody in the building understands by month four. Lifecycle marketing software is a real product category that deserves to exist; Canopy is just not in it. The mechanism splits into three primitives: sequences, workflows, and rules. Each has a narrow purpose and reads from the audit log in a different way. Sequences are multi-step outbound with reply-exit. A prospect enters a sequence at the operator's invocation; the sequence sends step one immediately or on a delay; step two follows after a configured interval; the prospect can be removed from the sequence by replying to any of the messages, by being moved to a deal stage that exits the sequence, or by the operator manually stopping it. Reply-exit is the part that matters most: a prospect who replies stops receiving the next message in the chain because the audit log writes the inbound reply event, the sequence's exit-condition rule reads that event, and the next step is cancelled. Without reply-exit, automated outbound chains keep firing into a conversation the prospect has already started, and the result is the kind of email cadence that makes recipients hate the sender. Reply-exit is non-optional for the same reason brakes are non-optional on a car. Workflow rules fire on domain events: a deal moves stage or changes owner, a quote is accepted, an invoice is paid, a form is submitted, a date comes due, a contact goes quiet for a number of days. Twenty-five triggers, conditions grouped as all or any, up to ten steps from fourteen actions, and an otherwise branch for when the conditions are not met. Nothing a rule or a sequence changes sets off a rule that watches for changes, so rules cannot loop, and a rule switched on today does not reach back to fire for things that happened before it. Test this rule runs a saved or half-built rule against any record and shows what would happen, step by step and why a step would be refused, without saving or sending anything. Rules are the lowest-level primitive: they condition on what changed in the audit log, not just what was triggered. The difference matters. A workflow fires on 'a deal was moved to proposal'; a rule fires on 'a deal was moved from qualified to proposal' (the from-state matters), or 'a deal was moved to proposal by operator X' (the actor matters), or 'a deal was moved to proposal AND its value is above twenty-five thousand dollars' (the field condition matters). Rules read the before-and-after snapshot from the audit log entry, not just the entry's event type, which means rules can be specific about what triggered them in ways workflows cannot. The cost of this expressiveness is that rules are a lower-level surface and require more thought to write correctly; the benefit is that the same expressiveness covers cases that would otherwise need custom code. Email templates are each teammate's own library: a subject and a body with merge fields that fill from the record at send time, taken out of the picker by archiving rather than deleting. A merge field the record cannot fill stops that one email rather than sending the braces, and the step is recorded as not sent with the reason. So 'what did this prospect actually receive last Tuesday' is answered by the enrollment's own history, which says what every step did, when, and why a step did not go out, rather than by reconstructing it from a mail platform's logs. Bulk actions cover the cases where automation is overkill. The operator wants to send a one-time outbound to a list of contacts, not enroll them in a sequence; the bulk-action tooling lets them compose the message, select the contacts, preview the merged copy, and send. Each bulk action writes a single audit-log entry with the affected contact IDs, the message content, and the actor. The audit log lets the buyer answer 'who sent this email to these fifty contacts' without sifting through fifty individual send records. One more primitive sits beside those three, because the thing a growing team needs most is a way to stop. An approval process decides which deals, quotes or invoices need a sign-off before they move on, with up to two steps and a named teammate, any manager or several of them at each. While a request waits the record is locked, and the lock holds everywhere the record can be changed, the phone and the rules included, so a quote a manager has not yet seen cannot be emailed by a rule that fired in the meantime. Every automated action writes the rule that fired it back to the audit log. This is the load-bearing inversion of the inline-automation path. When something automates that should not have, the operator opens the audit log, finds the action, reads the rule that fired it, and either tunes the rule or disables it. The trail does not require a debugging session against a vendor's internal logs because the trail is in the buyer's own database. The same query that explains why an email sent also explains why a follow-up task got created or why a workflow chained into another workflow. The honest exclusion: this is not a marketing automation suite. A sequence step can now test what happened, opened, clicked, replied, a tag, a stage, and send the enrollment one way or the other, forward only, and the sequence's page counts the whole journey step by step. What it will not become is a thousand-step lifecycle program with cohort analysis and predictive scoring, because the operators it is built for would not know how to operate that surface, and the operators who would are not buying small-business engagements. The operational consequence the buyer feels is the one the architecture targets: when something automates that should not have, the answer is one query away. The rule that fired is named in the audit log entry. The before-and-after state is retrievable. The rollback is a single bulk action against the affected records. The next ten things happen without the operator remembering them, and when one of those ten was wrong, the system explains itself instead of obscuring the cause. That is the version of automation that fits the architecture, and it is the one that holds up over months of operation.