Layered Enforcement

⬇ Download this section

Scope: This page defines the conceptual model and implementation contract for layered style guidance enforcement across McClatchy CSA. It is the human-readable companion to the machine-readable artifacts at _data/rules/schema.yaml, _data/rules/precedence.yaml, and _data/rules/conflict-register.yaml. Engineering ingests the machine-readable files; humans (editors + product) work from this page.


11.1 The Four-Layer Model

Style guidance lives in four layers, each more specific than the last. When two layers say different things, the lower (more specific) layer wins.

Layer Rank What it covers Where it lives
General 1 (lowest) Universal rules across all McClatchy content. AP-Compatible is the default backbone §1 General Guidelines · §2 Headlines · §6 Publishing Guidelines · §10.6 AP-Compatible
Persona 2 Audience-specific overrides §4 Personas (Discover Browser, Curious Optimizer, Watercooler Insider, Curious Explorer, Wonder-Driven Science Enthusiast)
Article Format 3 Format-specific overrides §3 Article Formats (Everything to Know, FAQ, What to Know Next; pending: Recipe, Timeline, Interview, Recap, Fan Theory / Fan Question, Obituary, Couple / Baby, Cast Introduction / Update; retired: Discover Explainer)
Platform 4 (highest) Distribution-platform + per-publication overrides §10 Platform Guidance (SmartNews, Apple News, Us Weekly, Trend Hunter B2C, Woman’s World, AP-Compatible)

Default precedence (highest first): [platform, format, persona, general]. A rule may redefine its precedence—e.g., system-wide compliance rules use precedence: [general] to indicate that no override is allowed.


11.2 How a Rule Resolves

For a piece of content with attributes { persona, format, platform }:

  1. Walk the rule’s overrides array in precedence order, highest layer first
  2. The first override whose selector matches the content’s attributes wins
  3. If no override matches at any layer, the rule’s default.value applies
  4. If two overrides at the same precedence layer both match, apply tie-breakers (most-specific selector → most-recent introduction → data-validated wins → editor resolution)

The full algorithm is in _data/rules/precedence.yaml.


11.3 Worked Examples

Example 1—Em dash spacing on a Woman’s World piece

Rule: punctuation.em_dash_surrounding_spaces (boolean)

Layer Value Source
General true (spaces on both sides—AP standard) docs/ap-compatible-quick.md + docs/ap-compatible-condensed.md (Em Dash)
Persona (no override)
Format (everything-to-know) (no override)
Platform (womans-world) false (no spaces; AMI house-style deviation from AP) docs/womans-world.md §10.5

Resolution: the platform override matches → em dashes have no spaces for this piece. (USW restates the AP default explicitly with kind: restate; only WW deviates.)


Example 2—Couples-verb agreement on a Woman’s World cast piece

Rule: grammar.couple_verb_agreement (enum: singular plural)
Layer Value Source
General singular (AP collective-noun treatment) docs/ap-compatible-condensed.md
Persona (no override)
Format (cast) (no override)
Platform (womans-world) singular (AMI default; mashups always plural) docs/womans-world.md §10.5

Resolution: platform override matches but does not change the value → couples take singular verbs. The override is restated for clarity (Woman’s World is the AMI default; Us Weekly is the AMI exception that flips to plural).


Example 3—Headline character count on an FAQ for the Curious Optimizer published to Apple News

Rule: headline.char_count (range)

Layer Value Source
General 80–100 docs/brand-guidelines.md §1.2
Persona (curious-optimizer) (no override)
Format (faq) (no override)
Platform (apple-news) 90–120 (sweet spot 110–119, data-validated) docs/platform-apple-news.md §10.2

Resolution: platform override matches → 90–120 characters, target 110–119. Even though the content is also an FAQ for the Curious Optimizer, no rule at those layers contradicts the platform’s range.


Example 4—Headline char count on an Everything-to-Know with no platform specified

Rule: headline.char_count (range)

Layer Value Source
General 80–100 docs/brand-guidelines.md §1.2
Persona (no override)
Format (everything-to-know) 80–150 docs/everything-to-know.md
Platform (no destination yet)

Resolution: no platform override applies → format override matches → 80–150 characters. ETK heds may run longer than the universal default.


Example 5—Word “God” in a Woman’s World recipe piece

Rule: faith.god_word_permitted (enum)

Layer Value Source
General editorial-judgment (no general guidance)
Persona (no override)
Format (recipe) (no override)
Platform (womans-world) permitted-only-in-faith-pieces docs/womans-world.md §10.5

Resolution: platform override applies. Critical clause: “Apply faith-related guidelines only when content is explicitly about faith. Never force faith themes into unrelated content.” A recipe is not a faith piece → “God” is not used here despite WW permitting it elsewhere.


Example 6—Three layers all weigh in on a constraint

A Trend Hunter B2C piece in the FAQ format targeting the Curious Optimizer persona, distributed via Apple News:

Rule General Persona Format Platform Resolution
voice.audience_framing either psychographic-only (none) psychographic-only psychographic-only (persona + platform agree; either alone would resolve the rule)
headline.char_count 80–100 (none) (none) 90–120 (apple-news) 90–120 (platform wins)
body.faq_block_word_count (none) (none) 100–200 words (none) 100–200 words (format adds; no other layer addresses it)
voice.banned_slang (none) (none) (none) TH B2C: [slay, bestie, vibes] banned list applies (additive)

This is the typical case—different rules resolve at different layers, none of which conflict. The architecture is designed so layers stack without erasing each other unless they intentionally override.


11.4 Override Kinds

A rule’s per-layer override can be one of three kinds:

Kind Meaning Example
override Layer changes the value already set at a higher (lower-rank) layer USW flips couples-verb from singularplural
additive No higher-layer value exists; the layer introduces a constraint FAQ format adds body.faq_block_word_count: 100–200 (no general rule)
restriction Layer narrows the scope of an existing rule Apple News adds AI-disclosure requirements on top of the general AI disclosure

A value: null on an override means “this layer removes the rule entirely.” Used rarely—see §1.8.1 retraction of the 80–120 word intro rule for the pattern.


11.5 Reconciliation with the CSA Backend (current state vs editorial model)

There is an important conceptual gap between the editorial model described above (lower layer overrides higher layer on conflict) and the CSA backend’s current implementation (all layers stack; no override semantics). Engineering’s own documentation makes this explicit.

Per the CSA engineering Confluence page “How Style Guides Work” (PGS space, page 1949663238, last updated 2026-05-05):

“Style guides are composed in four stacked layers—none override each other, they all stack together”

This is the load-bearing sentence. The current implementation is stacking, not overriding. Whatever each layer contributes is concatenated into the prompt; conflicts are left for the LLM to reconcile at runtime, non-deterministically.

CSA Engineering’s Current Trust Hierarchy

Layer Trust Level What It Is Example
0 Constitution Journalism ethics—always present, never overridden Quote integrity, no hallucination
1 Quality Content quality standards—always present AP style, anti-slop rules
2 Voice Platform + organization voice guides Woman’s World tone, Charlotte Observer brand voice
3 Editorial Per-article editor notes “Lead with the economic angle”

How CSA Currently Resolves Style Guides for a Piece

Per the same Confluence page, three inputs determine which guides get loaded for a given draft—and all three contribute independently to Layer 2 stacking:

  1. Email domain (indirect)—the user’s email maps to an organization at login (e.g., @usmagazine.com → US Weekly org). The org ID drives which Layer 2 organization voice guides load
  2. Assigned organization (direct)—admin can override a user’s org assignment via the admin panel (e.g., Jane at @usmagazine.com manually assigned to Woman’s World). Email-level override always wins over domain-level
  3. Platform Distribution step (direct)—when a writer selects a platform formatter (Local News, Woman’s World, US Weekly, etc.), that platform name drives which Layer 2 platform voice guides load

The org-assignment and platform-selection inputs are independent. Org override changes which org-voice guides load; platform selection changes which platform-voice guides load. Both Layer 2 sub-stacks load simultaneously, and engineering acknowledges they can conflict—e.g., Jane gets assigned to Woman’s World but selects US Weekly in Platform Distribution → she gets WW org voice AND USW platform voice in the same prompt.

Where Editorial Model and Current Implementation Diverge

Editorial concept Where in editorial model Where in CSA backend today Implementation gap
Universal rules Layer 1 (General) L0 Constitution + L1 Quality maps cleanly
Audience persona Layer 2 (Persona) not modeled—no persona-specific guide loading gap—Persona is editorial-side only
Article format Layer 3 (Format) not modeled—style_guide field exists in code per Confluence but is “informational only and is NOT currently used to apply style guides automatically” gap—Format is editorial-side only
Platform / publication Layer 4 (Platform) L2 Voice (platform sub-stack + org sub-stack, both load) exists but stacks rather than overrides
Per-piece direction not in editorial model L3 Editorial exists; orthogonal to the layered model
Conflict resolution semantics Lower layer overrides higher No override; all layers stack fundamental semantic gap

National Team Gap (from same Confluence page)

A @mcclatchy.com user creating content for multiple publications has a specific problem in the current system:

This is a real gap engineering has named. The layered enforcement register described on this page closes that gap—it makes Persona, Format, and Platform first-class layers, regardless of how the user reached the content.

Proposed Composer Extension

To honor the editorial 4-layer hierarchy, the Composer should walk:

  1. L0 Constitution (inviolable; rules with precedence: [general] and empty overrides)
  2. L1 Quality + General Guidance (the rule defaults—default.value)
  3. Persona (from CSA Target Audience selection at draft time—overrides matching selector: { persona: ... })
  4. Article Format (from Format selector at draft time—overrides matching selector: { format: ... })
  5. Platform / Publication (from destination + Platform Distribution selection—overrides matching selector: { platform: ... } or { publication: ... })

For each rule, the precedence-resolution algorithm in _data/rules/precedence.yaml returns the effective value for the piece. The Composer assembles the prompt using only resolved values—not by stacking every layer’s text verbatim. Verbatim-stacking contradictory rules is the failure mode the register exists to prevent.

This proposal asks engineering to add override semantics to Layer 2 (and to promote Persona + Format to first-class layers). The current “all stack, none override” approach leaves the LLM to reconcile conflicts at runtime, and its resolution is non-deterministic: a piece run twice can resolve the same conflict differently. Override semantics, executed at composition time, eliminate that variance.

How CSA Selects the AP Tier

Engineering’s audit doc (style-guides-for-pierce-audit.md, 2026-05-08) confirms the CSA Composer automatically selects which AP-Compatible tier to load based on content type:

Content type AP tier loaded Token cost
Breaking news / high-volume batch Quick ~2K
Most situations (default) Condensed ~12K
Investigative / features / in-depth analysis Thorough ~25K

This means the AP-Compatible page hierarchy in §10.6 maps directly to a runtime decision: pick the tier that matches the content type. The Quick / Condensed / Thorough split is a token-economy decision the Composer makes per piece, not an editorial preference. AP applies to all platforms (it’s the always-on Layer 1 quality backbone underneath every Layer 2 voice guide), but only one tier is loaded at a time.

Implementation Routing

Each rule’s enforcement_target field tells engineering where the rule applies:


11.6 What Engineering Receives

When CSA engineering ingests the layered enforcement system, they receive:

Three machine-readable files (canonical)

File Purpose
_data/rules/schema.yaml Defines what a rule entry looks like
_data/rules/precedence.yaml Defines the resolution algorithm + tie-breakers + Composer extension proposal
_data/rules/conflict-register.yaml Every known cross-layer rule + its overrides

All three are downloadable from the same-origin Cloudflare-Access-gated /assets/sources/rules/ path (see build-downloads.sh for the publishing mechanism).

Two human-readable docs (companion)

Page Purpose
Layered Enforcement (this page) Conceptual model + worked examples + reconciliation with CSA backend Trust Hierarchy
Conflict Register (human view) Every rule + its overrides, formatted as readable Markdown tables

11.7 What This Doesn’t Solve (Yet)


11.8 Maintenance Protocol

When a new rule is established or an existing rule changes:

  1. Author or update the canonical doc page (e.g., docs/<format>.md, docs/<platform>.md)
  2. Add or update the rule entry in _data/rules/conflict-register.yaml with the appropriate default and overrides
  3. Update the human-readable twin at docs/conflict-register.md (hand-maintained mirror in v1.0)
  4. Bump csa-content-standards version + add changelog entry
  5. Re-run scripts/build-downloads.sh to regenerate downloadable copies in assets/sources/ and assets/rules/
  6. CSA engineering pulls the updated YAML on next ingest cycle

11.9 Reference Hierarchy

When this guide doesn’t address an enforcement question, defer in order:

  1. The relevant doc page (e.g., docs/<format>.md or docs/<platform>.md)
  2. _data/rules/conflict-register.yaml for the resolved value
  3. _data/rules/precedence.yaml for resolution semantics
  4. _data/rules/schema.yaml for structural questions about the rule entry shape
  5. CSA backend backend/style_guides/README.md for the Trust Hierarchy + Composer behavior
  6. docs/ap-compatible.md for the underlying journalism standard