A
?
← Handbook

Ad naming

Atlas's naming was, in Alex's words, "anyhow". Two real names from one account show why that cost something concrete:

AM - ASC - Tailored Tee IMG GRP 3     AM = Atlas Media  → a producer
ND - ASC - STATICV1                   ND = National Day → a season

Both occupy the first slot and they are not the same kind of thing. That single ambiguity is why the question "did our creative beat the client's?" could not be answered — the marker meant producer sometimes and theme other times. And every ND ad sits inside a campaign already called *National Day Campaign*, so the prefix spends the most valuable characters in the name repeating something the platform already groups by.

Each level says what only it can say

Level Carries Example
Campaignobjective, season, promotionNational Day Campaign
Ad settargetingMid-Target
Adthe creative itselfATL-A7K2-VID-v1

Nothing is repeated downward. A season in an ad name is a wasted field: the campaign already carries it and the join is free.

The ad name

TES_the-loan-doesnt-pause_TOF-fear_confront_v1_2608_ATL_M47Q
│   │                     │        │        │  │    │   └── angle code
│   │                     │        │        │  │    └────── producer
│   │                     │        │        │  └─────────── launch month (YYMM)
│   │                     │        │        └────────────── iteration
│   │                     │        └─────────────────────── hook type
│   │                     └──────────────────────────────── stage + mechanism — the goal
│   └────────────────────────────────────────────────────── the argument, in words
└────────────────────────────────────────────────────────── format

The name is an analytics substrate, not a label. Alex's framing, which is the one that decides the design: *"so that when you parse you can know what creative strategy to go forward with without having to view the creative and analyse — you can just see the name and know, oh, testimonials did well."*

So it carries every axis the creative strategy actually varies on. Length is close to free because the portal generates the name and a person copies it — nobody composes one, so an extra field costs a wider column rather than a harder job.

Format leads so that sorting by name in Ads Manager groups by format, which makes "testimonials did well" visible without a query. The angle sits immediately after, so both survive a truncated column.

Field Values Why it is here
formatSTA VID CAR REE UGC TES LNGTestimonial and long-form static are their own formats, not flavours of video and image — they persuade differently
anglefree slug, capped at 28 chars on a word boundaryThe argument, readable. Articles are kept: a slugifier that silently edits meaning is worse than a verbose one
stage-mechanismTOF MOF BOF × the mechanism taxonomyThe goal. Same vocabulary as the gap report and the generator, deliberately — a parallel vocabulary is how results stop grouping against the decisions that produced them
hookfrom the library in skills/script-crafth2 records that a hook changed; this records what to
iterationv2 new execution · h2 new hook onlyWithout the split, replication / iteration / net-new cannot be measured
launchedYYMMThe only field recording how old an asset is. Every other date says when an ad *ran*, and fatigue is a function of age
producerATL CLI EXTAnswers whether our work earns its fee
code4 chars, alphabet excludes I O 0 1Resolves to persona, offer, full argument. Typed by hand, and a misread code attributes to the wrong idea

Checked against industry practice

The shape agrees with what is broadly recommended: underscores as delimiters, no spaces, version numbers, each level progressively more specific, and a written guide everyone follows. Two fields were added *because* of that check — hook type and launch month are what teams add once they test at volume, and both answer something nothing else in the system can.

Three commonly-recommended fields are deliberately absent:

  • Platform. Already a column on the result, and repeating it downward is exactly the error ND made.
  • Aspect ratio. Real for placement analysis, not yet a decision Atlas varies on.
  • Language and market. Singapore, countrywide. The same guidance warns against cramming the string, and these would be constants.

What the name does not carry, and why

Persona and offer are sentences, not slugs. Including them would double the length to duplicate what the database already holds against the code. The name summarises; the code resolves.

Legacy names are never renamed

Decided, not deferred. Renaming a live ad breaks the join between the old name and the results already recorded against it, and buys nothing — the angle is the one field a rename cannot supply anyway, since no name implies which argument an ad was making.

So the estate is permanently mixed, and that has a consequence worth stating: a share of spend can never be attributed to an angle, and it is not a gap. lineageCoverage therefore measures attributed over attributable rather than over total, and reports legacy spend separately as closed. Measuring against total would produce a number that can never reach 100%, and a metric that cannot be satisfied is one people stop reading.

Three categories, and they need different responses:

Meaning Response
AttributedNamed under the convention, code resolvedNothing — working
Attributable, unlinkedNamed correctly, code points at no angle we holdChase it; something is wrong
LegacyPredates the conventionClosed. Leave it

Where the convention is absent the old prefix inference still runs, so a legacy name keeps whatever signal it has rather than losing it.