The Frozen File - Keeping the CRM Export From Touching the Rules

The Frozen File - Keeping the CRM Export From Touching the Rules

The problem

A sales-enablement tool generates each rep's daily account briefing by combining two very different kinds of text in one prompt. The first kind is fixed: always include a disclaimer, always use a three-section layout, never mention competitor pricing. The second kind changes daily: that day's CRM export, the accounts touched, the open opportunities, the last activity on each. Both lived in the same prompt string, hand-edited together, because that's how the prompt got written the first time and nobody had a reason to split it yet.

The CRM's export format drifts roughly monthly. A field gets added. A field gets renamed. Someone on the data team ships a change that has nothing to do with the sales-enablement tool and everything to do with their own roadmap, and the briefing generator breaks unless someone edits the prompt to parse the new format. That's ordinary, unglamorous churn, the kind every system with an upstream dependency eventually absorbs.

Here's where it goes wrong. Whoever edits the prompt to accommodate the new CRM format is touching the same text block that holds the disclaimer requirement, the layout rule, and the competitor-pricing constraint. Nothing about the edit separates those two concerns. The editor's intent is entirely about parsing the new CRM fields. Their fingers are in the same paragraph as the compliance rules, and nothing stops a routine edit from silently corrupting text the editor never meant to touch. I ran six scripted CRM-format edits against this setup, tracking whether each of the four fixed rules survived. At least two of the six produced a violation, a missing disclaimer, a two-section layout instead of three, a stray mention of a competitor's pricing that crept in because the editor was focused on the CRM parsing logic and wasn't rereading the whole block for compliance every single time.

What makes this a distinct problem, separate from just being careful, is that being careful doesn't scale. Nobody rereads four rules buried in a paragraph every time they fix a CRM parsing bug. They fix the bug, test that the CRM data renders, and ship. The rules survive by accident when they survive at all.

The pattern

The fix physically separates the two kinds of text into two different artifacts, checked in as their own files rather than two sections stitched into one string. The frozen section, the role description, the layout requirement, the disclaimer, the competitor-pricing constraint, lives in its own file, checked into version control, edited only under explicit review. The volatile section, today's CRM snippet, gets templated into a clearly delimited slot in the assembled prompt, something like a placeholder token that the frozen file references but never contains.

The mechanism here is structural rather than a matter of discipline. When the CRM format changes for the seventh time, the editor opens the volatile template logic. They don't open the frozen file, because the frozen file isn't where the CRM parsing lives anymore. It can't be touched by an edit that was never about it in the first place, because it isn't the same document. I reran the same six scripted CRM-format edits against this split version and got zero frozen-rule violations across all six. Not because anyone tried harder to be careful. Because the edit physically couldn't reach the rules text anymore.

There's a version-control benefit that falls out of this almost for free. A frozen file that changes only under explicit review has a clean history. Every commit to it represents an actual, deliberate decision to change a compliance rule, the kind of decision that used to get lost as an accidental side effect of a CRM parsing fix landing in the same file. If a disclaimer ever does go missing in production, the frozen file's commit history tells you exactly when and why, because nothing else could have touched it.

Design considerations

I want to be precise about what this split actually claims, because it's a narrow claim and I'd rather you know the edges than assume it does more than it does. This closes one specific failure mode: an edit whose real intent is volatile-section work bleeding into frozen text because both lived in the same undifferentiated block. It says nothing about every other way a prompt can drift. A frozen section can still be wrong the day it's written. A reviewer can still approve a bad change to the frozen file, because explicit review is built to catch an edit that shouldn't have been there, and it has nothing to say about whether a deliberate, intentional change is actually correct. The split buys you protection against one specific failure shape, an edit meant for one thing touching another thing by accident, and it buys you exactly that and nothing more.

The harder calibration question is deciding what actually belongs in the frozen file versus what belongs in the volatile slot. It's tempting to draw the line at "things that change often" versus "things that don't," but that's not quite the right axis. The real axis is who owns the change and under what process. The disclaimer requirement changes rarely, but when it does change, it needs legal review, not a quick fix from whoever noticed the CRM broke again. The CRM snippet changes constantly, and nobody needs to review each day's actual account data, only the logic that parses it. Put anything that needs deliberate sign-off in the frozen file, regardless of how often it happens to change, and put anything that's mechanically regenerated per run in the volatile slot, regardless of how stable its structure happens to be.

There's a subtlety here that only shows up once prompt-prefix caching enters the picture for cost reasons: physical order matters differently for different purposes. This split is about edit governance, who's allowed to touch which text, gated by review. For that purpose, whether the frozen section sits first or the volatile section sits first in the assembled prompt doesn't matter at all. The split's whole point, that a routine edit can't touch the rules, holds regardless of which piece comes first. Keeping a cache-stable prefix for cost reasons is a genuinely separate concern with its own ordering requirement, and conflating the two costs either the governance benefit or the caching benefit, whichever one gets compromised to satisfy the other. They can coexist. They just aren't the same discipline wearing two names.