Ad rewritten mid-campaign
A campaign is planned top-down: a brief, then messaging, then ads and landing pages. It changes bottom-up, because the ads are where results arrive. This example takes a headline that wins in market and asks how far up the campaign its result should reach.
The system
Section titled “The system”A paid campaign for Tally, a budgeting app, aimed at people aged 25 to 34.
| Artifact-set | Holds |
|---|---|
{brief} |
Objective, audience, the single-minded proposition, budget, and target cost per sign-up |
{messaging} |
The messaging framework: headline themes, proof points, and the substantiation on file for each claim |
{ads} |
Ad copy and visuals for paid social and search, with their variants |
{launches} |
Which ad variants are live, from when, and on what budget |
{landing page} |
The page the ads send traffic to |
{campaign results} |
Spend, clicks, sign-ups, and cost per sign-up for each ad and page variant |
Ad copy and a launch are different kinds of write. Copy can be revised in place until it
runs. A launch spends money the moment it serves, and the spend cannot be recalled. Pausing
it is a new launch decision, not a revision of the old one. So {ads} is
owned by the workflow that writes it, and
{launches} is its output.
{campaign results} is written by the ad platform’s and the analytics tool’s reporting,
its controller. No workflow writes it.
Two people are the campaign’s approvers. The brand lead holds positioning: the proposition and what the framework allows. The performance marketer holds spend. The model lets either approve any stop; the team sends direction to the brand lead and spend to the performance marketer.
Connections:
{brief}to{messaging}{messaging}to{ads}{messaging}to{landing page}{ads}to{landing page}{ads}to{launches}: every live launch runs an ad as it is written{launches}to{campaign results}: every live launch meets the brief’s target cost per sign-up{landing page}to{campaign results}: every live page variant meets the same target
The fourth connection is message match: a visitor who clicks on a promise expects to find it
at the top of the page. The framework does not say which headline a page must open on for a
given ad, so the match cannot be checked through {messaging}. It is the same kind of
sibling connection as the API docs in the
component library example. Which end
yields is declared by the workflow below, not by the connection.
The brief’s proposition is Tally shows you where your money goes. The framework allows headlines about clarity and control. It lists savings as a proof point, active users save a median of $612 in their first year, backed by a 2025 analysis of 40,000 accounts. The figure may appear in body copy, with its basis stated.
Workflows
Section titled “Workflows”| Workflow | Input | Owned | Output | Shape |
|---|---|---|---|---|
| Campaign planning | {brief} |
{messaging} |
none | one link |
| Creative production | {messaging} |
{ads} |
{launches} |
chain |
| Page build | {messaging} |
{landing page} |
none | one link |
| Message match | {ads} |
{landing page} |
none | one link |
The declarations are top-down, the way the team plans. Every workflow
reads the set above it and writes the set below,
and message match makes the ads the specification of the page. Only campaign planning owns
{messaging}, and it reads the brief. No workflow owns {brief}.
Every workflow keeps the default leash. A write that removes or reverses part of the set’s standing specification stops for approval.
A positioning call is the brand lead’s. Asking the brand lead once to decide and again to
approve the framework that carries the decision out adds a stop and no judgement. So when
the brand lead makes a positioning call in a run, they
pre-approve the rest of the run’s writes to
{messaging}, {ads}, and {landing page}. The model would let them pre-approve every
gate. They leave launches out, because the team sends spend to the performance marketer.
Under that leash, creative production’s edits to ad copy proceed when the criteria pass and they only add. A launch commits spend, so it needs the performance marketer’s approval.
Writes to {ads} and {landing page} wait while {messaging} has a pending writer, as the
workflows’ strain policy declares.
The default lets owned writes proceed, and here that would reconcile a live ad’s copy against
a framework about to change. A change to the framework waits on a person, and that can take
days.
The change
Section titled “The change”Three weeks in, the team learns that the savings figure sells the app better than clarity does. The finding reaches the campaign by one of two routes, one per variant.
Variant A: the change lands in an ad
Section titled “Variant A: the change lands in an ad”A performance marketer writes a new paid social headline in the ad platform, Tally users
save $612 in their first year, and launches it. Within a week it has three times the
click-through rate of the control headline and meets the target cost per sign-up. The change
touches {ads} and {launches}.
Expected run
Section titled “Expected run”- Lift. The change touches
{ads}and{launches}. - Find candidates. Creative production owns
{ads}and outputs{launches}, so it is an upstream candidate. Message match reads{ads}as an input, so it is a downstream candidate. Campaign planning and page build span neither set. - Distill. Creative production reads the change
within its span,
{messaging}to{ads}to{launches}. Intent: lead paid social with the savings figure. The results are why the marketer kept the headline. They are not what the headline is for. Message match reads the headline itself, because{ads}is its input: a visitor from a savings ad expects the figure at the top of the page. - Ask upward. Creative production asks the controller of
{messaging}, the set above{ads}. The intent implies two criteria there: paid social headlines may lead with the savings figure, and every figure states its basis where it appears. The framework keeps savings in body copy, so{messaging}is affected. It is creative production’s input, so the job is routed to campaign planning, which alone owns it. - Route. Campaign planning’s job asks the controller of
{brief}. The brief carries one proposition in every channel. The intent is about paid social and says nothing about the other channels, so it does not replace the proposition. The two stand together and contradict each other, which is a conflict. No workflow owns{brief}, so no run can clear it. It is raised as an obligation against the brief, as selection step 6 requires, and the conflict goes to the brand lead. - Schedule. The live launch runs a figure with no basis. A launch is an output, so the
strain clears only by a superseding launch, and until then it is held as
obligation. In the
run ledger,
campaign planning’s job waits on the decision, and creative production’s reconciliation
at
{ads}waits on{messaging}. Message match does not wait on that reconciliation, because the source counts as settled. Its write to the page meets the page’s standing criteria from{messaging}, which keep savings out of headlines, so it waits on the same set. - Decide. The brand lead decides that paid social may lead with savings until the
campaign ends, as a test, and that the proposition holds everywhere else. The decision is
recorded, lands in
{messaging}and{brief}, the sets it affects, and creates the next version of the criteria. The run is stopped on the brand lead, so the brand lead also pre-approves the run’s remaining writes to the framework, the ads, and the page. - Replay from
{messaging}. The framework’s controller amends it under the new version: savings-led headlines in paid social and on its landing page variant, with the basis stated. The amended framework is marked output of the run, and creative production and page build, which read it, pick it up under the run’s intent. - Reconcile at the source. The controller of
{ads}reconciles the marketer’s headline against the criteria arriving from the framework. It keeps the headline and adds a basis line. A live launch cannot be revised, so the controller of{launches}reports the change as a superseding relaunch with the basis line. Below{ads}, the page’s controller joins message match’s and page build’s criteria and writes a paid social variant that opens on the figure. - Leash. The ad copy and the page variant only add: a basis line on a new variant, and a page variant beside the ones that stand. They proceed when the criteria pass. The amended framework is different. Before the run it kept savings out of headlines, and the write reverses that for paid social. By the default it stops for approval, here from the brand lead. The brand lead made exactly that call in step 7 and pre-approved the writes that follow it, so the write proceeds when its criteria pass. The brand lead is asked once. The reconciliation report is a builder outcome: a kept headline and a filled hole. The relaunch is an output, so it goes to the performance marketer for approval. Once live, it supersedes the arriving launch and the obligation clears.
Settled state
Section titled “Settled state”{brief}keeps its proposition, with a recorded exception for paid social.{messaging}permits savings-led headlines in paid social and on its landing page variant, with the basis stated.{ads}holds the marketer’s headline with a basis line.{launches}records the original launch, superseded by the relaunch with the basis line.{landing page}has a paid social variant that opens on the figure.{campaign results}is unchanged by the run. The relaunch differs from the tested launch by a basis line, and its own cost per sign-up is held as obligation strain on{launches}to{campaign results}until the reporting catches up.
Status: Holds
Section titled “Status: Holds”The run carries the result from one ad up to the brief, where positioning is decided, and stops there for a person. That is the behaviour the team would want. An ad test informs the positioning and does not rewrite it.
The route up is now a workflow, not a side effect. The controller of {messaging} answers
that the framework is affected, the job is routed to campaign planning because the framework
is creative production’s input, and campaign planning’s own question to the brief is where
the conflict surfaces. The declared roles make that the only route.
Two things stop the run for a person, and either would be enough. {brief} has no owner, so
selection step 6 raises it. The framework’s write reverses a criterion it stood under, so
the leash stops it. If the team declared a workflow that owns {brief}, step 6 would no
longer fire, and that workflow’s write of the exception would narrow the proposition and
stop at the leash. A result reaches positioning through the brand lead either way.
The leash separates three things the earlier run treated as two. Rewriting copy adds and proceeds on the criteria. Reversing what the framework allows waits for the person who holds positioning. Relaunching spends money and waits for the person who holds spend.
The run asks the brand lead once because the brand lead pre-approves at the decision. Without that, the conflict decision and the leash stop are two asks of one person for one call. Two things rest on judgement. The first is that a conflict handed to a person counts as a stop at which an approver may pre-approve. The run waits on the brand lead there, so it reads as one. The second is width. The pre-approval covers every later write to the three sets, not only what the decision removed. A framework write that removed more than the paid social exception would still proceed if its criteria pass and its controller is sure of it. A declared rule that passed only writes removing what the decision removed would be narrower. Pre-approval trades that for needing no rule per set.
The relaunch approval reaches the performance marketer, who also made the change. The Leash section accepts that for a solo developer or author and is silent for a team. Here it does no harm, because the change of direction was approved by the brand lead, and the marketer approves only spend.
Reconciliation keeps the headline that has results. An earlier reading replayed savings-led ads from the framework, which had never run, and recorded a choice between them and the marketer’s headline. The marketer’s headline is now kept wherever it meets the criteria, and only its missing basis is added.
Variant B: the change lands on the landing page
Section titled “Variant B: the change lands on the landing page”Instead, a web editor who has seen the same analysis changes the landing page headline to
Save $612 in your first year, to lift conversion. The ads are unchanged. The change
touches {landing page}.
Expected run
Section titled “Expected run”- Lift. The change touches
{landing page}. - Find candidates. Page build and message match both own
{landing page}, so both are upstream candidates. No workflow reads{landing page}as an input, so there are no downstream candidates. - Distill. Page build reads the change within
{messaging}to{landing page}. The page serves every visitor, and the change names no channel. Intent: lead with the savings figure wherever visitors land. Message match reads it within{ads}to{landing page}, where the paid social and search ads that send traffic to the page all promise clarity. It states the same intent. Email sends traffic too, and neither span narrows the change to one channel. - Ask upward. Page build asks the controller of
{messaging}: the page may lead with the figure, with its basis stated. The framework keeps savings in body copy, so it is affected, and the job is routed to campaign planning. Message match asks the controller of{ads}: every ad that sends traffic to the page may lead with the figure and makes a promise the page keeps. The ads promise clarity, so they are affected, and the job is routed to creative production. Creative production’s job asks the controller of{messaging}, which is affected, and routes to campaign planning, whose job the ledger already holds. - Route. Campaign planning’s job asks the controller of
{brief}. This time the intent covers every channel, which is the proposition itself. The two contradict each other. No workflow owns{brief}, so no run can clear the strain on it. It is raised as an obligation against the brief, as selection step 6 requires, and the conflict goes to the brand lead. The brand lead either replaces the proposition with savings or refuses the change. - Schedule. No output changed, so nothing is held as obligation yet. Creative
production’s job and the reconciliation at
{landing page}wait on{messaging}. - Reconcile at the source. Whatever the decision, the editor’s headline has the same
hole as variant A’s: it gives no basis. If savings replaces the proposition, the page’s
controller keeps the headline and adds the basis. If the change is refused, it restores
the clarity headline. A savings page variant has no results yet, so its cost per sign-up
is held as obligation strain on
{landing page}to{campaign results}. - Leash. If savings replaces the proposition, every write below the brief reverses something that stood before the run: the framework’s clarity headlines, the ads’ clarity promise, and the page’s clarity headline. Each stops for approval by default, here from the brand lead. The brand lead pre-approved them when deciding to replace the proposition, so each write proceeds when its criteria pass. The rewritten ads leave every live launch running copy that no longer exists, so each needs a superseding launch, and those are outputs that wait for the performance marketer. If the change is refused, the restored page matches its standing specification, and the write proceeds without a stop.
Settled state
Section titled “Settled state”Either savings leads in every channel under a new proposition, or the change is refused. Neither is variant A’s state.
Status: Unresolved
Section titled “Status: Unresolved”Variants A and B carry one finding, that savings sells better than clarity to this audience, and they settle in states that meet different criteria. Confluence is claimed over criteria, so this is not a harmless difference between settled states. If the two changes carry one intent, confluence is lost.
Distilling within each workflow does not fix it. It moves where the scope comes from, from the walks to the spans. From an ad, the only upstream candidate is creative production, and the change sits on one paid social ad. From the page, page build and message match both read a page that serves every channel, and nothing in either span narrows it. The controllers above do not narrow it either. They derive criteria from the intent they are handed, and nothing in the model revises an intent from a controller’s answer. Each variant keeps the scope of the artifact the change landed in, with the model’s own structure behind it rather than the distiller’s taste.
The finding came from paid social results, and those live in {campaign results}. No
workflow spans that set, so no workflow distills with it and no controller is asked about
it. Selection step 6 does not catch this. It raises an affected set that no declared workflow
writes, and {campaign results} is never asked, so it is never affected. It is only unread.
The model has no step for evidence that no workflow reads.
One obstacle of the earlier reading is gone. Its walks stopped at the first set that
contradicted the change, before any evidence further up. Asking now continues past an
affected set, and an affected input is routed as an intent to every one of its owners.
Suppose the team declared a workflow that reads {campaign results} and owns {messaging}.
It would receive the routed job, with the root intent and the framework’s criteria, and read
them within a span that holds the results. The evidence covers paid social only, so the
criteria its controllers derive for the framework are scoped to paid social. The ledger hands the framework’s controller that intent together with campaign
planning’s every-channel one, and the two conflict there, which puts the scope in front of a
person. It still does not narrow variant B’s intent at the page, where the change landed. Whether it should is the question
Can distillation be made stable?
leaves open. This pair gives it a case where the instability comes from the structure of the
field, not from the distiller.
The brand lead’s decision can hide the divergence. A brand lead facing variant B’s wider conflict can choose variant A’s narrower exception, and then the two runs agree. They agree because a person chose, and a run with no person in it would not.
The leash does not change this, and neither does pre-approval. The leash checks each write against what the set stood under before the run, and both variants start from the same framework. Pre-approval only spares the brand lead a second ask in each. What differs is the intent each run hands the brand lead, and neither reads that.
What it tests
Section titled “What it tests”- Outputs against owned sets in one workflow. Ad copy is revised in place. A launch spends money, so strain on it clears only by a superseding launch.
- The leash on spend and on direction. Copy and pages that only add proceed on the criteria. A write that reverses what the framework allowed stops for the brand lead, and every launch waits for the performance marketer. The campaign has two approvers.
- Pre-approval that avoids asking one person twice. The brand lead decides the conflict and pre-approves the direction writes that follow, and leaves launches to the performance marketer. It is wider than a rule tied to what the decision removed.
- Selection that routes an
affected input to its owner.
{messaging}is affected and is creative production’s input, so the job is routed to campaign planning even though the change never touched a set it spans. - A sibling connection outside software. Message match relates two implementations of
{messaging}that the framework does not reach, as the component library’s API docs relate to its code. - Conflict against replacement. Variant A’s intent narrows the proposition without replacing it, so the two criteria stand together and conflict.
- Criteria that can only be evaluated in the world. Target cost per sign-up is a criterion
over the outcome, and the outcome needs spend. The inversion
treats the arriving change as a prediction and the criteria derived above it as the check.
For this criterion the arriving change is the only evidence, so
reconciliation keeps
it, and a new launch is held as obligation strain until
{campaign results}reports on it. - Scope inherited from the entry artifact. Variant B distils a wider intent because the page it landed on serves more channels, and each workflow’s span follows that structure rather than correcting it.
- Evidence no workflow reads.
{campaign results}holds the finding, and no workflow’s distillation, no controller asked, and no application of selection step 6 reach an unread set. - A set no workflow owns. Positioning is decided in
{brief}, which no workflow writes, so both variants reach it through a routed job, raise it as an obligation under step 6, and hand the conflict to a person. It is not the only way a person is reached. The leash stops the framework’s reversal too, and would stop a write to the brief if a workflow owned it. - The run ledger
and strain policy. Writes below
{messaging}wait while a person decides, because the team declared it, not because the ledger requires it. The recorded decision is where the strategy call is made, and it lands in the sets it affects. - Legal review is left out. Most campaigns clear claims through a review gate. This example folds that review into the substantiation criterion rather than modelling it as a workflow.