| name | brand-lint |
| description | DBA prevalence checker (Romaniuk ≥80%), banned-phrase + AI-slop + E-E-A-T scanner, GEO citation density check (≥1 citation per dollar amount, ≥1 statistic per H2). Runs as `pnpm brand:lint` for content data files. Used by Stage 5 Brand+Guardrail (binary pass/fail). |
| metadata | {"family":"ops","owner":"brand + content","last_reviewed":"2026-04-29T00:00:00.000Z","version":"1.0.0","related_skills":["marketing-foundations","content-review","ai-seo"],"kpis":["DBA prevalence ≥80% per asset (corpus-wide rolling scan)","100% of dollar amounts have inline citation","100% of H2 sections have ≥1 statistic","0 banned-phrase / AI-slop instances on shipped content"],"marketing_pillar":3,"seo_standard":"B","kpi_tier":3,"funnel_stage":"all","content_class":"all","maturity_stage":"descriptive","used_by_stages":[5]} |
Brand Lint
Per-page + corpus-wide brand asset enforcement. Runs as pnpm brand:lint / pnpm brand:lint:all.
When to Use
- Stage 5 Brand+Guardrail per-content-commit (binary pass/fail).
- Weekly corpus scan (DBA prevalence rolling check).
- Pre-merge gate via lefthook on PRs touching content data files.
Do Not Use When
- Need editorial scoring (the 6-dimension rubric) — use
content-review.
- Need editorial acceptance scoring — use
content-review.
Per-Page Checks (Stage 5 input)
For every modified content file, scan and pass/fail:
1. Banned phrases (BRAND.md)
- Reject any banned phrase from
nextjs-app/docs/BRAND.md banned-phrase registry.
- Examples: "best in the industry", "industry-leading", "revolutionary", "amazing", "game-changing".
2. AI-slop patterns
- Generic uncertainty ("studies show", "many experts agree") without named source.
- Listicles with vacuous bullets.
- "It's important to note that..." filler.
- Sentences starting with "Whether you're a..." (overused AI opening).
3. Citation density (GEO Pillar 1 — Aggarwal et al. KDD 2024)
- Scan body text for dollar amounts + percentages.
- For each: require an inline
(Source Year) citation OR adjacent DataSourceCitation component.
- Fail if
dollar_amounts > citations_count.
4. Statistic density per H2 (GEO Pillar 2)
- Parse content into H2 sections.
- For each H2: require ≥1 numeric statistic with unit/context.
- Fail if any H2 has 0 statistics.
5. Quotation requirement (GEO Pillar 3)
- For data-rich templates (role-page, comparison-page, original-research-page): require ≥1 quotation (worker testimonial, expert quote).
- Fail if 0 quotations on those templates.
6. Mandatory components per template
- AuthorByline present (DBA V2)?
- DataSourceCitation present where claims warrant (DBA V3)?
- ContentFreshness / "Last updated" visible (DBA V5)?
- FAQ-with-schema present (DBA S2)?
- InternalLinkHub present (DBA S4)?
- Contextual CTA present (DBA S5)?
7. Linguistic DBA enforcement
- L1: prefer "shifts" over "assignments"/"gigs" in non-technical sections (≥80% threshold per page)
- L2: "the app" over "the platform" in worker-facing copy
- L3: "Flexers" for community-context references
- L4: pay range first, then average
8. YMYL-specific (Pillar 3 financial + compliance)
- Reviewed-by line present?
- ≥3 Tier 1-2 citations per article (BLS / DOL / IRS / state agency)?
- Methodology link/callout?
Corpus-Wide Checks (Weekly via weekly-vital-loop)
For each DBA in marketing-foundations/reference/dbas.md:
prevalence = pages_with_dba / total_eligible_pages
- Pass:
prevalence ≥ 80% (Romaniuk threshold)
- Warn:
prevalence ≥ 60% and trending down
- Fail (corpus-wide warning to brand team):
prevalence < 60%
Per-DBA targets at marketing-foundations/reference/excellence-targets.md Pillar 3 table.
Output Contract
Per-page (Stage 5 input)
Pass/fail JSON + markdown summary:
file: <path>
status: pass | fail
blocking_issues:
- type: missing_citation | banned_phrase | ai_slop | missing_dba | etc
line: <number>
text: <quoted snippet>
rule: <rule reference>
fix: <suggested fix>
warnings:
- <similar shape, non-blocking>
If status: fail, Stage 5 posts Slack APPROVAL gate per PIPELINE.md.
Corpus-wide (weekly)
Markdown at nextjs-app/docs/reports/<date>/brand-lint-corpus.md:
## Brand-Lint Corpus Scan — <date>
### DBA Prevalence
| DBA | Eligible pages | Pages with DBA | Prevalence | Status |
|---|---|---|---|---|
| V1 Flex Pink | 1560 | 1480 | 95% | PASS |
| V2 AuthorByline | 870 | 845 | 97% | PASS |
| V3 DataSourceCitation | 920 | 880 | 96% | PASS |
| ... | ... | ... | ... | ... |
### Trends (4-week rolling)
- <DBA>: trending up/down/flat
### Action Items
- (none) / surface as Stage 6 template-update opportunity for next Discovery
Implementation
Runs as pnpm brand:lint. Intended for pre-push use on any change to:
nextjs-app/src/features/*/data/**/*.ts
nextjs-app/src/lib/data/articles/**/*.ts
nextjs-app/src/lib/data/cities/**/*.ts
- Other content data files
Pre-push: per-page check on changed files. Weekly cron-equivalent via weekly-vital-loop: corpus-wide scan.
References