<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Glassjaw Blog</title>
  <link>https://glassjaw.ai/blog/</link>
  <atom:link href="https://glassjaw.ai/rss.xml" rel="self" type="application/rss+xml"/>
  <description>Notes from the Glassjaw team on CRM strategy, lifecycle marketing, data and personalisation.</description>
  <language>en</language>
  <lastBuildDate>Mon, 28 Sep 2026 09:00:00 +0000</lastBuildDate>
  <item>
    <title>Snowflake, CDP and the experience layer: a conversation between Zeotap and Glassjaw</title>
    <link>https://glassjaw.ai/blog/2026-09-28-snowflake-cdp-and-the-experience-layer/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-09-28-snowflake-cdp-and-the-experience-layer/</guid>
    <pubDate>Mon, 28 Sep 2026 09:00:00 +0000</pubDate>
    <category>Data &amp; personalisation</category>
    <description>Shorter procurement, governance inherited rather than mirrored, and one set of definitions behind both the dashboard and the campaign tool. Zeotap and Glassjaw on what a warehouse-native CDP changes for activation teams, and when it is the wrong answer.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-09-28-snowflake-cdp-and-the-experience-layer.webp" alt="Abstract cover art: linked nodes and edges on a dark blue field" width="1792" height="1024"></p>
<p>Ahead of Snowflake World Tour, Paul McCord, Alliances Director at Zeotap, and Aleksandra (Sasha) Chernykh, Co-Founder &amp; Lead Consultant, Glassjaw, compared notes on what actually changes for activation teams when the customer data platform lives inside the warehouse and where the model still hits its limits.</p>
<h2>There's a lot of noise about composable and native CDPs on Snowflake this year. What's actually different in the conversations you're having with customers, versus twelve months ago?</h2>
<p><strong>Paul McCord, Zeotap:</strong> The procurement conversation has shortened noticeably. A year ago, most customers came in evaluating a CDP as a standalone vendor decision: security review, InfoSec, the full cycle. Today, more of them arrive with Snowflake already approved internally and treat the CDP as an additional module on a platform they already trust. That shifts the buying committee, the timelines and, frankly, the objections. The question is less "can we trust this vendor" and more "how do we get this live inside our existing governance."</p>
<p><strong>Aleksandra (Sasha) Chernykh, Glassjaw:</strong> The conversation has moved from access to agreement. A year ago, many CRM teams were asking data teams for exports so they could build audiences in their own tools. Now, they increasingly want to work from the definitions analytics already trusts. "Active customer", "lapsed", "high value": when those numbers disagree between the dashboard and the campaign tool, the CRM team loses the argument every time. We're seeing CRM and data teams come together much earlier, with better questions about definitions, ownership and activation.</p>
<h2>Where do you see teams struggle when the CDP sits outside the warehouse?</h2>
<p><strong>Aleksandra (Sasha) Chernykh, Glassjaw:</strong> I see the same three things break. The first is timing. When data has to be copied out before anyone can act on it, the sync schedule quietly becomes the real send time. That is how a customer who bought an hour ago still gets the abandoned-cart email, discount included.</p>
<p>The second is definitions. Each team rebuilds its cohorts in the tool it owns, the numbers drift apart, and nobody can say which list is right.</p>
<p>The third is measurement. Behavioural events land in the activation tool but don't always make it back into the analytical layer cleanly, so teams can see who clicked but struggle to connect that activity to what actually changed. The result is hundreds of segments and no way to tell which ones earn their keep.</p>
<p><strong>Paul McCord, Zeotap:</strong> The pattern I'd add is what happens to governance. When customer data is copied into a second environment, the row access policies, masking rules and role-based controls have to be maintained in two places. Teams get it right on day one, and then over eighteen months the two systems drift. That's not a criticism of any specific architecture — it's just what happens when the same rules live in two places and two teams own them.</p>
<h2>When the CDP runs natively in Snowflake, what changes in practice for the activation team?</h2>
<p><strong>Paul McCord, Zeotap:</strong> Three things, in the order teams tend to notice them. First, no data transit at activation, which removes a class of compliance conversations. Second, inherited governance: the access rules already in the warehouse apply to the CDP automatically, not by mirroring. Third, and this is the one that matters most for activation teams: the features engineered for analytics and the features used for segmentation live in the same place. You stop rebuilding definitions of "active customer" or "high-value cohort" in two systems that don't quite agree with each other.</p>
<p><strong>Aleksandra (Sasha) Chernykh, Glassjaw:</strong> The biggest change is that targeting can become much closer to the actual customer state. Imagine a customer who browsed repeatedly, purchased yesterday and has since become a high-value customer. Instead of CRM working from yesterday's exported segment while analytics has the newer picture, both can work from the same underlying data and definitions. That changes more than audience building. Suppression, prioritisation, personalisation and next-best-action decisions can all become more reliable. For the activation team, the value isn't really "the CDP is in Snowflake". It's that fewer assumptions sit between what the business knows about a customer and the experience that customer actually receives.</p>
<h2>Where's the native model the wrong answer?</h2>
<p><strong>Paul McCord, Zeotap:</strong> When Snowflake isn't the strategic Data Cloud, or when a team is running multiple warehouses in parallel and wants to keep that optionality, the native route costs more than it gives back. Same story if the warehouse itself is immature, the CDP will inherit whatever governance gaps are already there. In those cases, the external Zero-Copy model is the right answer, not a fallback.</p>
<p><strong>Aleksandra (Sasha) Chernykh, Glassjaw:</strong> When the problem isn't the data. If the emails go out too often or say the wrong thing, moving the CDP won't fix that, and it's one of the most common issues I find in CRM audits. I'd also be cautious where Snowflake isn't genuinely the organisation's central customer-data layer yet. Native architecture is powerful when the foundation underneath it is mature. It shouldn't become a reason to redesign an entire data estate when the actual problem is strategy, execution or operating model.</p>
<h2>You're both at Snowflake World Tour this month. What conversation do you want to have with people who stop by?</h2>
<p><strong>Aleksandra (Sasha) Chernykh, Glassjaw:</strong> The question I'd love to hear is: "We have Snowflake, we have a CRM platform, and we have plenty of customer data, so why are our customer experiences still disconnected?" That's where the interesting conversation starts. The next phase isn't about collecting more data. It's about shortening the distance between what a brand knows about a customer and what it actually does with that knowledge.</p>
<p><strong>Paul McCord, Zeotap:</strong> The most useful conversations I have at these events are with teams who've already made the Snowflake bet and are trying to work out what should stay in the warehouse and what shouldn't. If that's you, come and find us, the honest answer is usually more interesting than the pitch.</p>]]></content:encoded>
  </item>
  <item>
    <title>Handing a CRM programme back to an in-house team</title>
    <link>https://glassjaw.ai/blog/2026-09-22-handing-back-the-programme/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-09-22-handing-back-the-programme/</guid>
    <pubDate>Tue, 22 Sep 2026 09:00:00 +0000</pubDate>
    <category>CRM strategy</category>
    <description>A good handover transfers decisions, not just logins. What to document, how to run the parallel period, and what tends to break in the first ninety days after.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-09-22-handing-back-the-programme.webp" alt="Abstract cover art: concentric arcs around a bright focal point on a dark blue field" width="1792" height="1024"></p>
<p>The handovers that go badly are rarely the ones where something is broken. They are the ones where everything works. Every journey is live, every dashboard is green, and six weeks later nobody in the building can say why the win-back programme waits ninety days rather than sixty.</p>
<p>The assets transfer fine. Logins, templates, segment definitions and documentation all move in an afternoon. What does not move is the reasoning, and a programme whose reasoning has been lost degrades quietly. Nobody notices for a quarter, because the campaigns keep sending.</p>
<p>We think an engagement should be designed to end well from the day it starts, and the test of whether it did is not whether the new team can keep the programme running. It is whether they can change it.</p>
<h2>Design the exit before you design the first sprint</h2>
<p>The right time to agree how an engagement ends is the week it begins. By the time somebody raises it in month eighteen, a set of dependencies has formed that nobody chose.</p>
<p>Three things should be settled at the start, in writing:</p>
<ul>
<li>Which capabilities are being built in-house and which are being bought for the duration. A team that never intends to run deliverability itself needs a different plan from one that does.</li>
<li>Who on the client side shadows each workstream, by name, with time protected for it. A shadow with no allocated hours is a name on a slide.</li>
<li>What the handover artefacts are, and where they live. In the client's own systems from day one, not in an agency drive to be exported later.</li>
</ul>
<p>That third point sounds administrative and is the one that decides the rest. Documentation written in the client's environment gets read and corrected as the work happens. Documentation exported at the end is written once, by someone in a hurry, and read by nobody.</p>
<p>The same discipline applies in the other direction when an engagement starts, and we set out what a good brief contains in <a href="https://glassjaw.ai/blog/2026-04-18-briefing-an-agency/">briefing an agency</a>. A brief that names the intended end state produces a much easier handover than one that does not.</p>
<h2>Transfer the decisions, not just the assets</h2>
<p>Every mature programme is a pile of decisions that look arbitrary from outside. The sunset window is one hundred and eighty days. The basket journey carries no discount. Two segments are excluded from the weekly newsletter. Push goes before email on one journey and after it on another.</p>
<p>Each of those had a reason, usually a test result, a complaint spike, a legal review or a commercial argument. Without the reasons, the new team faces an unpleasant choice. Preserve everything, which freezes the programme, or change things and rediscover the original problems.</p>
<p>So the central handover artefact is a decision log. One line per decision, with the date, the person, the reason and the evidence. It does not need to be elegant. It needs to be complete enough that an incoming manager can tell a deliberate choice from an accident.</p>
<p>We write it continuously rather than at the end, because a decision log assembled retrospectively is a reconstruction. Two of the entries will be wrong, and they will be the two that matter.</p>
<h2>The list of things that actually have to move</h2>
<p>Beyond the decision log, the handover has a fixed inventory. Working through it takes longer than people budget, and skipping items is how the first quarter goes wrong.</p>
<ol>
<li><strong>Access and ownership.</strong> Every platform, with named owners and a billing contact. Every integration's credentials, with their rotation schedule. Any account still registered to an agency email address is a future outage.</li>
<li><strong>Sending domains and DNS.</strong> Which records exist, who may change them, and how a change is requested. <a href="https://glassjaw.ai/blog/terms/deliverability/">Deliverability</a> fails slowly and silently when this is unclear, and it is the single most common gap we find after a transition.</li>
<li><strong>Data models and contracts.</strong> The models behind the <a href="https://glassjaw.ai/blog/terms/single-customer-view/">single customer view</a>, their tests, and the <a href="https://glassjaw.ai/blog/terms/data-contract/">data contract</a> with each upstream system. What the field means, who produces it, how often, and what happens when it is late.</li>
<li><strong>Naming and segment conventions.</strong> How campaigns, segments and journeys are named, and why. This is the convention that decays fastest after a handover, and reporting decays with it.</li>
<li><strong>The message inventory.</strong> Every broadcast, trigger and transactional template, with its owner, trigger, audience and last review date. Including the ones marketing does not own.</li>
<li><strong>Consent and preference handling.</strong> How the <a href="https://glassjaw.ai/blog/terms/preference-centre/">preference centre</a> writes back, where consent is stored, and what the timestamp and source look like for each channel.</li>
<li><strong>Measurement definitions.</strong> What each headline metric counts, in words a finance colleague can check. Where holdouts sit and how they are maintained.</li>
<li><strong>Incident runbooks.</strong> What to do when a sync fails, a send goes to the wrong segment, a complaint rate spikes, or a template renders wrongly. Each with the first three steps and who to call.</li>
<li><strong>The roadmap and its funding case.</strong> Not just what is next, but the argument that got it funded, which is the part that has to be repeated next year. We covered how to build that argument in <a href="https://glassjaw.ai/blog/2025-12-02-roadmap-finance-will-fund/">a roadmap finance will fund</a>.</li>
</ol>
<p>Read that list as a checklist to complete before the last month, not during it.</p>
<h2>Run it in parallel, in both directions</h2>
<p>A handover that consists of documents and a workshop is a hope rather than a plan. The transfer has to be rehearsed while there is still someone to catch the mistakes.</p>
<p>We run two phases. In the first, the agency continues to ship and the in-house team reviews everything before it goes out. That surfaces the tacit rules nobody wrote down, because the reviewer asks why.</p>
<p>In the second, the roles reverse. The in-house team builds, schedules and sends, and the agency reviews. This phase is the one that matters, and it needs to run long enough to include a full cycle of the programme's real work. A month of business as usual, at least one peak or campaign moment, one incident, and one reporting cycle.</p>
<p>If the second phase produces no questions at all, something is wrong. Either the team is not really doing the work, or they are not yet confident enough to say what they do not understand.</p>
<h2>What tends to break in the first ninety days</h2>
<p>Some failures are predictable enough to plan for directly.</p>
<p>Deliverability drifts, because nobody inherited the weekly check. A key person leaves within the first two quarters and takes the undocumented query with them. A vendor renewal arrives with nobody who remembers what was negotiated. A scheduled job fails and the alert goes to a mailbox that was deactivated with the agency's accounts.</p>
<p>The counter to all four is the same. Name the recurring obligations explicitly, with owners and a frequency, and put them in the same calendar the team already uses. Weekly deliverability review, monthly message inventory check, quarterly consent audit, annual vendor review.</p>
<p>Then agree a light support arrangement for the first quarter. Not a retainer that recreates the dependency, but a defined number of hours for questions, with the expectation that the number falls each month. If it does not fall, the handover has not finished.</p>
<p>The honest measure comes a little later. Six months on, has the team shipped something you would not have built. If they have, the capability transferred. If the programme looks exactly as you left it, what transferred was only the operating manual.</p>]]></content:encoded>
  </item>
  <item>
    <title>The questions to ask when choosing a CRM stack</title>
    <link>https://glassjaw.ai/blog/2026-09-08-choosing-your-crm-stack/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-09-08-choosing-your-crm-stack/</guid>
    <pubDate>Tue, 08 Sep 2026 09:00:00 +0000</pubDate>
    <category>Platforms &amp; implementation</category>
    <description>How to choose between engagement platforms, CDPs, warehouses and reverse-ETL tools by asking about data ownership, cadence, running cost and team fit.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-09-08-choosing-your-crm-stack.webp" alt="Abstract cover art: stacked isometric blocks on a dark blue field" width="1792" height="1024"></p>
<p>Stack selection usually starts with a shortlist of vendor names and ends with a decision nobody can explain eighteen months later. The names are the least useful place to begin.</p>
<p>Start instead with the tool classes. Four of them cover almost everything a CRM programme needs, and most confusion in selection comes from two vendors in different classes being compared as if they did the same job.</p>
<p>We are deliberately not ranking products here. The right combination depends on your data, your volumes and the team you actually have, and the same vendor can be an excellent fit for one brand and a poor one for its competitor.</p>
<h2>Learn the four tool classes before the demos</h2>
<p><strong>The engagement platform</strong> sends the messages. It holds journeys, campaigns, templates, frequency rules and channel delivery across email, push, SMS, in-app and web. Braze, Bloomreach, Insider and Maestra sit in this class, among others.</p>
<p><strong>The customer data platform</strong> collects, resolves and segments customer data, then pushes audiences to downstream tools. Some engagement platforms include CDP-style capability, which is where category confusion usually starts.</p>
<p><strong>The warehouse</strong> is where your customer, order, product and event data lives in queryable form. Snowflake and Databricks are common choices, alongside the cloud-native options.</p>
<p><strong>The reverse-ETL tool</strong> moves data from the warehouse into operational tools, so a segment defined in SQL becomes an audience in the engagement platform. Hightouch is the best-known example of this class.</p>
<p>A stack can combine these in several shapes. Warehouse plus reverse-ETL plus engagement platform is common now, and so is CDP plus engagement platform with no warehouse involvement.</p>
<p>Both shapes work. What does not work is buying two tools that each assume they own segmentation.</p>
<h2>Start from the warehouse question</h2>
<p>The first real question is where the single version of your customer will live, and who controls it.</p>
<p>If you already have a warehouse with clean order and event data, build the stack around it. Define segments in SQL, sync them out, and keep the engagement platform focused on delivery and journey logic. You get one definition of "active customer" that marketing and finance can both point at.</p>
<p>If you have no warehouse and no data team, a CDP or a data-capable engagement platform will get you live much faster. The trade-off is that your segment logic now lives inside a vendor, and moving it later is real work.</p>
<p>Questions to ask in either case:</p>
<ul>
<li>Who can change a segment definition, and how long does that take?</li>
<li>If we replaced the engagement platform next year, what would we have to rebuild?</li>
<li>Where is the identity resolution happening, and can we inspect its rules?</li>
<li>Can analytics reproduce a marketing segment independently?</li>
</ul>
<h2>Ask what the engagement platform is actually for</h2>
<p>Demos tend to showcase journey builders. Useful, but rarely the deciding factor. The differences that matter show up in operations.</p>
<p>Work through these with each vendor, using your own scenarios rather than theirs:</p>
<ul>
<li>Channels: which do you need on day one, and which are genuinely native rather than a partner integration?</li>
<li>Volume and velocity: peak sends per hour, and how real-time the triggers are in practice.</li>
<li>Deliverability controls: dedicated IP options, warm-up support, seed testing, and how sending reputation is managed. If you are starting from a new IP, our note on <a href="https://glassjaw.ai/blog/2026-05-26-ip-warming-from-zero/">IP warming from zero</a> covers what that process demands.</li>
<li>Localisation: how multi-language content is handled inside one journey.</li>
<li>Permissions: whether you can let a regional team build without letting them send.</li>
<li>Data in and out: event ingestion limits, and whether you can export raw event data on your own schedule.</li>
</ul>
<p>That last one matters more than it looks. If you cannot get event-level data back out cheaply, your revenue reporting is stuck inside the vendor's definitions, which is the problem we describe in <a href="https://glassjaw.ai/blog/2026-07-28-crm-to-revenue-measurement/">CRM to revenue measurement</a>.</p>
<h2>Price the running cost, not the licence</h2>
<p>Licence fees are the visible number and often not the largest one. Build a two-year cost view that includes the parts vendors do not quote.</p>
<p>Count implementation, which is usually three to six months of work for a mid-sized programme. Count warehouse compute if segments run frequently. Count data volume growth, since most contracts price on profiles or events and both grow faster than expected.</p>
<p>Count the internal cost too. A stack that needs a data engineer to change a segment has a permanent staffing requirement attached to it, and that cost outlives any discount you negotiate at signature.</p>
<p>Then ask about the exit. Contract length, data export format, notice period, and what happens to your journey logic if you leave.</p>
<h2>Match the stack to the team you have</h2>
<p>The most common selection error we see is buying for the team the company plans to hire rather than the one it has.</p>
<p>A warehouse-first stack rewards a team with SQL skills and analytics support. A CDP-led stack rewards a marketing team that needs to move without engineering. Neither is more advanced, and they fail in different ways.</p>
<p>Run a proof of concept on one real programme, not a sandbox. Build your actual onboarding journey, with your actual data, and see how long each step takes. Two weeks of that beats two months of feature comparison.</p>
<p>Where a selection needs an independent view, or the build needs hands, that is what our <a href="https://glassjaw.ai/services/implementation/">implementation</a> team does.</p>
<h2>What to do this week</h2>
<ul>
<li>Write down which of the four tool classes each product in your current stack occupies, and mark any job that two tools both claim.</li>
<li>Pick one segment definition and trace who can change it, where it lives, and how long a change takes to reach a send.</li>
<li>Build a two-year cost view for your current stack including implementation, compute and internal time, then compare it to the licence figure you usually quote.</li>
</ul>]]></content:encoded>
  </item>
  <item>
    <title>A testing cadence that survives a busy quarter</title>
    <link>https://glassjaw.ai/blog/2026-08-18-testing-cadence/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-08-18-testing-cadence/</guid>
    <pubDate>Tue, 18 Aug 2026 09:00:00 +0000</pubDate>
    <category>Testing &amp; optimisation</category>
    <description>How to keep a CRM testing programme running at a steady weekly rhythm with a real backlog, honest sample sizes, one variable at a time and a decision log.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-08-18-testing-cadence.webp" alt="Abstract cover art: a bar series under a trend line on a dark blue field" width="1792" height="1024"></p>
<p>Almost every CRM team we meet intends to test more. Very few do, and the reason is consistent. Testing is the first thing dropped when the campaign calendar gets heavy, because it is the only item with no external deadline.</p>
<p>The fix is not more enthusiasm. It is a cadence: a fixed number of tests in flight, a fixed day for decisions, and a backlog that someone owns. Rhythm beats ambition here, because a small test running every week compounds and a big test planned every quarter rarely ships.</p>
<p>This post covers how we set that rhythm up, size tests honestly, and keep the results from evaporating the moment the person who ran them changes role.</p>
<h2>Fix the rhythm before the roadmap</h2>
<p>Start by deciding how many tests you can genuinely have live at once. For most teams sending a few campaigns a week, the answer is one or two. Anything more and the audiences start overlapping.</p>
<p>Then put two recurring slots in the calendar. A short weekly session to launch what is ready and check what is running. A longer monthly session to read completed tests and update the backlog.</p>
<p>Assign one owner for the backlog. Not a committee. The owner decides what goes next, and their job is to make sure the queue is never empty when the weekly slot arrives.</p>
<p>Keep the backlog visible and ranked. We rank on expected impact divided by effort, and we require a written hypothesis before an idea can enter the queue at all.</p>
<h2>Size the test honestly, then set the stop rule</h2>
<p>Most CRM tests are underpowered, which is why so many read as "no clear winner". Before launching, work out the sample you need for the effect size you care about.</p>
<p>A rough guide we use: detecting a one percentage point difference on a ten per cent click rate needs tens of thousands of recipients per cell. Detecting a twenty per cent difference in conversion on a small segment may be impossible at your volume, and that is useful to know before you spend two weeks on it.</p>
<p>Set the stop rule at launch, not during the test:</p>
<ul>
<li>The fixed sample size or the fixed end date, whichever you chose.</li>
<li>The metric that decides the outcome, named exactly, with the measurement window.</li>
<li>The guardrail metrics that would stop the test early, such as unsubscribe rate or complaint rate.</li>
</ul>
<p>Then stop looking at it daily. Peeking at results and calling a winner when the line crosses is the most common way CRM teams convince themselves of things that are not true.</p>
<p>When a test does produce a winner, check that it holds against revenue rather than clicks. The reasoning behind that sits in our note on <a href="https://glassjaw.ai/blog/2026-07-28-crm-to-revenue-measurement/">CRM to revenue measurement</a>.</p>
<h2>Test one variable, and make it a big one</h2>
<p>Change one thing per test. If you change the subject line, the layout and the send time together, a win tells you nothing you can reuse.</p>
<p>More importantly, make the one thing substantial. Testing two near-identical subject lines wastes a slot and returns a result you cannot detect. Testing a discount-led message against a value-led message returns something you can build on.</p>
<p>A rough order of impact we work through with most programmes:</p>
<ul>
<li>Who receives it. Segment definition and eligibility rules move numbers more than copy does.</li>
<li>When it arrives. Timing, frequency and the trigger delay on behavioural messages.</li>
<li>What it offers. Incentive level, incentive type, and whether there is an incentive at all.</li>
<li>What it says. Positioning and message angle, before subject line wording.</li>
<li>How it looks. Layout, imagery and call-to-action treatment.</li>
</ul>
<p>Most teams start at the bottom of that list because it is the easiest thing to change. Start at the top instead.</p>
<h2>Keep a decision log</h2>
<p>A test result that lives in a chat message has a shelf life of about six weeks. After that the team retests the same thing, usually without realising.</p>
<p>Keep one file with a row per completed test: hypothesis, variants, audience, sample size, result, the decision taken, and the date. Ten lines each, no slide decks.</p>
<p>Record the losers and the inconclusive tests too. Knowing that send-time optimisation made no measurable difference last spring is worth as much as knowing what worked, and it stops the idea coming back every planning cycle.</p>
<p>Review the log before each planning session. The question is simple: what have we already learned that this quarter's plan ignores?</p>
<h2>Retire what has done its job</h2>
<p>Tests are not permanent. Once a variant wins and you roll it out, close the test and move the slot to something new.</p>
<p>Some results do expire. Creative fatigue, seasonal effects and audience mix all shift, so anything that shaped a major programme decision is worth re-running roughly once a year.</p>
<p>Audit your live tests quarterly and kill the ones that have been running for months without reaching their sample size. They are occupying audience and attention for nothing.</p>
<p>If you want an outside team to run this rhythm and hold the decision log, that is a standing part of our <a href="https://glassjaw.ai/services/optimisation/">optimisation</a> work.</p>
<h2>What to do this week</h2>
<ul>
<li>Put a recurring thirty-minute testing slot in the calendar and name one person as backlog owner.</li>
<li>Take the next test you had planned and calculate the sample size it needs before you build it.</li>
<li>Start a decision log with the last five tests you ran, including the ones that were inconclusive.</li>
</ul>]]></content:encoded>
  </item>
  <item>
    <title>The campaign QA checklist we run before every send</title>
    <link>https://glassjaw.ai/blog/2026-08-04-campaign-qa-checklist/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-08-04-campaign-qa-checklist/</guid>
    <pubDate>Tue, 04 Aug 2026 09:00:00 +0000</pubDate>
    <category>Testing &amp; optimisation</category>
    <description>The standing pre-send checklist we work through on every campaign: audience counts, rendering, links, technical checks, sign-off and the first half hour after send.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-08-04-campaign-qa-checklist.webp" alt="Abstract cover art: a bar series under a trend line on a dark blue field" width="1792" height="1024"></p>
<p>Nearly every campaign disaster we have been asked to help with was caused by something small and checkable. A segment saved with the wrong operator. A personalisation token that rendered as raw syntax for every record with a blank name field. A link to a staging domain that nobody clicked because everyone was reading the copy.</p>
<p>None of them were creative failures, and none were caught by an approval process that consisted of forwarding a preview to three people and waiting for replies saying "looks good".</p>
<p>What follows is the checklist we run before every send. It is deliberately boring, it takes about forty minutes on a standard campaign, and it is the same list whether the send is twelve thousand people or two million. The value is in running it the same way every time, so the step that gets skipped is visible.</p>
<h2>Count the audience twice, from two directions</h2>
<p>Start with the audience, because it is the only error you cannot correct after the fact. Everything else can be followed by a fix; the wrong recipients cannot be un-received.</p>
<ol>
<li>Pull the count in the sending platform and, separately, from the warehouse or a second query. If the two disagree by more than a rounding difference, stop and find out why before anything else happens.</li>
<li>Read the <a href="https://glassjaw.ai/blog/terms/segment/">segment</a> definition out loud, in words, to another person. Ambiguity between "and" and "or" survives every visual builder ever made but rarely survives being spoken.</li>
<li>Compare the count with the last comparable send. A change of more than a quarter in either direction needs an explanation, and "we grew" is not one unless someone can point to the growth.</li>
<li>Confirm the suppressions are attached: global unsubscribes, complaints, hard bounces, deceased and data-request suppressions, plus any campaign-specific exclusions.</li>
<li>Check the overlap with anything else going out in the same window, so that a customer is not receiving three messages within an hour from three different owners.</li>
<li>Export twenty real records from the audience and read them. Not a preview — the actual rows, with the fields the template will use.</li>
</ol>
<p>That last step catches more than the other five combined. It is also where you notice that a segment you inherited quietly includes test accounts, internal staff or a cohort that should have aged out. Definitions drift, and the cohort work we described in <a href="https://glassjaw.ai/blog/2026-03-20-cohorts-that-change-the-roadmap/">cohorts that change the roadmap</a> is only trustworthy if the underlying segments are re-read occasionally rather than reused on faith.</p>
<h2>Render it where people actually read it</h2>
<p>Preview panes lie. They render a simplified version of a message in a browser, and browsers are not mail clients.</p>
<p>Send to a <a href="https://glassjaw.ai/blog/terms/seed-list/">seed list</a> that covers the clients your audience genuinely uses, which you should confirm from your own data rather than from an industry summary. For most programmes that means the two dominant webmail providers, the desktop client your corporate recipients use, and iOS and Android mail apps on real devices.</p>
<p>Then check, on each:</p>
<ul>
<li>Subject line and preheader as they truncate on a phone, not as they appear in the platform field.</li>
<li>Dark mode. Logos with white backgrounds and text set in near-black are the usual casualties.</li>
<li>Images off. The message must still make sense and still have a clickable route through.</li>
<li>Alt text present on every image that carries meaning, and absent on decorative ones.</li>
<li>Plain-text version, which is still generated in many stacks by a converter that produces unreadable output nobody has looked at in two years.</li>
</ul>
<p>For anything with <a href="https://glassjaw.ai/blog/terms/dynamic-content/">dynamic content</a>, the seed test is not enough. Build a proof list containing one real record per variant, plus the edge cases. The empty field, the very long product name, the customer in a different currency, the person whose only qualifying purchase was returned. Send to that list and read every version.</p>
<p>Set a default for every token and check the default renders sensibly. "Hi there" is a perfectly good fallback; the token name in curly braces is not.</p>
<h2>Click every link with tracking switched on</h2>
<p>Read the message as a recipient would and click everything, in the seed version rather than in the preview, so tracking parameters are present.</p>
<p>What this catches: staging and localhost URLs, expired campaign pages, redirects that drop the tracking parameters. Also links to a category that sold out this morning, and footer links copied from a template built for another market.</p>
<p>Confirm the tracking parameters match the convention your reporting expects, exactly, including case. A campaign tagged inconsistently is not merely untidy. It lands in a different bucket in every downstream model, and the channel inputs feeding work like <a href="https://glassjaw.ai/blog/2026-03-11-mmm-for-crm-teams/">marketing mix modelling for CRM teams</a> are only as good as the tagging behind them.</p>
<p>Check the unsubscribe path last, and check it properly. Click the footer link and confirm the page loads, is legible on a phone and does not require a login. Separately, use the mailbox provider's own control to confirm <a href="https://glassjaw.ai/blog/terms/one-click-unsubscribe/">one-click unsubscribe</a> works from the headers and that the suppression reaches your platform.</p>
<h2>The technical checks nobody enjoys</h2>
<p>These are quick, and they are the ones that protect the programme rather than the campaign.</p>
<ul>
<li>From-name and from-address correct for this stream, and the reply address monitored by a human or routed to the service desk.</li>
<li>Sending domain and stream correct, so a promotional campaign is not going out over the transactional path.</li>
<li>Authentication passing on the seed messages, checked in the received headers rather than assumed from last month's configuration.</li>
<li>Message size within the limit at which the dominant webmail provider clips the content, since a clipped message hides the footer and the unsubscribe link.</li>
<li>Rate and throttling settings appropriate to the volume, particularly for a send larger than your usual pattern, because <a href="https://glassjaw.ai/blog/terms/deliverability/">deliverability</a> problems often start as queueing problems.</li>
<li>Any test sends and internal addresses removed from the audience before scheduling.</li>
</ul>
<h2>Sign-off, timing and who is holding the switch</h2>
<p>Sign-off should name a person per area rather than collecting general approval. In practice that is one owner for audience, one for content and offer accuracy, and one for the technical checks. Three names, recorded against the campaign, with the time they signed.</p>
<p>Check the schedule in the recipient's time zone, and check the day. The most common scheduling error we see is a send set for the correct clock time in the wrong zone, and the second is a campaign scheduled on a date that a public holiday has moved.</p>
<p>Before the send goes into the queue, confirm two things out loud: who can stop it once it starts, and whether they have the permissions to do so. Test that assumption on a quiet day rather than discovering it during a live incident.</p>
<h2>The first half hour after you press send</h2>
<p>The checklist does not end at the send. Someone stays with it for thirty minutes and watches the delivery rate, the bounce rate, the early complaint signals and the destination page's server response.</p>
<p>A landing page that falls over under the opening burst is the failure most often missed, because everyone is watching the email platform. Have the page owner watching their own dashboard at the same time, and agree in advance what the two of you do if either number looks wrong.</p>
<p>The hard part of all this is not writing the list. It is keeping it in use when the campaign is late and the deadline was yesterday, which is precisely when the errors happen. Put it in the workflow tool as a real gate with the three names attached, not in a document that people intend to open.</p>]]></content:encoded>
  </item>
  <item>
    <title>Connecting CRM activity to revenue you can defend</title>
    <link>https://glassjaw.ai/blog/2026-07-28-crm-to-revenue-measurement/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-07-28-crm-to-revenue-measurement/</guid>
    <pubDate>Tue, 28 Jul 2026 09:00:00 +0000</pubDate>
    <category>Testing &amp; optimisation</category>
    <description>A practical route from campaign metrics to CRM revenue: define incremental lift, agree an attribution rule and report numbers finance will accept.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-07-28-crm-to-revenue-measurement.webp" alt="Abstract cover art: a bar series under a trend line on a dark blue field" width="1792" height="1024"></p>
<p>Most CRM teams can tell you their open rate to one decimal place and cannot tell you what the programme is worth. That gap is why CRM budgets get cut first in a tight quarter.</p>
<p>The problem is rarely a lack of data. It is that three different numbers all get called "CRM revenue", nobody has agreed which one is being discussed, and the finance team has quietly stopped believing any of them.</p>
<p>Fixing this is less about analytics sophistication than about agreement. Pick a definition, write it down, instrument it once, and report the same number every month even when it moves in the wrong direction.</p>
<h2>Separate the three numbers people confuse</h2>
<p>There are three distinct figures, and mixing them is the root of most CRM reporting arguments.</p>
<ul>
<li>Attributed revenue: orders where a CRM touch appears in the customer's path, under some attribution rule.</li>
<li>Influenced revenue: revenue from customers who received any CRM contact in a period, with no claim of causation.</li>
<li>Incremental revenue: the difference between what happened and what would have happened without the programme.</li>
</ul>
<p>Attributed revenue is easy to produce and easy to attack. Influenced revenue is almost always a large number and almost always meaningless. Incremental revenue is the only one that answers the budget question.</p>
<p>Report all three if you must, but label them clearly and tell people which one you are managing towards. We manage towards incremental revenue and use attributed revenue as an operational signal for campaign triage.</p>
<h2>Agree an attribution rule before you build the report</h2>
<p>An attribution rule is a business decision dressed as a technical one. Agree it with finance and analytics in a single meeting, and record it in writing.</p>
<p>Three choices to settle:</p>
<ul>
<li>Window length. Seven days after click is a common starting point for email, shorter for push, longer for considered purchases.</li>
<li>Touch type. Does an open count, or only a click? Our default is click, because opens have been unreliable since privacy protections became widespread.</li>
<li>Credit model. Last CRM touch within the window is the simplest defensible rule. Fractional models are fine if everyone understands them.</li>
</ul>
<p>Then hold the rule still. Changing the window mid-year makes year-on-year comparison impossible and invites the suspicion that the number was tuned.</p>
<h2>Use holdouts as the default, not the exception</h2>
<p>A holdout group is the cheapest way to make a CRM number credible. Withhold the programme from a random sample, compare revenue per recipient over a fixed period, and the difference is your lift.</p>
<p>We run two layers. A small global holdout, typically one to five per cent of the addressable base, kept out of all marketing contact and refreshed on a fixed schedule. Then per-campaign holdouts on high-volume sends.</p>
<p>Some practical rules we apply:</p>
<ul>
<li>Randomise at the customer level, not the send level, or the same people keep getting held out.</li>
<li>Keep the global holdout stable for at least a full purchase cycle before reading it.</li>
<li>Exclude transactional and service messages from the holdout. You cannot withhold a delivery notification.</li>
<li>Measure revenue per eligible customer, not per opened email, so the comparison is fair.</li>
</ul>
<p>Expect the incremental number to be smaller than the attributed one. That is the point. A programme that shows attributed revenue ten times higher than measured lift is telling you it is largely claiming credit for purchases that would have happened anyway.</p>
<h2>Instrument the data once, in the warehouse</h2>
<p>Reporting built inside the engagement platform will always be limited to what that platform saw. Orders, returns, margin and customer history live elsewhere.</p>
<p>Land send, delivery, open, click and unsubscribe events in the warehouse alongside order data, and join on a stable customer identifier. Then build the revenue report there, once, and let the platform handle operational metrics only.</p>
<p>This also removes a familiar argument. When the platform and the finance report disagree, you want one join to inspect rather than two black boxes to compare.</p>
<p>If your event data is patchy or your identifiers do not join cleanly, that is an audit job before it is a measurement job. Our <a href="https://glassjaw.ai/blog/2026-05-12-crm-audit-checklist/">CRM audit checklist</a> covers the data checks we run first.</p>
<h2>Report in a format finance will accept</h2>
<p>Finance cares about three things: what the programme cost, what it returned, and how confident you are. Build the monthly report around those.</p>
<p>Include the cost side honestly. Platform licence, data infrastructure, agency or team cost, and any incentive or discount funded by CRM. Discount cost in particular is often missing, and it is usually the largest variable.</p>
<p>Show confidence intervals or sample sizes on lift figures. A measured lift of four per cent with a wide interval is an honest statement. The same number presented as a point estimate will be treated as a point estimate forever.</p>
<p>Keep the report short. One page with revenue, cost, net contribution, lift, and a two-line commentary on what changed. Detail belongs in an appendix that nobody reads and everyone is glad exists.</p>
<p>Where teams want help building this end to end, that measurement work sits inside our <a href="https://glassjaw.ai/services/optimisation/">optimisation</a> practice.</p>
<h2>What to do this week</h2>
<ul>
<li>Write one sentence defining your CRM revenue number, including window, touch type and credit model, and send it to finance for agreement.</li>
<li>Set up a global holdout of one to five per cent, randomised at customer level, and note the date you started it so you know when it can be read.</li>
<li>Pull last month's attributed revenue and last month's discount cost into the same view, and see whether the net contribution is still positive.</li>
</ul>]]></content:encoded>
  </item>
  <item>
    <title>Multilingual campaign ops without the chaos</title>
    <link>https://glassjaw.ai/blog/2026-07-14-multilingual-campaign-ops/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-07-14-multilingual-campaign-ops/</guid>
    <pubDate>Tue, 14 Jul 2026 09:00:00 +0000</pubDate>
    <category>Industry notes</category>
    <description>How we run weekly CRM campaigns across a dozen languages using one journey, locale-driven content, a fixed translation window and per-locale QA.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-07-14-multilingual-campaign-ops.webp" alt="Abstract cover art: concentric arcs around a bright focal point on a dark blue field" width="1792" height="1024"></p>
<p>Running one campaign in one language is a content problem. Running the same campaign in twelve languages on a weekly cadence is an operations problem. The copy is rarely what breaks first.</p>
<p>What breaks is the handover. Someone writes, someone translates, someone builds, someone presses send. Each step carries its own deadline and its own version of the truth, and by the third market the brief has quietly drifted.</p>
<p>We see the same failure pattern at brands with international audiences. A journey gets cloned per market, each clone picks up a small local fix, and two quarters later nobody knows which version is canonical. Correcting one broken link then means correcting it fourteen times.</p>
<h2>Keep one journey, vary the content</h2>
<p>Our first rule is that market is a content variable, not a journey variable. One canvas, one set of entry rules, one exit condition, and a content block that resolves by locale at send time.</p>
<p>Cloning feels fast on day one. It costs you every day after that. Each clone becomes a separate place where a consent rule, a suppression list or a tracking parameter can go stale without anyone noticing.</p>
<p>Some splits are legitimate. Different legal wording, a market with no SMS channel, a promotion that runs in two countries only. Split on those reasons, write the reason down next to the journey, and review every split once a quarter.</p>
<p>The same discipline applies to lifecycle programmes, which is why we set the structure up front rather than retrofitting it. We covered that groundwork earlier on this topic in <a href="https://glassjaw.ai/blog/2026-06-23-onboarding-journey-design/">onboarding journey design</a>.</p>
<h2>Decide where language lives in your data model</h2>
<p>Locale should sit on the profile as a single attribute, written by a rule you can explain out loud. Most teams have three candidate signals: declared language preference, account country, and device or browser language.</p>
<p>Rank them once. Declared preference wins, country fills the gap, device language is the last resort. Store the source of the value too, so you can tell a guess from a choice.</p>
<p>Then define a fallback chain rather than a default. A profile marked fr-CA should fall back to fr before it falls back to en. Without a chain, one missing translation quietly drops the recipient into English.</p>
<p>Two checks we run on every new market:</p>
<ul>
<li>Every locale in the profile data has a matching content variant, or an explicit fallback.</li>
<li>No locale value exists that the platform cannot resolve. Free-text language fields are where this goes wrong.</li>
</ul>
<h2>Give translation a window, not a chat thread</h2>
<p>Translation requests that live in a messaging thread arrive late and undocumented. We replace that with a fixed weekly window: source strings freeze on a set day, translations return two working days later, build starts the morning after.</p>
<p>Send translators the full context, not a spreadsheet of fragments. That means the layout, the character limits, the audience, and the intent of the message. A subject line brief without a character limit comes back 60 characters long and gets truncated on mobile.</p>
<p>Keep a shared glossary for product names, tier names and anything legal. Decide once whether a brand term is translated or left in English, and record the decision. Re-litigating that every campaign is a slow tax on the team.</p>
<h2>QA each locale before the send, not after</h2>
<p>Locale QA is a checklist, and it is short enough to run properly. We hold ours to items that have genuinely broken sends:</p>
<ul>
<li>Rendering: subject line length, preheader, push truncation on the shortest supported handset.</li>
<li>Personalisation tokens: every token has a fallback, and the fallback reads naturally in that language.</li>
<li>Numbers and dates: currency symbol, decimal separator, date order, and time zone in the copy.</li>
<li>Direction and script: right-to-left layouts and non-Latin scripts checked in a real client, not a preview pane.</li>
<li>Legal and links: the correct footer, the correct unsubscribe wording, and links pointing at the right locale of the site.</li>
</ul>
<p>Run it on live seed profiles in each locale rather than on test data. A seed list with real attribute values catches the fallback problems that clean test records never will.</p>
<h2>Plan the calendar around local reality</h2>
<p>A single global send time is a compromise everywhere. Schedule by local time zone, and accept that your reporting day now spans more hours than your working day.</p>
<p>Build a market calendar of public holidays, school terms and category-specific events. Retail peaks differ by country. Sports and entertainment schedules move weekly and force real deadlines on the content chain.</p>
<p>Our work on Premier Padel runs dozens of multilingual tournaments a month across more than a million unified users, and the calendar is what makes that survivable. The journeys are fixed, the content is locale-driven, and the tournament schedule feeds the timing rather than the build.</p>
<p>Agree in advance what happens when a translation misses the window. Our default is to send the fallback language on time rather than delay the whole campaign. Hold that rule for a month and deadlines start being met.</p>
<p>Measure at market level as well as in aggregate. A programme that looks flat overall often hides one market improving and another declining. The same goes for testing: a locale-specific send time or a market-specific frequency cap is usually worth more than another localised subject line test.</p>
<p>If you want a second pair of hands on the weekly build and QA rhythm, that is the kind of work our <a href="https://glassjaw.ai/services/execution/">execution</a> team runs day to day.</p>
<h2>What to do this week</h2>
<ul>
<li>Count your journeys that exist only because of language, and pick two to merge back into a single locale-driven canvas.</li>
<li>Write down your locale fallback chain, then query your profile data for any locale value that has no matching content variant.</li>
<li>Put a translation freeze day in the calendar, tell the team the window, and hold it for the next four campaigns.</li>
</ul>]]></content:encoded>
  </item>
  <item>
    <title>Designing an onboarding journey around one first action</title>
    <link>https://glassjaw.ai/blog/2026-06-23-onboarding-journey-design/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-06-23-onboarding-journey-design/</guid>
    <pubDate>Tue, 23 Jun 2026 09:00:00 +0000</pubDate>
    <category>Lifecycle &amp; retention</category>
    <description>Onboarding fails when it explains features instead of removing obstacles. How we pick the activation moment and build the first thirty days around it.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-06-23-onboarding-journey-design.webp" alt="Abstract cover art: paths branching between waypoints on a dark blue field" width="1792" height="1024"></p>
<p>The standard onboarding programme is a five-email tour of the product. Email one welcomes, emails two to four each explain a feature, email five asks for a review. It is easy to build, easy to approve, and it rarely changes retention.</p>
<p>The problem is the premise. New customers are not short of information about your product, they are short of a reason to come back tomorrow. A tour answers a question they have not asked yet.</p>
<p>We build onboarding journeys backwards from a single behaviour: the first action that reliably predicts whether someone is still here in ninety days. Everything in the programme either moves a person towards that action or gets cut.</p>
<h2>Find the activation moment in your own data</h2>
<p>Every product has a threshold behaviour. Completing a profile, making a second purchase, inviting a colleague, listening to three episodes, adding a payment method. Your version is in your data already.</p>
<p>Find it this way. Take everyone who signed up between six and twelve months ago, split them into retained and churned, and compare what each group did in their first fourteen days. Look for the behaviour where the gap between the two groups is widest.</p>
<p>Then check that the relationship holds when you control for obvious confounders such as acquisition channel and plan tier. Plenty of correlations are just a proxy for high-intent traffic, and building a programme around one of those wastes a quarter.</p>
<p>Write the result as a single sentence with a number and a window. Customers who complete two bookings within fourteen days retain at roughly three times the rate of those who complete one. That sentence is the brief for the whole journey.</p>
<h2>Map the first thirty days backwards from that action</h2>
<p>Start at the activation moment and work backwards through every step a person must take to reach it. Account created, verified, preference set, first item added, first order placed, first order received.</p>
<p>For each step, write down the obstacle rather than the feature. People do not fail to set a delivery preference because they never heard of delivery preferences. They fail because they were on a phone, mid-commute, and the form asked for a postcode they could not remember.</p>
<p>Then decide which obstacle a message can genuinely remove. Some cannot be solved by CRM at all, and naming those honestly is useful, because it sends the problem to the product team where it belongs.</p>
<p>The remaining obstacles become your message set. In most programmes that is four to seven messages across thirty days, not the fifteen that a feature tour produces.</p>
<h2>Build the triggers on behaviour, not on elapsed time</h2>
<p>A time-based drip sends message three on day five whether or not the person has already done what message three asks for. That is how customers end up being told to complete a step they finished on day one.</p>
<p>Use your segmentation layers here. State decides whether someone is in the onboarding programme at all, behaviour decides which message fires next, and attributes decide the content inside it. The <a href="https://glassjaw.ai/blog/2026-06-09-segmentation-framework/">three-layer framework</a> keeps this manageable once the journey has branches.</p>
<p>Practical rules we hold to:</p>
<ul>
<li>Every message has an entry condition and an exit condition, both written before the copy.</li>
<li>A person exits the step the moment they complete its action, even if the message is queued.</li>
<li>Time-based sends exist only as a fallback when no behavioural signal is available.</li>
<li>Maximum one onboarding message per person per day across all channels, enforced centrally.</li>
<li>The whole programme has a hard exit at thirty days, after which people move into business as usual.</li>
</ul>
<p>That last rule matters. Without a hard exit, people accumulate in onboarding for months and receive a strange mix of beginner guidance and promotional campaigns.</p>
<h2>Write to the obstacle and measure the action</h2>
<p>Onboarding copy should be short, specific and single-purpose. One message, one action, one link. The subject line names the obstacle, the body removes it, and nothing else competes for attention.</p>
<p>Measure each message on completion of its step, not on opens or clicks. A message with a modest open rate that moves sixty per cent of recipients through a step is doing its job better than a widely opened message that moves nobody.</p>
<p>Report the programme on one number: the share of new customers who reach the activation moment within the window. Track it weekly by signup cohort, since a monthly average hides the effect of every change you make.</p>
<p>Test one variable at a time, and give each test a full cohort before reading it. Onboarding volumes are usually smaller than broadcast volumes, so patience is the difference between a result and a coincidence. The build and iteration side of this sits in our <a href="https://glassjaw.ai/services/execution/">execution</a> work.</p>
<h2>What to do this week</h2>
<ul>
<li>Pull the first fourteen days of behaviour for retained and churned cohorts, and identify the action with the widest gap between them.</li>
<li>Write the steps to that action in order, with the real obstacle named under each one, and mark which obstacles a message can remove.</li>
<li>Add an explicit exit condition to every message in your current onboarding programme, plus a hard exit at thirty days.</li>
</ul>]]></content:encoded>
  </item>
  <item>
    <title>A segmentation framework your team can actually maintain</title>
    <link>https://glassjaw.ai/blog/2026-06-09-segmentation-framework/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-06-09-segmentation-framework/</guid>
    <pubDate>Tue, 09 Jun 2026 09:00:00 +0000</pubDate>
    <category>Data &amp; personalisation</category>
    <description>Most segmentation decks describe segments nobody can build. Here is a three-layer framework that survives platform migrations, staff changes and audit season.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-06-09-segmentation-framework.webp" alt="Abstract cover art: clustered nodes joined by edges on a dark blue field" width="1792" height="1024"></p>
<p>Every programme we inherit has a segmentation deck somewhere. It has personas with names like Ambitious Amir, a colourful grid, and no connection at all to the audience definitions running in the platform.</p>
<p>The gap exists because the deck was written by strategists and the segments are built by whoever is closest to the send button. Under deadline, people build what the tool makes easy, and the framework quietly stops being used.</p>
<p>So we build segmentation the other way round. Start from what the data can support, keep the number of definitions small, and give every segment a named owner and a refresh rule.</p>
<h2>Separate the three layers before you name anything</h2>
<p>Confusion comes from treating three different things as one. Pull them apart and most segmentation arguments resolve themselves.</p>
<p>The first layer is state: facts about where someone is right now. Subscribed, active, lapsed, churned, trialling, high value. State is mutually exclusive, so every contact sits in exactly one bucket, and it drives which programme they belong to.</p>
<p>The second layer is attribute: durable descriptive facts such as market, language, product held, acquisition channel and lifecycle start date. Attributes stack freely and drive content selection within a programme.</p>
<p>The third layer is behaviour: what somebody did recently, expressed as a time-bounded event. Viewed a category twice in seven days, abandoned a basket, opened four of the last five sends. Behaviour is volatile and drives triggers, not list membership.</p>
<p>Write each layer on a separate page. If a proposed segment mixes all three, it usually belongs in the triggers rather than the audience structure.</p>
<h2>Keep the base set small and countable</h2>
<p>We aim for six to ten state segments covering the whole file, with no gaps and no overlaps. Every contact must resolve into one, including the awkward ones such as unsubscribed purchasers and staff accounts.</p>
<p>For each state segment, record four things in a single document:</p>
<ul>
<li>The definition in plain English, in one sentence, with no conditionals.</li>
<li>The technical definition, as the actual query or platform filter, copied verbatim.</li>
<li>The current count, with the date it was counted.</li>
<li>The named person who approves changes to the definition.</li>
</ul>
<p>Count them all and add the numbers up. If the total does not match your total addressable file, the definitions have gaps or overlaps, and that is a genuinely useful thing to find before a campaign goes out.</p>
<p>Resist the request for a special segment for a single campaign. Those definitions live forever, drift from the base set, and are the main reason programmes end up with four hundred audiences nobody understands.</p>
<h2>Give every segment a refresh rule and an owner</h2>
<p>A segment without a refresh rule is a snapshot pretending to be a definition. Write down how often each one recalculates, and where the calculation happens.</p>
<p>Decide deliberately between warehouse and platform. Complex state logic belongs in the warehouse where it can be tested and versioned, then synced into the platform as a simple attribute. Fast behavioural logic belongs in the platform, close to the trigger.</p>
<p>We put the state layer in the warehouse, refreshed nightly, and let the platform own behaviour in real time. That split keeps the expensive logic in one testable place and the fast logic where latency matters.</p>
<p>Ownership is the part teams skip. Each segment needs one person who approves definition changes, and a changelog entry every time a definition moves. Without that, two people optimise the same audience in opposite directions and nobody can explain the drop in performance.</p>
<h2>Decide what personalisation each segment earns</h2>
<p>Not every segment deserves bespoke content. Personalisation costs production time, and a variant that nobody measures is pure overhead.</p>
<p>We grade each segment into three tiers.</p>
<p>Tier one gets a dedicated creative treatment and its own reporting. Tier two gets modular blocks swapped inside a shared template. Tier three gets the default, with only the greeting and the product feed varying.</p>
<p>Sizing decides the tier. A segment below roughly two per cent of your addressable file rarely justifies bespoke creative unless its value per customer is exceptional. Be honest about that, and put the saved time into the segments that move revenue.</p>
<p>Review the tiers quarterly against performance. Segments graduate and segments get demoted, and both are normal. The framework exists to be edited, not admired.</p>
<h2>Test the framework against your existing programmes</h2>
<p>Before you roll anything out, run the new structure against what you already send. Take the message inventory from your audit and map each message to a state segment, an attribute filter and a behavioural trigger.</p>
<p>Anything that will not map is telling you something. Either the framework has a gap, or the message is targeting an audience nobody can defend. Both findings are worth having before launch.</p>
<p>We usually find two or three messages with no home, and they are almost always legacy sends that should have been retired at the <a href="https://glassjaw.ai/blog/2026-05-12-crm-audit-checklist/">audit stage</a>. Fixing the segmentation becomes a good excuse to switch them off. Helping teams get to that structure is a large part of what we do in <a href="https://glassjaw.ai/services/crm-strategy/">CRM strategy</a>.</p>
<h2>What to do this week</h2>
<ul>
<li>Write your state, attribute and behaviour layers on three separate pages, and move any mixed definitions into the layer where they belong.</li>
<li>Document the six to ten state segments with plain English definitions, technical definitions, current counts and named owners.</li>
<li>Add up the segment counts and reconcile the total against your addressable file, then investigate every gap and overlap you find.</li>
</ul>]]></content:encoded>
  </item>
  <item>
    <title>IP warming from zero without wrecking deliverability</title>
    <link>https://glassjaw.ai/blog/2026-05-26-ip-warming-from-zero/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-05-26-ip-warming-from-zero/</guid>
    <pubDate>Tue, 26 May 2026 09:00:00 +0000</pubDate>
    <category>Platforms &amp; implementation</category>
    <description>A practical IP warming plan for new sending infrastructure, from authentication and seed list selection through a four-week ramp you can defend.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-05-26-ip-warming-from-zero.webp" alt="Abstract cover art: stacked isometric blocks on a dark blue field" width="1792" height="1024"></p>
<p>Moving to a new email platform means moving to new sending infrastructure, and mailbox providers have no history with your new IP addresses. They treat an unknown sender cautiously, which is reasonable of them and inconvenient for you.</p>
<p>The fix is warming: a deliberate ramp in volume over two to four weeks, sending to your most engaged contacts first, so providers build a positive record before you send anything at scale. Rush it and you land in spam folders that take months to climb out of.</p>
<p>We have run this process on migrations of several million profiles. The plan below is the one we use, and the order of the steps matters more than the exact daily numbers.</p>
<h2>Fix authentication before you send a single message</h2>
<p>Warming an IP with broken authentication teaches providers that your mail is suspicious. Everything in this section must be verified before day one of the ramp.</p>
<ul>
<li>SPF record published for the sending domain, with the new platform's infrastructure included and the record under the ten lookup limit.</li>
<li>DKIM signing enabled with a 2048-bit key, and the signing domain aligned with the visible From domain.</li>
<li>DMARC published, starting at p=none with an aggregate reporting address someone actually reads.</li>
<li>A dedicated sending subdomain for marketing traffic, kept separate from transactional and corporate mail.</li>
<li>Reverse DNS on each new IP resolving to a hostname on your own domain.</li>
<li>Feedback loops registered with the providers that offer them, routed into your suppression logic automatically.</li>
</ul>
<p>Send a seed test to a spread of Gmail, Outlook, Yahoo and corporate addresses. Check headers, not just the inbox placement, and confirm that both SPF and DKIM pass with alignment.</p>
<h2>Build the seed list from proven engagement</h2>
<p>The warming audience is the most important decision in the whole exercise. You want contacts who reliably open, click and reply, because positive engagement signals are what build the reputation.</p>
<p>Define the seed list as people who have opened or clicked in the last thirty days, have a valid purchase or login in the last ninety, and have never complained or hard bounced. In most programmes that is between five and fifteen per cent of the file.</p>
<p>Sort that group by recency of engagement and mail it in descending order. Your best contacts see the first send, your merely good contacts join in week three. If your audit surfaced a data quality problem, resolve it before building this list, since the <a href="https://glassjaw.ai/blog/2026-05-12-crm-audit-checklist/">CRM audit checklist</a> exists precisely to catch that kind of issue early.</p>
<h2>Ramp the volume across four weeks</h2>
<p>A common shape doubles daily volume each day for the first week, then continues doubling every second day, holding steady whenever metrics wobble. Something like this works for a file of a few hundred thousand:</p>
<ul>
<li>Days one to three: 200, 500, 1,000 per IP, sent to the most engaged decile only.</li>
<li>Days four to seven: 2,000, 5,000, 10,000, 20,000, still inside the top engagement tier.</li>
<li>Week two: 40,000 to 100,000 per day, adding the next engagement tier once complaint rates stay flat.</li>
<li>Week three: 150,000 to 400,000 per day, introducing your regular campaign content rather than warming sends.</li>
<li>Week four: full volume, with the least engaged segments reintroduced last, or not at all.</li>
</ul>
<p>Send at a consistent time each day. Providers read volume spikes as a signal, and an erratic schedule during warming looks like exactly the thing they filter.</p>
<p>Hold the ramp, do not reverse it, if a metric breaks threshold. Reversing volume sharply is itself a signal worth avoiding.</p>
<h2>Watch the signals that decide the outcome</h2>
<p>Blended metrics will not tell you what is happening. Break every number down by mailbox provider, because Gmail and Microsoft respond to different things and usually fail at different points in the ramp.</p>
<p>Thresholds we hold to during warming:</p>
<ul>
<li>Complaint rate under 0.1 per cent per provider. Above 0.3 per cent, pause and cut the audience back to the previous tier.</li>
<li>Hard bounce rate under 2 per cent. A spike here means the list is older than someone told you.</li>
<li>Open rate materially above your historical average, because a warming list should outperform your file.</li>
<li>Deferrals and throttling messages read daily from the platform logs, not weekly.</li>
</ul>
<p>Deferrals are normal early on. Persistent 4xx responses from one provider after week two mean that provider is not convinced, and the answer is usually tighter audience selection rather than more volume.</p>
<p>On our Premier Padel work, careful warming took delivery past 99 per cent and supported open rates above 45 per cent once the programme reached full volume. That outcome came from patience during the ramp, not from anything clever afterwards.</p>
<h2>Plan the hand-off to business as usual</h2>
<p>Warming does not end when you hit full volume. Reputation decays with silence, so a dedicated IP needs a reasonably consistent weekly cadence to stay healthy.</p>
<p>Keep the suppression rules you built during warming. The inactivity window, the complaint routing and the bounce handling were doing real work, and quietly dropping them a month later undoes the ramp.</p>
<p>Document the whole exercise: dates, volumes, audiences and provider metrics. The next migration, or the next new IP, starts from evidence instead of memory. This is the same discipline we apply across our <a href="https://glassjaw.ai/services/implementation/">implementation</a> projects.</p>
<h2>What to do this week</h2>
<ul>
<li>Verify SPF, DKIM, DMARC and reverse DNS on the new sending domain, and send a seed test that confirms alignment in the headers.</li>
<li>Build and export the warming seed list, sorted by engagement recency, and check what share of your file it represents.</li>
<li>Draft the daily volume schedule with named audience tiers, and agree the complaint and bounce thresholds that will pause the ramp.</li>
</ul>]]></content:encoded>
  </item>
  <item>
    <title>A CRM audit checklist that changes what you ship next</title>
    <link>https://glassjaw.ai/blog/2026-05-12-crm-audit-checklist/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-05-12-crm-audit-checklist/</guid>
    <pubDate>Tue, 12 May 2026 09:00:00 +0000</pubDate>
    <category>CRM strategy</category>
    <description>How we run a CRM audit in two weeks, what to pull, what to measure, and how to turn the findings into a ranked backlog instead of a slide deck.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-05-12-crm-audit-checklist.webp" alt="Abstract cover art: concentric arcs around a bright focal point on a dark blue field" width="1792" height="1024"></p>
<p>Most CRM audits produce a deck and very little else. The findings are usually accurate, the recommendations are sensible, and six months later the programme is still sending the same four emails to the same undifferentiated list.</p>
<p>We run audits differently. The deliverable is not a document, it is a ranked backlog with owners and effort estimates, and the audit is not finished until the first three items sit in a sprint.</p>
<p>Below is the checklist we work through, in the order we work through it. For a mid-sized programme it takes about two weeks, longer if nobody has mapped the data before.</p>
<h2>Start with the data layer, not the campaigns</h2>
<p>Campaign quality is downstream of data quality, so we never begin with creative. We begin with a sample export of a thousand customer profiles and read it by hand. That hour tells us more than a week in admin screens.</p>
<p>The questions we answer first:</p>
<ul>
<li>Which system is the source of truth for customer identity, and what key joins records across systems?</li>
<li>How many profiles exist, and what share are duplicates or orphaned test records?</li>
<li>Which attributes update in real time, which update nightly, and which have been static since the last import?</li>
<li>What behavioural events are tracked, and does the event schema match what the platform actually expects?</li>
<li>Where is consent stored for each contactable address, and can you produce the timestamp and source on demand?</li>
</ul>
<p>If two of those answers are vague, stop the audit and fix the answers. Everything downstream is guesswork until you can name the source of truth.</p>
<h2>Inventory every message a customer can receive</h2>
<p>Build one spreadsheet covering every broadcast, triggered message, transactional template, push notification, SMS and in-app message. One row per message, no exceptions, including the ones marketing does not own.</p>
<p>For each row, record the trigger, the audience definition, the owner, the date it was last edited, the volume in the last ninety days, and the headline performance. Then add a column that nobody enjoys filling in: is this message still true?</p>
<p>We routinely find templates that have been sending for two years, referencing a product tier that no longer exists or a support address nobody monitors. Those are not optimisation problems. They are switch-off decisions, and they can be made in an afternoon.</p>
<h2>Check deliverability before you judge performance</h2>
<p>A programme with a twelve per cent open rate and an authentication problem does not have a content problem. Judging creative before you have cleared the technical path wastes everyone's time.</p>
<p>Work through this list for every sending domain:</p>
<ul>
<li>SPF, DKIM and DMARC records present, aligned, and pointing at the domains you actually send from.</li>
<li>Transactional, marketing and lifecycle traffic separated by subdomain or stream, so one bad campaign cannot damage receipts.</li>
<li>Hard bounce and complaint rates tracked by domain group, not just as a single blended figure.</li>
<li>A written inactivity policy, with a defined window after which you stop mailing a non-opener.</li>
<li>List growth sources documented, with any purchased, scraped or appended data identified and quarantined.</li>
</ul>
<p>Pull ninety days of delivery data by mailbox provider. Gmail and Microsoft frequently tell different stories, and a blended average hides both.</p>
<h2>Score the programme, then rank the fixes</h2>
<p>We score four dimensions from one to five: data readiness, deliverability, lifecycle coverage, and measurement. Every score needs a sentence of evidence attached, so the number is arguable rather than decorative.</p>
<p>Lifecycle coverage is the one that usually exposes the gap. Map your customer stages across the top of a page, then place every message from the inventory underneath its stage.</p>
<p>Acquisition and promotion columns tend to be crowded. Onboarding, reactivation and win-back are often empty.</p>
<p>Then rank the fixes. We use a simple impact against effort grid and cap the resulting backlog at twelve items, because a backlog of forty is a way of choosing nothing. Each item gets a named owner, an estimate in days, and a dependency note.</p>
<p>The cap matters more than the scoring method. An audit that produces twelve ranked, owned, estimated items will change the programme. One that produces a hundred observations will not.</p>
<h2>Make the audit repeatable</h2>
<p>Write down what you pulled, where you pulled it from, and which queries you ran. Six months later, someone will want to know whether things improved, and the answer is only credible if the second audit uses the same method.</p>
<p>We keep the audit workbook in the client's own environment rather than ours. If the checklist only works when an agency runs it, it is a dependency rather than a capability, and that is the wrong outcome. The same principle shapes how we approach <a href="https://glassjaw.ai/services/crm-strategy/">CRM strategy</a> engagements generally.</p>
<p>Set a calendar reminder for two quarters out. Re-score the four dimensions, compare, and rebuild the backlog from what you find.</p>
<h2>What to do this week</h2>
<ul>
<li>Export a thousand customer profiles and read them by hand, noting every field that is empty, stale or inconsistent.</li>
<li>Build the message inventory in a single spreadsheet, one row per message, and flag every template nobody has edited in twelve months.</li>
<li>Run an authentication check on every sending domain and confirm that transactional traffic is separated from marketing traffic.</li>
</ul>]]></content:encoded>
  </item>
  <item>
    <title>Briefing a CRM agency: what to hand over on day one</title>
    <link>https://glassjaw.ai/blog/2026-04-18-briefing-an-agency/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-04-18-briefing-an-agency/</guid>
    <pubDate>Sat, 18 Apr 2026 09:00:00 +0000</pubDate>
    <category>CRM strategy</category>
    <description>What to give a CRM agency at kickoff so the first month produces work rather than discovery: access, constraints, the numbers you argue about, and who decides.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-04-18-briefing-an-agency.webp" alt="Abstract cover art: concentric arcs around a bright focal point on a dark blue field" width="1792" height="1024"></p>
<p>Kickoff is at ten on a Monday. The brief is a forty-slide deck about brand positioning. Three of the four platform logins do not work. The analyst who knows how the customer table is built is on leave until the following week.</p>
<p>By Friday the agency has produced a list of questions. By the end of the month it has produced an audit, which is a polite way of saying it has spent four weeks finding out what the client already knew. The retainer clock has been running the whole time.</p>
<p>This is the normal shape of a CRM engagement, and it is avoidable. Almost everything that makes the first month slow is a thing the client already has, in a form nobody thought to hand over.</p>
<h2>The brief that costs a month</h2>
<p>Most briefs describe ambition and omit constraint. They say the programme should be more personalised, more automated and better measured, which no agency will disagree with and none can act on.</p>
<p>What an agency needs on day one is the opposite: the specific shape of the situation. What exists, what it is wired to, what has already been tried, what is not allowed, and what has to be true by when.</p>
<p>A useful brief is short. Two pages of decisions plus a folder of artefacts beats forty slides of aspiration, because the artefacts are what the work is actually built from.</p>
<p>Write the objective as a sentence with a number and a date, then list what has already been attempted against it and what happened. The failed attempts are the most valuable part of the document and the part most often left out.</p>
<h2>Access is the critical path, so start it before kickoff</h2>
<p>Access always takes longer than anyone expects. Every week of delay is a week of the engagement spent on something other than the work.</p>
<p>Start the requests two weeks before kickoff, and treat the list as a project with an owner:</p>
<ul>
<li>The engagement platform, at a permission level that allows building, not only viewing.</li>
<li>The analytics and reporting tools, including the raw data warehouse if there is one.</li>
<li>The read-only database or warehouse schema behind the customer record.</li>
<li>Whatever handles consent and preferences, plus the records that prove it.</li>
<li>The domain registrar or DNS, or a named person who can publish a record within a day.</li>
<li>Ticketing and documentation, so the agency can see what the engineering team is already committed to.</li>
</ul>
<p>DNS is the one that reliably bites. Authentication changes need a record published, the registrar is often owned by a different department, and a two-day task becomes a three-week one.</p>
<p>Add a named contact per system, not a shared inbox. Access requests that go to a queue arrive after the work they were needed for.</p>
<h2>Hand over the numbers you already argue about</h2>
<p>Every organisation has a handful of numbers that get re-derived in different ways by different teams. An agency will walk into that argument blind in about week two.</p>
<p>Give them the definitions up front, along with the disagreement. Active customer. Repeat purchase rate. Contactable base. Revenue attributed to CRM. What counts as a new customer after a two-year gap.</p>
<p>This is the practical value of a <a href="https://glassjaw.ai/blog/terms/single-customer-view/">single customer view</a>, even an imperfect one. If a document exists that says which system owns identity and how records are joined, hand it over on day one. If it does not exist, say so plainly, because that changes the first month's plan considerably.</p>
<p>The same applies to field-level definitions. A <a href="https://glassjaw.ai/blog/terms/data-contract/">data contract</a> listing the attributes the programme depends on, their refresh frequency and their owner is worth more than any brief. Where one exists, it removes weeks of inference.</p>
<p>Then add the awkward numbers. Current <a href="https://glassjaw.ai/blog/terms/deliverability/">deliverability</a> by mailbox provider, complaint rates, the share of the list that has not opened anything in a year. Agencies find these in the first fortnight anyway, and sharing them early buys a month of honest planning.</p>
<h2>Say what is fixed and what is negotiable</h2>
<p>The fastest way to waste an agency's first month is to let them design against constraints that were never stated. Write the constraints down, in three groups.</p>
<p><strong>Fixed</strong>: the platform contract with two years left, the legal review that every send must pass, the fortnightly release train, the brand rules that cannot move. These bound the solution space and should be stated without apology.</p>
<p><strong>Negotiable</strong>: things that could change with a business case, such as a template system, an approval step or a data feed frequency. Naming these tells the agency where to spend effort arguing.</p>
<p><strong>Open</strong>: everything nobody has decided yet. Being explicit that something is open is more useful than a vague answer that gets treated as settled.</p>
<p>Budget belongs in the fixed list. An agency that knows the annual number will propose work that fits it, and <a href="https://glassjaw.ai/blog/2025-12-02-roadmap-finance-will-fund/">a roadmap finance will actually fund</a> is built from the same information. Withholding the budget produces proposals nobody can approve.</p>
<p>Commercial constraints count too. If certain <a href="https://glassjaw.ai/blog/terms/segment/">segments</a> cannot receive discounts, or a category carries a margin the programme must protect, say so at the start. That is the same discipline we described in <a href="https://glassjaw.ai/blog/2025-11-05-loyalty-and-margin/">loyalty and margin</a>, and it is far cheaper to apply before a mechanic is designed than after.</p>
<h2>Name who decides, and how approval works</h2>
<p>Engagements stall on approval more often than on capability. The work is built, then waits ten days for sign-off from someone who was not at kickoff and disagrees with a decision made in week one.</p>
<p>Put four names in the brief. The single person who can approve creative and mechanics. The person who owns the data side and can commit engineering time. The legal or compliance reviewer. And the person who breaks a tie when the first two disagree.</p>
<p>Then write the approval path as a sequence with durations. Who sees the work, in what order, and how long each step takes. If legal review takes five working days, that is a fact the plan has to be built around rather than a surprise to be discovered.</p>
<p>One more thing, easy to give and rarely given: the last two years of programme history. Which campaigns were tried, what the results were, and which ideas have already been rejected internally and why. Without it an agency will confidently propose something that failed in 2024.</p>
<h2>What day thirty should look like</h2>
<p>If the handover is done properly, the first month produces shipped work rather than a discovery document. A reasonable expectation is one journey rebuilt or launched, one measurement problem fixed, and a ranked backlog everyone has argued over.</p>
<p>Agree that expectation in writing before the engagement starts. An agency that knows it is judged on what shipped in the first month will ask for access in week minus two, which is the behaviour you wanted anyway. Our own <a href="https://glassjaw.ai/services/crm-strategy/">CRM strategy</a> engagements are set up on exactly that basis.</p>]]></content:encoded>
  </item>
  <item>
    <title>AI agents in lifecycle marketing: what we let them do</title>
    <link>https://glassjaw.ai/blog/2026-04-13-what-we-let-agents-do/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-04-13-what-we-let-agents-do/</guid>
    <pubDate>Mon, 13 Apr 2026 09:00:00 +0000</pubDate>
    <category>Industry notes</category>
    <description>Which lifecycle decisions we let an automated system make, which stay with a person, and the guardrails in between: bounded actions, logged decisions and a human gate.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-04-13-what-we-let-agents-do.webp" alt="Abstract cover art: concentric arcs around a bright focal point on a dark blue field" width="1792" height="1024"></p>
<p>A client's marketing director asked us a fair question in a planning session this spring. The team had been shown a demonstration where an automated system built an audience, wrote the email, chose the offer and scheduled the send, all from a one-line instruction. Could we do that, and if not, why not?</p>
<p>The honest answer is that most of the pieces in that demonstration work. The part that does not work is the arrangement: one system making four kinds of decision, with no separation between them and no record of which decision caused which outcome.</p>
<p>We do use automated decisioning in the programmes we run. What we hold to is a boundary that has not moved much in two years. The system may decide who, when, and in what order. A person decides what it costs, what it claims, and whether we are allowed to contact this person at all.</p>
<h2>Three different decisions get called "the campaign"</h2>
<p>Untangling this is most of the work. What looks like a single decision is usually three, with very different consequences when it goes wrong.</p>
<p>The first is <strong>decisioning</strong>: which message a given person should receive, from a set of candidates, and when. It is reversible, it is measurable, and a mistake costs one slightly less relevant email.</p>
<p>The second is <strong>authorship</strong>: what the message actually says. A mistake here can be a false claim, a tone that damages the brand, or a statement the business cannot stand behind.</p>
<p>The third is <strong>economics</strong>: what the offer is worth, who qualifies, and what margin the business is prepared to give up. A mistake here is expensive immediately, and often at scale before anyone notices.</p>
<p>Most disagreements about automation in CRM are really disagreements about which of these three is being discussed. Once they are separated, the answers become much less controversial.</p>
<h2>What we let an automated system decide</h2>
<p>Inside a bounded set of options, ranking and timing are well suited to automation, and humans are not especially good at them.</p>
<ul>
<li><strong>Ranking candidate messages.</strong> Given a person and a list of messages they are eligible for, choose the one to send. This is <a href="https://glassjaw.ai/blog/terms/next-best-action/">next best action</a> as it has been practised for years, and the scoring underneath it is usually an ordinary <a href="https://glassjaw.ai/blog/terms/propensity-model/">propensity model</a> rather than anything new.</li>
<li><strong>Timing within an allowed window.</strong> Choosing the hour of send for an individual, inside a window a person has defined and inside the contact policy.</li>
<li><strong>Allocating scarce contact slots.</strong> When three journeys want the same person this week and the cap allows one, deciding which one wins, according to a priority order a person has set.</li>
<li><strong>Selecting content blocks from an approved library.</strong> Choosing which <a href="https://glassjaw.ai/blog/terms/dynamic-content/">dynamic content</a> module to show from a set that has already been reviewed and signed off.</li>
<li><strong>Drafting.</strong> Producing variants, subject lines and summaries for a person to review, edit and approve before anything is scheduled.</li>
<li><strong>Operational work.</strong> Writing a first version of a segment query, reconciling two reports, flagging a journey whose volume has dropped, summarising a week of test results.</li>
</ul>
<p>The common feature is that the system is choosing from options someone has already approved. It is picking from a menu, not writing one.</p>
<p>Drafting deserves its own note, because that is where teams get the fastest return and the most trouble. A model can produce forty subject lines in a minute. Whether any of them sound like your brand depends entirely on whether somebody has written the voice down first. That is the argument we made in <a href="https://glassjaw.ai/blog/2025-08-21-brand-voice-at-scale/">keeping a brand voice consistent at scale</a>. Without that, automated drafting produces volume and a slow drift towards a generic register that nobody notices until a customer mentions it.</p>
<h2>What stays with a person</h2>
<p>Four areas we do not automate, and the reasoning is the same in each case: the cost of being wrong is not proportional to the benefit of being right.</p>
<p><strong>Offer economics.</strong> Discount depth, who qualifies, and how often. A system optimising for conversion will find that a larger discount converts better, because it does. Margin sits outside its view unless somebody models it carefully, and by the time a mispriced offer shows up in the management accounts it has been sent to a lot of people.</p>
<p><strong>Brand and factual claims.</strong> Anything asserting a fact about the product, a price, a delivery promise, a regulated statement or a comparison with a competitor. These need a human who is accountable for their truth. In regulated categories that accountability is a legal requirement rather than a preference.</p>
<p><strong>Consent and data use.</strong> No automated system decides who may be contacted, on what channel, on what lawful basis. Under <a href="https://glassjaw.ai/blog/terms/gdpr/">GDPR</a> and its equivalents, the record of consent and the logic of suppression are the things you will be asked to produce, and they must be explainable by a person who understands them. Suppression logic in particular should be deliberately dull and deliberately human.</p>
<p><strong>Anything irreversible at scale.</strong> Sending to the whole file, changing a global contact policy, altering data in the source system, deleting records. A person presses that button.</p>
<h2>Guardrails that make the rest safe</h2>
<p>The division of labour only holds if it is built into the system rather than written in a policy document nobody reads.</p>
<ol>
<li><strong>A bounded action space.</strong> The system chooses from an enumerated set of approved actions. It cannot invent a new message type, a new audience or a new offer. Everything it can do is something a person has already said yes to.</li>
<li><strong>Hard limits it cannot override.</strong> Frequency caps, suppression lists, send volume ceilings and market restrictions are enforced outside the decisioning layer, so no optimisation can trade them away.</li>
<li><strong>A logged decision for every send.</strong> Which options were considered, which was chosen, on what score, under which model version. Without this you cannot debug a strange outcome, and you cannot answer a customer asking why they received something.</li>
<li><strong>Staged exposure.</strong> New automated logic starts on a small share of the audience, with a control group held back, and grows only when the numbers justify it.</li>
<li><strong>A stop control that works in seconds.</strong> One person, one switch, reverting to the previous behaviour without an engineering deployment.</li>
<li><strong>A named owner.</strong> Every automated decision has a human whose job it is to defend it. If nobody can be named, the automation does not ship.</li>
</ol>
<p>None of this is novel. It is the same discipline that applies to any automated system touching customers, applied to a newer set of tools.</p>
<h2>Read a sample of what it did, every week</h2>
<p>Automated decisioning fails quietly. Performance does not collapse; it drifts, and the metrics that would reveal the drift are averages that hide it.</p>
<p>So we sit down weekly and read actual decisions. Twenty or thirty at random, plus the ones at the extremes: the person who received the most messages, the person who received none, the offer that went to the smallest segment. You are looking for decisions that are defensible in aggregate but obviously wrong for that individual.</p>
<p>The accountability question is the one still waiting for a good answer. A system can hold a decision, but it cannot own one. When an automated send goes wrong in a way that reaches a customer or a regulator, the organisation needs a named person who understood the logic, agreed to it, and can explain it. Designing that person into the process from the start is much easier than appointing them afterwards.</p>]]></content:encoded>
  </item>
  <item>
    <title>Cohort analysis that changes the roadmap</title>
    <link>https://glassjaw.ai/blog/2026-03-20-cohorts-that-change-the-roadmap/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-03-20-cohorts-that-change-the-roadmap/</guid>
    <pubDate>Fri, 20 Mar 2026 09:00:00 +0000</pubDate>
    <category>Testing &amp; optimisation</category>
    <description>Most cohort charts get admired and ignored. How to define cohorts around a decision, read the curve in three parts, and turn a finding into work someone owns.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-03-20-cohorts-that-change-the-roadmap.webp" alt="Abstract cover art: a bar series under a trend line on a dark blue field" width="1792" height="1024"></p>
<p>Nearly every quarterly review deck we are shown contains a cohort chart. The triangular grid of months, shaded from dark to light, with retention decaying left to right. Everyone nods at it. Nobody has ever changed a plan because of it.</p>
<p>The chart is not the problem. <a href="https://glassjaw.ai/blog/terms/cohort-analysis/">Cohort analysis</a> is the only routine way to see whether a programme is changing customer behaviour, as opposed to whether a good month happened. The problem is that the standard chart is built to be shown rather than to answer a question, so it answers none.</p>
<p>A cohort view earns its place when somebody could act differently depending on what it says. That constraint changes how you define the cohort, what you plot, and which comparisons you allow yourself to make.</p>
<h2>Define the cohort around a decision you might take</h2>
<p>Start from the decision, then build the cohort that informs it. The default of grouping by signup month is fine for a health check and almost useless for a roadmap choice.</p>
<p>Useful cohort definitions we come back to:</p>
<ul>
<li><strong>First-purchase category or product.</strong> Tells you whether some entry points produce better customers, which changes merchandising and acquisition briefs.</li>
<li><strong>Acquisition channel or campaign.</strong> Tells you whether cheap traffic is expensive later, which changes the budget split.</li>
<li><strong>First-order discount depth, banded.</strong> Tells you what you are buying with the welcome offer.</li>
<li><strong>Onboarding treatment received.</strong> Tells you whether the journey you built is doing anything after the first month.</li>
<li><strong>First-week behaviour, such as completing a profile or a second session.</strong> Tells you which activation milestone is worth designing around.</li>
</ul>
<p>Each of those maps to a decision with a budget behind it. Signup month maps to nothing you can change.</p>
<p>Write the decision on the chart before you build it. One line at the top: "if early-discount cohorts retain materially worse, we cut the welcome offer depth in Q3". A chart with that sentence attached gets discussed differently from one captioned "retention by cohort".</p>
<h2>Read the curve in three parts</h2>
<p>A <a href="https://glassjaw.ai/blog/terms/retention-curve/">retention curve</a> is not one number, and averaging it destroys the information. Read it as three separate things, because each has a different cause and a different fix.</p>
<p><strong>The first drop.</strong> From period zero to period one, usually the steepest fall on the chart. This is an onboarding and expectation problem: the product or service did not do what the purchase implied, or nobody helped the customer reach the point where it would. CRM can move this, and it is normally where the fastest wins are.</p>
<p><strong>The slope.</strong> The decay across the middle periods. This is habit and relevance. Frequency, assortment, and whether your contact strategy matches the natural purchase cycle. Moves slowly, responds to programme design rather than single campaigns.</p>
<p><strong>The floor.</strong> Whether the curve flattens and at what level. A curve that flattens has a loyal core, and the floor height multiplied by cohort size is roughly what your base is worth. A curve that keeps declining has no core, which is a business-model finding rather than a marketing one.</p>
<p>Plot the three separately over successive cohorts. A programme change that improves the first drop but leaves the slope untouched is still a real win, and it will be invisible in a blended <a href="https://glassjaw.ai/blog/terms/churn-rate/">churn rate</a> that mixes all three together.</p>
<h2>Compare cohorts only when one thing differs</h2>
<p>The most common analytical error we see is comparing cohorts that differ in several ways at once and attributing the gap to the most recent change.</p>
<p>The January cohort was acquired during a sale, in a different channel mix, at a different discount depth, and it also got the new onboarding journey. Its retention is better. The onboarding journey gets the credit, the team invests further, and nothing improves next quarter.</p>
<p>Guardrails worth holding to:</p>
<ol>
<li>Hold the acquisition source constant, or split the comparison by source and check the direction is consistent within each.</li>
<li>Hold the discount band constant. Promotional cohorts behave differently for at least a year.</li>
<li>Compare equal maturity windows. A three-month-old cohort read at month three against a year-old cohort read at month twelve is not a comparison.</li>
<li>Check seasonality by looking at the same month in previous years, not only at adjacent months.</li>
<li>Watch the denominator. If acquisition volume doubled, the newer cohort contains different people, and mix explains more than treatment.</li>
</ol>
<p>When too many things differ, say so and stop. An honest "we cannot separate these effects" is a finding, and it usually justifies running an actual experiment next quarter instead of another retrospective read.</p>
<h2>Turn the finding into work somebody owns</h2>
<p>A cohort finding becomes a roadmap item only if it survives three questions. What would we do differently? How much is it worth? Who owns it?</p>
<p>Work the value question with the same arithmetic every time. Take the difference in <a href="https://glassjaw.ai/blog/terms/repeat-purchase-rate/">repeat purchase rate</a> between the cohorts, apply it to the volume of customers entering that state each month, and convert to contribution rather than revenue. Express the result as annual contribution and state the assumptions beside it.</p>
<p>That converts "discount-acquired customers retain worse" into something a planning meeting can act on. Shifting the welcome offer from twenty per cent to fifteen is worth roughly this much a year if the difference holds, and costs us this many first orders. Now two people can disagree about a number rather than about a chart.</p>
<p>Record the decision and its expected effect where the next reader will find it. The <a href="https://glassjaw.ai/blog/2025-12-18-the-decision-log/">decision log</a> exists for exactly this: cohort findings mature over months, and by the time the evidence arrives the people involved have moved on or reinterpreted what they meant.</p>
<p>Then set the read date. A cohort-driven change takes at least one full cohort maturity window to evaluate, so book the review at the point the data will exist, not at the end of the quarter.</p>
<h2>What a cohort chart cannot tell you</h2>
<p>Three limits, all worth stating out loud when the chart goes up.</p>
<p>Cohorts are observational. They show that a group behaved differently, never that your treatment caused it. Where a decision is expensive or reversible only at cost, the cohort view is the hypothesis and a holdout or a proper experiment is the evidence. Treating a cohort difference as causal is how a plausible finding becomes a wasted year.</p>
<p>Cohorts also see only the customers you already have. They cannot tell you what the brand campaign did to acquisition quality, or how much of the change came from pricing, distribution or a competitor's move. That question needs the top-down view, which is why we paired it with <a href="https://glassjaw.ai/blog/2026-03-11-mmm-for-crm-teams/">marketing mix modelling for CRM teams</a> earlier this month. The two methods answer different questions and disagree productively.</p>
<p>The last limit is about <a href="https://glassjaw.ai/blog/terms/clv/">lifetime value</a>. A cohort's value estimate is a projection until the cohort has matured, and the projection is most confident exactly when it is least useful. Keep the horizon short, state it, and resist the temptation to extrapolate a curve you have only seen the first third of.</p>
<h2>What to do this week</h2>
<ul>
<li>Take your standing cohort chart and write the decision it would inform at the top. If you cannot, rebuild the cohort definition around one you actually face.</li>
<li>Split your current retention curve into first drop, slope and floor, and track the three separately across the last six cohorts.</li>
<li>Pick one cohort difference you already believe in, cost it in annual contribution with the assumptions written down, and take it to the next planning meeting as a proposal rather than an observation.</li>
</ul>]]></content:encoded>
  </item>
  <item>
    <title>Marketing mix modelling for CRM teams</title>
    <link>https://glassjaw.ai/blog/2026-03-11-mmm-for-crm-teams/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-03-11-mmm-for-crm-teams/</guid>
    <pubDate>Wed, 11 Mar 2026 09:00:00 +0000</pubDate>
    <category>Testing &amp; optimisation</category>
    <description>Why CRM sits awkwardly inside a marketing mix model, how to give it the right variables, and how to use holdouts to calibrate the model rather than argue with it afterwards.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-03-11-mmm-for-crm-teams.webp" alt="Abstract cover art: a bar series under a trend line on a dark blue field" width="1792" height="1024"></p>
<p>The finance team commissions a marketing mix model. Eight months of work later, the results land: paid search is doing well, the brand campaign is doing better than anyone expected, and CRM has a coefficient close to zero. A meeting is scheduled to discuss the CRM budget.</p>
<p>The CRM lead in that meeting is usually right on the substance and completely unprepared to argue it. The programme genuinely does drive revenue, the model genuinely does not see it, and explaining why requires a conversation about collinearity that nobody in the room wants to have on a Tuesday afternoon.</p>
<p>We have sat on the CRM side of that meeting several times. The way to win it is to be involved eight months earlier, when the variables are being specified, rather than eight months later when the coefficients are being defended. What follows is what a CRM team needs to know to do that.</p>
<h2>What the model measures, and why CRM fits it badly</h2>
<p>A marketing mix model is a regression on aggregated time series. Weekly or daily sales on one side, weekly or daily marketing activity on the other, plus controls for price, seasonality, distribution, competitor activity and whatever else moves the business. It estimates how much of the variation in sales each input explains.</p>
<p>That design has real strengths. It needs no user-level tracking, it covers offline and brand activity, and it can be pointed at the whole business rather than the trackable part of it. As privacy constraints have tightened, this is why <a href="https://glassjaw.ai/blog/terms/mmm/">MMM</a> came back into fashion after a decade of user-level <a href="https://glassjaw.ai/blog/terms/attribution-model/">attribution models</a> being the default.</p>
<p>The weaknesses fall disproportionately on CRM. Three of them, in order of how much damage they do.</p>
<p>CRM volume tracks the business rather than driving it. You send more when there is more to say and more people to say it to, and both of those move with the trading calendar. The model sees CRM activity rising and falling with sales, which is exactly what a variable with no causal effect would also look like.</p>
<p>CRM effects are fast and small per message. Media effects are modelled with adstock and diminishing returns over weeks. A triggered email's effect is mostly spent within days, at a magnitude that is hard to separate from noise in a weekly aggregate.</p>
<p>And much of what CRM does is retention, which shows up as sales that did not fall. A model fitted to explain variation struggles with a variable whose job is to reduce variation.</p>
<h2>The collinearity problem, stated plainly</h2>
<p>This is the part worth being able to explain in one minute, because it is the crux of the meeting.</p>
<p>When two inputs move together, a regression cannot reliably tell them apart. It will allocate the shared effect between them in a way that depends on small details of the data and the specification. The split can change substantially if you add a week of data or change a control.</p>
<p>CRM send volume is usually correlated with the promotional calendar, with paid media bursts, and with the season. It is one of the most collinear variables in the whole model. So its estimated coefficient is unstable almost by construction, and a small or negative value is weak evidence rather than a finding.</p>
<p>The right response is not to claim the model is wrong. It is to ask two questions of whoever built it. What is the uncertainty interval on the CRM coefficient, and how much does it move across reasonable alternative specifications.</p>
<p>If the interval is wide and the estimate swings across specifications, the honest conclusion is that the model cannot resolve CRM at this level of detail. That is a very different statement from "CRM does not work", and getting it stated in those words is most of the job.</p>
<h2>Give the model variables it can actually use</h2>
<p>Much of the problem is fixable at specification time, and the CRM team is the only group that can fix it. Bring these to the modelling team before the data is pulled.</p>
<ul>
<li><strong>Split the programme into behaviourally distinct groups.</strong> Broadcast promotional sends, triggered lifecycle messages and operational messages behave nothing alike. Modelled as one line called "CRM emails", they average into meaninglessness.</li>
<li><strong>Supply reach, not sends.</strong> Messages delivered, or better, delivered to people who have engaged recently. Send counts inflated by an unengaged file add variation that carries no effect.</li>
<li><strong>Separate promotional depth from message volume.</strong> If your sends carry discounts, the model will otherwise credit the discount to CRM or the CRM to the discount. Supply discount depth as its own variable.</li>
<li><strong>Flag the calendar explicitly.</strong> Peak weeks, sale periods and any week with an unusual send pattern. Controls that absorb the seasonality stop it being attributed to whatever moved with it.</li>
<li><strong>Provide base size as a control.</strong> Active contactable file size changes slowly and matters enormously. Without it, growth in the base is invisible and its effect lands on send volume.</li>
</ul>
<p>Each of these reduces the collinearity a little, and together they can move the CRM estimate from uninterpretable to merely uncertain.</p>
<p>One thing not to bring: a request that the model be adjusted until CRM looks better. That request is remembered, and it discredits the next legitimate methodological point you make.</p>
<h2>Use holdouts to calibrate the model, not to dispute it</h2>
<p>The strongest position a CRM team can hold in a modelling conversation is to arrive with experimental results already in hand.</p>
<p>Geographic or audience holdouts give a direct read on <a href="https://glassjaw.ai/blog/terms/incrementality/">incrementality</a>, independent of any regression. A <a href="https://glassjaw.ai/blog/terms/holdout-group/">holdout group</a> excluded from a programme for a defined period, compared against a matched group that received it, measures the thing the model is trying to estimate.</p>
<p>Modern practice is to use those results as inputs rather than as rebuttals. Experiment results can inform the model directly, tightening the range the coefficient is allowed to occupy, so the regression is anchored by measured effects instead of guessing between collinear variables. Ask whether the model is being calibrated this way, and offer the experiments if it is not.</p>
<p>For that to be possible, the experiments have to exist before the model is built. That means running a standing holdout at the programme level, not just per campaign, and keeping it for long enough to read a retention effect rather than a promotional one. A quarter is a reasonable minimum; a full year is better for anything seasonal.</p>
<p>Treat this as infrastructure rather than as a project. The holdout costs a small amount of revenue every week and it is the only asset that settles these arguments quickly.</p>
<h2>Agree what the model is allowed to settle</h2>
<p>The failure mode we see most is not a bad model. It is a good model used to answer questions it was never designed for.</p>
<p>An MMM works at the level of channel budgets over months. It is reasonable to ask it whether the CRM programme as a whole is contributing, and roughly at what scale. It is not reasonable to ask it whether a particular journey should have four messages or five, or whether Tuesday beats Thursday. Those are questions for controlled tests within the programme, of the kind we described when covering <a href="https://glassjaw.ai/blog/2025-10-20-send-time-optimisation/">send-time optimisation</a>, where the unit of analysis matches the unit of decision.</p>
<p>Write the division down before the results arrive. Which decisions the model informs, which decisions experiments inform, and what happens when the two disagree. Our preference is explicit: where a well-run experiment and a model conflict on the same question, the experiment wins, and the disagreement is recorded as a prompt to examine the specification.</p>
<p>Recording it is the point. This is exactly what a <a href="https://glassjaw.ai/blog/2025-12-18-the-decision-log/">decision log</a> is for, and the entry should capture what was decided, on what evidence, and what would change the answer. Eight months later, when the next model run produces a different number, that entry is the difference between a calm review and the same meeting again.</p>
<p>Before the next run, ask the modelling team for the current CRM specification and the uncertainty intervals, and ask whether any experiment results are being used to calibrate it. Those two questions will tell you within a week how much weight the output deserves.</p>]]></content:encoded>
  </item>
  <item>
    <title>Data contracts between marketing and engineering</title>
    <link>https://glassjaw.ai/blog/2026-02-24-data-contracts/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-02-24-data-contracts/</guid>
    <pubDate>Tue, 24 Feb 2026 09:00:00 +0000</pubDate>
    <category>Data &amp; personalisation</category>
    <description>How to write and enforce data contracts for the events a CRM programme depends on, so a routine release stops silently breaking personalisation and models.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-02-24-data-contracts.webp" alt="Abstract cover art: clustered nodes joined by edges on a dark blue field" width="1792" height="1024"></p>
<p>On a Monday morning the recommendation block in the weekly email is empty for about a fifth of recipients. Nobody deployed anything on the marketing side. The campaign ran as scheduled, the template is unchanged, and the platform reports no errors.</p>
<p>Three hours later someone works out that a release the previous Thursday renamed a field in the product-view event, from product_id to item_id, as part of a tidy-up. The engineer who made the change had no reason to think anyone outside the app was reading it. The pipeline accepted the new shape without complaint, because it was built to be forgiving. The transformation that fills the recommendation table quietly produced nothing.</p>
<p>This is the most common category of CRM incident we are called into, and it is almost never caused by carelessness. It is caused by an absent agreement. Nobody had written down which events the marketing programme depends on, what shape they must arrive in, and who to tell before changing them.</p>
<h2>What a data contract is, in practice</h2>
<p>A <a href="https://glassjaw.ai/blog/terms/data-contract/">data contract</a> is a versioned, machine-readable definition of a dataset that a producing team commits to and a consuming team builds against. Strip away the vocabulary and it contains six things:</p>
<ul>
<li>The schema: field names, types, whether each is required, and allowed values for anything enumerated.</li>
<li>Semantics: what each field means in plain English, including the edge cases. Does order total include tax, shipping and discount, and in which currency.</li>
<li>The producer, named as a team rather than a person.</li>
<li>Freshness and volume expectations: how late the data may be, and the range of daily volume outside which something is wrong.</li>
<li>The change policy: what counts as a breaking change, how much notice is required, and how versions coexist during a migration.</li>
<li>The consumers, so a producer can see who they would affect.</li>
</ul>
<p>It is not a document in a wiki. A contract that lives where nobody works is a record of an intention. The contract needs to sit in the repository, in a format a test can read, so that violating it fails a build rather than an email campaign.</p>
<h2>Start with the events that have already broken something</h2>
<p>Do not try to put the whole event stream under contract. The programme that tries this stalls within a month, because the inventory work is large and produces nothing visible until it is finished.</p>
<p>Start from incidents. Pull the last two or three quarters of anything that went wrong with personalisation, segmentation or reporting, and list the events involved. That list is short, specific, and already has organisational agreement that it matters.</p>
<p>Then add the events that feed anything automated and customer-facing. In most programmes that means the small set underneath the decision layer: the signals that drive <a href="https://glassjaw.ai/blog/2025-09-22-next-best-action/">next best action</a> and the features behind any scoring model. These are the highest-risk data paths in the business, because failure is silent. A broken dashboard is noticed within a day. A model quietly running on a field that has been null for three weeks is not.</p>
<p>Ten to fifteen events is a good first scope. Covering those properly is worth more than covering everything loosely.</p>
<h2>Put the contract where engineers already work</h2>
<p>The contract should be a file in the producing service's repository, reviewed like code, with the schema expressed in whatever format your stack already uses.</p>
<p>That placement is a deliberate choice about ownership. If the contract lives in the marketing team's space, then changing it is marketing's job and engineers will not read it. If it lives beside the code that emits the event, then a developer changing that code sees the contract in the same diff, and the review conversation happens at the right moment.</p>
<p>Marketing's contribution is the semantic layer, not the schema syntax. The plain-English meaning of each field, the business rules, the list of things that have gone wrong before. Write that section yourself and keep it specific. "Revenue excludes VAT, excludes shipping, and is recorded at the point of dispatch rather than order placement" prevents more incidents than any type declaration.</p>
<p>Version the contract properly. A breaking change means a new version with a stated overlap period during which both shapes are produced, not a rename on a Thursday afternoon.</p>
<h2>Enforce at three points, because one is not enough</h2>
<p>A contract that is not tested is a description of how things used to work.</p>
<p><strong>At the producer.</strong> A test in the producing service's build asserts that emitted events match the contract. This is the cheapest place to catch a problem, because it happens before the change reaches anything else.</p>
<p><strong>In the pipeline.</strong> Validate on arrival. Events that violate the contract go to a quarantine table rather than into the main stream, and the count of quarantined events is alerted on. Be careful with the default here: many <a href="https://glassjaw.ai/blog/terms/elt/">ELT</a> setups are deliberately permissive, loading whatever arrives so that nothing is lost, which is a sensible default for storage and a poor one for decisions.</p>
<p><strong>At the consumer.</strong> Tests on the transformation layer assert the properties the programme actually relies on. In a <a href="https://glassjaw.ai/blog/terms/dbt/">dbt</a> project this is straightforward: not-null, uniqueness, accepted values, and relationships between tables. Add freshness checks, because stale data passes every schema test ever written.</p>
<p>Alert on all three to a channel the CRM team reads. The failure mode we see most often is an alert that fires correctly into a channel only the data team watches. There it competes with every other alert and gets triaged as low priority, because nobody in that channel knows a campaign depends on it.</p>
<h2>Marketing's side of the bargain</h2>
<p>Contracts fail when they are treated as a demand rather than an agreement. If marketing asks for guarantees and offers nothing, engineering will treat the process as overhead and comply minimally.</p>
<p>What the marketing side has to bring:</p>
<ul>
<li>A named owner for each consuming dataset, who answers questions and approves changes.</li>
<li>Deprecation. If a field was requested for a campaign two years ago and nothing reads it now, say so and let it be removed. Unused fields under contract are a tax on every future change.</li>
<li>Fewer one-off requests. A new field added for a single campaign, outside the schema, is how the drift starts.</li>
<li>Realistic freshness requirements. Asking for real-time on a dataset that a weekly email reads makes every other requirement look negotiable.</li>
<li>Attendance at the review when a breaking change is proposed, including the ones that arrive at an inconvenient time.</li>
</ul>
<p>This is also the moment to be honest about the <a href="https://glassjaw.ai/blog/terms/single-customer-view/">single customer view</a>. Contracts govern the inputs; they do not resolve identity. If two systems disagree about who a person is, well-specified events will simply deliver that disagreement more reliably. Identity resolution is a separate piece of work and should not be smuggled into this one.</p>
<h2>What changes once the contracts exist</h2>
<p>The immediate effect is fewer silent failures, which is hard to celebrate because it shows up as an absence.</p>
<p>The more interesting effect is on what becomes buildable. Models are only as stable as their features, and the practical constraint on the kind of scoring described in <a href="https://glassjaw.ai/blog/2025-09-13-propensity-models-you-can-run/">propensity models you can run</a> is rarely the algorithm. It is that the inputs change shape without warning, so a model that validated well in March is making decisions on different data by June.</p>
<p>Contracts also change how <a href="https://glassjaw.ai/blog/terms/event-tracking/">event tracking</a> requests get handled. Once there is a defined process for adding an event, marketing stops asking for tags to be added ad hoc and starts specifying properly, which is faster for both sides after the first month.</p>
<p>The part that stays hard is that a contract makes ownership disputes visible without settling them. When an event has three producers and no clear owner, writing the contract is the moment everyone discovers it. That discovery is valuable, and it is also a conversation that a schema file cannot have for you. Expect to spend the first few weeks on ownership rather than syntax, and budget for it openly.</p>]]></content:encoded>
  </item>
  <item>
    <title>Two years of sender rules: what is now table stakes</title>
    <link>https://glassjaw.ai/blog/2026-02-04-sender-rules-two-years-on/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-02-04-sender-rules-two-years-on/</guid>
    <pubDate>Wed, 04 Feb 2026 09:00:00 +0000</pubDate>
    <category>Platforms &amp; implementation</category>
    <description>Two years after the first bulk sender requirements, authentication is the floor rather than an achievement. What a current baseline looks like and what still goes wrong.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-02-04-sender-rules-two-years-on.webp" alt="Abstract cover art: stacked isometric blocks on a dark blue field" width="1792" height="1024"></p>
<p>Two years ago this month, the first of the large mailbox providers began applying published requirements to bulk senders. A great many marketing teams spent that February in a DNS panel for the first time. Microsoft followed with its own set last May. The requirements now cover the majority of most brands' addressable inboxes.</p>
<p>What has changed since is not mainly technical. When we audit a programme today, the authentication records are almost always present and usually correct. Two years ago that was the finding. Today it is the starting position, and the interesting failures sit somewhere else entirely.</p>
<p>That shift is worth naming plainly, because plenty of teams still describe their authentication set-up as an achievement. It is not. It is the entry fee, and the things that separate a healthy programme from a struggling one are now downstream of it.</p>
<h2>What the current baseline actually looks like</h2>
<p>If you want a single description of where a competent programme sits at the start of this year, it is roughly this.</p>
<ul>
<li>SPF, DKIM and <a href="https://glassjaw.ai/blog/terms/dmarc/">DMARC</a> published for every domain and subdomain that sends, with alignment confirmed by inspection rather than assumed from a dashboard.</li>
<li>A DMARC policy at enforcement, meaning quarantine or reject, not monitoring only.</li>
<li>Aggregate DMARC reports parsed into something a person reads weekly, with an alert when an unrecognised source appears.</li>
<li>Transactional, marketing and lifecycle traffic separated onto different subdomains so that one bad campaign cannot damage receipts.</li>
<li>One-click unsubscribe present on every marketing stream, including the ones sent from systems marketing does not own, and honoured across all systems within the required window.</li>
<li>Complaint rates monitored per mailbox provider, weekly, with a named owner.</li>
<li>A written inactivity policy that actually stops mail going to people who have not engaged.</li>
</ul>
<p>Every item on that list applies across the major providers. The specifics differ, and the Microsoft requirements brought their own details, which we went through in <a href="https://glassjaw.ai/blog/2025-05-10-outlook-sender-requirements/">the Outlook sender requirements</a>. Building one baseline that satisfies all of them is far easier than maintaining three variants.</p>
<h2>The failures have moved from DNS to process</h2>
<p>A record that was correct when it was published stays correct until somebody changes something. In practice, somebody always does.</p>
<p>The recurring causes of a broken set-up now are organisational rather than technical:</p>
<ul>
<li>A new tool starts sending as the company domain because a team bought it with a card and nobody was asked.</li>
<li>A rebrand or domain migration moves the From address, and the authentication work follows six weeks later than the first send.</li>
<li>An email platform rotates DKIM keys and the corresponding DNS record is never updated, because the person who owned that relationship has changed role.</li>
<li>DMARC reports arrive at a mailbox nobody has opened since the project that created it ended.</li>
<li>A subdomain created for a one-off campaign in a regional market inherits nothing and is never decommissioned.</li>
</ul>
<p>The remedy for all five is the same, and it is dull. Somebody owns sender authentication as a named responsibility, there is a change process for anything that sends mail as the company, and the reports feed an alert rather than a folder.</p>
<p>We have started treating that ownership question as part of the audit rather than a recommendation from it. A programme where nobody can answer who is allowed to edit a DNS record will regress, whatever its records say today.</p>
<h2>Enforcement is the step most teams still have not taken</h2>
<p>Publishing a DMARC record in monitoring mode satisfies a compliance checkbox and protects nobody. It observes, and it instructs receiving servers to do nothing differently.</p>
<p>Moving to enforcement is what stops other people sending as you, and it remains the most common gap we find. The reason is usually a reasonable fear of blocking legitimate mail, and the answer is a staged path rather than a single change.</p>
<ol>
<li>Complete the sender inventory from the aggregate reports, and keep reading them until a fortnight passes with no unidentified source.</li>
<li>Authenticate or relocate every legitimate source. Anything that cannot be authenticated moves to a subdomain of its own or stops.</li>
<li>Move to quarantine with a small percentage applied, raise it in steps, and watch the reports between steps.</li>
<li>Move to reject once quarantine has run clean for several weeks.</li>
<li>Set a policy for subdomains explicitly rather than relying on inheritance you have not checked.</li>
</ol>
<p>The whole sequence takes a couple of months of mostly waiting. It is not difficult work and it is almost never scheduled, because nothing visibly breaks while it is left undone.</p>
<h2>BIMI is a consequence, not a strategy</h2>
<p>Every few months a brand team asks about getting the logo into the inbox. <a href="https://glassjaw.ai/blog/terms/bimi/">BIMI</a> is a reasonable thing to want, and a poor thing to lead with.</p>
<p>It requires DMARC at enforcement, a logo in the right format, and for the major providers a certificate proving you own the mark. In other words, it requires you to have already finished the work above, plus a trademark process and an annual cost.</p>
<p>That is why we treat it as a reward rather than a goal. If a brand team's request for BIMI is what finally funds the move to enforcement, that is a good outcome. If it becomes the project, teams end up buying a certificate for a domain whose complaint rate is the actual problem.</p>
<p>Be realistic about the benefit too. Display varies by client and by context, and the sender name and subject line still do most of the work in deciding whether a message is opened. Recognition is worth something. It is not worth reordering the roadmap for.</p>
<h2>Complaint rate and list hygiene are where the work now lives</h2>
<p>With authentication settled, the <a href="https://glassjaw.ai/blog/terms/deliverability/">deliverability</a> problems we are called into trace back to who is on the list and how often they are mailed.</p>
<p>The <a href="https://glassjaw.ai/blog/terms/complaint-rate/">complaint rate</a> is the only requirement that cannot be configured. It is a behavioural measure, reported per provider, and it responds to a short list of things. The quality of the acquisition source, the frequency of sending, how easy the unsubscribe is to find, and whether dormant addresses are still being mailed.</p>
<p>Good <a href="https://glassjaw.ai/blog/terms/list-hygiene/">list hygiene</a> at this point means four habits, held to consistently:</p>
<ul>
<li>Every acquisition source is documented, measured separately, and can be switched off on its own.</li>
<li>A sunset policy runs automatically, with a defined inactivity window and a final re-permission attempt before the stop.</li>
<li>The preference centre offers a real choice of frequency and topic, because the alternative to a useful option is the spam button.</li>
<li>Engagement is measured on clicks and site behaviour rather than opens, since machine-fetched opens make the open signal unreliable for this purpose.</li>
</ul>
<p>That last point has grown more important as inbox clients have changed how mail is presented and categorised, something we looked at when <a href="https://glassjaw.ai/blog/2025-02-07-apple-mail-categories/">Apple Mail introduced categories</a>. Where a message lands and how it is grouped now affects engagement metrics in ways that have nothing to do with your sending set-up.</p>
<h2>What to check this quarter</h2>
<p>Pull the DMARC policy for every sending domain and subdomain, and write down which are at enforcement and which are not. If the answer to any is monitoring only, schedule the staged move now rather than after the next incident.</p>
<p>Then find the last six weeks of aggregate reports and look for a sender you cannot name. There is usually one, and it is usually a tool somebody bought in good faith. Finding it is a better use of a morning than any campaign optimisation available to you.</p>]]></content:encoded>
  </item>
  <item>
    <title>Fewer unsubscribes without hiding the unsubscribe</title>
    <link>https://glassjaw.ai/blog/2026-01-20-fewer-unsubscribes/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-01-20-fewer-unsubscribes/</guid>
    <pubDate>Tue, 20 Jan 2026 09:00:00 +0000</pubDate>
    <category>Lifecycle &amp; retention</category>
    <description>Hiding the opt-out converts unsubscribes into complaints, which cost far more. How we reduce the demand for unsubscribing through pressure, relevance and a real pause.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-01-20-fewer-unsubscribes.webp" alt="Abstract cover art: paths branching between waypoints on a dark blue field" width="1792" height="1024"></p>
<p>The brief comes down from someone senior after a bad month. List growth has flattened, unsubscribes are up, and the instruction is to reduce them. Within a week a designer has been asked to make the footer link smaller, lighter and further down the page.</p>
<p>It works, in the narrow sense. Unsubscribes fall. Complaints rise, and complaints are the expensive currency. A person who cannot find the opt-out uses the report button instead, and providers read that button as evidence about your sending rather than about one email.</p>
<p>The useful framing is that an unsubscribe is not the problem. It is the receipt for a decision that was made several messages earlier. The work is reducing how many people arrive at that decision, not obstructing the last step.</p>
<h2>Hiding the link only changes the exit route</h2>
<p>Start with the arithmetic that makes the design instinct wrong. An unsubscribe removes one address from your list. A spam complaint removes that address and also contributes to a provider-level signal that affects delivery to everybody else on that domain.</p>
<p>The published <a href="https://glassjaw.ai/blog/terms/complaint-rate/">complaint rate</a> thresholds the major providers work to are low — measured in tenths of a per cent — and sustained sending above them costs placement across the whole programme. Trading an unsubscribe for a complaint is a bad trade at almost any exchange rate.</p>
<p>There is also a compliance floor that is not negotiable. Bulk senders are expected to carry a working <a href="https://glassjaw.ai/blog/terms/one-click-unsubscribe/">one-click unsubscribe</a> in the message headers and to action the request within a couple of days. Test yours this week rather than assuming it works. Send a message to a real mailbox, use the provider's own unsubscribe control rather than the footer link, and confirm the suppression landed in your platform. We find broken header unsubscribes in a surprising number of otherwise well-run programmes, usually after a template migration.</p>
<p>Make the footer link plain, legible and where people expect it. The goal is that nobody who wants to leave ever has to think about how.</p>
<h2>Reduce the pressure before you touch anything else</h2>
<p>The most reliable cause of unsubscribes is volume, and the second is volume disguised as relevance. If a programme has increased send frequency over the last year without changing its cap structure, that is where the answer is.</p>
<p>What we look at first:</p>
<ul>
<li>Messages per person per week, by engagement tier, over the last quarter — not average sends, which hides the tail.</li>
<li>The share of people receiving the maximum allowed, which tells you whether the cap is a limit or a target.</li>
<li>Whether triggered and automated messages count against the cap or sit outside it.</li>
<li>Which campaigns were added in the last six months, and what was removed to make room. Usually nothing was.</li>
</ul>
<p>Then set <a href="https://glassjaw.ai/blog/terms/frequency-capping/">frequency capping</a> by tier rather than by campaign. Highly engaged customers tolerate more; people who last opened four months ago do not, and sending them the same weekly cadence produces unsubscribes and complaints in roughly equal measure.</p>
<p>A reduction in volume for the least engaged tier almost always improves the programme's total revenue as well, because the sends that were generating the opt-outs were generating very little else.</p>
<h2>Offer a smaller decision than all or nothing</h2>
<p>Most unsubscribe pages present one option: leave. A good <a href="https://glassjaw.ai/blog/terms/preference-centre/">preference centre</a> presents several, and the one that recovers the most people is the simplest.</p>
<p>Give people a pause. Four weeks, three months, until after a season. Say the date it ends, honour it exactly, and send a single message when it does. In our experience a meaningful share of people who take a pause remain contactable afterwards, and they would otherwise have been gone permanently.</p>
<p>Then offer the other reductions:</p>
<ul>
<li>Fewer messages, as a stated number rather than a vague promise of "less often".</li>
<li>Topic choices that map to things people actually recognise — new arrivals, sale, order updates, the specific brand or category they buy.</li>
<li>Channel choices, so someone who dislikes email but reads push can say so.</li>
<li>A single clear route to full unsubscribe, on the same page, not buried behind the alternatives.</li>
</ul>
<p>Two design rules make the difference between a preference centre that works and one that annoys. It must be reachable without logging in, because the person reading is on a phone and will not retrieve a password to do you a favour. And every option must take effect immediately, including in journeys already in flight, or you will have promised something you do not deliver.</p>
<h2>Fix the messages that cause it, not the ones that carry it</h2>
<p>Unsubscribe rate is attributed to the send that carried the click, which is misleading. The message people leave on is often just the one that arrived after a run of poor ones.</p>
<p>Look at the sequence instead. Pull the last five messages each unsubscriber received and look for patterns. The same offer three times, a campaign for a category they have never bought, a re-send to openers that felt like a mistake.</p>
<p>Two sources of avoidable irritation come up repeatedly. The first is promotional content pushed into operational messages — the pattern we took apart in <a href="https://glassjaw.ai/blog/2025-05-17-transactional-email-audit/">the transactional email audit</a>. People expect a receipt to be a receipt, and marketing in that slot is read as a trick, which produces complaints rather than unsubscribes.</p>
<p>The second is contact with people who never knowingly joined. Customers acquired through a third party often do not recognise your name at all, and the answer is a properly designed introduction rather than immediate campaign pressure. We covered that handover in <a href="https://glassjaw.ai/blog/2025-07-22-marketplace-journeys/">journeys for marketplace customers</a>, and it remains the highest-unsubscribe cohort in most retail programmes.</p>
<h2>Measure it per person, and let people leave quietly</h2>
<p>Per-send unsubscribe rate is a weak metric. It rewards mailing a smaller, better audience and punishes reaching new people, and it tells you nothing about cumulative fatigue.</p>
<p>Report two numbers instead. The share of the active list that unsubscribed in the quarter, and the share of new subscribers who left within their first ninety days. The first measures pressure on the programme. The second measures whether your acquisition promise and your sending behaviour match.</p>
<p>Finally, accept that some of the list should go without being asked. A <a href="https://glassjaw.ai/blog/terms/sunset-policy/">sunset policy</a> that stops mailing people after a defined period of no engagement removes the addresses most likely to complain, before they do. Done properly it lowers both your unsubscribe rate and your complaint rate, and it improves placement for everyone still receiving you.</p>
<h2>What to change this month</h2>
<ul>
<li>Send yourself a campaign and complete an unsubscribe using the mailbox provider's own control, then confirm the suppression arrived.</li>
<li>Add a pause option to the unsubscribe page with three stated durations, and make it work without a login.</li>
<li>Pull the last five messages received by everyone who unsubscribed last month, and read fifty of those sequences yourself.</li>
</ul>]]></content:encoded>
  </item>
  <item>
    <title>Migrating engagement platforms without a dark month</title>
    <link>https://glassjaw.ai/blog/2026-01-13-migration-without-a-dark-month/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2026-01-13-migration-without-a-dark-month/</guid>
    <pubDate>Tue, 13 Jan 2026 09:00:00 +0000</pubDate>
    <category>Platforms &amp; implementation</category>
    <description>Platform migrations lose a month of sending because of how they are planned, not because they must. How to run both systems, move programme by programme and warm safely.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2026-01-13-migration-without-a-dark-month.webp" alt="Abstract cover art: stacked isometric blocks on a dark blue field" width="1792" height="1024"></p>
<p>Every platform migration plan we are shown has the same shape. Eight weeks of build, a cut-over weekend, then a few weeks described as stabilisation. Somewhere in that period, usually without anyone writing it down, the programme stops sending.</p>
<p>The gap gets called a quiet phase. In practice it is a month in which nobody receives a welcome journey, no baskets are recovered, and the reactivation series does not run. The revenue does not come back later, because the customers it would have reached moved on.</p>
<p>A dark month is a planning decision rather than a technical requirement. Nothing about replacing an engagement platform requires you to stop talking to customers, provided the old system stays switched on while the new one earns its traffic.</p>
<h2>The dark month comes from cutting over all at once</h2>
<p>Big-bang cut-over is attractive because it is simple to describe and easy to put on a plan. One date, one switch, one set of approvals.</p>
<p>It also concentrates every risk on a single weekend. Templates, data feeds, journey logic, sending reputation, integrations and reporting all change at once, and when something misbehaves on the Monday there is no way to tell which change caused it.</p>
<p>The response is always the same: pause sends until it is sorted. That pause is the dark month, and it is produced by the plan, not by the platform.</p>
<p>The alternative is to treat migration as a traffic-shifting exercise. Both systems run. Programmes move over one at a time, in an order you choose. The old platform keeps sending everything that has not moved yet, and stays available as a rollback until the last programme is across.</p>
<h2>Run both, and move one programme at a time</h2>
<p>Parallel running costs a few weeks of double licensing. That is almost always cheaper than the sends you would otherwise lose, and the comparison is worth putting in the business case explicitly.</p>
<p>Move programmes in order of risk and volume, lowest first:</p>
<ol>
<li>A single low-volume triggered message, such as a review request, to prove the end-to-end path.</li>
<li>Transactional and service messages, if they are in scope, since the content is stable and the audiences are small per send.</li>
<li>Triggered lifecycle journeys: welcome, basket, replenishment. These carry most of the value and benefit from careful attention.</li>
<li>Segmented broadcasts to engaged recipients.</li>
<li>Full-file broadcasts, last, once the sending reputation on the new platform is established.</li>
</ol>
<p>One rule holds the whole thing together: a programme lives in exactly one platform at any moment. Never run the same journey in both, because the suppression logic in each system cannot see the other, and customers receive everything twice.</p>
<p>Turn the old version off at the moment the new one goes live, in the same working session, with both people in the same call.</p>
<h2>Warm the new sending identity with traffic you already trust</h2>
<p>New sending infrastructure has no reputation. Mailbox providers judge it on early behaviour, and the fastest way to fail is to send a large promotional broadcast to a cold list on day one.</p>
<p><a href="https://glassjaw.ai/blog/terms/ip-warming/">IP warming</a> is why the migration order above starts with triggered messages. Transactional and lifecycle traffic has excellent engagement, small daily volumes and predictable patterns, which is exactly what a new sending identity needs to establish itself.</p>
<p>The practice we follow:</p>
<ul>
<li>Start with your most engaged recipients, defined by opens and clicks in the last thirty days, and widen gradually.</li>
<li>Increase daily volume in steps, holding at each step long enough to see the result rather than pushing through a schedule.</li>
<li>Watch delivery by mailbox provider, not as a blended figure. Providers respond to new senders differently and at different speeds.</li>
<li>Keep authentication records for the new platform published and verified before the first send, including the return-path domain.</li>
<li>Stop increasing volume the moment complaint or bounce rates move, and hold until they settle.</li>
</ul>
<p>Plan a realistic number of weeks, and do not let a launch date compress it. Reputation damage during warming takes far longer to repair than the schedule you were protecting.</p>
<p>The choice between a new domain and your existing sending domain deserves an explicit decision. Keeping the domain and changing the underlying infrastructure carries over some history, but it also means a problem during warming touches mail you already depend on. Whichever you choose, write down the reason, because someone will ask in six months.</p>
<h2>Port the data model, not the campaign library</h2>
<p>The instinct is to recreate what exists. That is how programmes arrive on a new platform carrying the same two hundred templates, forty of which nobody has sent in two years.</p>
<p>Migration is the one moment when deleting things is easy to approve. Inventory every message, mark each keep, rebuild or retire, and expect a third of the library to be retirable. Rebuild only what earns its place.</p>
<p>Data is the opposite: it needs more care than people budget for, not less. Start from the <a href="https://glassjaw.ai/blog/terms/single-customer-view/">single customer view</a> rather than from the old platform's field list, because that list encodes years of workarounds.</p>
<p>Write a <a href="https://glassjaw.ai/blog/terms/data-contract/">data contract</a> for the new platform before any field is mapped. Field name, type, allowed values, refresh frequency, owner, and the source system. Anything without an owner does not get created.</p>
<p>Feed it the way you feed everything else. If profile and audience data already arrives through <a href="https://glassjaw.ai/blog/2025-04-24-reverse-etl-in-practice/">reverse ETL from the warehouse</a>, point that pipeline at the new destination and keep a single definition of each attribute. Migrations that let the new platform compute its own version of a segment produce two numbers for the same thing within a quarter.</p>
<p>Where there is no warehouse to work from, the approach in <a href="https://glassjaw.ai/blog/2025-03-28-single-customer-view-without-a-cdp/">building a single customer view without a CDP</a> still gives you one place to define identity before the mapping starts.</p>
<h2>Decide the cut-over rules and the rollback in advance</h2>
<p>Each programme move needs three things agreed in writing beforehand. What must be true to go live. What you will watch for the first seventy-two hours. And what would make you switch back.</p>
<p>Rollback is the one people skip, usually because the old platform is still running and everyone assumes reverting is obvious. It is not obvious at three in the afternoon when a journey is misfiring and two teams disagree about whether it is serious.</p>
<p>Name the specific numbers. Delivery rate below a stated floor, complaint rate above a stated ceiling, or a volume that differs from forecast by more than an agreed margin. Name the person who calls it, and keep the old journey in a paused state rather than deleted until the new one has run for a full cycle.</p>
<p>Then keep the <a href="https://glassjaw.ai/blog/terms/deliverability/">deliverability</a> dashboard from the old platform alive for a quarter after the last programme moves. It is the only baseline you will have when someone asks whether things got better or worse.</p>]]></content:encoded>
  </item>
  <item>
    <title>The decision log that stops two years of tests evaporating</title>
    <link>https://glassjaw.ai/blog/2025-12-18-the-decision-log/</link>
    <guid isPermaLink="true">https://glassjaw.ai/blog/2025-12-18-the-decision-log/</guid>
    <pubDate>Thu, 18 Dec 2025 09:00:00 +0000</pubDate>
    <category>Testing &amp; optimisation</category>
    <description>Two years of testing and nobody can say what was learned. The decision log we keep for CRM programmes: the fields that matter, why null results go in it, and why entries expire.</description>
    <content:encoded><![CDATA[<p><img src="https://glassjaw.ai/assets/img/blog/2025-12-18-the-decision-log.webp" alt="Abstract cover art: a bar series under a trend line on a dark blue field" width="1792" height="1024"></p>
<p>A new lifecycle manager joined a client in October and asked a reasonable question in her second week. Do we put a discount in the welcome series or not?</p>
<p>Nobody could answer. The test had been run, everyone agreed on that much. It was roughly eighteen months ago, the person who ran it had left, the platform's reporting only retained a year of campaign data, and the deck was in somebody's personal drive. What survived was a sentence in a strategy document saying the welcome offer had been "validated", with no number, no date and no definition of what it had been validated against.</p>
<p>So the team ran it again. Two months of a programme's testing capacity spent rediscovering something the company already knew. This is the most common form of waste we see in mature CRM programmes, and it has nothing to do with test design.</p>
<h2>A decision log is not a test archive</h2>
<p>The distinction matters, because most teams already have something that looks like a log and it does not solve this problem.</p>
<p>A test archive is a folder of results. It is organised by campaign, it grows without limit, and nobody reads it because finding the relevant entry takes longer than rerunning the test.</p>
<p>A decision log is organised by question. One row per question the business has settled, holding what was decided, on what evidence, and when it expires. A test that produced no decision does not get a row of its own. A decision made without a test does, because those are exactly the ones that get relitigated.</p>
<p>The test is evidence. The decision is the asset. Keeping only the evidence is how you end up with a shelf full of results and a team that cannot say what it believes.</p>
<h2>The fields that make an entry useful two years later</h2>
<p>Keep it short enough that people actually fill it in. We use nine fields, and the discipline is that an entry with an empty field is not finished.</p>
<ol>
<li><strong>The question, in plain language.</strong> "Does a first-order discount in the welcome series increase ninety-day revenue per new subscriber?" Not "welcome series test v3".</li>
<li><strong>The date the decision was taken</strong>, and the period the evidence covers. Seasonality is the most common reason an old result stops holding.</li>
<li><strong>What was actually compared.</strong> Both variants described well enough to rebuild them, including the audience definition and any exclusions.</li>
<li><strong>The population and the volume.</strong> How many people in each arm, and which audience they were drawn from.</li>
<li><strong>The primary metric and its measurement window</strong>, chosen before the test ran. One metric, not five.</li>
<li><strong>The result</strong>, as an effect size with an interval rather than a verdict. "Between minus one and plus four per cent, centred near one" is a far more useful record than "no significant difference".</li>
<li><strong>The decision taken</strong>, which is not the same as the result. Sometimes you adopt a variant that did not win, for cost or brand reasons, and that reasoning needs to be written down or it will look like an error later.</li>
<li><strong>Confidence, in one word.</strong> High, medium or low, judged by the person who ran it.</li>
<li><strong>Where the raw data lives</strong>, as a query, a table name or an export path that will still resolve after the platform is replaced.</li>
</ol>
<p>Nine fields take about fifteen minutes to fill in. The test took six weeks.</p>
<h2>Write the entry before the test runs, not after</h2>
<p>Open the row when you design the test. Question, comparison, population, primary metric and window all get written down before a single send goes out, and nothing in that set may be edited afterwards.</p>
<p>This single habit fixes several problems at once. It stops the metric being chosen after the results are in, which is the most common way an <a href="https://glassjaw.ai/blog/terms/ab-test/">A/B test</a> produces a conclusion it does not support. It forces an explicit decision rule: what result would make us change, and what result would make us leave things alone. And it surfaces the tests that are underpowered before you spend six weeks on them, because writing the expected volume next to the expected effect size makes the arithmetic unavoidable.</p>
<p>Agree the stopping rule in the same sitting. When the test will be read, and that it will not be read early because someone is impatient. Peeking at a running test and stopping when it looks good is how a programme accumulates results that never replicate, whatever the <a href="https://glassjaw.ai/blog/terms/statistical-significance/">significance</a> figure on the dashboard says.</p>
<h2>Record the results that found nothing</h2>
<p>Most tests do not move the metric. That is a normal property of a well-run programme, not a failure, and those entries are the ones with the highest long-term value.</p>
<p>A null result tells the next person that this question has been asked, at this volume, and did not produce an answer worth acting on. Without it, the same idea returns in the next planning cycle wearing a different name, and the team spends another six weeks on it.</p>
<p>Be careful about how you phrase it. "No difference" is almost never what you found. What you found is that any difference was smaller than the test could detect, which is a statement about your sample as much as about the variants. Recording the interval rather than the verdict keeps that honest, and lets someone later judge whether it is worth retesting at a larger volume.</p>
<p>The same applies to programme-level evidence. When you run a <a href="https://glassjaw.ai/blog/terms/holdout-group/">holdout group</a> and find that a journey's <a href="https://glassjaw.ai/blog/terms/incrementality/">incremental contribution</a> is smaller than everyone assumed, that finding must survive the person who ran it. The <a href="https://glassjaw.ai/blog/2025-06-05-holdouts-that-prove-it/">incremental read on a programme</a> is the most expensive evidence you will produce, and it is also the most likely to be quietly forgotten when it is unflattering.</p>
<h2>Give every decision an expiry date</h2>
<p>An entry without a review date becomes folklore. Somebody quotes it three years on, the underlying conditions have changed, and no one can remember how strong the evidence was.</p>
<p>Set the review date by how fast the thing decays. Our rough guidance:</p>
<ul>
<li>Creative and subject-line findings: six months. Audience habits and competitor behaviour move underneath them.</li>
<li>Offer and discount decisions: one year, or sooner if margin structure changes.</li>
<li>Timing and cadence: one year. Everything we said about <a href="https://glassjaw.ai/blog/2025-10-20-send-time-optimisation/">send-time optimisation</a> depends on behaviour that shifts with device mix and seasonality.</li>
<li>Structural decisions such as journey architecture or contact policy: two years.</li>
</ul>
<p>When a date passes, the entry is not deleted. It moves to a review list, and somebody decides whether to retest, to reaffirm without evidence, or to mark it unresolved. All three are legitimate outcomes. The only bad outcome is an entry nobody has looked at since it was written, still being cited as fact.</p>
<h2>Keep it where the platform cannot take it away</h2>
<p>Put the log outside the marketing platform. Platforms get replaced, reporting windows expire, and accounts get closed when a contract ends. A plain table in the company's own document system or warehouse will outlive all of it.</p>
<p>Give it one owner, and review it in the same meeting where next quarter's tests are planned. Reading the last six entries before proposing new ones takes ten minutes, and it is the single cheapest way to stop repeating work.</p>
<p>The hard part is not the format. It is that nobody is rewarded for writing down a null result, and everybody is busy in the week a test finishes. The only fix we have found is to make the entry part of the definition of done, so a test is not finished when the deck is presented, but when the row is complete.</p>]]></content:encoded>
  </item>
</channel>
</rss>
